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
9 * This file is expected to be included directly in the header.
13 #ifndef LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
14 #define LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
16 // framework libraries
17 #include "cetlib_except/exception.h"
20 #include "TGeoMatrix.h"
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
32 //------------------------------------------------------------------------------
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);
43 //--------------------------------------------------------------------------
44 template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
45 bool doBuffersOverlap(T const* src, T const* dest)
47 return (dest < (src + SrcN)) && (src < (dest + DestN));
50 template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
51 void checkVectorBufferOverlap(T const* src, T const* dest)
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";
59 assert(!doBuffersOverlap(src, dest));
60 } // checkVectorBufferOverlap()
62 //--------------------------------------------------------------------------
64 } // namespace details
67 //------------------------------------------------------------------------------
68 template <typename Matrix>
69 void geo::LocalTransformation<Matrix>::LocalToWorld(double const* local, double* world) const
71 details::checkVectorBufferOverlap(local, world);
72 fGeoMatrix.LocalToMaster(local, world);
73 } // geo::LocalTransformation::LocalToWorld()
75 //------------------------------------------------------------------------------
76 template <typename Matrix>
77 void geo::LocalTransformation<Matrix>::LocalToWorldVect(double const* local, double* world) const
79 details::checkVectorBufferOverlap(local, world);
80 fGeoMatrix.LocalToMasterVect(local, world);
81 } // geo::LocalTransformation::LocalToWorldVect()
83 //------------------------------------------------------------------------------
84 template <typename Matrix>
85 void geo::LocalTransformation<Matrix>::WorldToLocal(double const* world, double* local) const
87 details::checkVectorBufferOverlap(local, world);
88 fGeoMatrix.MasterToLocal(world, local);
89 } // geo::LocalTransformation::WorldToLocal()
91 //------------------------------------------------------------------------------
92 template <typename Matrix>
93 void geo::LocalTransformation<Matrix>::WorldToLocalVect(const double* world, double* local) const
95 details::checkVectorBufferOverlap(local, world);
96 fGeoMatrix.MasterToLocalVect(world, local);
97 } // geo::LocalTransformation::WorldToLocalVect()
99 //------------------------------------------------------------------------------
100 template <typename Matrix>
101 template <typename DestPoint, typename SrcPoint>
102 DestPoint geo::LocalTransformation<Matrix>::WorldToLocalImpl(SrcPoint const& world) const
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()
110 //......................................................................
111 template <typename Matrix>
112 template <typename DestVector, typename SrcVector>
113 DestVector geo::LocalTransformation<Matrix>::WorldToLocalVectImpl(SrcVector const& world) const
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()
121 //......................................................................
122 template <typename Matrix>
123 template <typename DestPoint, typename SrcPoint>
124 DestPoint geo::LocalTransformation<Matrix>::LocalToWorldImpl(SrcPoint const& local) const
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()
132 //......................................................................
133 template <typename Matrix>
134 template <typename DestVector, typename SrcVector>
135 DestVector geo::LocalTransformation<Matrix>::LocalToWorldVectImpl(SrcVector const& local) const
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()
143 //------------------------------------------------------------------------------
144 // specialisations (template implementations)
148 //----------------------------------------------------------------------------
150 inline TGeoHMatrix transformationFromPath<TGeoHMatrix>(std::vector<TGeoNode const*> const& path,
153 TGeoHMatrix matrix = *(path[0]->GetMatrix());
154 for (size_t i = 1; i <= depth; ++i)
155 matrix.Multiply(path[i]->GetMatrix());
157 } // geo::LocalTransformation<TGeoHMatrix>::transformationFromPath()
160 inline TGeoHMatrix transformationFromPath<TGeoHMatrix, GeoNodeIterator_t>(GeoNodeIterator_t begin,
161 GeoNodeIterator_t end)
163 if (begin == end) return {TGeoIdentity()};
165 TGeoHMatrix matrix = *((*iNode)->GetMatrix());
166 while (++iNode != end)
167 matrix.Multiply((*iNode)->GetMatrix());
170 } // geo::LocalTransformation<TGeoHMatrix>::transformationFromPath(ITER)
172 //----------------------------------------------------------------------------
174 inline HepGeom::Transform3D transformationFromPath<HepGeom::Transform3D>(
175 std::vector<TGeoNode const*> const& path,
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]));
184 } // geo::LocalTransformation<HepGeom::Transform3D>::transformationFromPath()
187 HepGeom::Transform3D inline transformationFromPath<HepGeom::Transform3D>(GeoNodeIterator_t begin,
188 GeoNodeIterator_t end)
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]));
196 } // geo::LocalTransformation<HepGeom::Transform3D>::transformationFromPath()
198 //----------------------------------------------------------------------------
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; }
208 //--------------------------------------------------------------------------
210 } // namespace details
212 //----------------------------------------------------------------------------
216 //------------------------------------------------------------------------------
218 #endif // LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC