9#include "GaudiKernel/SystemOfUnits.h"
23 std::stringstream sstr{};
24 sstr <<
"[x,y,z]=(" <<
v.x() <<
"," <<
v.y() <<
"," <<
v.z()
25 <<
") [theta/eta/phi]=(" << (
v.theta() / Gaudi::Units::degree) <<
","
26 <<
v.eta() <<
"," <<
v.phi() <<
")";
33 auto out_file = std::make_unique<TFile>(
m_outFile.value().c_str(),
"RECREATE");
34 if (!out_file || !out_file->IsOpen() || out_file->IsZombie()) {
37 return StatusCode::FAILURE;
39 out_file->mkdir(
"SinglePads");
40 out_file->mkdir(
"ActiveSurfaces");
44 std::unique_ptr<TGraph>&
graph = id_graph.second;
49 const int lay = is_mm ? mm_helper.
gasGap(
id) : st_helper.
gasGap(
id);
50 const std::string ch_name =
53 std::to_string(std::abs(stEta)) + (stEta > 0 ?
"A" :
"C") +
55 std::to_string(ml) +
"L" + std::to_string(lay);
56 TDirectory* dir = out_file->GetDirectory(
"SinglePads");
57 dir->WriteObject(
graph.get(), ch_name.c_str());
59 const int signed_lay =
layerId(
id);
60 std::unique_ptr<TGraph>& lay_graph =
m_nswLayers[signed_lay];
63 std::string lay_name = std::string{is_mm ?
"MMG" :
"STG"} +
"W" +
64 std::to_string(ml) + (stEta > 0 ?
"A" :
"C") +
66 out_file->WriteObject(lay_graph.get(), lay_name.c_str());
71 dir = out_file->GetDirectory(
"ActiveSurfaces");
73 dir->WriteObject(active_area.get(), lay_name.c_str());
76 return StatusCode::SUCCESS;
83 return StatusCode::SUCCESS;
87 return StatusCode::SUCCESS;
88 ATH_MSG_INFO(
"Executing NSWGeoPlottingAlg for the first time");
96 std::unique_ptr<TGraph>& pad_graph = id_graph.second;
98 const int signed_lay =
layerId(
id);
99 std::unique_ptr<TGraph>& wheel_graph =
m_nswLayers[signed_lay];
114 if ((is_mm || std::abs(locPos.y()) < 1.e-3) &&
116 ATH_MSG_ALWAYS(
" Backmapping of the strip number did not work for "
118 << locPos.x() <<
" " << locPos.y() <<
" "
127 pad_graph->SetPoint(pad_graph->GetN(), globPos.x(), globPos.y());
129 wheel_graph->SetPoint(wheel_graph->GetN(), globPos.x(), globPos.y());
136 Amg::Vector2D l_cen{Amg::Vector2D::Zero()}, l_left{Amg::Vector2D::Zero()},
137 l_right{Amg::Vector2D::Zero()};
145 return StatusCode::FAILURE;
147 const int chan = id_helper.
channel(
id);
149 design->
center(chan, l_cen);
155 return StatusCode::SUCCESS;
167 <<
" does not have strip "
168 <<
strip <<
"... Why?");
174 <<
" does not have strip " <<
strip
181 <<
" does not have strip "
182 <<
strip <<
"... Why?");
185 auto uv_intersects = [&]() {
188 return StatusCode::SUCCESS;
189 const int gap = id_helper.
gasGap(
id);
191 if ((ml == 1 && gap == 2) || (ml == 2 && gap == 4))
192 return StatusCode::SUCCESS;
196 const int u_gap = ml == 1 ? 3 : 1;
197 const int v_gap = ml == 1 ? 4 : 2;
202 u_center{Amg::Vector3D::Zero()}, v_center{Amg::Vector3D::Zero()};
204 u_left{Amg::Vector3D::Zero()}, v_left{Amg::Vector3D::Zero()};
206 u_right{Amg::Vector3D::Zero()}, v_right{Amg::Vector3D::Zero()};
208 StatusCode
sc = global_points(x_id, x_left, x_center, x_right);
209 if(
sc.isFailure())
return StatusCode::FAILURE;
210 sc = global_points(u_id, u_left, u_center, u_right);
211 if(
sc.isFailure())
return StatusCode::FAILURE;
212 sc = global_points(v_id, v_left, v_center, v_right);
213 if(
sc.isFailure())
return StatusCode::FAILURE;
219 std::optional<double> uv_isect =
223 ATH_MSG_ERROR(
"Failed to intersect the uv strips for identifiers "
229 return StatusCode::FAILURE;
231 const Amg::Vector3D uv_ipoint = u_center + (*uv_isect) * u_dir;
232 const Amg::Vector2D cen_diff = (uv_ipoint - x_center).block<2, 1>(0, 0);
233 if (cen_diff.dot(cen_diff) > std::numeric_limits<float>::epsilon()) {
240 <<
" intersect at the center of the corresponding x "
241 "strip. But they don't. "
244 <<
" vs." << std::endl
250 std::optional<double> ux_isect =
253 ATH_MSG_ERROR(
"Failed to intersect the ux strips for identifiers "
259 return StatusCode::FAILURE;
262 <<
to_string(x_center + (*ux_isect) * x_dir) <<
" "
265 std::optional<double> vx_isect =
268 ATH_MSG_ERROR(
"Failed to intersect the vx strips for identifiers "
274 return StatusCode::FAILURE;
277 <<
to_string(x_center + (*vx_isect) * x_dir) <<
" "
280 return StatusCode::SUCCESS;
286 if (!surface_histo) {
292 double d = std::max(std::max(design->
xSize(), design->
maxYSize()),
294 for (
double x = surf_cent.x() - d;
x <= surf_cent.x() + d;
x += 1) {
295 for (
double y = surf_cent.y() - d;
y <= surf_cent.y() + d;
y += 1) {
304 surface_histo->Fill(
x,
y);
310 return StatusCode::SUCCESS;
316 for (
const std::string station : {
"MML",
"MMS"}) {
323 bool is_valid{
false};
332 for (
int i_layer = 1; i_layer <= 4; ++i_layer) {
334 id_helper.
channelID(module_id, ml, i_layer, 10);
335 m_nswPads[id] = std::make_unique<TGraph>();
337 int signed_layer =
layerId(
id);
339 m_nswLayers[signed_layer] = std::make_unique<TGraph>();
344 "ActiveNSW;x [mm]; y [mm]", 1000, -5001, 5001., 1000,
352 return StatusCode::SUCCESS;
359 int lay = id_helper.
gasGap(
id);
368 int lay = id_helper.
gasGap(
id);
369 return (16 + 4 * (ml - 1) + (lay - 1)) * (
eta > 0 ? 1 : -1);
377 for (
const std::string station : {
"STS",
"STL"}) {
386 bool is_valid{
false};
394 for (
int lay = 1; lay <= 4; ++lay) {
399 for (
const Identifier&
id : {strip_id, wire_id}) {
400 m_nswPads[id] = std::make_unique<TGraph>();
401 int signed_layer =
layerId(
id);
403 m_nswLayers[signed_layer] = std::make_unique<TGraph>();
408 "ActiveNSW;x [mm]; y [mm]", 1000, -5001, 5001., 1000,
417 return StatusCode::SUCCESS;
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_ALWAYS(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
detray::unit< scalar_t > unit
const ServiceHandle< StoreGateSvc > & detStore() const
TGraph * graph(std::string_view graphName, std::string_view tDir="", std::string_view stream="")
Simplify the retrieval of registered TGraphs.
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier multilayerID(const Identifier &channeldID) const
int channel(const Identifier &id) const override
static int stationPhiMin()
int gasGap(const Identifier &id) const override
get the hashes
static int multilayerMin()
static int multilayerMax()
static int stationPhiMax()
int multilayer(const Identifier &id) const
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
virtual int numberOfStrips(const Identifier &layerId) const override final
number of strips per layer
bool insideActiveBounds(const Identifier &id, const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const
boundary check Wrapper Trk::PlaneSurface::insideBounds() taking into account the passivated width
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MMReadoutElement * getMMReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const sTgcReadoutElement * getsTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
StatusCode initMicroMega()
std::map< int, std::unique_ptr< TGraph > > m_nswLayers
Map showing the edges of the 16 layers of the NSW.
std::map< Identifier, std::unique_ptr< TGraph > > m_nswPads
Map containing each PCB of the NSW seperately.
StatusCode execute(const EventContext &ctx) override
Execute method.
std::map< int, std::unique_ptr< TH1 > > m_nswActiveAreas
Map showing the active areas of the NSW to show the passivation.
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
Gaudi::Property< std::string > m_outFile
StatusCode finalize() override
StatusCode initialize() override
int layerId(const Identifier &id) const
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
virtual int numberOfStrips(const Identifier &layerId) const override final
number of strips per layer
const std::string & stationNameString(const Identifier &id) const
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const override
This method calls the inside() method of the Bounds.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
This is the base class for all tracking detector elements with read-out relevant information.
virtual const Amg::Vector3D & center() const =0
Return the center of the element.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
int multilayer(const Identifier &id) const
static int stationPhiMax()
int channelType(const Identifier &id) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
static int multilayerMax()
static int stationPhiMin()
static int stationEtaMin()
static int multilayerMin()
static int stationEtaMax()
int gasGap(const Identifier &id) const override
get the hashes
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
Identifier multilayerID(const Identifier &channeldID) const
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the Athena extensions are properly loaded.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
bool center(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the center on the strip.
bool leftEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the left edge of the strip.
int numberOfMissingBottomStrips() const
Returns the number of missing bottom strips.
bool rightEdge(int channel, Amg::Vector2D &pos) const
STRIPS ONLY: Returns the right edge of the strip.
double hasStereoAngle() const
returns whether the stereo angle is non-zero
int channelNumber(const Amg::Vector2D &pos) const
calculate local channel number, range 1=nstrips like identifiers. Returns -1 if out of range