Skip to content
Snippets Groups Projects
Commit 0f22af4d authored by Ishan Kiritbhai Vyas's avatar Ishan Kiritbhai Vyas Committed by Edward Moyse
Browse files

R4 sTGC Geometry - Adding Pad Readout Element

Adding basic pad dimensions to geometry tool and readoutElement. temporarily using the wiredesignptr to build the pads. Changing wireGrouplayer active area dimensions to match the R3 implementation, using padWidth instead of stripWidth
parent 68baf4f6
No related branches found
No related tags found
No related merge requests found
Showing
with 978 additions and 195 deletions
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "GeoModelsTgcTest.h"
......@@ -110,8 +110,6 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
const Identifier genPadID =id_helper.channelID(stIndex, stEta, stPhi,
stML, 1, sTgcIdHelper::sTgcChannelTypes::Pad, 1);
//// Chamber Details from sTGCDetectorDescription
int numLayers = readoutEle->numberOfLayers(true);
double yCutout = readoutEle->getDesign(genStripID)->yCutout();
......@@ -125,9 +123,15 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
double lGapLength = readoutEle->getDesign(genStripID)->maxYSize();
double gapHeight = readoutEle->getDesign(genStripID)->xSize();
double sPadLength = readoutEle->getPadDesign(genPadID)->sPadWidth;
double lPadLength = readoutEle->getPadDesign(genPadID)->lPadWidth;
m_sGapLength = sGapLength;
m_lGapLength = lGapLength;
m_gapHeight = gapHeight;
m_sPadLength = sPadLength;
m_lPadLength = lPadLength;
//// Chamber lengths for debug
double sChamberLength = readoutEle->getPadDesign(genPadID)->sWidth;
double lChamberLength = readoutEle->getPadDesign(genPadID)->lWidth;
......@@ -147,8 +151,8 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
stML, lay, sTgcIdHelper::sTgcChannelTypes::Wire, 1);
const Identifier layStripID =id_helper.channelID(stIndex, stEta, stPhi,
stML, lay, sTgcIdHelper::sTgcChannelTypes::Strip, 1);
// const Identifier layPadID =id_helper.channelID(stIndex, stEta, stPhi,
// stML, lay, sTgcIdHelper::sTgcChannelTypes::Pad, 1);
const Identifier layPadID =id_helper.padID(stIndex, stEta, stPhi,
stML, lay, sTgcIdHelper::sTgcChannelTypes::Pad, 1, 1);
//// Wire Dimensions
unsigned int numWires = readoutEle->numberOfWires(layWireID);
......@@ -225,16 +229,28 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
m_stripRot.push_back(locToGlob);
m_stripRotGasGap.push_back(lay);
}
/*
////Pad Dimensions
int numPads = readoutEle->numberOfPads(layPadID);
unsigned int numPads = readoutEle->numberOfPads(layPadID);
int numPadEta = readoutEle->getPadDesign(layPadID)->nPadH;
int numPadPhi = readoutEle->getPadDesign(layPadID)->nPadColumns;
double firstPadHeight = readoutEle->getPadDesign(layPadID)->firstRowPos;
double padHeight = readoutEle->getPadDesign(layPadID)->inputRowPitch;
double padPhiShift = readoutEle->getPadDesign(layPadID)->PadPhiShift;
double firstPadPhiDiv = readoutEle->getPadDesign(layPadID)->firstPhiPos;
double anglePadPhi = readoutEle->getPadDesign(layPadID)->inputPhiPitch;
double beamlineRadius = readoutEle->getPadDesign(layPadID)->radialDistance;
m_numPads.push_back(numPads);
m_numPadEta.push_back(numPadEta);
m_numPadPhi.push_back(numPadPhi);
m_firstPadHeight.push_back(firstPadHeight);
m_padHeight.push_back(padHeight);
m_padPhiShift.push_back(padPhiShift);
m_firstPadPhiDiv.push_back(firstPadPhiDiv);
m_anglePadPhi = anglePadPhi;
m_beamlineRadius = beamlineRadius;
//// Global transformations for pads
for (int phiIndex = 1; phiIndex <= numPadPhi; ++phiIndex) {
for(int etaIndex = 1; etaIndex <= numPadEta; ++etaIndex) {
......@@ -244,25 +260,38 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
if(!isValid) {
ATH_MSG_WARNING("The following pad ID is not valid: " << padID);
}
Amg::Vector3D padPos(Amg::Vector3D::Zero());
std::array<Amg::Vector3D,4> padCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
Amg::Vector2D localPadPos(Amg::Vector2D::Zero());
Amg::Vector3D globalPadPos(Amg::Vector3D::Zero());
std::array<Amg::Vector2D,4> localPadCorners{make_array<Amg::Vector2D, 4>(Amg::Vector2D::Zero())};
std::array<Amg::Vector3D,4> globalPadCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
readoutEle->padPosition(padID, localPadPos);
readoutEle->padGlobalPosition(padID, globalPadPos);
readoutEle->padCorners(padID, localPadCorners);
readoutEle->padGlobalCorners(padID, globalPadCorners);
readoutEle->padGlobalPosition(padID, padPos);
readoutEle->padGlobalCorners(padID, padCorners);
m_localPadPos.push_back(localPadPos);
m_localPadCornerBL.push_back(localPadCorners[0]);
m_localPadCornerBR.push_back(localPadCorners[1]);
m_localPadCornerTL.push_back(localPadCorners[2]);
m_localPadCornerTR.push_back(localPadCorners[3]);
m_globalPadPos.push_back(padPos);
m_globalPadCornerBR.push_back(padCorners[0]);
m_globalPadCornerBL.push_back(padCorners[1]);
m_globalPadCornerTR.push_back(padCorners[2]);
m_globalPadCornerTL.push_back(padCorners[3]);
m_globalPadPos.push_back(globalPadPos);
m_globalPadCornerBR.push_back(globalPadCorners[0]);
m_globalPadCornerBL.push_back(globalPadCorners[1]);
m_globalPadCornerTR.push_back(globalPadCorners[2]);
m_globalPadCornerTL.push_back(globalPadCorners[3]);
m_padEta.push_back(etaIndex);
m_padPhi.push_back(phiIndex);
m_padGasGap.push_back(lay);
}
if (etaIndex != 1 || phiIndex != 1) continue;
const Amg::Transform3D locToGlob = readoutEle->transform(padID);
m_padRot.push_back(locToGlob);
m_padRotGasGap.push_back(lay);
}
}
*/
}
return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
......
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONGEOMODELTESTR4_GEOMODELSTGCTEST_H
#define MUONGEOMODELTESTR4_GEOMODELSTGCTEST_H
......@@ -81,6 +81,10 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm {
MuonVal::CoordSystemsBranch m_wireGroupRot{m_tree, "wireGroupRot"};
MuonVal::VectorBranch<uint8_t>& m_wireGroupRotGasGap{m_tree.newVector<uint8_t>("wireGroupRotGasGap")};
/// Rotation matrix of the respective pad layers
MuonVal::CoordSystemsBranch m_padRot{m_tree, "padRot"};
MuonVal::VectorBranch<uint8_t>& m_padRotGasGap{m_tree.newVector<uint8_t>("padRotGasGap")};
//// Wire Dimensions
MuonVal::VectorBranch<uint>& m_numWires{m_tree.newVector<uint>("numWires")}; // nWires
MuonVal::VectorBranch<uint>& m_firstWireGroupWidth{m_tree.newVector<uint>("firstWireGroupWidth")}; // firstWireGroup <= 20
......@@ -104,21 +108,35 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm {
MuonVal::VectorBranch<uint>& m_stripNum{m_tree.newVector<uint>("stripNumber")}; // strip number
MuonVal::VectorBranch<uint8_t>& m_stripGasGap{m_tree.newVector<uint8_t>("stripGasGap")}; // gas gap number
MuonVal::VectorBranch<float>& m_stripLengths{m_tree.newVector<float>("stripLengths")}; // Length of each strip
/*
/// Pad dimensions
MuonVal::VectorBranch<uint>& m_numPads{m_tree.newVector<uint>("numPads")};
MuonVal::VectorBranch<uint>& m_numPads{m_tree.newVector<uint>("numPads")}; //total number of pads in a layer
MuonVal::ScalarBranch<float>& m_sPadLength{m_tree.newScalar<float>("sPadLength")}; // sPadWidth
MuonVal::ScalarBranch<float>& m_lPadLength{m_tree.newScalar<float>("lPadLength")}; // lPadWidth
MuonVal::VectorBranch<uint>& m_numPadEta{m_tree.newVector<uint>("numPadEta")}; //nPadH
MuonVal::VectorBranch<uint>& m_numPadPhi{m_tree.newVector<uint>("numPadPhi")}; //nPadPhi
MuonVal::VectorBranch<float>& m_firstPadHeight{m_tree.newVector<float>("firstPadHeight")}; //firstPadH
MuonVal::VectorBranch<float>& m_padHeight{m_tree.newVector<float>("padHeight")}; //PadH
MuonVal::VectorBranch<float>& m_padPhiShift{m_tree.newVector<float>("padPhiShift")}; //PadPhiShift_A
MuonVal::VectorBranch<float>& m_firstPadPhiDiv{m_tree.newVector<float>("firstPadPhiDiv")}; //firstPadPhiDivision_A
MuonVal::ScalarBranch<float>& m_anglePadPhi{m_tree.newScalar<float>("anglePadPhi")}; // anglePadPhi
MuonVal::ScalarBranch<float>& m_beamlineRadius{m_tree.newScalar<float>("beamlineRadius")};
MuonVal::TwoVectorBranch m_localPadPos{m_tree, "localPadPos"};
MuonVal::TwoVectorBranch m_localPadCornerBR{m_tree, "localPadCornerBR"};
MuonVal::TwoVectorBranch m_localPadCornerBL{m_tree, "localPadCornerBL"};
MuonVal::TwoVectorBranch m_localPadCornerTR{m_tree, "localPadCornerTR"};
MuonVal::TwoVectorBranch m_localPadCornerTL{m_tree, "localPadCornerTL"};
MuonVal::ThreeVectorBranch m_globalPadPos{m_tree, "globalPadPos"};
MuonVal::ThreeVectorBranch m_globalPadCornerBR{m_tree, "globalPadCornerBR"};
MuonVal::ThreeVectorBranch m_globalPadCornerBL{m_tree, "globalPadCornerBL"};
MuonVal::ThreeVectorBranch m_globalPadCornerTR{m_tree, "globalPadCornerTR"};
MuonVal::ThreeVectorBranch m_globalPadCornerTL{m_tree, "globalPadCornerTL"};
MuonVal::ThreeVectorBranch m_globalPadPos{m_tree, "globalPadPos"};
MuonVal::VectorBranch<uint8_t>& m_padGasGap{m_tree.newVector<uint8_t>("padGasGap")}; // gas gap number
MuonVal::VectorBranch<uint>& m_padEta{m_tree.newVector<uint>("padEtaNumber")}; // pad number in eta direction
MuonVal::VectorBranch<uint>& m_padPhi{m_tree.newVector<uint>("padPhiNumber")}; // pad number in phi direction
*/
};
}
......
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONGEOMODELR4_STGCREAOUDGEOMTOOL_H
......@@ -59,21 +59,13 @@ class sTgcReadoutGeomTool : public AthAlgTool,
std::vector<int> numPadPhi; //nPadPhi
std::vector<double> firstPadHeight; //firstPadH
std::vector<double> padHeight; //padH
///Extra Pad Variables
std::vector<int> PadPhiShift;
double anglePadPhi{0.};
std::vector<double> firstPadPhiDivision;
std::vector<int> firstPadRow;
double lPadWidth{0.};
std::vector<int> rankPadEta; //rankPadH
std::vector<int> rankPadPhi; //rankPadPhi
double sPadWidth{0.};
double lPadLength{0.};
double sPadLength{0.};
double gasTck{0.}; //gasTck
};
struct FactoryCache {
......@@ -83,10 +75,10 @@ class sTgcReadoutGeomTool : public AthAlgTool,
std::set<StripDesignPtr, StripDesignSorter> stripDesigns{};
std::set<WireDesignPtr, WireDesignSorter> wireGroupDesigns{};
std::set<PadDesignPtr, PadDesignSorter> padDesigns{};
ParamBookTable parameterBook{};
CutOutTable cutOuts{};
};
/// Helper struct to translate the GeoModelShape into the parameters
......@@ -110,7 +102,6 @@ class sTgcReadoutGeomTool : public AthAlgTool,
StatusCode readParameterBook(FactoryCache& cache);
/// Loads the chamber dimensions from GeoModel
StatusCode loadDimensions(sTgcReadoutElement::defineArgs& args, FactoryCache& factory);
};
} // namespace MuonGMR4
......
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include <MuonGeoModelR4/sTgcReadoutGeomTool.h>
......@@ -67,7 +67,6 @@ sTgcReadoutGeomTool::sTgcShape sTgcReadoutGeomTool::extractParameters(const GeoS
return result;
}
StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& define, FactoryCache& factoryCache) {
ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
<<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
......@@ -115,6 +114,7 @@ StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& d
for (physVolWithTrans& gapVol : allGasGaps) {
StripDesignPtr stripDesign = std::make_unique<StripDesign>();
WireDesignPtr wireGroupDesign = std::make_unique<WireGroupDesign>();
PadDesignPtr padDesign = std::make_unique<PadDesign>();
sTgcShape gapPars = extractParameters(m_geoUtilTool->extractShape(gapVol.volume));
......@@ -129,7 +129,7 @@ StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& d
ATH_MSG_VERBOSE("Created new strip design "<<(*stripDesign));
//WireGroupDesign
wireGroupDesign->defineTrapezoid(gapPars.shortWidth, gapPars.longWidth, gapPars.halfHeight);
wireGroupDesign->defineTrapezoid(0.5*paramBook.sPadLength, 0.5*paramBook.lPadLength, gapPars.halfHeight);
wireGroupDesign->flipTrapezoid();
unsigned int numWireGroups = paramBook.numWireGroups[gasGap];
/// Placing wires in the designated wireGroups for easy retrieval later, first and last are placed separately.
......@@ -146,23 +146,45 @@ StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& d
paramBook.wirePitch,
paramBook.wireWidth,
numWireGroups);
wireGroupDesign->defineWireCutout(paramBook.wireCutout[gasGap]);
//PadDesign
padDesign->defineTrapezoid(0.5*paramBook.sPadLength, 0.5*paramBook.lPadLength, gapPars.halfHeight);
padDesign->flipTrapezoid();
padDesign->definePadRow(paramBook.firstPadPhiDivision[gasGap],
paramBook.numPadPhi[gasGap],
paramBook.anglePadPhi,
paramBook.PadPhiShift[gasGap]);
padDesign->definePadColumn(paramBook.firstPadHeight[gasGap],
paramBook.numPadEta[gasGap],
paramBook.padHeight[gasGap]);
}
/// Stacking strip and wireGroup layers
++gasGap;
/// Stacking strip, wireGroup and pad layers
++gasGap;
///wireGroups
wireGroupDesign = (*factoryCache.wireGroupDesigns.emplace(wireGroupDesign).first);
StripLayer wireGroupLayer(gapVol.transform * Amg::getRotateY3D(180* Gaudi::Units::deg), wireGroupDesign, sTgcReadoutElement::createHash(gasGap, sTgcIdHelper::Wire, 0));
ATH_MSG_VERBOSE("Added new wireGroup layer at "<<wireGroupLayer);
define.wireGroupLayers.push_back(std::move(wireGroupLayer));
if(!define.wireGroupDesign) define.wireGroupDesign = wireGroupDesign;
///Strips
stripDesign = (*factoryCache.stripDesigns.emplace(stripDesign).first);
StripLayer stripLayer(gapVol.transform * Amg::getRotateZ3D(-90. * Gaudi::Units::deg) *
Amg::getRotateY3D(180* Gaudi::Units::deg), stripDesign,
sTgcReadoutElement::createHash(gasGap, sTgcIdHelper::Strip, 0));
ATH_MSG_VERBOSE("Added new strip layer at "<< stripLayer);
define.stripLayers.push_back(std::move(stripLayer));
if (!define.stripDesign) define.stripDesign = stripDesign;
if (!define.stripDesign) define.stripDesign = stripDesign;
///Pads
double beamlineRadius = define.physVol->getAbsoluteTransform().translation().perp();
padDesign->defineBeamlineRadius(beamlineRadius);
ATH_MSG_DEBUG("The beamline radius is: " << beamlineRadius);
StripLayer padLayer(gapVol.transform * Amg::getRotateY3D(180* Gaudi::Units::deg), padDesign, sTgcReadoutElement::createHash(gasGap, sTgcIdHelper::Pad, 0));
ATH_MSG_VERBOSE("Added new pad layer at "<<padLayer);
define.padLayers.push_back(std::move(padLayer));
if(!define.padDesign) define.padDesign = padDesign;
}
return StatusCode::SUCCESS;
}
......@@ -259,19 +281,15 @@ StatusCode sTgcReadoutGeomTool::readParameterBook(FactoryCache& cache) {
parBook.numPadPhi = tokenizeInt(record->getString("nPadPhi"), ";");
parBook.firstPadHeight = tokenizeDouble(record->getString("firstPadH"), ";");
parBook.padHeight = tokenizeDouble(record->getString("padH"), ";");
///Extra Pad Variables
parBook.PadPhiShift = tokenizeInt(record->getString("PadPhiShift"), ";");
parBook.anglePadPhi = record->getDouble("anglePadPhi");
parBook.firstPadPhiDivision = tokenizeDouble(record->getString("firstPadPhiDivision"), ";");
parBook.firstPadRow = tokenizeInt(record->getString("firstPadRow"), ";");
parBook.lPadWidth = record->getDouble("lPadWidth");
parBook.rankPadEta = tokenizeInt(record->getString("rankPadH"), ";");
parBook.rankPadPhi = tokenizeInt(record->getString("rankPadPhi"), ";");
parBook.sPadWidth = record->getDouble("sPadWidth");
parBook.lPadLength = record->getDouble("lPadWidth");
parBook.sPadLength = record->getDouble("sPadWidth");
parBook.gasTck = record->getDouble("gasTck");
ATH_MSG_DEBUG("Parameters of the chamber " << key << " are: "
ATH_MSG_ALWAYS("Parameters of the chamber " << key << " are: "
<< " numStrips: " << parBook.numStrips
<< " stripPitch: " << parBook.stripPitch
<< " stripWidth: " << parBook.stripWidth
......@@ -288,16 +306,11 @@ StatusCode sTgcReadoutGeomTool::readParameterBook(FactoryCache& cache) {
<< " Pads in Phi: " << parBook.numPadPhi
<< " firstPadHeight: " << parBook.firstPadHeight
<< " padHeight: " << parBook.padHeight
///ExtraPadVariables
<< " PadPhiShift: " << parBook.PadPhiShift
<< " anglePadPhi: " << parBook.anglePadPhi
<< " firstPadPhiDivision: " << parBook.firstPadPhiDivision
<< " firstPadRow: " << parBook.firstPadRow
<< " lPadWidth: " << parBook.lPadWidth
<< " rankPadEta: " << parBook.rankPadEta
<< " rankPadPhi: " << parBook.rankPadPhi
<< " sPadWidth: " << parBook.sPadWidth
<< " lPadLength: " << parBook.lPadLength
<< " sPadLength: " << parBook.sPadLength
<< " gasGapTck: " << parBook.gasTck);
}
return StatusCode::SUCCESS;
......
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include "GeoModelsTgcTest.h"
#include <ActsGeometryInterfaces/ActsGeometryContext.h>
......@@ -100,7 +100,7 @@ StatusCode GeoModelsTgcTest::execute() {
}
const sTgcIdHelper& id_helper{m_idHelperSvc->stgcIdHelper()};
for (int layer = 1; layer <= reElement->numLayers(); ++layer) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::Strip/*Pad*/; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::Pad; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
unsigned int numChannel = 0;
bool isValidLay{false};
const Identifier layID = id_helper.channelID(reElement->identify(),
......@@ -110,6 +110,10 @@ StatusCode GeoModelsTgcTest::execute() {
continue;
}
switch(chType) {
case sTgcIdHelper::sTgcChannelTypes::Pad:
numChannel = reElement->numPads(layID);
break;
case sTgcIdHelper::sTgcChannelTypes::Strip:
numChannel = reElement->numStrips(layID);
break;
......@@ -151,6 +155,10 @@ StatusCode GeoModelsTgcTest::execute() {
ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chID)<<" wireGroup position "
<<Amg::toString(reElement->globalChannelPosition(gctx, measHash)));
}
else if (chType == sTgcIdHelper::sTgcChannelTypes::Pad) {
ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chID)<<" Pad position "
<<Amg::toString(reElement->globalChannelPosition(gctx, measHash)));
}
}
}
}
......@@ -184,7 +192,7 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
m_readoutTransform = transform;
const sTgcIdHelper& id_helper{m_idHelperSvc->stgcIdHelper()};
for (int layer = 1; layer <= reElement->numLayers(); ++layer) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::/*Pad*/Strip; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::Pad; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
unsigned int numWireGroup = 0;
/// Use idHelper to get the identifier
bool isValidLay{false};
......@@ -197,8 +205,68 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
/// Gas Gap dimensions
m_sGapLength = reElement->sGapLength(layID);
m_lGapLength = reElement->lGapLength(layID);
m_sPadLength = reElement->sPadLength(layID);
m_lPadLength = reElement->lPadLength(layID);
m_gapHeight = reElement->gapHeight(layID);
switch (chType) {
case sTgcIdHelper::sTgcChannelTypes::Pad:
m_numPads.push_back(reElement->numPads(layID));
m_numPadEta.push_back(reElement->numPadEta(layID));
m_numPadPhi.push_back(reElement->numPadPhi(layID));
m_firstPadHeight.push_back(reElement->firstPadHeight(layID));
m_padHeight.push_back(reElement->padHeight(layID));
m_padPhiShift.push_back(reElement->padPhiShift(layID));
m_firstPadPhiDiv.push_back(reElement->firstPadPhiDiv(layID));
m_anglePadPhi = reElement->anglePadPhi(layID);
m_beamlineRadius = reElement->beamlineRadius(layID);
for (unsigned int pad = 1; pad <= reElement->numPads(layID); ++pad) {
bool isValidPad{false};
const Identifier padID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, pad, isValidPad);
if (!isValidPad) {
ATH_MSG_WARNING("Invalid Identifier detected for readout element "
<<m_idHelperSvc->toStringDetEl(reElement->identify())
<<" layer: "<<layer<<" pad: "<<pad<<" channelType: "<<chType);
continue;
}
Amg::Vector2D localPadPos(Amg::Vector2D::Zero());
std::array<Amg::Vector2D,4> localPadCorners{make_array<Amg::Vector2D, 4>(Amg::Vector2D::Zero())};
Amg::Vector3D globalPadPos(Amg::Vector3D::Zero());
std::array<Amg::Vector3D,4> globalPadCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
localPadPos = reElement->localChannelPosition(padID);
localPadCorners = reElement->localPadCorners(padID);
m_localPadPos.push_back(localPadPos);
m_localPadCornerBL.push_back(localPadCorners[0]);
m_localPadCornerBR.push_back(localPadCorners[1]);
m_localPadCornerTL.push_back(localPadCorners[2]);
m_localPadCornerTR.push_back(localPadCorners[3]);
globalPadPos = reElement->globalChannelPosition(gctx, padID);
globalPadCorners = reElement->globalPadCorners(gctx, padID);
m_globalPadPos.push_back(globalPadPos);
m_globalPadCornerBR.push_back(globalPadCorners[0]);
m_globalPadCornerBL.push_back(globalPadCorners[1]);
m_globalPadCornerTR.push_back(globalPadCorners[2]);
m_globalPadCornerTL.push_back(globalPadCorners[3]);
m_padEta.push_back(reElement->padEta(padID));
m_padPhi.push_back(reElement->padPhi(padID));
m_padGasGap.push_back(layer);
if (pad != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, padID);
ATH_MSG_DEBUG("The local to global transformation on layers is: " << Amg::toString(locToGlob));
m_padRot.push_back(locToGlob);
m_padRotGasGap.push_back(layer);
}
break;
case sTgcIdHelper::sTgcChannelTypes::Strip:
m_numStrips = reElement->numStrips(layID);
m_stripPitch = reElement->stripPitch(layID);
......@@ -208,23 +276,23 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
const Identifier stripID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, strip, isValidStrip);
if (!isValidStrip) {
ATH_MSG_WARNING("Invalid Identifier detected for readout element "
<<m_idHelperSvc->toStringDetEl(reElement->identify())
<<" layer: "<<layer<<" strip: "<<strip<<" channelType: "<<chType);
continue;
}
m_localStripPos.push_back((reElement->localChannelPosition(stripID)).block<2,1>(0,0));
m_globalStripPos.push_back(reElement->globalChannelPosition(gctx, stripID));
m_stripGasGap.push_back(layer);
m_stripNum.push_back(strip);
m_stripLengths.push_back(reElement->stripLength(stripID));
if (!isValidStrip) {
ATH_MSG_WARNING("Invalid Identifier detected for readout element "
<<m_idHelperSvc->toStringDetEl(reElement->identify())
<<" layer: "<<layer<<" strip: "<<strip<<" channelType: "<<chType);
continue;
}
m_localStripPos.push_back((reElement->localChannelPosition(stripID)).block<2,1>(0,0));
m_globalStripPos.push_back(reElement->globalChannelPosition(gctx, stripID));
m_stripGasGap.push_back(layer);
m_stripNum.push_back(strip);
m_stripLengths.push_back(reElement->stripLength(stripID));
if (strip != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, stripID);
ATH_MSG_DEBUG("The local to global transformation on layers is: " << Amg::toString(locToGlob));
m_stripRot.push_back(locToGlob);
m_stripRotGasGap.push_back(layer);
if (strip != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, stripID);
ATH_MSG_DEBUG("The local to global transformation on layers is: " << Amg::toString(locToGlob));
m_stripRot.push_back(locToGlob);
m_stripRotGasGap.push_back(layer);
}
break;
......@@ -244,22 +312,22 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
const Identifier wireGroupID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, wireGroup, isValidWire);
if (!isValidWire) {
ATH_MSG_WARNING("Invalid Identifier detected for readout element "
<<m_idHelperSvc->toStringDetEl(reElement->identify())
<<" layer: "<<layer<<" wireGroup: "<<wireGroup<<" channelType: "<<chType);
continue;
}
m_localWireGroupPos.push_back(reElement->localChannelPosition(wireGroupID));
m_globalWireGroupPos.push_back(reElement->globalChannelPosition(gctx, wireGroupID));
m_wireGroupGasGap.push_back(layer);
m_wireGroupNum.push_back(wireGroup);
if (wireGroup != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, wireGroupID);
ATH_MSG_DEBUG("The local to global transformation on layers is: " << Amg::toString(locToGlob));
m_wireGroupRot.push_back(locToGlob);
m_wireGroupRotGasGap.push_back(layer);
if (!isValidWire) {
ATH_MSG_WARNING("Invalid Identifier detected for readout element "
<<m_idHelperSvc->toStringDetEl(reElement->identify())
<<" layer: "<<layer<<" wireGroup: "<<wireGroup<<" channelType: "<<chType);
continue;
}
m_localWireGroupPos.push_back(reElement->localChannelPosition(wireGroupID));
m_globalWireGroupPos.push_back(reElement->globalChannelPosition(gctx, wireGroupID));
m_wireGroupGasGap.push_back(layer);
m_wireGroupNum.push_back(wireGroup);
if (wireGroup != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, wireGroupID);
ATH_MSG_DEBUG("The local to global transformation on layers is: " << Amg::toString(locToGlob));
m_wireGroupRot.push_back(locToGlob);
m_wireGroupRotGasGap.push_back(layer);
}
break;
}
......
......@@ -64,8 +64,8 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm{
MuonVal::ScalarBranch<float>& m_lChamberLength{m_tree.newScalar<float>("lChamberLength")};
MuonVal::ScalarBranch<float>& m_chamberHeight{m_tree.newScalar<float>("chamberHeight")};
/// GasGap Lengths for debug
MuonVal::ScalarBranch<float>& m_sGapLength{m_tree.newScalar<float>("sGapLength")};
MuonVal::ScalarBranch<float>& m_lGapLength{m_tree.newScalar<float>("lGapLength")};
MuonVal::ScalarBranch<float>& m_sGapLength{m_tree.newScalar<float>("sGapLength")}; //sStripWidth
MuonVal::ScalarBranch<float>& m_lGapLength{m_tree.newScalar<float>("lGapLength")}; //lStripWidth
MuonVal::ScalarBranch<float>& m_gapHeight{m_tree.newScalar<float>("gapHeight")};
......@@ -83,6 +83,10 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm{
MuonVal::CoordSystemsBranch m_wireGroupRot{m_tree, "wireGroupRot"};
MuonVal::VectorBranch<uint8_t>& m_wireGroupRotGasGap{m_tree.newVector<uint8_t>("wireGroupRotGasGap")};
/// Rotation matrix of the respective pad layers
MuonVal::CoordSystemsBranch m_padRot{m_tree, "padRot"};
MuonVal::VectorBranch<uint8_t>& m_padRotGasGap{m_tree.newVector<uint8_t>("padRotGasGap")};
/// Strip dimensions
MuonVal::ScalarBranch<uint>& m_numStrips{m_tree.newScalar<uint>("numStrips")}; // nStrips
MuonVal::ScalarBranch<float>& m_stripPitch{m_tree.newScalar<float>("stripPitch")}; // stripPitch 3.2mm
......@@ -105,21 +109,36 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm{
MuonVal::ThreeVectorBranch m_globalWireGroupPos{m_tree, "globalWireGroupPos"}; //Position in ATLAS coordinates
MuonVal::VectorBranch<uint8_t>& m_wireGroupNum{m_tree.newVector<uint8_t>("wireGroupNum")}; // wire Group number
MuonVal::VectorBranch<uint8_t>& m_wireGroupGasGap{m_tree.newVector<uint8_t>("wireGroupGasGap")}; // gas gap number
/*
/// Pad dimensions
MuonVal::VectorBranch<uint>& m_numPads{m_tree.newVector<uint>("numPads")};
/// Pad dimensions
MuonVal::VectorBranch<uint>& m_numPads{m_tree.newVector<uint>("numPads")}; //total number of pads in a layer
MuonVal::ScalarBranch<float>& m_sPadLength{m_tree.newScalar<float>("sPadLength")}; // sPadWidth
MuonVal::ScalarBranch<float>& m_lPadLength{m_tree.newScalar<float>("lPadLength")}; // lPadWidth
MuonVal::VectorBranch<uint>& m_numPadEta{m_tree.newVector<uint>("numPadEta")}; //nPadH
MuonVal::VectorBranch<uint>& m_numPadPhi{m_tree.newVector<uint>("numPadPhi")}; //nPadPhi
MuonVal::VectorBranch<float>& m_firstPadHeight{m_tree.newVector<float>("firstPadHeight")}; //firstPadH
MuonVal::VectorBranch<float>& m_padHeight{m_tree.newVector<float>("padHeight")}; //PadH
MuonVal::VectorBranch<float>& m_padPhiShift{m_tree.newVector<float>("padPhiShift")}; //PadPhiShift_A (defined float in R3)
MuonVal::VectorBranch<float>& m_firstPadPhiDiv{m_tree.newVector<float>("firstPadPhiDiv")}; //firstPadPhiDivision
MuonVal::ScalarBranch<float>& m_anglePadPhi{m_tree.newScalar<float>("anglePadPhi")}; // anglePadPhi
MuonVal::ScalarBranch<float>& m_beamlineRadius{m_tree.newScalar<float>("beamlineRadius")};
MuonVal::TwoVectorBranch m_localPadCornerBR{m_tree, "localPadCornerBR"};
MuonVal::TwoVectorBranch m_localPadCornerBL{m_tree, "localPadCornerBL"};
MuonVal::TwoVectorBranch m_localPadCornerTR{m_tree, "localPadCornerTR"};
MuonVal::TwoVectorBranch m_localPadCornerTL{m_tree, "localPadCornerTL"};
MuonVal::TwoVectorBranch m_localPadPos{m_tree, "localPadPos"};
MuonVal::ThreeVectorBranch m_globalPadCornerBR{m_tree, "globalPadCornerBR"};
MuonVal::ThreeVectorBranch m_globalPadCornerBL{m_tree, "globalPadCornerBL"};
MuonVal::ThreeVectorBranch m_globalPadCornerTR{m_tree, "globalPadCornerTR"};
MuonVal::ThreeVectorBranch m_globalPadCornerTL{m_tree, "globalPadCornerTL"};
MuonVal::ThreeVectorBranch m_globalPadPos{m_tree, "globalPadPos"};
MuonVal::VectorBranch<uint8_t>& m_padGasGap{m_tree.newVector<uint8_t>("padGasGap")}; // gas gap number
MuonVal::VectorBranch<uint>& m_padEta{m_tree.newVector<uint>("padEtaNumber")}; // pad number in eta direction
MuonVal::VectorBranch<uint>& m_padPhi{m_tree.newVector<uint>("padPhiNumber")}; // pad number in phi direction
*/
MuonVal::VectorBranch<uint>& m_padPhi{m_tree.newVector<uint>("padPhiNumber")}; // pad number in phi direction
};
}
#endif
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONREADOUTGEOMETRYR4_PADDESIGN_H
#define MUONREADOUTGEOMETRYR4_PADDESIGN_H
#include <MuonReadoutGeometryR4/StripDesign.h>
#include "CxxUtils/ArrayHelper.h"
#include <GaudiKernel/SystemOfUnits.h>
namespace MuonGMR4{
/* The pad readout channels in sTgc chambers consists of 2D structure. Chambers may contain
* different number of pads depending on the gasGap. Measurements in the eta direction for pads
* are in millimeters, whereas for the phi direction, we have angular measurements in degrees.
* same number of wires. Hence, the channel width & pitch vary across the board. The wire group
* PadDesign inherits from the StripDesign class and contains functions that can define the geometry
* of pad layers. There are several functions to get the corners and center of each individual pads
* w.r.t. the center of the chamber. Extra methods will be added according to the needs.
*/
class PadDesign;
using PadDesignPtr = GeoModel::TransientConstSharedPtr<PadDesign>;
class PadDesign: public StripDesign {
public:
PadDesign() = default;
/// set sorting operator
bool operator<(const PadDesign& other) const;
/// Defines the Phi direction layout of the pad detector by specifing the starting angle w.r.t.
/// the layer center, the number of pads in the phi direction, angular pitch to the next pad,
/// and finally, the staggering in mm for the inner edges of the pads. Note: the outer edges of
/// the pads with either phi = 1, or phi = numPadPhi are fixed, they do not stagger.
void definePadRow(const double firstPadPhiDiv,
const int numPadPhi,
const double anglePadPhi,
const int padPhiShift);
/// Defines the Eta direction layout of the pad detector by specifing the height of the first pad
/// in millimeters, the number of pads in the eta direction, height of the pads other than the first row,
/// and finally, the maximum number of pads accomodated in a pad column which is 18, hardcoded. The numbering for
/// the next pad column will start with a factor of 19, regardless of the number of pads in the previous column.
void definePadColumn(const double firstPadHeight,
const int numPadEta,
const double padHeight,
const int maxPadEta = 18);
/// Returns the total number of pads in a layer
int numPads() const;
/// Returns the angle of the first pad outer edge w.r.t. the gasGap center from the beamline
double firstPadPhiDiv() const;
/// Returns the number of pads in the Phi direction in the given gasGap layer
int numPadPhi() const;
/// Returns the angular pitch of the pads in the phi direction
double anglePadPhi() const;
/// Returns the staggering shift of inner pad edges in the phi direction
double padPhiShift() const;
/// Returns the height of the pads that are adjacent to the bottom edge of the trapezoid active area
double firstPadHeight() const;
/// Returns the number of pads in the eta direction in the given layer
int numPadEta() const;
/// Returns the height of all the pads that are not adjacent to the bottom edge of the trapezoid active area
double padHeight() const;
/// Returns the maximum number of pads that can be contained in a column of a pad. Used to match the pad numbering scheme
int maxPadEta() const;
/// Returns the pad number in the conventional pad numbering scheme from the sequential channel number
int padNumber(const int channel) const;
/// Returns a pair of Eta and Phi index for the given sequential channel number
std::pair<int, int> padEtaPhi(const int channel) const;
/// Returns the Eta index of the pad for the given sequential channel number
int padEta(const int channel) const;
/// Returns the Phi index of the pad for the given sequential channel number
int padPhi(const int channel) const;
/// Extracting the distance from gasGap center to beamline from the local to global transformation of the padLayer
void defineBeamlineRadius(const double radius);
/// Returns the distance between the gasGap center and the beamline
double beamlineRadius() const;
/// Defining an array of four vectors to store the pad corner position in the order of the enum defined below
using localCornerArray = std::array<Amg::Vector2D, 4>;
enum padCorners{ botLeft=0, botRight, topLeft, topRight };
/// Returns an array of local pad corner positions given the sequential pad channel or the Eta/Phi Id.
localCornerArray padCorners(const int channel) const;
localCornerArray padCorners(const std::pair<int, int>& padEtaPhi) const;
/// Override from stripDesign. This function will give the center of the pad by taking the sequential channel number as input
Amg::Vector2D stripPosition(int stripNum) const override final;
private:
void print(std::ostream& ostr) const override final;
/// Angle of the first pad outer edge w.r.t. the gasGap center from the beamline
double m_firstPadPhiDiv{0.};
/// Number of pads in the Phi direction in the given gasGap layer
int m_numPadPhi{0};
/// Angular pitch of the pads in the phi direction
double m_anglePadPhi{0.};
/// The staggering shift of inner pad edges in the phi direction
double m_padPhiShift{0.};
/// Height of the pads that are adjacent to the bottom edge of the trapezoid active area
double m_firstPadHeight{0.};
/// Number of pads in the eta direction in the given layer
int m_numPadEta{0};
/// Height of all the pads that are not adjacent to the bottom edge of the trapezoid active area
double m_padHeight{0.};
/// The maximum number of pads that can be contained in a column of a pad. Used to match the pad numbering scheme
int m_maxPadEta{18};
/// Stores the beamline radius extracted from the local to global transformation
double m_radius{0.};
};
struct PadDesignSorter{
bool operator()(const PadDesignPtr&a, const PadDesignPtr& b) const {
return (*a) < (*b);
}
bool operator()(const PadDesign&a ,const PadDesign& b) const {
return a < b;
}
};
}
#include <MuonReadoutGeometryR4/PadDesign.icc>
#endif
\ No newline at end of file
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONREADOUTGEOMETRYR4_PADDESIGN_ICC
#define MUONREADOUTGEOMETRYR4_PADDESIGN_ICC
#include <MuonReadoutGeometryR4/PadDesign.h>
namespace MuonGMR4 {
using CheckVector2D = PadDesign::CheckVector2D;
inline int PadDesign::numPads() const { return m_numPadPhi * m_numPadEta; }
inline double PadDesign::firstPadPhiDiv() const { return m_firstPadPhiDiv; }
inline int PadDesign::numPadPhi() const { return m_numPadPhi; }
inline double PadDesign::anglePadPhi() const { return m_anglePadPhi; }
inline double PadDesign::padPhiShift() const { return m_padPhiShift; }
inline double PadDesign::firstPadHeight() const { return m_firstPadHeight; }
inline int PadDesign::numPadEta() const { return m_numPadEta; }
inline double PadDesign::padHeight() const { return m_padHeight; }
inline int PadDesign::maxPadEta() const { return m_maxPadEta; }
inline int PadDesign::padNumber(const int channel) const {
int padEta = padEtaPhi(channel).first;
int padPhi = padEtaPhi(channel).second;
int padNumber = (padPhi - 1) * maxPadEta() + padEta;
return padNumber;
};
inline std::pair<int, int> PadDesign::padEtaPhi(const int channel) const {
int padEta = (channel -1) % numPadEta() + 1;
int padPhi = (channel -1) / numPadEta() + 1;
if (channel < 0 || padEta > numPadEta() || padPhi > numPadPhi()) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" Pad channel " << channel << " is out of range. Maximum range: " << numPads());
ATH_MSG_DEBUG(__FILE__<<":"<<__LINE__<<" Pad channel: "<< channel<< " padEta: "<<padEta<<" numPadEta: "<<numPadEta()<<" padPhi "<<padPhi<<" numPadPhi: "<<numPadPhi()<<" total pads "<<numPads());
return std::make_pair(0, 0);
}
return std::make_pair(padEta, padPhi);
}
inline int PadDesign::padEta(const int channel) const {
return padEtaPhi(channel).first;
}
inline int PadDesign::padPhi(const int channel) const {
return padEtaPhi(channel).second;
}
inline double PadDesign::beamlineRadius() const {
return m_radius;
}
using localCornerArray = std::array<Amg::Vector2D, 4>;
inline localCornerArray PadDesign::padCorners(const int channel) const {
return padCorners(padEtaPhi(channel));
}
inline Amg::Vector2D PadDesign::stripPosition(int channel) const {
if (padEta(channel) == 0 || padPhi(channel) == 0) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The pad number "<<channel
<<" is out of range. Maximum range: " << numPads());
return Amg::Vector2D::Zero();
}
localCornerArray Corners = padCorners(channel);
Amg::Vector2D padCenter = 0.25 * (Corners[botLeft] + Corners[botRight] + Corners[topLeft] + Corners[topRight]);
return padCenter;
}
}
#endif
\ No newline at end of file
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
*/
#ifndef MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
#define MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
......
......@@ -7,7 +7,7 @@
#include <MuonReadoutGeometryR4/MuonReadoutElement.h>
#include <MuonReadoutGeometryR4/StripDesign.h>
#include <MuonReadoutGeometryR4/WireGroupDesign.h>
//#include <MuonReadoutGeometryR4/DiamondStripDesign.h>
#include <MuonReadoutGeometryR4/PadDesign.h>
#include <MuonReadoutGeometryR4/StripLayer.h>
#ifndef SIMULATIONBASE
# include "Acts/Surfaces/TrapezoidBounds.hpp"
......@@ -34,7 +34,6 @@ class sTgcReadoutElement : public MuonReadoutElement {
};
/// Set of parameters to describe an sTGC chamber
struct parameterBook {
/// sTGC Chamber Details
......@@ -59,16 +58,18 @@ class sTgcReadoutElement : public MuonReadoutElement {
unsigned int nChTypes{0};
/// Diamond cutout height
double yCutout{0.};
//// firstStripPitch needed for the globalChannelPosition function
std::vector<double> firstStripPitch{};
std::vector<StripLayer> stripLayers{};
std::vector<StripLayer> wireGroupLayers{};
std::vector<StripLayer> padLayers{};
StripDesignPtr stripDesign{nullptr};
WireDesignPtr wireGroupDesign{nullptr};
PadDesignPtr padDesign{nullptr};
#ifndef SIMULATIONBASE
ActsTrk::SurfaceBoundSetPtr<Acts::TrapezoidBounds> layerBounds{};
#endif
......@@ -114,15 +115,22 @@ class sTgcReadoutElement : public MuonReadoutElement {
/// Gas Gaps
double firstStripPitch(const Identifier& measId) const;
double firstStripPitch(const IdentifierHash& measHash) const;
/// Length of gas Gap on short side
/// Length of gas Gap on short side for strips
double sGapLength(const Identifier& measId) const;
double sGapLength(const IdentifierHash& measHash) const;
/// Length of gas Gap on long side
/// Length of gas Gap on long side for strips
double lGapLength(const Identifier& measId) const;
double lGapLength(const IdentifierHash& measHash) const;
/// Length of gas Gap on short side for wireGroup/Pads
double sPadLength(const Identifier& measId) const;
double sPadLength(const IdentifierHash& measHash) const;
/// Length of gas Gap on long side for wireGroup/Pads
double lPadLength(const Identifier& measId) const;
double lPadLength(const IdentifierHash& measHash) const;
/// Height of gas Gap
double gapHeight(const Identifier& measId) const;
double gapHeight(const IdentifierHash& measHash) const;
////Strips
/// Number of strips in a chamber
unsigned int numStrips(const Identifier& measId) const;
......@@ -156,6 +164,58 @@ class sTgcReadoutElement : public MuonReadoutElement {
unsigned int numWireGroups(unsigned int gasGap) const;
/// Wire Cutout of a gas Gap
double wireCutout(unsigned int gasGap) const;
//// Pads
/// Total number of pads in the given layer
unsigned int numPads(const Identifier& measId) const;
unsigned int numPads(const IdentifierHash& measHash) const;
/// Returns the number of pads in the eta direction in the given layer
unsigned int numPadEta(const Identifier& measId) const;
unsigned int numPadEta(const IdentifierHash& measHash) const;
/// Returns the number of pads in the Phi direction in the given gasGap layer
unsigned int numPadPhi(const Identifier& measId) const;
unsigned int numPadPhi(const IdentifierHash& measHash) const;
/// Returns the height of the pads that are adjacent to the bottom edge of the trapezoid active area
double firstPadHeight(const Identifier& measId) const;
double firstPadHeight(const IdentifierHash& measHash) const;
/// Returns the height of all the pads that are not adjacent to the bottom edge of the trapezoid active area
double padHeight(const Identifier& measId) const;
double padHeight(const IdentifierHash& measHash) const;
/// Returns the staggering shift of inner pad edges in the phi direction
double padPhiShift(const Identifier& measId) const;
double padPhiShift(const IdentifierHash& measHash) const;
/// Returns the angle of the first pad outer edge w.r.t. the gasGap center from the beamline for the given pad identifier
double firstPadPhiDiv(const Identifier& measId) const;
double firstPadPhiDiv(const IdentifierHash& measHash) const;
/// Returns the angular pitch of the pads in the phi direction
double anglePadPhi(const Identifier& measId) const;
double anglePadPhi(const IdentifierHash& measHash) const;
/// Returns the maximum number of pads that can be contained in a column of a pad. Used to match the pad numbering scheme
unsigned int maxPadEta(const Identifier& measId) const;
unsigned int maxPadEta(const IdentifierHash& measHash) const;
/// Returns the pad number in the conventional pad numbering scheme from the sequential channel number
unsigned int padNumber(const Identifier& measId) const;
unsigned int padNumber(const IdentifierHash& measHash) const;
/// Returns a pair of Eta and Phi index for the given pad identifier
std::pair<uint, uint> padEtaPhi(const Identifier& measId) const;
std::pair<uint, uint> padEtaPhi(const IdentifierHash& measHash) const;
/// Returns the Eta index of the pad for the given pad identifier
unsigned int padEta(const Identifier& measId) const;
unsigned int padEta(const IdentifierHash& measHash) const;
/// Returns the Phi index of the pad for the given pad identifier
unsigned int padPhi(const Identifier& measId) const;
unsigned int padPhi(const IdentifierHash& measHash) const;
/// Returns the distance between the gasGap center and the beamline
double beamlineRadius(const Identifier& measId) const;
double beamlineRadius(const IdentifierHash& measHash) const;
/// Returns an array of four 2D vectors representing corner positions of the pads
using localCornerArray = std::array<Amg::Vector2D, 4>;
localCornerArray localPadCorners(const Identifier& measId) const;
localCornerArray localPadCorners(const IdentifierHash& measHash) const;
/// Returns an array of four 3D vectors representing corner positions of the pads
using globalCornerArray = std::array<Amg::Vector3D, 4>;
globalCornerArray globalPadCorners(const ActsGeometryContext& ctx, const Identifier& measId) const;
globalCornerArray globalPadCorners(const ActsGeometryContext& ctx, const IdentifierHash& measHash) const;
/// Retrieves the readoutElement Layer given the Identifier/Hash
const StripDesign& stripDesign(const Identifier& measId) const;
const StripDesign& stripDesign(const IdentifierHash& measHash) const;
......@@ -168,10 +228,16 @@ class sTgcReadoutElement : public MuonReadoutElement {
/// Retrieves the readoutElement Layer given the gasGap
const WireGroupDesign& wireDesign(unsigned int gasGap) const;
/// Returns the global strip/wire position
/// Retrieves the readoutElement Layer given the Identifier/Hash
const PadDesign& padDesign(const Identifier& measId) const;
const PadDesign& padDesign(const IdentifierHash& measHash) const;
/// Retrieves the readoutElement Layer given the gasGap
const PadDesign& padDesign(unsigned int gasGap) const;
/// Returns the global pad/strip/wireGroup position
Amg::Vector3D globalChannelPosition(const ActsGeometryContext& ctx, const Identifier& measId) const;
Amg::Vector3D globalChannelPosition(const ActsGeometryContext& ctx, const IdentifierHash& measHash) const;
/// Returns the local strip/wire position
/// Returns the local pad/strip/wireGroup position
Amg::Vector2D localChannelPosition(const Identifier& measId) const;
Amg::Vector2D localChannelPosition(const IdentifierHash& measHash) const;
......@@ -201,10 +267,9 @@ class sTgcReadoutElement : public MuonReadoutElement {
const unsigned int channel,
const unsigned int wireInGrp = 0);
private:
/// Returns channel position for a given identifierHash
static unsigned int stripNumber(const IdentifierHash& measHash);
static unsigned int channelNumber(const IdentifierHash& measHash);
/// Returns the channel type for a given identifierHash
static unsigned int chType(const IdentifierHash& measHash);
/// Returns the gasGap (0 to 3) for a given identifierHash
......
......@@ -37,6 +37,10 @@ inline double sTgcReadoutElement::sGapLength(const Identifier& measId) const { r
inline double sTgcReadoutElement::sGapLength(const IdentifierHash& measHash) const { return 2*stripDesign(measHash).shortHalfHeight(); }
inline double sTgcReadoutElement::lGapLength(const Identifier& measId) const { return 2*stripDesign(measId).longHalfHeight(); }
inline double sTgcReadoutElement::lGapLength(const IdentifierHash& measHash) const { return 2*stripDesign(measHash).longHalfHeight(); }
inline double sTgcReadoutElement::sPadLength(const Identifier& measId) const { return 2*padDesign(measId).shortHalfHeight(); }
inline double sTgcReadoutElement::sPadLength(const IdentifierHash& measHash) const { return 2*padDesign(measHash).shortHalfHeight(); }
inline double sTgcReadoutElement::lPadLength(const Identifier& measId) const { return 2*padDesign(measId).longHalfHeight(); }
inline double sTgcReadoutElement::lPadLength(const IdentifierHash& measHash) const { return 2*padDesign(measHash).longHalfHeight(); }
inline double sTgcReadoutElement::gapHeight(const Identifier& measId) const { return 2*stripDesign(measId).halfWidth(); }
inline double sTgcReadoutElement::gapHeight(const IdentifierHash& measHash) const { return 2*stripDesign(measHash).halfWidth(); }
......@@ -61,6 +65,42 @@ inline unsigned int sTgcReadoutElement::numWireGroups(unsigned int gasGap) const
inline unsigned int sTgcReadoutElement::firstWireGroupWidth(unsigned int gasGap) const { return wireDesign(gasGap).numWiresInGroup(1); }
inline double sTgcReadoutElement::wireCutout(unsigned int gasGap) const { return wireDesign(gasGap).wireCutout(); }
inline unsigned int sTgcReadoutElement::numPads(const Identifier& measId) const { return padDesign(measId).numPads(); }
inline unsigned int sTgcReadoutElement::numPads(const IdentifierHash& measHash) const { return padDesign(measHash).numPads(); }
inline unsigned int sTgcReadoutElement::numPadEta(const Identifier& measId) const { return padDesign(measId).numPadEta(); }
inline unsigned int sTgcReadoutElement::numPadEta(const IdentifierHash& measHash) const { return padDesign(measHash).numPadEta(); }
inline unsigned int sTgcReadoutElement::numPadPhi(const Identifier& measId) const { return padDesign(measId).numPadPhi(); }
inline unsigned int sTgcReadoutElement::numPadPhi(const IdentifierHash& measHash) const { return padDesign(measHash).numPadPhi(); }
inline double sTgcReadoutElement::firstPadHeight(const Identifier& measId) const { return padDesign(measId).firstPadHeight(); }
inline double sTgcReadoutElement::firstPadHeight(const IdentifierHash& measHash) const { return padDesign(measHash).firstPadHeight(); }
inline double sTgcReadoutElement::padHeight(const Identifier& measId) const { return padDesign(measId).padHeight(); }
inline double sTgcReadoutElement::padHeight(const IdentifierHash& measHash) const { return padDesign(measHash).padHeight(); }
inline double sTgcReadoutElement::padPhiShift(const Identifier& measId) const { return padDesign(measId).padPhiShift(); }
inline double sTgcReadoutElement::padPhiShift(const IdentifierHash& measHash) const { return padDesign(measHash).padPhiShift(); }
inline double sTgcReadoutElement::firstPadPhiDiv(const Identifier& measId) const { return padDesign(measId).firstPadPhiDiv(); }
inline double sTgcReadoutElement::firstPadPhiDiv(const IdentifierHash& measHash) const { return padDesign(measHash).firstPadPhiDiv(); }
inline double sTgcReadoutElement::anglePadPhi(const Identifier& measId) const { return padDesign(measId).anglePadPhi(); }
inline double sTgcReadoutElement::anglePadPhi(const IdentifierHash& measHash) const { return padDesign(measHash).anglePadPhi(); }
inline unsigned int sTgcReadoutElement::maxPadEta(const Identifier& measId) const { return padDesign(measId).anglePadPhi(); }
inline unsigned int sTgcReadoutElement::maxPadEta(const IdentifierHash& measHash) const { return padDesign(measHash).anglePadPhi(); }
inline unsigned int sTgcReadoutElement::padNumber(const Identifier& measId) const { return padNumber(measurementHash(measId)); }
inline unsigned int sTgcReadoutElement::padNumber(const IdentifierHash& measHash) const { return padDesign(measHash).padNumber(channelNumber(measHash)); }
inline std::pair<uint, uint> sTgcReadoutElement::padEtaPhi(const Identifier& measId) const { return padEtaPhi(measurementHash(measId)); }
inline std::pair<uint, uint> sTgcReadoutElement::padEtaPhi(const IdentifierHash& measHash) const { return padDesign(measHash).padEtaPhi(channelNumber(measHash)); }
inline unsigned int sTgcReadoutElement::padEta(const Identifier& measId) const { return padEta(measurementHash(measId)); }
inline unsigned int sTgcReadoutElement::padEta(const IdentifierHash& measHash) const { return padDesign(measHash).padEta(channelNumber(measHash)); }
inline unsigned int sTgcReadoutElement::padPhi(const Identifier& measId) const { return padPhi(measurementHash(measId)); }
inline unsigned int sTgcReadoutElement::padPhi(const IdentifierHash& measHash) const { return padDesign(measHash).padPhi(channelNumber(measHash)); }
inline double sTgcReadoutElement::beamlineRadius(const Identifier& measId) const { return padDesign(measId).beamlineRadius(); }
inline double sTgcReadoutElement::beamlineRadius(const IdentifierHash& measHash) const { return padDesign(measHash).beamlineRadius(); }
using localCornerArray = std::array<Amg::Vector2D, 4>;
inline localCornerArray sTgcReadoutElement::localPadCorners(const Identifier& measId) const { return localPadCorners(measurementHash(measId)); }
inline localCornerArray sTgcReadoutElement::localPadCorners(const IdentifierHash& measHash) const { return padDesign(measHash).padCorners(channelNumber(measHash)); }
using globalCornerArray = std::array<Amg::Vector3D, 4>;
inline globalCornerArray sTgcReadoutElement::globalPadCorners(const ActsGeometryContext& ctx, const Identifier& measId) const {
return globalPadCorners(ctx, measurementHash(measId));
}
inline const StripDesign& sTgcReadoutElement::stripDesign(const Identifier& measId) const {
unsigned int gasGap = m_idHelper.gasGap(measId);
return m_pars.stripLayers[gasGap-1].design();
......@@ -83,6 +123,17 @@ inline const WireGroupDesign& sTgcReadoutElement::wireDesign(unsigned int gasGap
return static_cast<const WireGroupDesign&>(m_pars.wireGroupLayers[gasGap-1].design());
}
inline const PadDesign& sTgcReadoutElement::padDesign(const Identifier& measId) const {
unsigned int gasGap = m_idHelper.gasGap(measId);
return static_cast<const PadDesign&>(m_pars.padLayers[gasGap-1].design());
}
inline const PadDesign& sTgcReadoutElement::padDesign(const IdentifierHash& measHash) const {
return padDesign(measurementId(measHash));
}
inline const PadDesign& sTgcReadoutElement::padDesign(unsigned int gasGap) const {
return static_cast<const PadDesign&>(m_pars.padLayers[gasGap-1].design());
}
inline IdentifierHash sTgcReadoutElement::measurementHash(const Identifier& measId) const {
if (idHelperSvc()->detElId(measId) != identify()) {
ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
......@@ -111,7 +162,7 @@ inline IdentifierHash sTgcReadoutElement::layerHash(const IdentifierHash& measHa
return IdentifierHash{static_cast<unsigned int>(measHash) & (~mask)};
}
inline unsigned int sTgcReadoutElement::stripNumber(const IdentifierHash& measHash) {
inline unsigned int sTgcReadoutElement::channelNumber(const IdentifierHash& measHash) {
using namespace sTgcIdMeasHashFields;
constexpr unsigned int mask = (minusOne << wireInGrpShift);
const unsigned int stripedHash = (~mask) & static_cast<unsigned int>(measHash);
......@@ -130,7 +181,7 @@ inline unsigned int sTgcReadoutElement::gasGapNumber(const IdentifierHash& measH
return (static_cast<unsigned int>(measHash) &(~mask) );
}
inline Identifier sTgcReadoutElement::measurementId(const IdentifierHash& measHash) const {
return m_idHelper.channelID(identify(), multilayer(), gasGapNumber(measHash) + 1, chType(measHash), stripNumber(measHash));
return m_idHelper.channelID(identify(), multilayer(), gasGapNumber(measHash) + 1, chType(measHash), channelNumber(measHash));
}
inline IdentifierHash sTgcReadoutElement::layerHash(const Identifier& measId) const {
if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
......@@ -146,13 +197,13 @@ inline Amg::Vector3D sTgcReadoutElement::globalChannelPosition(const ActsGeometr
return globalChannelPosition(ctx, measurementHash(measId));
}
inline const StripLayer& sTgcReadoutElement::stripLayer(const IdentifierHash& measHash) const {
inline const StripLayer& sTgcReadoutElement::stripLayer(const IdentifierHash& measHash) const {
unsigned int gasGap = gasGapNumber(measHash);
return m_pars.stripLayers[gasGap];
}
}
inline const StripLayer& sTgcReadoutElement::stripLayer(const Identifier& measId) const {
return stripLayer(measurementHash(measId));
}
}
} // namespace MuonGMR4
#endif
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
*/
#include <MuonReadoutGeometryR4/StripDesign.h>
......
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
*/
#include <MuonReadoutGeometryR4/WireGroupDesign.h>
#include <GaudiKernel/SystemOfUnits.h>
......
/*
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include <MuonReadoutGeometryR4/PadDesign.h>
#include <GaudiKernel/SystemOfUnits.h>
namespace MuonGMR4{
void PadDesign::print(std::ostream& ostr) const {
ostr<<"Dimension -- width x height [mm]: "<<halfWidth() * Gaudi::Units::mm<<" x ";
ostr<<shortHalfHeight()<<"/"<<longHalfHeight()<<" [mm], ";
if (hasStereoAngle()) ostr<<"stereo angle: "<<stereoAngle() / Gaudi::Units::deg<<", ";
ostr<<"position first pad "<<Amg::toString(stripPosition(firstStripNumber()),1);
ostr<<" *** Trapezoid edges "<<Amg::toString(cornerBotLeft(),1)<<" - "<<Amg::toString(cornerBotRight(), 1)<<" --- ";
ostr<<Amg::toString(cornerTopLeft(), 1)<<" - "<<Amg::toString(cornerTopRight(), 1);
ostr<<" -- numPadEta: "<<numPadEta()<<", numPadPhi: "<<numPadPhi()<<", pad height: "<<padHeight();
ostr<<" -- firstPadPhiDiv: "<<firstPadPhiDiv()<<", anglePadPhi: "<<anglePadPhi()<<", padPhiShift: "<<padPhiShift();
ostr<<" -- firstPadHeight: "<<firstPadHeight()<<", beamlineRadius: "<<beamlineRadius();
}
bool PadDesign::operator<(const PadDesign& other) const {
return static_cast<const StripDesign&>(*this) < other;
}
void PadDesign::definePadRow(const double firstPadPhiDiv,
const int numPadPhi,
const double anglePadPhi,
const int padPhiShift) {
m_firstPadPhiDiv = firstPadPhiDiv;
m_numPadPhi = numPadPhi;
m_anglePadPhi = anglePadPhi;
m_padPhiShift = static_cast<double>(padPhiShift);
};
void PadDesign::definePadColumn(const double firstPadHeight,
const int numPadEta,
const double padHeight,
const int maxPadEta) {
m_firstPadHeight = firstPadHeight;
m_numPadEta = numPadEta;
m_padHeight = padHeight;
m_maxPadEta = maxPadEta;
};
void PadDesign::defineBeamlineRadius(const double radius) {
m_radius = radius;
};
localCornerArray PadDesign::padCorners(const std::pair<int, int>& padEtaPhi) const {
int padEta = padEtaPhi.first;
int padPhi = padEtaPhi.second;
localCornerArray padCorners = {make_array<Amg::Vector2D, 4>(Amg::Vector2D::Zero())};
/// Variables to store the distance of the two sides of the pad w.r.t. the chamber origin
double botEdge{0.};
double topEdge{0.};
/// Variables to store the distance of the four points of the pad in x direction w.r.t. the chamber origin
double botLeftPoint{0.};
double botRightPoint{0.};
double topLeftPoint{0.};
double topRightPoint{0.};
/// Defining the top and the bottom edge of the active area depending on whether its a diamond or a trapezoid
double maxBottom = /*yCutout()? (-2. * halfWidth() + yCutout()) :*/ -halfWidth();
double maxTop = /*yCutout()? yCutout :*/ halfWidth();
/// Calculating the distance of top and bottom sides of the pad w.r.t. the chamber origin
if(padEta == 1) {
botEdge = maxBottom;
topEdge = botEdge + firstPadHeight();
}
else if(padEta > 1 && padEta <= numPadEta()) {
botEdge = maxBottom + firstPadHeight() + (padEta - 2) * padHeight();
topEdge = botEdge + padHeight();
if(padEta == numPadEta()) topEdge = maxTop;
}
else {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The given pad Eta " << padEta << " is out of range. Maximum range is " << numPadEta());
return padCorners;
}
/// Caculating the angular positions of the left and the right edges
double phiRight = firstPadPhiDiv() + (padPhi - 2) * anglePadPhi();
double phiLeft = firstPadPhiDiv() + (padPhi - 1) * anglePadPhi();
/// Defining tangent of the phi angles calculated above
double tanRight = std::tan(phiRight * Gaudi::Units::deg);
double tanLeft = std::tan(phiLeft * Gaudi::Units::deg);
/// Calculating distance from the beamline to the bottom and top edges of the pad
double botBase = botEdge + beamlineRadius();
double topBase = topEdge + beamlineRadius();
/// Calculating the distance of the four corners of the pad in x direction w.r.t. the chamber origin
botLeftPoint = -botBase * tanLeft;
botRightPoint = -botBase * tanRight;
topLeftPoint = -topBase * tanLeft;
topRightPoint = -topBase * tanRight;
/// Calculating the cosine of the angular positions to calculate the staggering in x direction w.r.t. the chamber origin
double cosRight = botBase / std::hypot(botRightPoint, botBase);
double cosLeft = botBase / std::hypot(botLeftPoint, botBase);
/// Adjusting the four corners of the pads for staggering in x direction w.r.t. the chamber origin
/// Outer edges of the trapezoid do not undergo staggering. Hence the if condition.
if (padPhi > 1 && padPhi < numPadPhi()) {
botLeftPoint += padPhiShift() * cosLeft;
botRightPoint += padPhiShift() * cosRight;
topLeftPoint += padPhiShift() * cosLeft;
topRightPoint += padPhiShift() * cosRight;
}
/// Adjusting the outer edges of the pads in diamond chambers (QL3)
/// There are pads in the outer columns that may contain five vertices when the topEdge of the pad is above the
/// gasGap origin and the bottom edge is below. This is only the case when yCutout is nonzero i.e. L3 sector.
/// In our logic, we are keeping only four corners for all the pads and essentially ignoring the fifth vertex
/// for these specific cases because the technical drawings suggest that the active ignored is very small and
/// the effect on reconstruction and digitization will be negligible.
/*
if (yCutout && topEdge > 0) {
if (padPhi == 1) {
topRightPoint = longHalfHeight();
if (botEdge > 0) botRightPoint = longHalfHeight();
}
if (padPhi == numPadPhi()) {
topLeftPoint = -longHalfHeight();
if (botEdge > 0) botLeftPoint = -longHalfHeight();
}
}
*/
/// Swapping the edges and the points in a mirror fashion if our initial assumptions about the left/Right
/// and top/Bottom are false.
if (botEdge > topEdge) {
ATH_MSG_VERBOSE("Swap top and bottom side "<<padEtaPhi.first<<"/"<<padEtaPhi.second);
std::swap(botEdge, topEdge);
}
if (botLeftPoint > botRightPoint) {
ATH_MSG_VERBOSE("Swap bottom left and right points "<<padEtaPhi.first<<"/"<<padEtaPhi.second);
std::swap(botLeftPoint, botRightPoint);
}
if (topLeftPoint > topRightPoint) {
ATH_MSG_VERBOSE("Swap top left and right points "<<padEtaPhi.first<<"/"<<padEtaPhi.second);
std::swap(topLeftPoint, topRightPoint);
}
padCorners[botLeft] = Amg::Vector2D(botLeftPoint, botEdge);
padCorners[botRight] = Amg::Vector2D(botRightPoint, botEdge);
padCorners[topLeft] = Amg::Vector2D(topLeftPoint, topEdge);
padCorners[topRight] = Amg::Vector2D(topRightPoint, topEdge);
return padCorners;
};
}
/*
Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
*/
#include <EventPrimitives/EventPrimitivesToStringConverter.h>
#include <GeoPrimitives/GeoPrimitivesHelpers.h>
......@@ -14,6 +14,7 @@ using parameterBook = sTgcReadoutElement::parameterBook;
std::ostream& operator<<(std::ostream& ostr, const parameterBook& pars) {
if (pars.stripDesign) ostr<<"Strips: "<<(*pars.stripDesign)<<std::endl;
if (pars.wireGroupDesign) ostr<<"Wire Groups: "<<(*pars.wireGroupDesign)<<std::endl;
if (pars.padDesign) ostr<<"Pads: "<<(*pars.padDesign)<<std::endl;
return ostr;
}
......@@ -57,6 +58,17 @@ StatusCode sTgcReadoutElement::initElement() {
return toStation(store) * fromGapToChamOrigin(hash);
}));
}
for (unsigned int layer = 0; layer < m_pars.padLayers.size(); ++layer) {
IdentifierHash layHash{layer};
if (gasGapNumber(m_pars.padLayers[layer].hash()) != layHash) {
ATH_MSG_FATAL("Layer "<<m_pars.padLayers[layer]<<" has a very strange hash. Expect "<<layer);
return StatusCode::FAILURE;
}
ATH_CHECK(insertTransform(m_pars.padLayers[layer].hash(),
[this](RawGeomAlignStore* store, const IdentifierHash& hash){
return toStation(store) * fromGapToChamOrigin(hash);
}));
}
ActsGeometryContext gctx{};
m_gasGapPitch = (center(gctx, createHash(1, sTgcIdHelper::sTgcChannelTypes::Strip, 0)) -
center(gctx, createHash(2, sTgcIdHelper::sTgcChannelTypes::Strip, 0))).mag();
......@@ -72,8 +84,11 @@ Amg::Transform3D sTgcReadoutElement::fromGapToChamOrigin(const IdentifierHash& m
else if (chType(measHash) == ReadoutChannelType::Wire && gasGap < m_pars.wireGroupLayers.size()) {
return m_pars.wireGroupLayers[gasGap].toOrigin();
}
else if (chType(measHash) == ReadoutChannelType::Pad && gasGap < m_pars.padLayers.size()) {
return m_pars.padLayers[gasGap].toOrigin();
}
else {
unsigned int maxReadoutLayers = m_pars.stripLayers.size() + m_pars.wireGroupLayers.size();
unsigned int maxReadoutLayers = m_pars.stripLayers.size() + m_pars.wireGroupLayers.size() + m_pars.padLayers.size();
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<< maxReadoutLayers);
return Amg::Transform3D::Identity();
......@@ -83,35 +98,35 @@ Amg::Transform3D sTgcReadoutElement::fromGapToChamOrigin(const IdentifierHash& m
Amg::Vector2D sTgcReadoutElement::localChannelPosition(const IdentifierHash& measHash) const {
if (chType(measHash) == ReadoutChannelType::Strip) {
Amg::Vector2D stripCenter{Amg::Vector2D::Zero()};
std::optional<Amg::Vector2D> stripCenterOpt = stripDesign(measHash).center(stripNumber(measHash));
std::optional<Amg::Vector2D> stripCenterOpt = stripDesign(measHash).center(channelNumber(measHash));
if (!stripCenterOpt) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The strip" << stripNumber(measHash) << "doesn't intersect with the edges of the trapezoid.");
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The strip" << channelNumber(measHash) << "doesn't intersect with the edges of the trapezoid.");
return stripCenter;
}
stripCenter = std::move(*stripCenterOpt);
if (stripNumber(measHash) == 1 && firstStripPitch(measHash) < stripPitch(measHash)) {
if (channelNumber(measHash) == 1 && firstStripPitch(measHash) < stripPitch(measHash)) {
stripCenter.x() += 0.25 * stripWidth(measHash);
}
if (stripNumber(measHash) == numStrips(measHash) && firstStripPitch(measHash) == stripPitch(measHash)) {
if (channelNumber(measHash) == numStrips(measHash) && firstStripPitch(measHash) == stripPitch(measHash)) {
stripCenter.x() -= 0.25 * stripWidth(measHash);
}
return stripCenter;
}
else if (chType(measHash) == ReadoutChannelType::Wire) {
Amg::Vector2D wireGroupCenter{Amg::Vector2D::Zero()};
std::optional<Amg::Vector2D> wireGroupCenterOpt = wireDesign(measHash).center(stripNumber(measHash));
std::optional<Amg::Vector2D> wireGroupCenterOpt = wireDesign(measHash).center(channelNumber(measHash));
if (!wireGroupCenterOpt) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wireGroup" << stripNumber(measHash) << "doesn't intersect with the edges of the trapezoid.");
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wireGroup" << channelNumber(measHash) << "doesn't intersect with the edges of the trapezoid.");
return wireGroupCenter;
}
wireGroupCenter = std::move(*wireGroupCenterOpt);
unsigned int gasGap = gasGapNumber(measHash) + 1;
if (stripNumber(measHash) == 1) {
if (channelNumber(measHash) == 1) {
ATH_MSG_DEBUG("The first wire pos is: " << wireGroupCenter.x() + (0.5 * firstWireGroupWidth(gasGap))* wirePitch(measHash) );
wireGroupCenter.x() = 0.5*(wireGroupCenter.x() + (0.5 * firstWireGroupWidth(gasGap) - 1)* wirePitch(measHash) - 0.5 * lGapLength(measHash));
}
else if (stripNumber(measHash) == numWireGroups(gasGap)) {
else if (channelNumber(measHash) == numWireGroups(gasGap)) {
ATH_MSG_DEBUG("The last wire center before modification is: " << wireGroupCenter.x());
wireGroupCenter.x() = 0.5 * (wireGroupCenter.x() + 0.5*lGapLength(measHash) -
(wireGroupWidth(gasGap) * wirePitch(measHash)));
......@@ -119,6 +134,16 @@ Amg::Vector2D sTgcReadoutElement::localChannelPosition(const IdentifierHash& mea
}
return wireGroupCenter;
}
else if (chType(measHash) == ReadoutChannelType::Pad) {
Amg::Vector2D padCenter{Amg::Vector2D::Zero()};
std::optional<Amg::Vector2D> padCenterOpt = padDesign(measHash).stripPosition(channelNumber(measHash));
if (!padCenterOpt) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The pad" << channelNumber(measHash) << "doesn't is not a valid pad number.");
return padCenter;
}
padCenter = std::move(*padCenterOpt);
return padCenter;
}
else {
ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<"Invalid channel type: " << chType(measHash));
return Amg::Vector2D::Zero();
......@@ -129,7 +154,7 @@ Amg::Vector3D sTgcReadoutElement::globalChannelPosition(const ActsGeometryContex
unsigned int layIdx = static_cast<unsigned int>(lHash);
unsigned int gasGap = gasGapNumber(measHash);
if (chType(measHash) == ReadoutChannelType::Strip && gasGap < m_pars.stripLayers.size()) {
return localToGlobalTrans(ctx, lHash) * m_pars.stripLayers[gasGap].localStripPos(stripNumber(measHash));
return localToGlobalTrans(ctx, lHash) * m_pars.stripLayers[gasGap].localStripPos(channelNumber(measHash));
}
else if (chType(measHash) == ReadoutChannelType::Wire && gasGap < m_pars.wireGroupLayers.size()) {
Amg::Vector3D wireGrPos{Amg::Vector3D::Zero()};
......@@ -137,16 +162,41 @@ Amg::Vector3D sTgcReadoutElement::globalChannelPosition(const ActsGeometryContex
wireGrPos.block<2,1>(0,0) = std::move(localWireGroup);
return localToGlobalTrans(ctx, lHash) * wireGrPos;
}
else if (chType(measHash) == ReadoutChannelType::Pad && gasGap < m_pars.padLayers.size()) {
Amg::Vector3D padPos{Amg::Vector3D::Zero()};
Amg::Vector2D localPad = localChannelPosition(measHash);
padPos.block<2,1>(0,0) = std::move(localPad);
return localToGlobalTrans(ctx, lHash) * padPos;
}
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<<m_pars.stripLayers.size());
return Amg::Vector3D::Zero();
}
using localCornerArray = std::array<Amg::Vector2D, 4>;
using globalCornerArray = std::array<Amg::Vector3D, 4>;
globalCornerArray sTgcReadoutElement::globalPadCorners(const ActsGeometryContext& ctx, const IdentifierHash& measHash) const {
const IdentifierHash lHash = layerHash(measHash);
unsigned int layIdx = static_cast<unsigned int>(lHash);
unsigned int gasGap = gasGapNumber(measHash);
globalCornerArray gPadCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
if (chType(measHash) == ReadoutChannelType::Pad && gasGap < m_pars.padLayers.size()) {
localCornerArray lPadCorners = localPadCorners(measHash);
for (unsigned int corner = 0; corner < lPadCorners.size(); ++corner) {
gPadCorners[corner].block<2,1>(0,0) = std::move(lPadCorners[corner]);
gPadCorners[corner] = localToGlobalTrans(ctx, lHash) * gPadCorners[corner];
}
return gPadCorners;
}
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<<m_pars.padLayers.size());
return gPadCorners;
}
Amg::Vector3D sTgcReadoutElement::chamberStripPos(const IdentifierHash& measHash) const {
const IdentifierHash lHash = layerHash(measHash);
unsigned int layIdx = static_cast<unsigned int>(lHash);
if (layIdx < m_pars.stripLayers.size()) {
return m_pars.stripLayers[layIdx].stripPosition(stripNumber(measHash));
return m_pars.stripLayers[layIdx].stripPosition(channelNumber(measHash));
}
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<<m_pars.stripLayers.size());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment