2 * @file larcorealg/Geometry/LocalTransformation.tcc
3 * @brief Class containing local-to-world transformations
4 * (template implementation)
5 * @see LocalTransformation.h
7 * This file is expected to be included directly in the header.
10 #ifndef LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
11 #define LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC
13 // framework libraries
14 #include "cetlib_except/exception.h"
17 #include "TGeoMatrix.h"
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
29 //------------------------------------------------------------------------------
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);
40 //--------------------------------------------------------------------------
41 template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
42 bool doBuffersOverlap(T const* src, T const* dest)
44 return (dest < (src + SrcN)) && (src < (dest + DestN));
47 template <typename T, std::size_t SrcN = 3, std::size_t DestN = SrcN>
48 void checkVectorBufferOverlap(T const* src, T const* dest)
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";
56 assert(!doBuffersOverlap(src, dest));
57 } // checkVectorBufferOverlap()
59 //--------------------------------------------------------------------------
61 } // namespace details
64 //------------------------------------------------------------------------------
65 template <typename Matrix>
66 void geo::LocalTransformation<Matrix>::LocalToWorld(double const* local, double* world) const
68 details::checkVectorBufferOverlap(local, world);
69 fGeoMatrix.LocalToMaster(local, world);
72 //------------------------------------------------------------------------------
73 template <typename Matrix>
74 void geo::LocalTransformation<Matrix>::LocalToWorldVect(double const* local, double* world) const
76 details::checkVectorBufferOverlap(local, world);
77 fGeoMatrix.LocalToMasterVect(local, world);
80 //------------------------------------------------------------------------------
81 template <typename Matrix>
82 void geo::LocalTransformation<Matrix>::WorldToLocal(double const* world, double* local) const
84 details::checkVectorBufferOverlap(local, world);
85 fGeoMatrix.MasterToLocal(world, local);
88 //------------------------------------------------------------------------------
89 template <typename Matrix>
90 void geo::LocalTransformation<Matrix>::WorldToLocalVect(const double* world, double* local) const
92 details::checkVectorBufferOverlap(local, world);
93 fGeoMatrix.MasterToLocalVect(world, local);
96 //------------------------------------------------------------------------------
97 template <typename Matrix>
98 template <typename DestPoint, typename SrcPoint>
99 DestPoint geo::LocalTransformation<Matrix>::WorldToLocalImpl(SrcPoint const& world) const
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]};
107 //......................................................................
108 template <typename Matrix>
109 template <typename DestVector, typename SrcVector>
110 DestVector geo::LocalTransformation<Matrix>::WorldToLocalVectImpl(SrcVector const& world) const
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]};
118 //......................................................................
119 template <typename Matrix>
120 template <typename DestPoint, typename SrcPoint>
121 DestPoint geo::LocalTransformation<Matrix>::LocalToWorldImpl(SrcPoint const& local) const
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]};
129 //......................................................................
130 template <typename Matrix>
131 template <typename DestVector, typename SrcVector>
132 DestVector geo::LocalTransformation<Matrix>::LocalToWorldVectImpl(SrcVector const& local) const
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]};
140 //------------------------------------------------------------------------------
141 // specialisations (template implementations)
145 //----------------------------------------------------------------------------
147 inline TGeoHMatrix transformationFromPath<TGeoHMatrix>(std::vector<GeoNodePathEntry> const& path,
150 TGeoHMatrix matrix = *(path[0].node->GetMatrix());
151 for (size_t i = 1; i <= depth; ++i)
152 matrix.Multiply(path[i].node->GetMatrix());
157 inline TGeoHMatrix transformationFromPath<TGeoHMatrix, GeoNodeIterator_t>(GeoNodeIterator_t begin,
158 GeoNodeIterator_t end)
160 if (begin == end) return {TGeoIdentity()};
162 TGeoHMatrix matrix = *(iNode->node->GetMatrix());
163 while (++iNode != end)
164 matrix.Multiply(iNode->node->GetMatrix());
168 //----------------------------------------------------------------------------
170 inline HepGeom::Transform3D transformationFromPath<HepGeom::Transform3D>(
171 std::vector<GeoNodePathEntry> const& path,
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]));
181 HepGeom::Transform3D inline transformationFromPath<HepGeom::Transform3D>(GeoNodeIterator_t begin,
182 GeoNodeIterator_t end)
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]));
190 //----------------------------------------------------------------------------
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; }
200 //--------------------------------------------------------------------------
202 } // namespace details
204 //----------------------------------------------------------------------------
208 //------------------------------------------------------------------------------
210 #endif // LARCOREALG_GEOMETRY_LOCALTRANSFORMATION_TCC