LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
TPCGeo.cxx
Go to the documentation of this file.
1 
5 // class header
7 
8 // LArSoft includes
10 #include "larcorealg/Geometry/geo_vectors_utils.h" // geo::vect::fillCoords()
11 
12 // Framework includes
13 #include "cetlib/container_algorithms.h"
14 #include "cetlib_except/exception.h"
16 
17 // ROOT includes
18 #include "TGeoBBox.h"
19 #include "TGeoMatrix.h"
20 #include "TGeoNode.h"
21 
22 // C/C++ standard libraries
23 #include <algorithm> // std::max(), std::copy()
24 #include <cassert>
25 #include <cmath>
26 #include <functional> // std::mem_fn()
27 #include <iterator> // std::inserter()
28 #include <map>
29 #include <sstream> // std::ostringstream
30 
31 namespace {
32  geo::Vector_t to_vector(geo::DriftAxis const driftAxis)
33  {
34  auto const [axis, sign] = driftAxis;
35  switch (axis) {
36  case geo::Coordinate::X: return geo::Xaxis() * to_int(sign);
37  case geo::Coordinate::Y: return geo::Yaxis() * to_int(sign);
38  case geo::Coordinate::Z: return geo::Zaxis() * to_int(sign);
39  }
40  return {}; // unreachable
41  }
42 }
43 
44 namespace geo {
45 
46  //......................................................................
47  TPCGeo::TPCGeo(TGeoNode const* tpc_node,
48  std::size_t hash_value,
49  TransformationMatrix&& trans,
50  DriftAxis const driftAxis,
51  double const driftDistance)
52  : fHash{hash_value}
53  , fTrans{std::move(trans)}
54  , fDriftAxis{driftAxis}
55  , fDriftDir{to_vector(driftAxis)}
56  , fDriftDistance{driftDistance}
57  {
58  // all planes are going to be contained in the volume named volTPC
59  // now get the total volume of the TPC
60  TGeoVolume* vc = tpc_node->GetVolume();
61  if (!vc) {
62  throw cet::exception("Geometry")
63  << "cannot find detector outline volume - bail ungracefully\n";
64  }
65 
66  fTotalVolume = vc;
67 
68  auto* active_node = NodeForActiveVolume(tpc_node);
69  // compute the active volume transformation too
70  auto ActiveHMatrix(fTrans.Matrix());
71  if (active_node) { ActiveHMatrix *= makeTransformationMatrix(*active_node->GetMatrix()); }
72 
74  fActiveVolume = active_node->GetVolume();
75 
76  MF_LOG_DEBUG("Geometry") << "detector total volume is " << fTotalVolume->GetName()
77  << "\ndetector active volume is " << fActiveVolume->GetName();
78 
79  // set the width, height, and lengths
80  auto const* active_volume_box = static_cast<TGeoBBox const*>(fActiveVolume->GetShape());
81  fActiveHalfWidth = active_volume_box->GetDX();
82  fActiveHalfHeight = active_volume_box->GetDY();
83  fActiveLength = 2.0 * active_volume_box->GetDZ();
84 
85  auto const* total_volume_box = static_cast<TGeoBBox const*>(fTotalVolume->GetShape());
86  fHalfWidth = total_volume_box->GetDX();
87  fHalfHeight = total_volume_box->GetDY();
88  fLength = 2.0 * total_volume_box->GetDZ();
89 
90  // Check that the rotation matrix to the world is the identity, if not we need to
91  // change the width, height and length values; the correspondence of these to x, y and
92  // z are not guaranteed to be trivial, so we store the two independently (cartesian
93  // dimensions in the bounding boxes, the sizes in data members directly).
94 
95  // TODO: there must be a more general way to do this...
96  double Rxx, Rxy, Rxz, Ryx, Ryy, Ryz, Rzx, Rzy, Rzz;
97  fTrans.Matrix().Rotation().GetComponents(Rxx, Rxy, Rxz, Ryx, Ryy, Ryz, Rzx, Rzy, Rzz);
98  if (Rxx != 1) {
99  if (std::abs(Rxz) == 1) {
100  fActiveHalfWidth = active_volume_box->GetDZ();
101  fHalfWidth = total_volume_box->GetDZ();
102  fWidthDir = Zaxis();
103  }
104  if (std::abs(Rxy) == 1) {
105  fActiveHalfWidth = active_volume_box->GetDY();
106  fHalfWidth = total_volume_box->GetDY();
107  fWidthDir = Yaxis();
108  }
109  }
110  if (Ryy != 1) {
111  if (std::abs(Rxy) == 1) {
112  fActiveHalfHeight = active_volume_box->GetDX();
113  fHalfHeight = total_volume_box->GetDX();
114  fHeightDir = Xaxis();
115  }
116  if (std::abs(Rzy) == 1) {
117  fActiveHalfHeight = active_volume_box->GetDZ();
118  fHalfHeight = total_volume_box->GetDZ();
119  fHeightDir = Zaxis();
120  }
121  }
122  if (Rzz != 1) {
123  if (std::abs(Rzx) == 1) {
124  fActiveLength = 2. * active_volume_box->GetDX();
125  fLength = 2. * total_volume_box->GetDX();
126  fLengthDir = Xaxis();
127  }
128  if (std::abs(Ryz) == 1) {
129  fActiveLength = 2. * active_volume_box->GetDY();
130  fLength = 2. * total_volume_box->GetDY();
131  fLengthDir = Yaxis();
132  }
133  }
134 
136  }
137 
138  //......................................................................
140  {
141  // 1. find the center of the face of the TPC opposite to the anode
142  // 2. compute the distance of it from the last wire plane
143 
144  //
145  // find the cathode center
146  //
147  Point_t cathodeCenter = GetActiveVolumeCenter();
148  auto const [axis, sign] = DriftAxisWithSign();
149  switch (axis) {
150  case Coordinate::X:
151  cathodeCenter.SetX(cathodeCenter.X() - to_int(sign) * ActiveHalfWidth());
152  break;
153  case Coordinate::Y:
154  cathodeCenter.SetY(cathodeCenter.Y() - to_int(sign) * ActiveHalfHeight());
155  break;
156  case Coordinate::Z:
157  cathodeCenter.SetZ(cathodeCenter.Z() - to_int(sign) * ActiveLength() / 2.0);
158  break;
159  }
160 
161  return cathodeCenter;
162  }
163 
164  //......................................................................
165  double TPCGeo::DriftDistance() const
166  {
167  return fDriftDistance;
168  }
169 
170  //......................................................................
171  std::string TPCGeo::TPCInfo(std::string indent /* = "" */, unsigned int verbosity /* = 1 */) const
172  {
173  std::ostringstream sstr;
174  PrintTPCInfo(sstr, indent, verbosity);
175  return sstr.str();
176  }
177 
178  //......................................................................
180  {
181  // note that this assumes no rotations of the TPC (except for rotations of a flat
182  // angle around one of the three main axes); to avoid this, we should transform the
183  // six vertices rather than just the centre
184 
185  // we rely on the asumption that the center of TPC is at the local origin
188 
189  // the center of the active volume may be elsewhere than the local origin:
190  auto const& activeCenter = GetActiveVolumeCenter();
191  fActiveBox.SetBoundaries(activeCenter.X() - ActiveHalfWidth(),
192  activeCenter.X() + ActiveHalfWidth(),
193  activeCenter.Y() - ActiveHalfHeight(),
194  activeCenter.Y() + ActiveHalfHeight(),
195  activeCenter.Z() - ActiveHalfLength(),
196  activeCenter.Z() + ActiveHalfLength());
197  }
198 
199  //......................................................................
201  {
202  auto const& activeBox = ActiveBoundingBox();
203  return {activeBox.CenterX(), activeBox.CenterY(), activeBox.MinZ()};
204  }
205 
206  //......................................................................
208  {
209  fID = tpcid;
210  }
211 
212  //......................................................................
213  TGeoNode const* TPCGeo::NodeForActiveVolume(TGeoNode const* tpc)
214  {
215  for (int i = 0, nd = tpc->GetNdaughters(); i < nd; ++i) {
216  auto daughter = tpc->GetDaughter(i);
217  if (daughter && strncmp(daughter->GetName(), "volTPCActive", 12) == 0) return daughter;
218  }
219  return nullptr;
220  }
221 }
void InitTPCBoundaries()
Recomputes the TPC boundary.
Definition: TPCGeo.cxx:179
Point_t GetCathodeCenter() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.cxx:139
void PrintTPCInfo(Stream &&out, std::string indent="", unsigned int verbosity=1) const
Prints information about this TPC.
Definition: TPCGeo.h:271
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
double fLength
Length of total volume.
Definition: TPCGeo.h:251
double ActiveHalfHeight() const
Half height (associated with y coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:94
double fActiveHalfWidth
Half width of active volume.
Definition: TPCGeo.h:246
TransformationMatrix_t const & Matrix() const
Direct access to the transformation matrix.
constexpr Vector Yaxis()
Returns a y axis vector of the specified type.
Definition: geo_vectors.h:215
BoxBoundedGeo fActiveBox
Box of the active volume.
Definition: TPCGeo.h:257
constexpr auto abs(T v)
Returns the absolute value of the argument.
double HalfLength() const
Length is associated with z coordinate [cm].
Definition: TPCGeo.h:112
DriftAxis DriftAxisWithSign() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.h:78
Class for approximate comparisons.
Point_t toWorldCoords(LocalPoint_t const &local) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:155
double ActiveHalfLength() const
Length (associated with z coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:100
double fHalfWidth
Half width of total volume.
Definition: TPCGeo.h:249
BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
Definition: TPCGeo.h:144
double fActiveLength
Length of active volume.
Definition: TPCGeo.h:248
TPCGeo(TGeoNode const *tpc_node, std::size_t hash_value, TransformationMatrix &&trans, DriftAxis driftAxis, double driftDistance)
Definition: TPCGeo.cxx:47
double ActiveHalfWidth() const
Half width (associated with x coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:90
std::string indent(std::size_t const i)
Utilities to extend the interface of geometry vectors.This library provides facilities that can be us...
constexpr int to_int(Coordinate const coord) noexcept
Enumerate the possible plane projections.
Definition: geo_types.h:124
constexpr Vector Xaxis()
Returns a x axis vector of the specified type.
Definition: geo_vectors.h:208
decltype(auto) makeTransformationMatrix(Trans &&trans)
Converts a transformation matrix into a geo::TransformationMatrix.
TGeoVolume * fTotalVolume
Total volume of TPC, called volTPC in GDML file.
Definition: TPCGeo.h:243
Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
static TGeoNode const * NodeForActiveVolume(TGeoNode const *tpc)
Definition: TPCGeo.cxx:213
void UpdateAfterSorting(TPCID tpcid)
Performs all updates after cryostat has sorted TPCs.
Definition: TPCGeo.cxx:207
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
Point_t GetActiveVolumeCenter() const
Returns the center of the TPC active volume in world coordinates [cm].
Definition: TPCGeo.h:135
double ActiveLength() const
Length (associated with z coordinate) of active TPC volume [cm].
Definition: TPCGeo.h:98
double HalfHeight() const
Height is associated with y coordinate [cm].
Definition: TPCGeo.h:106
constexpr Vector Zaxis()
Returns a z axis vector of the specified type.
Definition: geo_vectors.h:222
std::string TPCInfo(std::string indent="", unsigned int verbosity=1) const
Returns a string with information about this TPC.
Definition: TPCGeo.cxx:171
int sign(double val)
Definition: UtilFunc.cxx:104
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
TGeoVolume * fActiveVolume
Active volume of LAr, called volTPCActive in GDML file.
Definition: TPCGeo.h:242
double DriftDistance() const
Drift distance is defined as the distance between the anode and the cathode, in centimeters.
Definition: TPCGeo.cxx:165
TPCID fID
ID of this TPC.
Definition: TPCGeo.h:259
void SetBoundaries(Coord_t x_min, Coord_t x_max, Coord_t y_min, Coord_t y_max, Coord_t z_min, Coord_t z_max)
Sets the boundaries in world coordinates as specified.
Vector_t fWidthDir
Direction width refers to.
Definition: TPCGeo.h:253
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:42
#define MF_LOG_DEBUG(id)
LocalTransformation_t fTrans
TPC-to-world transformation.
Definition: TPCGeo.h:236
DriftAxis fDriftAxis
Definition: TPCGeo.h:238
Vector_t fHeightDir
Direction height refers to.
Definition: TPCGeo.h:254
Vector_t fLengthDir
Direction length refers to.
Definition: TPCGeo.h:255
Point_t fActiveCenter
Center of the active volume, in world coordinates [cm].
Definition: TPCGeo.h:244
ROOT libraries.
Point3DBase_t< TPCGeoCoordinatesTag > LocalPoint_t
Type of points in the local GDML TPC frame.
Definition: TPCGeo.h:55
Point_t GetFrontFaceCenter() const
Returns the center of the active TPC volume side facing negative z.
Definition: TPCGeo.cxx:200
double fHalfHeight
Half height of total volume.
Definition: TPCGeo.h:250
double HalfWidth() const
Width is associated with x coordinate [cm].
Definition: TPCGeo.h:102
ROOT::Math::Transform3D TransformationMatrix
Type of transformation matrix used in geometry.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fDriftDistance
Definition: TPCGeo.h:240
Encapsulate the construction of a single detector plane .
Vector_t fDriftDir
Definition: TPCGeo.h:239
double fActiveHalfHeight
Half height of active volume.
Definition: TPCGeo.h:247