AuxDetGeo.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file AuxDetGeo.cxx
3 /// \brief Encapsulate the geometry of an auxilary detector
4 ///
5 ////////////////////////////////////////////////////////////////////////
6 
7 #include <iostream>
8 #include <limits>
9 
10 #include "Geometry/AuxDetGeo.h"
11 #include "Geometry/AuxDetGeoObjectSorter.h"
12 
13 #include "TGeoManager.h"
14 #include "TGeoTube.h"
15 #include "TGeoTrd1.h"
16 #include "TGeoTrd2.h"
17 #include "TGeoMatrix.h"
18 #include "TGeoNode.h"
19 #include "TMath.h"
20 #include "TVector3.h"
21 
22 // Framework includes
24 #include "cetlib_except/exception.h"
25 
26 namespace gar {
27  namespace geo{
28 
29  //-----------------------------------------
30  AuxDetGeo::AuxDetGeo(std::vector<const TGeoNode*>& path,
31  int depth)
32  : fTotalVolume(0)
33  {
34 
35  TGeoVolume *vc = path[depth]->GetVolume();
36  if(vc){
37  fTotalVolume = vc;
38  if(!fTotalVolume)
39  throw cet::exception("AuxDetGeo") << "cannot find AuxDet volume\n";
40 
41  }// end if found volume
42 
43  MF_LOG_DEBUG("Geometry") << "detector total volume is " << fTotalVolume->GetName();
44 
45  // Build the matrix that takes us to the top world frame
46  // build a matrix to take us from the local to the world coordinates
47  // in one step
48  fGeoMatrix = new TGeoHMatrix(*path[0]->GetMatrix());
49  for(int i = 1; i <= depth; ++i){
50  fGeoMatrix->Multiply(path[i]->GetMatrix());
51  }
52 
53  // look for sensitive volumes - if there are none then this aux det
54  // could be from an older gdml file than the introduction of AuxDetSensitiveGeo
55  // in that case assume the full AuxDetGeo is sensitive and copy its information
56  // into a single AuxDetSensitive
57  this->FindAuxDetSensitive(path, depth);
58  if( fSensitive.size() < 1) fSensitive.push_back(new AuxDetSensitiveGeo(fTotalVolume, fGeoMatrix));
59 
60  // set the ends depending on whether the shape is a box or trapezoid
61  std::string volName(fTotalVolume->GetName());
62  if( volName.find("Trap") != std::string::npos ) {
63 
64  // Small Width
65  // ____ Height is the thickness
66  // / \ T of the trapezoid
67  // / \ |
68  // / \ | Length
69  // /__________\ _
70  // Width
71  fHalfHeight = ((TGeoTrd2*)fTotalVolume->GetShape())->GetDy1(); // same as Dy2()
72  fLength = 2.0*((TGeoTrd2*)fTotalVolume->GetShape())->GetDz();
73  fHalfWidth1 = ((TGeoTrd2*)fTotalVolume->GetShape())->GetDx1(); // at -Dz
74  fHalfWidth2 = ((TGeoTrd2*)fTotalVolume->GetShape())->GetDx2(); // at +Dz
75  }
76  else {
77  fHalfWidth1 = ((TGeoBBox*)fTotalVolume->GetShape())->GetDX();
78  fHalfHeight = ((TGeoBBox*)fTotalVolume->GetShape())->GetDY();
79  fLength = 2.0*((TGeoBBox*)fTotalVolume->GetShape())->GetDZ();
81  }
82 
83  }
84 
85  //......................................................................
87  {
88  if(fGeoMatrix) delete fGeoMatrix;
89  return;
90  }
91 
92  //......................................................................
93  void AuxDetGeo::FindAuxDetSensitive(std::vector<const TGeoNode*>& path,
94  unsigned int depth)
95  {
96  // Check if the current node is a senstive volume - we already know
97  // we are in an Auxiliary detector
98  std::string pathName(path[depth]->GetName());
99  if( pathName.find("Sensitive") != std::string::npos){
100  this->MakeAuxDetSensitive(path, depth);
101  return;
102  }
103 
104  // Explore the next layer down
105  unsigned int deeper = depth+1;
106  if (deeper>=path.size()) {
107  throw cet::exception("ExceededMaxDepth") << "Exceeded maximum depth\n";
108  }
109  const TGeoVolume* v = path[depth]->GetVolume();
110  int nd = v->GetNdaughters();
111  for (int i=0; i<nd; ++i) {
112  path[deeper] = v->GetNode(i);
113  this->FindAuxDetSensitive(path, deeper);
114  }
115  }
116 
117  //......................................................................
118  void AuxDetGeo::MakeAuxDetSensitive(std::vector<const TGeoNode*>& path, int depth)
119  {
120  fSensitive.push_back(new AuxDetSensitiveGeo(path, depth));
121  }
122 
123  //......................................................................
124  /// Transform a position from local frame to world frame
125  /// \param local : 3D array. Position in the local frame Input.
126  /// \param world : 3D array. Position in the world frame. Returned.
127  void AuxDetGeo::LocalToWorld(const double* local, double* world) const
128  {
129  fGeoMatrix->LocalToMaster(local,world);
130  }
131 
132  //......................................................................
133  /// Transform a 3-vector from local frame to world frame
134  /// \param local : 3D array. Position in the local frame Input.
135  /// \param world : 3D array. Position in the world frame. Returned.
136  void AuxDetGeo::LocalToWorldVect(const double* local, double* world) const
137  {
138  fGeoMatrix->LocalToMasterVect(local,world);
139  }
140 
141  //......................................................................
142  /// Transform a position from world frame to local frame
143  /// \param world : 3D array. Position in the world frame. Input.
144  /// \param local : 3D array. Position in the local frame Returned.
145  void AuxDetGeo::WorldToLocal(const double* world, double* local) const
146  {
147  fGeoMatrix->MasterToLocal(world,local);
148  }
149 
150  //......................................................................
151  /// Transform a 3-vector from world frame to local frame
152  /// \param world : 3D array. Position in the world frame. Input.
153  /// \param local : 3D array. Position in the local frame Returned.
154  void AuxDetGeo::WorldToLocalVect(const double* world, double* local) const
155  {
156  fGeoMatrix->MasterToLocalVect(world,local);
157  }
158 
159  //......................................................................
160  /// Return the center position of an AuxDet
161  /// \param xyz : 3-D array. The returned location.
162  /// \param localz : Distance along the length of the volume (z)
163  /// (cm). Default is 0.
164  void AuxDetGeo::GetCenter(double* xyz, double localz) const
165  {
166  double xyzLocal[3] = {0.,0.,localz};
167  this->LocalToWorld(xyzLocal, xyz);
168  }
169 
170  //......................................................................
171  // Return the unit normal vector (0,0,1) in local coordinates to global coordinates
172  void AuxDetGeo::GetNormalVector(double* xyzDir) const
173  {
174  double normal[3]={0.,0.,1.};
175  this->LocalToWorldVect(normal,xyzDir);
176  }
177 
178 
179  //......................................................................
180  // Get the distance from some point to this detector, xyz in global coordinates
181  double AuxDetGeo::DistanceToPoint(double * xyz) const
182  {
183  double Center[3];
184  GetCenter(Center);
185  return std::sqrt((Center[0]-xyz[0])*(Center[0]-xyz[0]) +
186  (Center[1]-xyz[1])*(Center[1]-xyz[1]) +
187  (Center[2]-xyz[2])*(Center[2]-xyz[2]));
188  }
189 
190  //......................................................................
191  size_t AuxDetGeo::FindSensitiveVolume(double const worldPos[3]) const
192  {
193  double local[3] = {0.};
194  for(unsigned int a = 0; a < fSensitive.size(); ++a) {
195 
196  this->SensitiveVolume(a).WorldToLocal(worldPos, local);
197  double HalfCenterWidth = (this->SensitiveVolume(a).HalfWidth1() + this->SensitiveVolume(a).HalfWidth2()) / 2;
198 
199  if( local[2] >= - this->SensitiveVolume(a).Length()/2 &&
200  local[2] <= this->SensitiveVolume(a).Length()/2 &&
201  local[1] >= - this->SensitiveVolume(a).HalfHeight() &&
202  local[1] <= this->SensitiveVolume(a).HalfHeight() &&
203  // if SensitiveVolume a is a box, then HalfSmallWidth = HalfWidth
204  local[0] >= - HalfCenterWidth + local[2]*(HalfCenterWidth-this->SensitiveVolume(a).HalfWidth2())/(this->SensitiveVolume(a).Length()/2) &&
205  local[0] <= HalfCenterWidth - local[2]*(HalfCenterWidth-this->SensitiveVolume(a).HalfWidth2())/(this->SensitiveVolume(a).Length()/2)
206  ) return a;
207 
208  }// for loop over AuxDetSensitive a
209 
210  throw cet::exception("Geometry") << "Can't find AuxDetSensitive for position ("
211  << worldPos[0] << ","
212  << worldPos[1] << ","
213  << worldPos[2] << ")\n";
214 
215  return UINT_MAX;
216  }
217 
218  //......................................................................
220  size_t & sv) const
221  {
222  sv = this->FindSensitiveVolume(worldLoc);
223  return this->SensitiveVolume(sv);
224  }
225 
226  //......................................................................
228  {
230 
231  return;
232  }
233 
234  }
235 } // gar
236 ////////////////////////////////////////////////////////////////////////
std::string string
Definition: nybbler.cc:12
const TGeoVolume * fTotalVolume
Total volume of AuxDet, called vol*.
Definition: AuxDetGeo.h:67
double fHalfWidth1
1st half width of volume, at -z/2 in local coordinates
Definition: AuxDetGeo.h:70
std::vector< AuxDetSensitiveGeo * > fSensitive
sensitive volumes in the detector
Definition: AuxDetGeo.h:73
AuxDetSensitiveGeo const & SensitiveVolume(size_t sv) const
Definition: AuxDetGeo.h:55
double fHalfHeight
half height of volume
Definition: AuxDetGeo.h:72
void LocalToWorldVect(const double *local, double *world) const
Definition: AuxDetGeo.cxx:136
void WorldToLocal(const double *world, double *local) const
void GetNormalVector(double *xyzDir) const
Definition: AuxDetGeo.cxx:172
TGeoHMatrix * fGeoMatrix
Transformation matrix to world frame.
Definition: AuxDetGeo.h:68
const double a
double DistanceToPoint(double *xyz) const
Definition: AuxDetGeo.cxx:181
size_t FindSensitiveVolume(double const worldLoc[3]) const
Definition: AuxDetGeo.cxx:191
void LocalToWorld(const double *local, double *world) const
Definition: AuxDetGeo.cxx:127
void FindAuxDetSensitive(std::vector< const TGeoNode * > &path, unsigned int depth)
Definition: AuxDetGeo.cxx:93
virtual void SortAuxDetSensitive(std::vector< geo::AuxDetSensitiveGeo * > &adsgeo) const =0
General GArSoft Utilities.
void SortSubVolumes(geo::AuxDetGeoObjectSorter const &sorter)
Definition: AuxDetGeo.cxx:227
void WorldToLocalVect(const double *world, double *local) const
Definition: AuxDetGeo.cxx:154
#define MF_LOG_DEBUG(id)
void WorldToLocal(const double *world, double *local) const
Definition: AuxDetGeo.cxx:145
AuxDetSensitiveGeo const & PositionToSensitiveVolume(double const worldLoc[3], size_t &sv) const
Definition: AuxDetGeo.cxx:219
AuxDetGeo(std::vector< const TGeoNode * > &path, int depth)
Definition: AuxDetGeo.cxx:30
LArSoft geometry interface.
Definition: ChannelGeo.h:16
void MakeAuxDetSensitive(std::vector< const TGeoNode * > &path, int depth)
Definition: AuxDetGeo.cxx:118
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fLength
length of volume, along z direction in local
Definition: AuxDetGeo.h:69
double fHalfWidth2
2nd half width (width1==width2 for boxes), at +z/2
Definition: AuxDetGeo.h:71
void GetCenter(double *xyz, double localz=0.0) const
Definition: AuxDetGeo.cxx:164