Skip to content
Snippets Groups Projects
Commit ac6ed612 authored by Ishan Kiritbhai Vyas's avatar Ishan Kiritbhai Vyas Committed by Tadej Novak
Browse files

R4 sTgcReadoutGeomTool - Adding Wiregroup Design

Creating a new MR for adding wires to stgc

Replacing gasGapPitch with gasGapThickness

First draft of  wire structure added to sTgcs. In process of making additional changes to the structure

Duplicating the numStrips function for measID and measHash successful

Adding Identifier dependency tofunctions retrieving basic strip properties. Also retrieving these values through striplayer as opposed to retrieving then direclty from stripDesign done previously.

Converting int to uint in R3 wire properties

Latest updates on resolving the global strippositions

introduce getter for wire design and fix build of wire design

adapt stripDesign getter in stgc fast digi

Adding indentifier as an input argument for functions that retrieve gasgap dimensions

Johannes has no alcohol

Fix layer transformations
parent d7909617
No related branches found
No related tags found
No related merge requests found
Showing
with 633 additions and 281 deletions
......@@ -143,18 +143,18 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
//// All the Vectors
for (int lay = 1; lay <= numLayers; ++lay) {
// const Identifier layWireID =id_helper.channelID(stIndex, stEta, stPhi,
// stML, lay, sTgcIdHelper::sTgcChannelTypes::Wire, 1);
const Identifier layWireID =id_helper.channelID(stIndex, stEta, stPhi,
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);
/*
//// Wire Dimensions
int numWires = readoutEle->numberOfWires(layWireID);
int firstWireGroupWidth = readoutEle->getDesign(layWireID)->firstPitch;
unsigned int numWires = readoutEle->numberOfWires(layWireID);
unsigned int firstWireGroupWidth = readoutEle->getDesign(layWireID)->firstPitch;
int numWireGroups = readoutEle->getDesign(layWireID)->nGroups;
int wireCutout = readoutEle->getDesign(layWireID)->wireCutout;
double wireCutout = readoutEle->getDesign(layWireID)->wireCutout;
double wirePitch = readoutEle->wirePitch();
double wireWidth = readoutEle->getDesign(layWireID)->inputWidth;
double wireGroupWidth = readoutEle->getDesign(layWireID)->groupWidth;
......@@ -176,18 +176,25 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
ATH_MSG_WARNING("The following wire group ID is not valid: " << wireGroupID);
}
Amg::Vector3D wireGroupPos(Amg::Vector3D::Zero());
Amg::Vector2D localWireGroupPos(Amg::Vector2D::Zero());
readoutEle->stripPosition(wireGroupID, localWireGroupPos);
m_localWireGroupPos.push_back(localWireGroupPos);
readoutEle->stripGlobalPosition(wireGroupID, wireGroupPos);
m_globalWireGroupPos.push_back(wireGroupPos);
m_wireGroupNum.push_back(wireGroupIndex);
m_wireGroupGasGap.push_back(lay);
if (wireGroupIndex != 1) continue;
const Amg::Transform3D locToGlob = readoutEle->transform(wireGroupID);
m_wireGroupRot.push_back(locToGlob);
m_wireGroupRotGasGap.push_back(lay);
}
*/
////Strip Dimensions
int numStrips = readoutEle->getDesign(layStripID)->nch;
double stripPitch = readoutEle->channelPitch(layStripID);
double stripWidth = readoutEle->getDesign(layStripID)->inputWidth;
int firstStripPitch = readoutEle->getDesign(layStripID)->firstPitch;
double firstStripPitch = readoutEle->getDesign(layStripID)->firstPitch;
m_numStrips = numStrips;
m_stripPitch = stripPitch;
......@@ -203,10 +210,12 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReado
ATH_MSG_WARNING("The following strip ID is not valid: " << stripID);
}
double stripLength = readoutEle->getDesign(stripID)->channelLength(stripIndex);
Amg::Vector3D stripPos(Amg::Vector3D::Zero());
readoutEle->stripGlobalPosition(stripID, stripPos);
m_globalStripPos.push_back(stripPos);
Amg::Vector3D globalStripPos(Amg::Vector3D::Zero());
Amg::Vector2D localStripPos(Amg::Vector2D::Zero());
readoutEle->stripPosition(stripID, localStripPos);
m_localStripPos.push_back(localStripPos);
readoutEle->stripGlobalPosition(stripID, globalStripPos);
m_globalStripPos.push_back(globalStripPos);
m_stripNum.push_back(stripIndex);
m_stripGasGap.push_back(lay);
m_stripLengths.push_back(stripLength);
......
......@@ -13,6 +13,7 @@
#include "MuonTesterTree/MuonTesterTree.h"
#include "MuonTesterTree/IdentifierBranch.h"
#include "MuonTesterTree/ThreeVectorBranch.h"
#include "MuonTesterTree/TwoVectorBranch.h"
#include "MuonTesterTree/CoordTransformBranch.h"
namespace MuonGM {
......@@ -75,24 +76,30 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm {
/// Rotation matrix of the respective strip layers
MuonVal::CoordSystemsBranch m_stripRot{m_tree, "stripRot"};
MuonVal::VectorBranch<uint8_t>& m_stripRotGasGap{m_tree.newVector<uint8_t>("stripRotGasGap")};
/*
/// Rotation matrix of the respective wireGroup layers
MuonVal::CoordSystemsBranch m_wireGroupRot{m_tree, "wireGroupRot"};
MuonVal::VectorBranch<uint8_t>& m_wireGroupRotGasGap{m_tree.newVector<uint8_t>("wireGroupRotGasGap")};
//// Wire Dimensions
MuonVal::VectorBranch<uint>& m_numWires{m_tree.newVector<uint>("numWires")}; // nWires
MuonVal::VectorBranch<short>& m_firstWireGroupWidth{m_tree.newVector<short>("firstWireGroupWidth")}; // firstWireGroup <= 20
MuonVal::VectorBranch<short>& m_numWireGroups{m_tree.newVector<short>("numWireGroups")}; // nWireGroups >19
MuonVal::VectorBranch<uint>& m_firstWireGroupWidth{m_tree.newVector<uint>("firstWireGroupWidth")}; // firstWireGroup <= 20
MuonVal::VectorBranch<uint>& m_numWireGroups{m_tree.newVector<uint>("numWireGroups")}; // nWireGroups >19
MuonVal::VectorBranch<float>& m_wireCutout{m_tree.newVector<float>("wireCutout")}; // wireCutout ~ 800mm
MuonVal::ScalarBranch<float>& m_wirePitch{m_tree.newScalar<float>("wirePitch")}; // wirePitch 1.8mm
MuonVal::ScalarBranch<float>& m_wireWidth{m_tree.newScalar<float>("wireWidth")}; // wireWidth 0.015mm
MuonVal::ScalarBranch<short>& m_wireGroupWidth{m_tree.newScalar<short>("wireGroupWidth")}; // wireGroupWidth 20
MuonVal::ScalarBranch<uint>& m_wireGroupWidth{m_tree.newScalar<uint>("wireGroupWidth")}; // wireGroupWidth 20
MuonVal::TwoVectorBranch m_localWireGroupPos{m_tree, "localWireGroupPos"};
MuonVal::ThreeVectorBranch m_globalWireGroupPos{m_tree, "globalWireGroupPos"};
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
*/
/// 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
MuonVal::ScalarBranch<float>& m_stripWidth{m_tree.newScalar<float>("stripWidth")}; // stripWidth 2.7mm
MuonVal::VectorBranch<float>& m_firstStripPitch{m_tree.newVector<float>("firstStripPitch")}; // firstStripWidth 1.6/3.2mm
MuonVal::TwoVectorBranch m_localStripPos{m_tree, "localStripPos"};
MuonVal::ThreeVectorBranch m_globalStripPos{m_tree, "globalStripPos"};
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
......
......@@ -65,7 +65,7 @@ StatusCode xAODSimHitTosTGCMeasCnvAlg::execute(const EventContext& ctx) const {
continue;
}
const Amg::Vector3D lHitPos{xAOD::toEigen(simHit->localPosition())};
int channelNumber = readOutEle->stripLayer(simStripLayerIdentifier).design().stripNumber(lHitPos.block<2,1>(0,0));
int channelNumber = readOutEle->stripDesign(simStripLayerIdentifier).stripNumber(lHitPos.block<2,1>(0,0));
Identifier simStripChannelIdentifier = id_helper.channelID(hitId, id_helper.multilayer(hitId), id_helper.gasGap(hitId),1, channelNumber, isValid);
if(channelNumber==-1){
ATH_MSG_WARNING("hit is outside bounds, rejecting it");
......
......@@ -54,12 +54,25 @@ class sTgcReadoutGeomTool : public AthAlgTool,
int wireGroupWidth{0}; //wireGroupWidth
std::vector<double> firstWirePos; //firstWire
//// Pads
std::vector<int> numPadEta; //nPadH
std::vector<int> numPadPhi; //nPadPhi
std::vector<double> firstPadHeight; //firstPadH
std::vector<double> padHeight; //padH
///Extra Pad Variables
std::vector<int> PadPhiShift_A;
std::vector<int> PadPhiShift_C;
double anglePadPhi{0.};
std::vector<double> firstPadPhiDivision_A;
std::vector<double> firstPadPhiDivision_C;
std::vector<int> firstPadRow;
double lPadWidth{0.};
std::vector<int> rankPadEta; //rankPadH
std::vector<int> rankPadPhi; //rankPadPhi
double sPadWidth{0.};
double gasTck{0.}; //gasTck
......@@ -71,11 +84,30 @@ class sTgcReadoutGeomTool : public AthAlgTool,
using CutOutTable = std::map<Identifier, std::vector<CutOutArea>>;
std::set<StripDesignPtr, StripDesignSorter> stripDesigns{};
std::set<WireDesignPtr, WireDesignSorter> wireGroupDesigns{};
ParamBookTable parameterBook{};
CutOutTable cutOuts{};
};
/// Helper struct to translate the GeoModelShape into the parameters
/// used to construct the readout element dimensions
struct sTgcShape{
/// Height of the module in radial direction
double halfHeight{0.};
/// Width of the module at the upper edge
double longWidth{0.};
/// Width of the module ath the bottom edge
double shortWidth{0.};
/// Thickness of the shape along global z
double thickness{0.};
/// Cut out of the module
double yCutOut{0.};
};
sTgcShape extractParameters(const GeoShape* shape) const;
/// Retrieves the auxillary tables from the database
StatusCode readParameterBook(FactoryCache& cache);
/// Loads the chamber dimensions from GeoModel
......
......@@ -38,6 +38,36 @@ sTgcReadoutGeomTool::sTgcReadoutGeomTool(const std::string& type,
declareInterface<IMuonReadoutGeomTool>(this);
}
sTgcReadoutGeomTool::sTgcShape sTgcReadoutGeomTool::extractParameters(const GeoShape* shape) const {
sTgcShape result{};
if (shape->typeID() == GeoTrd::getClassTypeID()) {
const GeoTrd* trd = static_cast<const GeoTrd*>(shape);
result.longWidth = trd->getXHalfLength1();
result.shortWidth = trd->getXHalfLength2();
result.halfHeight = trd->getYHalfLength1();
result.thickness = trd->getZHalfLength();
} else if (shape->typeID() == GeoSimplePolygonBrep::getClassTypeID()) {
const GeoSimplePolygonBrep* poly = static_cast<const GeoSimplePolygonBrep*>(shape);
std::vector<Amg::Vector2D> polyEdges = m_geoUtilTool->polygonEdges(*poly);
result.thickness = poly->getDZ() * Gaudi::Units::mm;
if (polyEdges.size() == 4) {
result.longWidth = 0.5 * (polyEdges[0].x() - polyEdges[1].x()) * Gaudi::Units::mm;
result.shortWidth = 0.5 * (polyEdges[3].x() - polyEdges[2].x()) * Gaudi::Units::mm;
result.halfHeight = 0.5 * (polyEdges[0].y() - polyEdges[3].y()) * Gaudi::Units::mm;
} else if (polyEdges.size() == 6) {
result.longWidth = 0.5 * (polyEdges[0].x() - polyEdges[1].x()) * Gaudi::Units::mm;
result.shortWidth = 0.5 * (polyEdges[4].x() - polyEdges[3].x()) * Gaudi::Units::mm;
result.halfHeight = 0.5 * (polyEdges[0].y() - polyEdges[4].y()) * Gaudi::Units::mm;
result.yCutOut = (polyEdges[1].y() - polyEdges[2].y()) * Gaudi::Units::mm;
}
} else {
ATH_MSG_FATAL("Unknown shape type "<<shape->type());
throw std::runtime_error("Invalid shape to extract sTGC parameters");
}
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));
......@@ -48,32 +78,14 @@ StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& d
}
ATH_MSG_DEBUG("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
/// The half sizes of the
if (shape->typeID() != GeoSimplePolygonBrep::getClassTypeID()) {
ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" expect shape to be a Trapezoid but it's "<<m_geoUtilTool->dumpShape(shape));
return StatusCode::FAILURE;
}
/// Registering vertices of the Polygon
const GeoSimplePolygonBrep* simplePoly = static_cast<const GeoSimplePolygonBrep*>(shape);
std::vector<Amg::Vector2D> polyChamb = m_geoUtilTool->polygonEdges(*simplePoly);
/// Building sTGC chamber
if (polyChamb.size() == 4) {
define.lHalfChamberLength = 0.5 * (polyChamb[0].x() - polyChamb[1].x()) * Gaudi::Units::mm;
define.sHalfChamberLength = 0.5 * (polyChamb[3].x() - polyChamb[2].x()) * Gaudi::Units::mm;
define.halfChamberTck = simplePoly->getDZ() * Gaudi::Units::mm;
define.halfChamberHeight = 0.5 * (polyChamb[0].y() - polyChamb[3].y()) * Gaudi::Units::mm;
define.yCutout = 0.;
}
else if (polyChamb.size() == 6) {
define.lHalfChamberLength = 0.5 * (polyChamb[0].x() - polyChamb[1].x()) * Gaudi::Units::mm;
define.sHalfChamberLength = 0.5 * (polyChamb[4].x() - polyChamb[3].x()) * Gaudi::Units::mm;
define.halfChamberTck = simplePoly->getDZ() * Gaudi::Units::mm;
define.halfChamberHeight = 0.5 * (polyChamb[0].y() - polyChamb[4].y()) * Gaudi::Units::mm;
define.yCutout = (polyChamb[1].y() - polyChamb[2].y()) * Gaudi::Units::mm;
} else {
ATH_MSG_FATAL("Found unusual polygon with number of vertices:" << polyChamb.size());
return StatusCode::FAILURE;
}
sTgcShape modPars = extractParameters(shape);
define.sHalfChamberLength = modPars.shortWidth;
define.lHalfChamberLength = modPars.longWidth;
define.halfChamberHeight = modPars.halfHeight;
define.halfChamberTck = modPars.thickness;
define.yCutout = modPars.yCutOut;
ATH_MSG_VERBOSE("chamber length (L/S) is: " << 2*define.lHalfChamberLength << "/"
<< 2*define.sHalfChamberLength << " chamber height is: "
<< 2*define.halfChamberHeight << " chamber thickness is: " << 2*define.halfChamberTck);
......@@ -93,55 +105,62 @@ StatusCode sTgcReadoutGeomTool::loadDimensions(sTgcReadoutElement::defineArgs& d
if (parBookItr == factoryCache.parameterBook.end()) {
ATH_MSG_FATAL("The chamber "<<define.chambDesign<<" is not part of the WSTGC table");
return StatusCode::FAILURE;
}
}
const wSTGCTable& paramBook{parBookItr->second};
define.gasTck = paramBook.gasTck;
/// Gasgaps are trapezoid
unsigned int gasGap{0};
for (physVolWithTrans& gapVol : allGasGaps) {
/// WireGroupDesign will join here
StripDesignPtr stripDesign = std::make_unique<StripDesign>();
const GeoShape* gapShape = m_geoUtilTool->extractShape(gapVol.physVol);
if (gapShape->typeID() == GeoTrd::getClassTypeID()) {
const GeoTrd* gapTrd = static_cast<const GeoTrd*>(gapShape);
double halfHeight = gapTrd->getZHalfLength();
double halfShortY = std::min(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
double halfLongY = std::max(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
double firstStripPos = -halfHeight + paramBook.firstStripPitch[gasGap];
stripDesign->defineTrapezoid(halfShortY, halfLongY, halfHeight);
WireDesignPtr wireGroupDesign = std::make_unique<WireGroupDesign>();
sTgcShape gapPars = extractParameters(m_geoUtilTool->extractShape(gapVol.physVol));
if (true || !gapPars.yCutOut) {
//StripDesign
double firstStripPos = -gapPars.halfHeight + paramBook.firstStripPitch[gasGap] - 0.5 * paramBook.stripPitch;
define.firstStripPitch = paramBook.firstStripPitch;
ATH_MSG_DEBUG("FirstStripPos is: " << Amg::toString(firstStripPos, 2) << " and the half height is: " << gapPars.halfHeight);
stripDesign->defineTrapezoid(gapPars.shortWidth, gapPars.longWidth, gapPars.halfHeight);
stripDesign->defineStripLayout(Amg::Vector2D{firstStripPos, 0.},
paramBook.stripPitch, paramBook.stripWidth, paramBook.numStrips);
ATH_MSG_VERBOSE("Created new strip design "<<(*stripDesign));
} else if (gapShape->typeID() == GeoSimplePolygonBrep::getClassTypeID()) {
/// Fetching edges of the diamond gasGap
const GeoSimplePolygonBrep* gapPoly = static_cast<const GeoSimplePolygonBrep*>(gapShape);
ATH_MSG_VERBOSE("Gas gap dimensions: "<<m_geoUtilTool->dumpShape(gapShape));
std::vector<Amg::Vector2D> polyGap = m_geoUtilTool->polygonEdges(*gapPoly);
double halfLongY = 0.5 * (polyGap[0].x() - polyGap[1].x()) * Gaudi::Units::mm;
double halfShortY = 0.5 * (polyGap[4].x() - polyGap[3].x()) * Gaudi::Units::mm;
double halfHeight = 0.5 * (polyGap[0].y() - polyGap[4].y()) * Gaudi::Units::mm;
double yCut = (polyGap[1].y() - polyGap[2].y()) * Gaudi::Units::mm;
double firstStripPos = -2*halfHeight + yCut + paramBook.firstStripPitch[gasGap];
///Need Diamond function
stripDesign->defineStripLayout(Amg::Vector2D{firstStripPos, 0.},
paramBook.stripPitch,
paramBook.stripWidth,
paramBook.numStrips);
stripDesign->defineTrapezoid(halfShortY, halfLongY, halfHeight);
ATH_MSG_VERBOSE("Added new strip design "<<(*stripDesign));
} else {
ATH_MSG_FATAL("Failed to extract a geo shape");
return StatusCode::FAILURE;
}
ATH_MSG_VERBOSE("Created new strip design "<<(*stripDesign));
/// Strip rotation by 90 degrees (Not sure if required)
gapVol.transform = gapVol.transform * Amg::getRotateY3D(-90. * Gaudi::Units::degree);
++gasGap;
//WireGroupDesign
wireGroupDesign->defineTrapezoid(gapPars.shortWidth, gapPars.longWidth, 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.
wireGroupDesign->declareGroup(paramBook.firstWireGroupWidth[gasGap]);
for (uint wireGr=2; wireGr<numWireGroups; wireGr++){
wireGroupDesign->declareGroup(paramBook.wireGroupWidth);
}
unsigned int lastWireGroup = (paramBook.numWires[gasGap] - wireGroupDesign->nAllWires());
wireGroupDesign->declareGroup(lastWireGroup);
/// Defining the wire group layout
/// firstWirePos locates the y-coordinate of the beginning of first WireGroup
double firstWirePos = paramBook.firstWirePos[gasGap];
wireGroupDesign->defineStripLayout(Amg::Vector2D{firstWirePos, 0.},
paramBook.wirePitch,
paramBook.wireWidth,
numWireGroups);
wireGroupDesign->defineWireCutout(paramBook.wireCutout[gasGap]);
}
/// Stacking strip and wireGroup layers
++gasGap;
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;
stripDesign = (*factoryCache.stripDesigns.emplace(stripDesign).first);
StripLayer stripLayer(gapVol.transform, stripDesign,
sTgcReadoutElement::createHash(gasGap, sTgcIdHelper::Strip, 0));
ATH_MSG_VERBOSE("Added new strip layer at "<<stripLayer);
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;
}
......@@ -171,12 +190,9 @@ StatusCode sTgcReadoutGeomTool::buildReadOutElements(MuonDetectorManager& mgr) {
#endif
for (auto& [key, pv] : mapFPV) {
/// The keys should be formatted like UPDATE!!
/// <STATION_NAME>_<MUON_CHAMBERTYPE>_etc. The <MUON_CHAMBERTYPE> also
/// indicates whether we're dealing with a MDT / TGC / CSC / RPC chamber
/// If we are dealing with a MDT chamber, then there are 3 additional
/// properties encoded into the chamber
/// <STATIONETA>_(<STATIONPHI>-1)_ML
/// Key formatted as follows for sTGC:
/// <sTGC>_<L/S + MODULE TYPE>_<QUADRUPLET NUMBER>_<ETA INDEX>_<PHI INDEX + 1>
/// e.g. sTGC_STL1QL2_1_6_1 .
std::vector<std::string> key_tokens = tokenize(key, "_");
if (key_tokens.size() != 5 ||
key_tokens[0].find("sTGC") == std::string::npos)
......@@ -193,6 +209,7 @@ StatusCode sTgcReadoutGeomTool::buildReadOutElements(MuonDetectorManager& mgr) {
#ifndef SIMULATIONBASE
define.layerBounds = layerBounds;
#endif
//Need identifier to get multilayer, the following constants don't matter.
define.detElId = idHelper.channelID(stName, stEta, stPhi, ml, 1, sTgcIdHelper::sTgcChannelTypes::Strip, 1, isValid);
if (!isValid) {
ATH_MSG_FATAL("Failed to build a good identifier out of " << key);
......@@ -242,6 +259,17 @@ 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_A = tokenizeInt(record->getString("PadPhiShift_A"), ";");
parBook.PadPhiShift_C = tokenizeInt(record->getString("PadPhiShift_C"), ";");
parBook.anglePadPhi = record->getDouble("anglePadPhi");
parBook.firstPadPhiDivision_A = tokenizeDouble(record->getString("firstPadPhiDivision_A"), ";");
parBook.firstPadPhiDivision_C = tokenizeDouble(record->getString("firstPadPhiDivision_C"), ";");
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.gasTck = record->getDouble("gasTck");
......@@ -262,6 +290,18 @@ StatusCode sTgcReadoutGeomTool::readParameterBook(FactoryCache& cache) {
<< " Pads in Phi: " << parBook.numPadPhi
<< " firstPadHeight: " << parBook.firstPadHeight
<< " padHeight: " << parBook.padHeight
///ExtraPadVariables
<< " PadPhiShift_A: " << parBook.PadPhiShift_A
<< " PadPhiShift_C: " << parBook.PadPhiShift_C
<< " anglePadPhi: " << parBook.anglePadPhi
<< " firstPadPhiDivision_A: " << parBook.firstPadPhiDivision_A
<< " firstPadPhiDivision_C: " << parBook.firstPadPhiDivision_C
<< " firstPadRow: " << parBook.firstPadRow
<< " lPadWidth: " << parBook.lPadWidth
<< " rankPadEta: " << parBook.rankPadEta
<< " rankPadPhi: " << parBook.rankPadPhi
<< " sPadWidth: " << parBook.sPadWidth
<< " gasGapTck: " << parBook.gasTck);
}
return StatusCode::SUCCESS;
......
......@@ -72,8 +72,8 @@ StatusCode GeoModelsTgcTest::execute() {
ATH_MSG_FATAL("Failed to retrieve "<<m_geoCtxKey.fullKey());
return StatusCode::FAILURE;
}
const ActsGeometryContext& gctx{**geoContextHandle};
for (const Identifier& test_me : m_testStations) {
ATH_MSG_DEBUG("Test retrieval of sTgc detector element "<<m_idHelperSvc->toStringDetEl(test_me));
const sTgcReadoutElement* reElement = m_detMgr->getsTgcReadoutElement(test_me);
......@@ -101,36 +101,57 @@ 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::Strip/*Wire*/; ++chType) {
unsigned int numStrip = reElement->numStrips();
for (unsigned int strip = 1; strip < numStrip ; ++strip) {
bool isValid{false};
const Identifier chId = id_helper.channelID(reElement->identify(),
for (int chType = sTgcIdHelper::sTgcChannelTypes::Strip/*Pad*/; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
unsigned int numChannel = 0;
bool isValidLay{false};
const Identifier layID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, 1, isValidLay);
if (!isValidLay) {
continue;
}
switch(chType) {
case sTgcIdHelper::sTgcChannelTypes::Strip:
numChannel = reElement->numStrips(layID);
break;
case sTgcIdHelper::sTgcChannelTypes::Wire:
numChannel = reElement->numWireGroups(layer);
break;
}
for (unsigned int channel = 1; channel < numChannel ; ++channel) {
bool isValidCh{false};
const Identifier chID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, strip, isValid);
if (!isValid) {
layer, chType, channel, isValidCh);
if (!isValidCh) {
continue;
}
/// Test the back and forth conversion of the Identifier
const IdentifierHash measHash = reElement->measurementHash(chId);
const IdentifierHash layHash = reElement->layerHash(chId);
const IdentifierHash measHash = reElement->measurementHash(chID);
const IdentifierHash layHash = reElement->layerHash(chID);
ATH_MSG_VERBOSE("layer: "<<layer<<", chType: "<<chType
<<" --> layerHash: "<<static_cast<unsigned>(layHash));
const Identifier backCnv = reElement->measurementId(measHash);
if (backCnv != chId) {
ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chId)
if (backCnv != chID) {
ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chID)
<<" failed. Got "<<m_idHelperSvc->toString(backCnv));
return StatusCode::FAILURE;
}
if (layHash != reElement->layerHash(measHash)) {
ATH_MSG_FATAL("Constructing the layer hash from the identifier "<<
m_idHelperSvc->toString(chId)<<" leads to different layer hashes "<<
m_idHelperSvc->toString(chID)<<" leads to different layer hashes "<<
layHash<<" vs. "<< reElement->layerHash(measHash));
return StatusCode::FAILURE;
}
ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chId)<<" strip position "
<<Amg::toString(reElement->stripPosition(gctx, measHash)));
if (chType == sTgcIdHelper::sTgcChannelTypes::Strip) {
ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chID)<<" strip position "
<<Amg::toString(reElement->globalChannelPosition(gctx, measHash)));
}
else if (chType == sTgcIdHelper::sTgcChannelTypes::Wire) {
ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chID)<<" wireGroup position "
<<Amg::toString(reElement->globalChannelPosition(gctx, measHash)));
}
}
}
}
......@@ -143,7 +164,6 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
const ActsGeometryContext& gctx,
const sTgcReadoutElement* reElement){
m_stIndex = reElement->stationName();
m_stEta = reElement->stationEta();
m_stPhi = reElement->stationPhi();
......@@ -152,55 +172,97 @@ StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx,
///
m_numLayers = reElement->numLayers();
m_yCutout = reElement->yCutout();
m_gasTck = reElement->gasGapPitch();
m_gasTck = reElement->gasGapThickness();
///
m_sChamberLength = reElement->sChamberLength();
m_lChamberLength = reElement->lChamberLength();
m_chamberHeight = reElement->chamberHeight();
///
m_sGapLength = reElement->sGapLength();
m_lGapLength = reElement->lGapLength();
m_gapHeight = reElement->gapHeight();
///
m_numStrips = reElement->numStrips();
m_stripPitch = reElement->stripPitch();
m_stripWidth = reElement->stripWidth();
///Wires and Pads will also come here
///Pads will come here
/// Dump the local to global transformation of the readout element
const Amg::Transform3D& transform{reElement->localToGlobalTrans(gctx)};
m_readoutTransform = transform;
const sTgcIdHelper& id_helper{m_idHelperSvc->stgcIdHelper()};
for (int layer = 1; layer <= reElement->numLayers(); ++layer) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::Pad; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
for (int chType = sTgcIdHelper::sTgcChannelTypes::/*Pad*/Strip; chType <= sTgcIdHelper::sTgcChannelTypes::Wire; ++chType) {
unsigned int numWireGroup = 0;
/// Use idHelper to get the identifier
bool isValidLay{false};
const Identifier layID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, 1, isValidLay);
if (!isValidLay) {
continue;
}
/// Gas Gap dimensions
m_sGapLength = reElement->sGapLength(layID);
m_lGapLength = reElement->lGapLength(layID);
m_gapHeight = reElement->gapHeight(layID);
switch (chType) {
case sTgcIdHelper::sTgcChannelTypes::Strip:
unsigned int numStrip = reElement->numStrips();
for (unsigned int strip = 1; strip <= numStrip ; ++strip) {
bool isValid{false};
m_numStrips = reElement->numStrips(layID);
m_stripPitch = reElement->stripPitch(layID);
m_stripWidth = reElement->stripWidth(layID);
for (unsigned int strip = 1; strip <= reElement->numStrips(layID); ++strip) {
bool isValidStrip{false};
const Identifier stripID = id_helper.channelID(reElement->identify(),
reElement->multilayer(),
layer, chType, strip, isValid);
if (!isValid) {
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_globalStripPos.push_back(reElement->stripPosition(gctx, stripID));
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(strip));
m_stripLengths.push_back(reElement->stripLength(stripID));
if (strip != 1) continue;
const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, stripID);
ATH_MSG_ALWAYS("The local to global transformation on layers is: " << Amg::toString(locToGlob));
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;
case sTgcIdHelper::sTgcChannelTypes::Wire:
m_wireGroupWidth = reElement->wireGroupWidth(layer);
numWireGroup = reElement->numWireGroups(layer);
m_wirePitch = reElement->wirePitch(layID);
m_wireWidth = reElement->wireWidth(layID);
m_numWires.push_back(reElement->numWires(layer));
m_firstWireGroupWidth.push_back(reElement->firstWireGroupWidth(layer));
m_numWireGroups.push_back(numWireGroup);
m_wireCutout.push_back(reElement->wireCutout(layer));
std::cout << "The number of wire groups are:" << numWireGroup << std::endl;
for (unsigned int wireGroup = 1; wireGroup <= numWireGroup; ++wireGroup) {
bool isValidWire{false};
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);
}
break;
}
}
}
......
......@@ -12,6 +12,7 @@
#include <MuonTesterTree/MuonTesterTree.h>
#include <MuonTesterTree/IdentifierBranch.h>
#include <MuonTesterTree/ThreeVectorBranch.h>
#include <MuonTesterTree/TwoVectorBranch.h>
#include <MuonReadoutGeometryR4/MuonDetectorManager.h>
#include <MuonTesterTree/CoordTransformBranch.h>
namespace MuonGMR4{
......@@ -80,27 +81,33 @@ class GeoModelsTgcTest : public AthHistogramAlgorithm{
MuonVal::CoordSystemsBranch m_stripRot{m_tree, "stripRot"};
MuonVal::VectorBranch<uint8_t>& m_stripRotGasGap{m_tree.newVector<uint8_t>("stripRotGasGap")};
/// Rotation matrix of the respective wireGroup layers
MuonVal::CoordSystemsBranch m_wireGroupRot{m_tree, "wireGroupRot"};
MuonVal::VectorBranch<uint8_t>& m_wireGroupRotGasGap{m_tree.newVector<uint8_t>("wireGroupRotGasGap")};
/// 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
MuonVal::ScalarBranch<float>& m_stripWidth{m_tree.newScalar<float>("stripWidth")}; // stripWidth 2.7mm
MuonVal::ThreeVectorBranch m_globalStripPos{m_tree, "globalStripPos"};
MuonVal::TwoVectorBranch m_localStripPos{m_tree, "localStripPos"}; //Position in chamber coordinates
MuonVal::ThreeVectorBranch m_globalStripPos{m_tree, "globalStripPos"}; //Position in ATLAS coordinates
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
/*
//// Wire Dimensions
MuonVal::VectorBranch<uint>& m_numWires{m_tree.newVector<uint>("numWires")}; // nWires
MuonVal::VectorBranch<short>& m_firstWireGroupWidth{m_tree.newVector<short>("firstWireGroupWidth")}; // firstWireGroup <= 20
MuonVal::VectorBranch<short>& m_numWireGroups{m_tree.newVector<short>("numWireGroups")}; // nWireGroups >19
MuonVal::VectorBranch<uint>& m_firstWireGroupWidth{m_tree.newVector<uint>("firstWireGroupWidth")}; // firstWireGroup <= 20
MuonVal::VectorBranch<uint>& m_numWireGroups{m_tree.newVector<uint>("numWireGroups")}; // nWireGroups >19
MuonVal::VectorBranch<float>& m_wireCutout{m_tree.newVector<float>("wireCutout")}; // wireCutout ~ 800mm
MuonVal::ScalarBranch<float>& m_wirePitch{m_tree.newScalar<float>("wirePitch")}; // wirePitch 1.8mm
MuonVal::ScalarBranch<float>& m_wireWidth{m_tree.newScalar<float>("wireWidth")}; // wireWidth 0.015mm
MuonVal::ScalarBranch<short>& m_wireGroupWidth{m_tree.newScalar<short>("wireGroupWidth")}; // wireGroupWidth 20
MuonVal::ThreeVectorBranch m_globalWireGroupPos{m_tree, "globalWireGroupPos"};
MuonVal::ScalarBranch<uint>& m_wireGroupWidth{m_tree.newScalar<uint>("wireGroupWidth")}; // wireGroupWidth 20
MuonVal::TwoVectorBranch m_localWireGroupPos{m_tree, "localWireGroupPos"}; //Position in chamber coordinates
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")};
MuonVal::VectorBranch<uint>& m_numPadEta{m_tree.newVector<uint>("numPadEta")}; //nPadH
......
......@@ -26,7 +26,7 @@ class WireGroupDesign: public StripDesign {
/// set sorting operator
bool operator<(const WireGroupDesign& other) const;
/// Adds a new group of wires to the design.
void declareGroup(const unsigned int numWires);
void declareGroup(const unsigned int x);
/// Returns the number of wires in a given group.
unsigned int numWiresInGroup(unsigned int groupNum) const;
/// Returns the number of all wires
......@@ -61,6 +61,11 @@ class WireGroupDesign: public StripDesign {
double wireLength(unsigned int groupNum,
unsigned int wireNum) const;
/// Extract the wireCutout for a wireGroup layer
double wireCutout() const;
/// Define the wirelength available for digitization in a gasGap
void defineWireCutout(const double wireCutout);
private:
void print(std::ostream& ostr) const override final;
Amg::Vector2D stripPosition(int stripNum) const override final;
......@@ -77,6 +82,10 @@ class WireGroupDesign: public StripDesign {
using wireGrpVector = std::vector<wireGroup>;
using wireGrpVectorItr = wireGrpVector::const_iterator;
wireGrpVector m_groups{};
/// Wire length available for digitization in a gas Gap
double m_wireCutout{0};
};
struct WireDesignSorter{
......
......@@ -93,6 +93,7 @@ namespace MuonGMR4 {
const int wire = std::round(wirePitches.value_or(-1.) / stripPitch()) +1;
return std::make_pair(wireGrp, wire);
}
}
......
......@@ -6,6 +6,8 @@
#include <MuonReadoutGeometryR4/MuonReadoutElement.h>
#include <MuonReadoutGeometryR4/StripDesign.h>
#include <MuonReadoutGeometryR4/WireGroupDesign.h>
//#include <MuonReadoutGeometryR4/DiamondStripDesign.h>
#include <MuonReadoutGeometryR4/StripLayer.h>
#ifndef SIMULATIONBASE
# include "Acts/Surfaces/TrapezoidBounds.hpp"
......@@ -58,12 +60,14 @@ class sTgcReadoutElement : public MuonReadoutElement {
/// Diamond cutout height
double yCutout{0.};
/// Pitch of the first strip of the gas gap
//// firstStripPitch needed for the globalChannelPosition function
std::vector<double> firstStripPitch{};
std::vector<StripLayer> stripLayers{};
std::vector<StripLayer> wireGroupLayers{};
StripDesignPtr stripDesign{nullptr};
StripDesignPtr wireGroupDesign{nullptr};
WireDesignPtr wireGroupDesign{nullptr};
#ifndef SIMULATIONBASE
ActsTrk::SurfaceBoundSetPtr<Acts::TrapezoidBounds> layerBounds{};
......@@ -93,12 +97,6 @@ class sTgcReadoutElement : public MuonReadoutElement {
/// Distance between 2 gas gaps
double gasGapPitch() const;
/// Length of gas Gap on short side
double sGapLength() const;
/// Length of gas Gap on long side
double lGapLength() const;
/// Height of gas Gap
double gapHeight() const;
/// Thickness of the chamber
double thickness() const override final; //chamberTck
/// Width of the chamber frame on the short side
......@@ -113,38 +111,69 @@ class sTgcReadoutElement : public MuonReadoutElement {
double gasGapThickness() const;
/// Returns the yCutout value of the chamber
double yCutout() const;
/// Gas Gaps
double firstStripPitch(const Identifier& measId) const;
double firstStripPitch(const IdentifierHash& measHash) const;
/// Length of gas Gap on short side
double sGapLength(const Identifier& measId) const;
double sGapLength(const IdentifierHash& measHash) const;
/// Length of gas Gap on long side
double lGapLength(const Identifier& measId) const;
double lGapLength(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;
unsigned int numStrips(const Identifier& measId) const;
unsigned int numStrips(const IdentifierHash& measHash) const;
/// Pitch of a strip
double stripPitch() const;
/// Width of a strip
double stripWidth() const;
double stripPitch(const Identifier& measId) const;
double stripPitch(const IdentifierHash& measHash) const;
/// Width of a strip
double stripWidth(const Identifier& measId) const;
double stripWidth(const IdentifierHash& measHash) const;
///Length of each strip
double stripLength(const int& stripNumb) const;
double stripLength(const Identifier& measId) const;
double stripLength(const IdentifierHash& measHash) const;
/// Number of Channel Types
unsigned int nChTypes() const;
/*
//// Wires
/// Number of wires in the gas gap
std::vector<unsigned int> numWires() const;
/// Number of wires in the first wire group
std::vector<short> firstWireGroupWidth() const;
/// Number of wire groups in the gas gap
std::vector<short> numWireGroups() const;
/// Wire Cutout
std::vector<double> wireCutout() const;
/// Pitch of the wire
double wirePitch{0.};
double wirePitch(const Identifier& measId) const;
double wirePitch(const IdentifierHash& measHash) const;
/// Width of a single wire
double wireWidth{0.};
double wireWidth(const Identifier& measId) const;
double wireWidth(const IdentifierHash& measHash) const;
/// Number of wires in a normal wire group
short wireGroupWidth{0};
*/
Amg::Vector3D stripPosition(const ActsGeometryContext& ctx, const Identifier& measId) const;
Amg::Vector3D stripPosition(const ActsGeometryContext& ctx, const IdentifierHash& measHash) const;
unsigned int wireGroupWidth(unsigned int gasGap) const;
/// Number of wires in the gas gap
unsigned int numWires(unsigned int gasGap) const;
/// Number of wires in the first wire group
unsigned int firstWireGroupWidth(unsigned int gasGap) const;
/// Number of wire groups in the gas gap
unsigned int numWireGroups(unsigned int gasGap) const;
/// Wire Cutout of a gas Gap
double wireCutout(unsigned int gasGap) const;
/// Retrieves the readoutElement Layer given the Identifier/Hash
const StripDesign& stripDesign(const Identifier& measId) const;
const StripDesign& stripDesign(const IdentifierHash& measHash) const;
/// Retrieves the readoutElement Layer given the gasGap
const StripDesign& stripDesign(unsigned int gasGap) const;
/// Retrieves the readoutElement Layer given the Identifier/Hash
const WireGroupDesign& wireDesign(const Identifier& measId) const;
const WireGroupDesign& wireDesign(const IdentifierHash& measHash) const;
/// Retrieves the readoutElement Layer given the gasGap
const WireGroupDesign& wireDesign(unsigned int gasGap) const;
/// Returns the global strip/wire 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
Amg::Vector2D localChannelPosition(const Identifier& measId) const;
Amg::Vector2D localChannelPosition(const IdentifierHash& measHash) const;
/// Constructs the identifier hash from the full measurement Identifier. The
/// hash is always defined w.r.t the specific detector element and used to
......@@ -174,8 +203,11 @@ class sTgcReadoutElement : public MuonReadoutElement {
private:
/// Returns channel position for a given identifierHash
static unsigned int stripNumber(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
static unsigned int gasGapNumber(const IdentifierHash& measHash);
Amg::Transform3D fromGapToChamOrigin(const IdentifierHash& layerHash) const;
Amg::Vector3D chamberStripPos(const IdentifierHash& measHash) const;
......
......@@ -9,20 +9,17 @@ namespace MuonGMR4 {
namespace sTgcIdMeasHashFields {
constexpr unsigned int minusOne = -1;
/// Hash field layout
//// (wireInGrp) | (channel) [1-1024] | (sTgcChannelType) [0-2] | (gasGap -1) [1-4]
//// (wireInGrp) | (channel) [1-512] | IsWireInGrp (0,1) | (sTgcChannelType) [0-2] | (gasGap -1) [1-4]
constexpr unsigned int gasGapShift = 0;
constexpr unsigned int chTypeShift = 3;
constexpr unsigned int chTypeShift = 2;
constexpr unsigned int wireInGrpBit = chTypeShift+ 2;
constexpr unsigned int chanShift = wireInGrpBit + 1;
constexpr unsigned int wireInGrpShift = chanShift +9;
constexpr unsigned int chanShift = chTypeShift + 3;
constexpr unsigned int wireInGrpShift = chanShift + 9;
}
inline double sTgcReadoutElement::chamberHeight() const { return 2.* m_pars.halfChamberHeight; }
inline double sTgcReadoutElement::sChamberLength() const { return 2.* m_pars.sHalfChamberLength; }
inline double sTgcReadoutElement::lChamberLength() const { return 2.* m_pars.lHalfChamberLength; }
inline double sTgcReadoutElement::sGapLength() const { return (m_pars.stripDesign ? 2.*m_pars.stripDesign->shortHalfHeight(): 0.); }
inline double sTgcReadoutElement::lGapLength() const { return (m_pars.stripDesign ? 2.*m_pars.stripDesign->longHalfHeight(): 0.); }
inline double sTgcReadoutElement::gapHeight() const { return (m_pars.stripDesign ? 2.*m_pars.stripDesign->halfWidth(): 0.); }
inline double sTgcReadoutElement::thickness() const { return 2.* m_pars.halfChamberTck; }
inline double sTgcReadoutElement::sFrameWidth() const { return m_pars.sFrameWidth; }
inline double sTgcReadoutElement::lFrameWidth() const { return m_pars.lFrameWidth; }
......@@ -32,10 +29,60 @@ inline unsigned int sTgcReadoutElement::nChTypes() const { return m_pars.nChType
inline double sTgcReadoutElement::gasGapThickness() const { return m_pars.gasTck; }
inline double sTgcReadoutElement::gasGapPitch() const { return m_gasGapPitch; }
inline double sTgcReadoutElement::yCutout() const { return m_pars.yCutout; }
inline unsigned int sTgcReadoutElement::numStrips() const { return (m_pars.stripDesign ? m_pars.stripDesign->numStrips(): 0u); }
inline double sTgcReadoutElement::stripPitch() const { return (m_pars.stripDesign ? m_pars.stripDesign->stripPitch(): 0.); }
inline double sTgcReadoutElement::stripWidth() const { return (m_pars.stripDesign ? m_pars.stripDesign->stripWidth(): 0.); }
inline double sTgcReadoutElement::stripLength(const int& stripNumb) const { return (m_pars.stripDesign ? m_pars.stripDesign->stripLength(stripNumb): 0.); }
inline double sTgcReadoutElement::firstStripPitch(const IdentifierHash& measHash) const { return m_pars.firstStripPitch[gasGapNumber(measHash)]; }
inline double sTgcReadoutElement::firstStripPitch(const Identifier& measId) const { return firstStripPitch(measurementHash(measId)); }
inline double sTgcReadoutElement::sGapLength(const Identifier& measId) const { return 2*stripDesign(measId).shortHalfHeight(); }
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::gapHeight(const Identifier& measId) const { return 2*stripDesign(measId).halfWidth(); }
inline double sTgcReadoutElement::gapHeight(const IdentifierHash& measHash) const { return 2*stripDesign(measHash).halfWidth(); }
inline unsigned int sTgcReadoutElement::numStrips(const Identifier& measId) const { return stripDesign(measId).numStrips(); }
inline unsigned int sTgcReadoutElement::numStrips(const IdentifierHash& measHash) const { return stripDesign(measHash).numStrips(); }
inline double sTgcReadoutElement::stripPitch(const Identifier& measId) const { return stripDesign(measId).stripPitch(); }
inline double sTgcReadoutElement::stripPitch(const IdentifierHash& measHash) const { return stripDesign(measHash).stripPitch(); }
inline double sTgcReadoutElement::stripWidth(const Identifier& measId) const { return stripDesign(measId).stripWidth(); }
inline double sTgcReadoutElement::stripWidth(const IdentifierHash& measHash) const { return stripDesign(measHash).stripWidth(); }
inline double sTgcReadoutElement::stripLength(const Identifier& measId) const { unsigned int channel = m_idHelper.channel(measId);
return stripDesign(measId).stripLength(channel); }
inline double sTgcReadoutElement::stripLength(const IdentifierHash& measHash) const { unsigned int channel = m_idHelper.channel(measurementId(measHash));
return stripDesign(measHash).stripLength(channel); }
inline double sTgcReadoutElement::wirePitch(const Identifier& measId) const { return wireDesign(measId).stripPitch(); }
inline double sTgcReadoutElement::wirePitch(const IdentifierHash& measHash) const { return wireDesign(measHash).stripPitch(); }
inline double sTgcReadoutElement::wireWidth(const Identifier& measId) const { return wireDesign(measId).stripWidth(); }
inline double sTgcReadoutElement::wireWidth(const IdentifierHash& measHash) const { return wireDesign(measHash).stripWidth(); }
inline unsigned int sTgcReadoutElement::wireGroupWidth(unsigned int gasGap) const { return wireDesign(gasGap).numWiresInGroup(2); }
inline unsigned int sTgcReadoutElement::numWires(unsigned int gasGap) const {return wireDesign(gasGap).nAllWires();}
inline unsigned int sTgcReadoutElement::numWireGroups(unsigned int gasGap) const { return wireDesign(gasGap).numStrips();}
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 const StripDesign& sTgcReadoutElement::stripDesign(const Identifier& measId) const {
unsigned int gasGap = m_idHelper.gasGap(measId);
return m_pars.stripLayers[gasGap-1].design();
}
inline const StripDesign& sTgcReadoutElement::stripDesign(const IdentifierHash& measHash) const {
return stripDesign(measurementId(measHash));
}
inline const StripDesign& sTgcReadoutElement::stripDesign(unsigned int gasGap) const {
return m_pars.stripLayers[gasGap-1].design();
}
inline const WireGroupDesign& sTgcReadoutElement::wireDesign(const Identifier& measId) const {
unsigned int gasGap = m_idHelper.gasGap(measId);
return static_cast<const WireGroupDesign&>(m_pars.wireGroupLayers[gasGap-1].design());
}
inline const WireGroupDesign& sTgcReadoutElement::wireDesign(const IdentifierHash& measHash) const {
return wireDesign(measurementId(measHash));
}
inline const WireGroupDesign& sTgcReadoutElement::wireDesign(unsigned int gasGap) const {
return static_cast<const WireGroupDesign&>(m_pars.wireGroupLayers[gasGap-1].design());
}
inline IdentifierHash sTgcReadoutElement::measurementHash(const Identifier& measId) const {
if (idHelperSvc()->detElId(measId) != identify()) {
ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
......@@ -50,10 +97,10 @@ inline IdentifierHash sTgcReadoutElement::createHash(const unsigned int gasGap,
const unsigned int channel,
const unsigned int wireInGrp) {
using namespace sTgcIdMeasHashFields;
/// Construct the Hash such that (channel) | (channelType) | (gasGap -1)
/// Construct the Hash such that (channel) | WireInGrpBit (0,1) | (channelType) | (gasGap -1)
if (channelType == ReadoutChannelType::WireInGrp) {
const unsigned int readOutHash = static_cast<unsigned int>(createHash(gasGap, ReadoutChannelType::Wire, channel));
return IdentifierHash {wireInGrp << wireInGrpShift | wireInGrpBit | readOutHash};
return IdentifierHash {wireInGrp << wireInGrpShift | (1<<wireInGrpBit) | readOutHash};
}
return IdentifierHash{ channel << chanShift | channelType << chTypeShift | (gasGap -1) };
}
......@@ -93,17 +140,18 @@ inline IdentifierHash sTgcReadoutElement::layerHash(const Identifier& measId) co
return createHash(m_idHelper.gasGap(measId), m_idHelper.channelType(measId), 0);
}
inline Amg::Vector2D sTgcReadoutElement::localChannelPosition(const Identifier& measId) const { return localChannelPosition(measurementHash(measId)); }
inline Amg::Vector3D sTgcReadoutElement::globalChannelPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
return globalChannelPosition(ctx, measurementHash(measId));
}
inline Amg::Vector3D sTgcReadoutElement::stripPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
return stripPosition(ctx, measurementHash(measId));
}
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));
//return m_pars.stripLayers[m_idHelper.gasGap(measId)-1];
}
} // namespace MuonGMR4
......
......@@ -34,7 +34,7 @@ namespace MuonGMR4{
{
const Amg::Vector2D dP = m_firstStripPos - other.m_firstStripPos;
if (std::hypot(dP.x(), dP.y()) > tolerance) {
if (dP.x() > tolerance) return dP.x()< 0.;
if (std::abs(dP.x()) > tolerance) return dP.x()< 0.;
return dP.y() < 0.;
}
}
......
......@@ -46,4 +46,8 @@ namespace MuonGMR4{
}
return m_groups[grpIdx].numWires;
}
}
\ No newline at end of file
double WireGroupDesign::wireCutout() const {return m_wireCutout;}
void WireGroupDesign::defineWireCutout(const double wireCutout){m_wireCutout=wireCutout;}
}
......@@ -31,7 +31,7 @@ StatusCode sTgcReadoutElement::initElement() {
ATH_MSG_FATAL("The readout element "<<idHelperSvc()->toStringDetEl(identify())<<" has no assigned alignable node");
return StatusCode::FAILURE;
}
if (m_pars.stripLayers.empty()) {
if (m_pars.stripLayers.empty() || m_pars.wireGroupLayers.empty()) {
ATH_MSG_FATAL("The readout element "<<idHelperSvc()->toStringDetEl(identify())<<" doesn't have any layers defined");
return StatusCode::FAILURE;
}
......@@ -46,29 +46,97 @@ StatusCode sTgcReadoutElement::initElement() {
return toStation(store) * fromGapToChamOrigin(hash);
}));
}
for (unsigned int layer = 0; layer < m_pars.wireGroupLayers.size(); ++layer) {
IdentifierHash layHash{layer};
if (gasGapNumber(m_pars.wireGroupLayers[layer].hash()) != layHash) {
ATH_MSG_FATAL("Layer "<<m_pars.wireGroupLayers[layer]<<" has a very strange hash. Expect "<<layer);
return StatusCode::FAILURE;
}
ATH_CHECK(insertTransform(m_pars.wireGroupLayers[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();
center(gctx, createHash(2, sTgcIdHelper::sTgcChannelTypes::Strip, 0))).mag();
return StatusCode::SUCCESS;
}
Amg::Transform3D sTgcReadoutElement::fromGapToChamOrigin(const IdentifierHash& hash) const{
unsigned int layIdx = static_cast<unsigned int>(hash);
unsigned int gasGap = gasGapNumber(hash);
if (gasGap < m_pars.stripLayers.size()) return m_pars.stripLayers[gasGap].toOrigin();
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<<m_pars.stripLayers.size());
return Amg::Transform3D::Identity();
Amg::Transform3D sTgcReadoutElement::fromGapToChamOrigin(const IdentifierHash& measHash) const{
unsigned int layIdx = static_cast<unsigned int>(measHash);
unsigned int gasGap = gasGapNumber(measHash);
if(chType(measHash) == ReadoutChannelType::Strip && gasGap < m_pars.stripLayers.size()) {
return m_pars.stripLayers[gasGap].toOrigin();
}
else if (chType(measHash) == ReadoutChannelType::Wire && gasGap < m_pars.wireGroupLayers.size()) {
return m_pars.wireGroupLayers[gasGap].toOrigin();
}
else {
unsigned int maxReadoutLayers = m_pars.stripLayers.size() + m_pars.wireGroupLayers.size();
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<< maxReadoutLayers);
return Amg::Transform3D::Identity();
}
}
Amg::Vector3D sTgcReadoutElement::stripPosition(const ActsGeometryContext& ctx, const IdentifierHash& measHash) const {
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));
if (!stripCenterOpt) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The strip" << stripNumber(measHash) << "doesn't intersect with the edges of the trapezoid.");
return stripCenter;
}
stripCenter = std::move(*stripCenterOpt);
if (stripNumber(measHash) == 1 && firstStripPitch(measHash) < stripPitch(measHash)) {
stripCenter.x() += 0.25 * stripWidth(measHash);
}
if (stripNumber(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));
if (!wireGroupCenterOpt) {
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wireGroup" << stripNumber(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) {
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)) {
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)));
ATH_MSG_DEBUG("The last wire center after modification is: " << wireGroupCenter.x());
}
return wireGroupCenter;
}
else {
ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<"Invalid channel type: " << chType(measHash));
return Amg::Vector2D::Zero();
}
}
Amg::Vector3D sTgcReadoutElement::globalChannelPosition(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);
if (gasGap < m_pars.stripLayers.size()) {
if (chType(measHash) == ReadoutChannelType::Strip && gasGap < m_pars.stripLayers.size()) {
return localToGlobalTrans(ctx, lHash) * m_pars.stripLayers[gasGap].localStripPos(stripNumber(measHash));
}
else if (chType(measHash) == ReadoutChannelType::Wire && gasGap < m_pars.wireGroupLayers.size()) {
Amg::Vector3D wireGrPos{Amg::Vector3D::Zero()};
Amg::Vector2D localWireGroup = localChannelPosition(measHash);
wireGrPos.block<2,1>(0,0) = std::move(localWireGroup);
return localToGlobalTrans(ctx, lHash) * wireGrPos;
}
ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
<<" is out of range. Maximum range "<<m_pars.stripLayers.size());
return Amg::Vector3D::Zero();
......
......@@ -80,7 +80,7 @@ G4bool sTgcSensitiveDetector::ProcessHits(G4Step* aStep,G4TouchableHistory*) {
// The middle of the gas gap is at X= 0
std::optional<double> travelDist = Amg::intersect<3>(localPos, localDir, Amg::Vector3D::UnitX(), 0.);
std::optional<double> travelDist = Amg::intersect<3>(localPos, localDir, Amg::Vector3D::UnitZ(), 0.);
if (!travelDist) return true;
const Amg::Vector3D locGapCross = localPos + (*travelDist) * localDir;
ATH_MSG_VERBOSE("Propagation to the gas gap center: "<<Amg::toString(locGapCross, 2));
......
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