ATLAS Offline Software
Loading...
Searching...
No Matches
PRDHandle_TGC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include "VP1Base/VP1Msg.h"
11
12#include <Inventor/nodes/SoSeparator.h>
13#include <Inventor/nodes/SoTranslation.h>
14#include <Inventor/nodes/SoTransform.h>
15
17
21
22
23//____________________________________________________________________
29
30//____________________________________________________________________
31SoTransform * PRDHandle_TGC::createTransform() const
32{
33 const TgcIdHelper * idhelper = VP1DetInfo::tgcIDHelper();
34 const Muon::TgcPrepData * prd = tgc();
35 if (!prd || !idhelper) {
36 return new SoTransform;
37 }
38
39 const Trk::Surface& theSurface = prd->detectorElement()->surface(prd->identify());
40 SoTransform * theHitTransform =0;
41 if (idhelper->isStrip( prd->identify() )){
42
43 int stripNo = idhelper->channel(prd->identify());
44 int gasGap = idhelper->gasGap(prd->identify());
45
46 const MuonGM::TgcReadoutElement* detEl = prd->detectorElement();
47
48 // calculate two points along the tgc phi strip in the local tgc reference frame
49 const Amg::Vector3D lposTGC = detEl->stripCenterLocX(gasGap, stripNo, 0.) * Amg::Vector3D::UnitX();
50 const double shift = detEl->getStationEta() > 0 ? 1.*Gaudi::Units::cm : - 1.*Gaudi::Units::cm;
51 const Amg::Vector3D lposTgcShifted = detEl->stripCenterLocX(gasGap, stripNo, shift) * Amg::Vector3D::UnitX()+
52 shift * Amg::Vector3D::UnitY();
53 const double angle = (lposTGC - lposTgcShifted).phi();
54 // for phi strips, use sinstereo to get correct orientation
55 Amg::RotationMatrix3D localRot{Amg::RotationMatrix3D::Identity()};
56
57
58 // std::ostream os;
59 // std::cout<<localRot.print(os)<<std::endl;
60 //double angle = M_PI/2.0 - asin(prd->detectorElement()->sinStereo(prd->identify())) ;
61 // double angle = asin(prd->detectorElement()->sinStereo(prd->identify())) ;
62 // trying by trial and error to set right component of matrix!
63 // setting theta=PI/4 rotated strips 45deg around z axis, but also a bit around x and y too! So clearly not working as expected.
64
65 // localRot.setPhi (M_PI/4);
66
67 if (0 < detEl->getStationEta()) {
68 Amg::setPhi (localRot, angle);
69 } else {
70 Amg::setPhi (localRot, -angle);
71 }
72 // std::cout<<localRot.print(os)<<std::endl;
73 // localRot.setPhi (angle);
74
75 // VP1Msg::message(QString::number(prd->identify().get_compact())+": angle="+QString::number(angle));
76 localRot*=theSurface.transform().rotation ();
77
78 Amg::Transform3D trans (localRot, theSurface.transform().translation());
79 // Trk::GlobalDirection difPosGlobal = gpos_shift-gpos;
80 // HepTransform3D toLocal = trans.inverse();
81 // Trk::GlobalDirection difPosLocal = toLocal*difPosGlobal;
82 // Trk::GlobalDirection difPosLocal2 = trans*difPosGlobal;
83
84 // std::cout << " global strip direction " << difPosGlobal << " local " << difPosLocal << " local2 " << difPosLocal2 << std::endl;
85 theHitTransform = VP1LinAlgUtils::toSoTransform(trans);
86 } else {
87 // eta strips just use surface orientiation
88 theHitTransform = VP1LinAlgUtils::toSoTransform(theSurface.transform());
89 }
90
91 Amg::Vector3D theHitGPos= theSurface.localToGlobal(prd->localPosition());
92 theHitTransform->translation.setValue((theHitGPos)[0], (theHitGPos)[1], (theHitGPos)[2]);
93 return theHitTransform;
94}
95
96//____________________________________________________________________
97void PRDHandle_TGC::buildShapes(SoNode*&shape_simple, SoNode*&shape_detailed)
98{
99 const TgcIdHelper * idhelper = VP1DetInfo::tgcIDHelper();
100 if (!idhelper)
101 return;
102
103 Identifier id = m_tgc->identify();
104
105 int plane = idhelper->gasGap( id );
106 int strip = idhelper->channel( id );
107 int isStrip = idhelper->isStrip( id );
108
109 double striplength =0.0, stripWidth = 0.0;
110
111 if (isStrip){
112 striplength = m_tgc->detectorElement()->stripLength();
113 stripWidth = m_tgc->detectorElement()->stripWidth(plane, strip);
114 } else {
115 striplength = m_tgc->detectorElement()->gangShortWidth(plane, strip);
116 stripWidth = m_tgc->detectorElement()->gangRadialLength(plane, strip);
117 }
118
119 if (static_cast<PRDCollHandle_TGC*>(collHandle())->project())
120 striplength += 300.0;//Fixme: Rough extension for now
121
122 shape_simple = common()->nodeManager()->getShapeNode_Strip(striplength);
123
124 const bool settingsShowRDOs = true; //FIXME: get from controller
125 SoSeparator * errDetailed = new SoSeparator;
126 const std::vector<Identifier> rdolist = m_tgc->rdoList();
127 if (rdolist.size() == 1 || !settingsShowRDOs)
128 {
129 errDetailed->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
130 std::max(10.0,stripWidth), //strip width -> fixme: std::max hack for now since stripWidth returns 0.0
131 3*0.8)); //strip thickness - hardcoded to be ~= the gas gap
132 } else
133 {
134 VP1Msg::message("Warning: TGC has additional elements in rdoList: THIS HAS NEVER BEEN TESTED");
135 SoSeparator * rdos = new SoSeparator;
136
137 const Amg::Vector3D& globalposHIT = m_tgc->detectorElement()->channelPos( id );
138 // get local position on wire plane, here we have to use a tolarance as the wire plane is located 2.5 CLHEP::mm
139 // from the strip plane
140 double tolerance = 3.;
141 std::optional<Amg::Vector2D>localposHIT = m_tgc->detectorElement()->surface( id ).Trk::Surface::globalToLocal(globalposHIT,tolerance);
142 if( !localposHIT )
143 {
144 localposHIT.emplace();
145 localposHIT->setZero();
146 VP1Msg::message("Warning: Local wire position is NULL");
147 }
148
149 rdos->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
150 std::max(10.0,stripWidth), //strip width -> fixme: std::max hack for now since stripWidth returns 0.0
151 3*0.8)); //strip thickness - hardcoded to be ~= the gas gap
152
153 SoTransparency * transparent = new SoTransparency;
154 transparent->transparency.setValue(0.5);
155 rdos->addChild( transparent );
156 Amg::Vector2D localposOLD = *localposHIT;
157 for (const Identifier& rdo_id : rdolist)
158 {
159 if (rdo_id == id )
160 continue;
161 const Amg::Vector3D& globalposRDO = m_tgc->detectorElement()->channelPos( rdo_id );
162 std::optional<Amg::Vector2D> localposRDO = m_tgc->detectorElement()->surface( rdo_id ).Trk::Surface::globalToLocal(globalposRDO,tolerance);
163 if (!localposRDO)
164 {
165 VP1Msg::message("Warning: Local wire position is NULL");
166 continue;
167 }
168
169 SoTranslation * localtrans = new SoTranslation;
170 localtrans->translation.setValue((*localposRDO)[Trk::locX]-localposOLD[Trk::locX],(*localposRDO)[Trk::locY]-localposOLD[Trk::locY],0);
171 rdos->addChild(localtrans);
172
173 rdos->addChild(common()->nodeManager()->getShapeNode_Strip(striplength,
174 std::max(10.0,stripWidth), //strip width -> fixme: std::max hack for now since stripWidth returns 0.0
175 3*0.8)); //strip thickness - hardcoded to be ~= the gas gap
176
177 localposOLD = *localposRDO;
178 }
179 errDetailed->addChild(rdos);
180 }
181 shape_detailed = errDetailed;
182 }
183
184//____________________________________________________________________
186 {
187 //Unique for each station.
188 const MuonGM::MuonStation* station = m_tgc->detectorElement()->parentMuonStation();
189 return station->getPhiIndex()-99999*station->getEtaIndex();//hopefully unique.
190 }
Scalar phi() const
phi method
T_ResultType project(ParameterMapping::type< N > parameter_map, const T_Matrix &matrix)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
SoNode * getShapeNode_Strip(double length, double width=0, double depth=0)
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
int getEtaIndex() const
a la AMDB
int getPhiIndex() const
a la AMDB
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
double stripCenterLocX(int gasGap, int strip, double radialPos) const
Returns the local X of the strip center at a given local radial position.
Class to represent TGC measurements.
Definition TgcPrepData.h:32
virtual const MuonGM::TgcReadoutElement * detectorElement() const override final
Returns the detector element corresponding to this PRD The pointer will be zero if the det el is not ...
PRDHandleBase(PRDCollHandleBase *)
PRDSysCommonData * common() const
PRDCollHandleBase * collHandle() const
SoTransform * createTransform() const
PRDHandle_TGC(PRDCollHandle_TGC *, const Muon::TgcPrepData *)
const Muon::TgcPrepData * m_tgc
const Muon::TgcPrepData * tgc() const
void buildShapes(SoNode *&shape_simple, SoNode *&shape_detailed)
HitsSoNodeManager * nodeManager() const
static void initClass()
SoSFFloat transparency
int channel(const Identifier &id) const override
int gasGap(const Identifier &id) const override
get the hashes
int isStrip(const Identifier &id) const
isStrip corresponds to measuresPhi
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
Abstract Base Class for tracking surfaces.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
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.
static const TgcIdHelper * tgcIDHelper()
static SoTransform * toSoTransform(const HepGeom::Transform3D &, SoTransform *t=0)
static void message(const QString &, IVP1System *sys=0)
Definition VP1Msg.cxx:30
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Amg::RotationMatrix3D setPhi(Amg::RotationMatrix3D mat, double angle, int convention=0)
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37