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