GCC Code Coverage Report


Directory: ./
File: src/util/transformations.cc
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 58 87 66.7%
Functions: 9 13 69.2%
Branches: 49 67 73.1%

Line Branch Exec Source
1 #include "na64util/transformations.hh"
2
3 #include <unordered_map>
4 #include <cassert>
5
6 namespace na64dp {
7 namespace util {
8
9 const na64sw_RotationOrder gStdRotationOrder
10 = na64sw_Rotation_zyx; // TODO: macro
11
12 template<> Matrix3T<float>
13 6 rotation_matrix<float>( na64sw_RotationOrder order, const float * angles ) {
14 Matrix3T<float> m;
15 6 int rc = na64sw_rotation_matrix_f(order, angles, m.m);
16
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(rc) {
17 NA64DP_RUNTIME_ERROR("Couldn't create (float) rotation matrix for"
18 " given axes order.");
19 }
20 6 return m;
21 }
22
23 template<> Matrix3T<double>
24 rotation_matrix<double>( na64sw_RotationOrder order, const double * angles ) {
25 Matrix3T<double> m;
26 int rc = na64sw_rotation_matrix_d(order, angles, m.m);
27 if(rc) {
28 NA64DP_RUNTIME_ERROR("Couldn't create (double float) rotation matrix for"
29 " given axes order.");
30 }
31 return m;
32 }
33
34 //
35 // Transformation object implementation
36
37 void
38 6 Transformation::_recache_affine_transforms() const {
39 6 _rotation = util::rotation_matrix(_rotationOrder, _angles);
40
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
24 for(int i = 0; i < 3; ++i) {
41 18 _shearAndScale.cm[i][0] = _u[i];
42 18 _shearAndScale.cm[i][1] = _v[i];
43 18 _shearAndScale.cm[i][2] = _w[i];
44 }
45 6 _affineMatrix = _rotation*_shearAndScale;
46 6 _cachesValid = true;
47 6 }
48
49 11 Transformation::Transformation()
50 11 : _cachesValid(false)
51 11 , _rotationOrder(gStdRotationOrder)
52 11 , _invertOffset(false)
53 11 , _offset{{0, 0, 0}}
54 11 , _u{{1, 0, 0}}, _v{{0, 1, 0}}, _w{{0, 0, 1}}
55 11 , _angles{0, 0, 0}
56 11 {}
57
58 Transformation::Transformation(const Transformation & other)
59 : _cachesValid(false)
60 , _rotationOrder(other._rotationOrder)
61 , _invertOffset(other._invertOffset)
62 , _offset(other._offset)
63 , _u(other._u), _v(other._v), _w(other._w)
64 , _angles{other._angles[0], other._angles[1], other._angles[2]}
65 {}
66
67 1 Transformation::Transformation( const Vec3 & offset_
68 , const Vec3 & u_, const Vec3 & v_, const Vec3 & w_
69 , Float_t alpha, Float_t beta, Float_t gamma
70 , na64sw_RotationOrder rotationOrder
71 , bool invertOffset
72 1 ) : _cachesValid(false)
73 1 , _rotationOrder(rotationOrder)
74 1 , _invertOffset(invertOffset)
75 1 , _offset(offset_)
76 1 , _u(u_), _v(v_), _w(w_)
77 1 , _angles{alpha, beta, gamma}
78 1 {}
79
80 Float_t
81 9 Transformation::angle( int i ) const {
82
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
9 if( i < 0 || i > 2 ) {
83 NA64DP_RUNTIME_ERROR("%d is out of range for transformation angle.", i);
84 }
85 9 return _angles[i];
86 }
87
88 void
89 10 Transformation::angle( int i, Float_t value ) {
90
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if( i < 0 || i > 2 ) {
91 NA64DP_RUNTIME_ERROR("%d is out of range for transformation angle.", i);
92 }
93 10 _invalidate_caches();
94 10 _angles[i] = value;
95 10 }
96
97
98 const Matrix3 &
99 Transformation::rotation_matrix() const {
100 if(!_cachesValid) _recache_affine_transforms();
101 return _rotation;
102 }
103
104 const Matrix3 &
105 Transformation::basis() const {
106 if(!_cachesValid) _recache_affine_transforms();
107 return _shearAndScale;
108 }
109
110 const Matrix3 &
111 15 Transformation::affine_matrix() const {
112
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
15 if(!_cachesValid) _recache_affine_transforms();
113 15 return _affineMatrix;
114 }
115
116
117 #if 0
118 void
119 apply_std_rotation( Vec3 & r
120 , const Float_t rot[3]
121 ) {
122 #if 1
123 const Float_t s1 = sin(rot[2]), c1 = cos(rot[2])
124 , s2 = sin(rot[1]), c2 = cos(rot[1])
125 , s3 = sin(rot[0]), c3 = cos(rot[0])
126 ;
127 Matrix3 m = {{ {c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2}
128 , {c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3}
129 , { -s2, c2*s3, c2*c3}
130 }};
131 r = m*r;
132 #else
133 //#if defined(ROOT_FOUND) && ROOT_FOUND
134 //r.RotateZ( M_PI * rot[2] / 180 );
135 //r.RotateY( M_PI * rot[1] / 180 );
136 //r.RotateX( M_PI * rot[0] / 180 );
137 //#endif
138 #endif
139 }
140 #endif
141
142 #if 0
143 void
144 cardinal_vectors( const float center[3]
145 , const float size[3]
146 , const float rot[3]
147 , Vec3 & o
148 , Vec3 & u, Vec3 & v, Vec3 & w
149 ) {
150 o.r[0] = center[0]; o.r[1] = center[1]; o.r[2] = center[2];
151 u.r[0] = size[0]; u.r[1] = 0.; u.r[2] = 0.;
152 v.r[0] = 0.; v.r[1] = size[1]; v.r[2] = 0.;
153 w.r[0] = 0.; w.r[1] = 0.; w.r[2] = size[2];
154
155 apply_std_rotation(u, rot);
156 apply_std_rotation(v, rot);
157 apply_std_rotation(w, rot);
158 }
159 #endif
160
161 static std::unordered_map< std::string, std::unordered_map<std::string, float> >
162 _gUnitsByQuantity;
163
164 1 static bool _init_units_conversion_table() {
165 #define DEFINE_UNITS_ENTRY( name, value, quantity ) \
166 { auto qIR = _gUnitsByQuantity.emplace(quantity, decltype(_gUnitsByQuantity)::mapped_type()); \
167 qIR.first->second.emplace( # name, Units:: name ); }
168
24/24
✓ Branch 2 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 20 taken 1 times.
✓ Branch 25 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 34 taken 1 times.
✓ Branch 38 taken 1 times.
✓ Branch 43 taken 1 times.
✓ Branch 47 taken 1 times.
✓ Branch 52 taken 1 times.
✓ Branch 56 taken 1 times.
✓ Branch 61 taken 1 times.
✓ Branch 65 taken 1 times.
✓ Branch 70 taken 1 times.
✓ Branch 74 taken 1 times.
✓ Branch 79 taken 1 times.
✓ Branch 83 taken 1 times.
✓ Branch 88 taken 1 times.
✓ Branch 92 taken 1 times.
✓ Branch 97 taken 1 times.
✓ Branch 101 taken 1 times.
✓ Branch 106 taken 1 times.
1 NA64SW_FOR_EVERY_UNITS(DEFINE_UNITS_ENTRY)
169 #undef DEFINE_UNITS_ENTRY
170 1 return true;
171 }
172
173 static bool _unitConverionTableInitialized
174 = _init_units_conversion_table();
175
176 float
177 2 Units::get_units_conversion_factor( const std::string & strUnitsFrom
178 , const std::string & strUnitsToOrQuantity
179 ) {
180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(_unitConverionTableInitialized);
181
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if( strUnitsToOrQuantity.empty() ) {
182 // look over all the available quantities
183 for( const auto & units : _gUnitsByQuantity ) {
184 auto it = units.second.find(strUnitsFrom);
185 if( units.second.end() != it ) return 1 / it->second;
186 }
187 throw errors::UnknownUnit(strUnitsFrom);
188 }
189
1/1
✓ Branch 1 taken 2 times.
2 auto qIt = _gUnitsByQuantity.find(strUnitsToOrQuantity);
190
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if(_gUnitsByQuantity.end() != qIt) {
191 // second argument is quantity => look for the units
192
1/1
✓ Branch 2 taken 1 times.
1 auto it = qIt->second.find(strUnitsFrom);
193
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 if(qIt->second.end() != it) return it->second;
194 throw errors::UnknownUnit(strUnitsFrom, strUnitsToOrQuantity);
195 }
196 // then both arguments are probably the units => find factors and return
197 // ratio, assuring both are of the same quantity
198
1/2
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 for( const auto & units : _gUnitsByQuantity ) {
199
1/1
✓ Branch 1 taken 4 times.
4 auto it1 = units.second.find(strUnitsFrom)
200
1/1
✓ Branch 1 taken 4 times.
4 , it2 = units.second.find(strUnitsToOrQuantity)
201 ;
202
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if( it1 == it2 ) {
203
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if(it1 == units.second.end()) continue;
204 1 return 1;
205 }
206
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
1 if( it1 == units.second.end() || it2 == units.second.end() )
207 throw errors::QuantityMismatch(strUnitsFrom, strUnitsToOrQuantity);
208 1 return it1->second / it2->second;
209 }
210 throw errors::UnknownUnit(strUnitsFrom, strUnitsToOrQuantity);
211 }
212
213
214 } // namespace ::na64dp::util
215 } // namespace na64dp
216
217