LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
LocalTransformation.tcc
Go to the documentation of this file.
1 /**
2  * @file larcorealg/Geometry/LocalTransformation.tcc
3  * @brief Class containing local-to-world transformations
4  * (template implementation)
5  * @see LocalTransformation.h
6  *
7  * This file is expected to be included directly in the header.
8  */
9 
10 #ifndef LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
11 #define LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
12 
13 // framework libraries
14 #include "cetlib_except/exception.h"
15 
16 // ROOT
17 #include "TGeoMatrix.h"
18 #include "TGeoNode.h"
19 
20 // CLHEP
21 #include "CLHEP/Geometry/Transform3D.h"
22 #include "CLHEP/Vector/Rotation.h" // CLHEP::HepRotation
23 #include "CLHEP/Vector/RotationInterfaces.h" // CLHEP::HepRep3x3
24 #include "CLHEP/Vector/ThreeVector.h" // CLHEP::Hep3Vector
25 
26 // C standard library
27 #include <cassert>
28 
29 //------------------------------------------------------------------------------
30 namespace geo {
31  namespace details {
32 
33  //--------------------------------------------------------------------------
34  template <typename Dest, typename Src>
35  struct TransformationMatrixConverter {
36  static decltype(auto) convert(Src const& trans);
37  static decltype(auto) convert(Src&& trans);
38  };
39 
40  //--------------------------------------------------------------------------
41  template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
42  bool doBuffersOverlap(T const* src, T const* dest)
43  {
44  return (dest < (src + SrcN)) && (src < (dest + DestN));
45  }
46 
47  template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
48  void checkVectorBufferOverlap(T const* src, T const* dest)
49  {
50  if (doBuffersOverlap<T, SrcN, DestN>(src, dest)) {
51  throw cet::exception("LocalTransformation")
52  << "source " << SrcN << "@[" << ((void*)src) << "]"
53  << " and destination " << DestN << "@[" << ((void*)dest) << "]"
54  << " buffers overlap!\n";
55  }
56  assert(!doBuffersOverlap(src, dest));
57  } // checkVectorBufferOverlap()
58 
59  //--------------------------------------------------------------------------
60 
61  } // namespace details
62 } // namespace geo
63 
64 //------------------------------------------------------------------------------
65 template <typename Matrix>
66 void geo::LocalTransformation<Matrix>::LocalToWorld(double const* local, double* world) const
67 {
68  details::checkVectorBufferOverlap(local, world);
69  fGeoMatrix.LocalToMaster(local, world);
70 }
71 
72 //------------------------------------------------------------------------------
73 template <typename Matrix>
74 void geo::LocalTransformation<Matrix>::LocalToWorldVect(double const* local, double* world) const
75 {
76  details::checkVectorBufferOverlap(local, world);
77  fGeoMatrix.LocalToMasterVect(local, world);
78 }
79 
80 //------------------------------------------------------------------------------
81 template <typename Matrix>
82 void geo::LocalTransformation<Matrix>::WorldToLocal(double const* world, double* local) const
83 {
84  details::checkVectorBufferOverlap(local, world);
85  fGeoMatrix.MasterToLocal(world, local);
86 }
87 
88 //------------------------------------------------------------------------------
89 template <typename Matrix>
90 void geo::LocalTransformation<Matrix>::WorldToLocalVect(const double* world, double* local) const
91 {
92  details::checkVectorBufferOverlap(local, world);
93  fGeoMatrix.MasterToLocalVect(world, local);
94 }
95 
96 //------------------------------------------------------------------------------
97 template <typename Matrix>
98 template <typename DestPoint, typename SrcPoint>
99 DestPoint geo::LocalTransformation<Matrix>::WorldToLocalImpl(SrcPoint const& world) const
100 {
101  double const worldArray[3] = {world.X(), world.Y(), world.Z()};
102  double localArray[3];
103  WorldToLocal(worldArray, localArray);
104  return {localArray[0], localArray[1], localArray[2]};
105 }
106 
107 //......................................................................
108 template <typename Matrix>
109 template <typename DestVector, typename SrcVector>
110 DestVector geo::LocalTransformation<Matrix>::WorldToLocalVectImpl(SrcVector const& world) const
111 {
112  double const worldArray[3] = {world.X(), world.Y(), world.Z()};
113  double localArray[3];
114  WorldToLocalVect(worldArray, localArray);
115  return {localArray[0], localArray[1], localArray[2]};
116 }
117 
118 //......................................................................
119 template <typename Matrix>
120 template <typename DestPoint, typename SrcPoint>
121 DestPoint geo::LocalTransformation<Matrix>::LocalToWorldImpl(SrcPoint const& local) const
122 {
123  double const localArray[3] = {local.X(), local.Y(), local.Z()};
124  double worldArray[3];
125  LocalToWorld(localArray, worldArray);
126  return {worldArray[0], worldArray[1], worldArray[2]};
127 }
128 
129 //......................................................................
130 template <typename Matrix>
131 template <typename DestVector, typename SrcVector>
132 DestVector geo::LocalTransformation<Matrix>::LocalToWorldVectImpl(SrcVector const& local) const
133 {
134  double const localArray[3] = {local.X(), local.Y(), local.Z()};
135  double worldArray[3];
136  LocalToWorldVect(localArray, worldArray);
137  return {worldArray[0], worldArray[1], worldArray[2]};
138 }
139 
140 //------------------------------------------------------------------------------
141 // specialisations (template implementations)
142 //
143 namespace geo {
144 
145  //----------------------------------------------------------------------------
146  template <>
147  inline TGeoHMatrix transformationFromPath<TGeoHMatrix>(std::vector<GeoNodePathEntry> const& path,
148  size_t depth)
149  {
150  TGeoHMatrix matrix = *(path[0].node->GetMatrix());
151  for (size_t i = 1; i <= depth; ++i)
152  matrix.Multiply(path[i].node->GetMatrix());
153  return matrix;
154  }
155 
156  template <>
157  inline TGeoHMatrix transformationFromPath<TGeoHMatrix, GeoNodeIterator_t>(GeoNodeIterator_t begin,
158  GeoNodeIterator_t end)
159  {
160  if (begin == end) return {TGeoIdentity()};
161  auto iNode = begin;
162  TGeoHMatrix matrix = *(iNode->node->GetMatrix());
163  while (++iNode != end)
164  matrix.Multiply(iNode->node->GetMatrix());
165  return matrix;
166  }
167 
168  //----------------------------------------------------------------------------
169  template <>
170  inline HepGeom::Transform3D transformationFromPath<HepGeom::Transform3D>(
171  std::vector<GeoNodePathEntry> const& path,
172  size_t depth)
173  {
174  auto const mat = transformationFromPath<TGeoHMatrix>(path, depth);
175  const Double_t* translation = mat.GetTranslation();
176  return HepGeom::Transform3D(CLHEP::HepRotation(CLHEP::HepRep3x3(mat.GetRotationMatrix())),
177  CLHEP::Hep3Vector(translation[0], translation[1], translation[2]));
178  }
179 
180  template <>
181  HepGeom::Transform3D inline transformationFromPath<HepGeom::Transform3D>(GeoNodeIterator_t begin,
182  GeoNodeIterator_t end)
183  {
184  auto const mat = transformationFromPath<TGeoHMatrix>(begin, end);
185  const Double_t* translation = mat.GetTranslation();
186  return HepGeom::Transform3D(CLHEP::HepRotation(CLHEP::HepRep3x3(mat.GetRotationMatrix())),
187  CLHEP::Hep3Vector(translation[0], translation[1], translation[2]));
188  }
189 
190  //----------------------------------------------------------------------------
191  namespace details {
192 
193  //--------------------------------------------------------------------------
194  template <typename Trans>
195  struct TransformationMatrixConverter<Trans, Trans> {
196  static Trans const& convert(Trans const& trans) { return trans; }
197  static Trans convert(Trans&& trans) { return trans; }
198  };
199 
200  //--------------------------------------------------------------------------
201 
202  } // namespace details
203 
204  //----------------------------------------------------------------------------
205 
206 } // namespace geo
207 
208 //------------------------------------------------------------------------------
209 
210 #endif // LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
211 
212 // Local variables:
213 // mode: c++
214 // End: