1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2016 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
23 #include <tap/basic.h>
24 #include <tap/float.h>
25 #include <tap/hkl-tap.h>
27 /* BEWARE THESE TESTS ARE DEALING WITH HKL INTERNALS WHICH EXPOSE A
28 * NON PUBLIC API WHICH ALLOW TO SHOOT YOURSELF IN YOUR FOOT */
30 #include "hkl/ccan/container_of/container_of.h"
31 #include "hkl-axis-private.h" /* temporary */
32 #include "hkl-geometry-private.h"
34 static void add_holder(void)
36 HklGeometry
*g
= NULL
;
37 HklHolder
*holder
= NULL
;
39 g
= hkl_geometry_new(NULL
);
40 is_int(0, darray_size(g
->holders
), __func__
);
42 holder
= hkl_geometry_add_holder(g
);
43 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
44 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
45 is_int(1, darray_size(g
->holders
), __func__
);
47 holder
= hkl_geometry_add_holder(g
);
48 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
49 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
50 is_int(2, darray_size(g
->holders
), __func__
);
52 ok(holder
== darray_item(g
->holders
, 1), __func__
);
57 static void get_axis(void)
60 HklGeometry
*g
= NULL
;
61 HklHolder
*holder
= NULL
;
62 const HklParameter
*axis0
;
65 g
= hkl_geometry_new(NULL
);
67 holder
= hkl_geometry_add_holder(g
);
68 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
69 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
71 holder
= hkl_geometry_add_holder(g
);
72 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
73 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
75 /* check the private API */
76 res
&= DIAG(0 == !hkl_geometry_get_axis_by_name(g
, "A"));
77 res
&= DIAG(0 == !hkl_geometry_get_axis_by_name(g
, "B"));
78 res
&= DIAG(0 == !hkl_geometry_get_axis_by_name(g
, "C"));
79 res
&= DIAG(1 == !hkl_geometry_get_axis_by_name(g
, "D"));
81 /* check the public API */
83 res
&= DIAG(NULL
!= hkl_geometry_axis_get(g
, "A", NULL
));
84 res
&= DIAG(NULL
== hkl_geometry_axis_get(g
, "D", NULL
));
86 res
&= DIAG(NULL
!= hkl_geometry_axis_get(g
, "A", &error
));
87 res
&= DIAG(error
== NULL
);
88 res
&= DIAG(NULL
== hkl_geometry_axis_get(g
, "D", &error
));
89 res
&= DIAG(error
!= NULL
);
90 g_clear_error(&error
);
93 axis0
= hkl_geometry_axis_get(g
, "A", NULL
);
94 res
&= DIAG(TRUE
== hkl_geometry_axis_set(g
, "A", axis0
, NULL
));
95 res
&= DIAG(FALSE
== hkl_geometry_axis_set(g
, "B", axis0
, NULL
));
98 res
&= DIAG(hkl_geometry_axis_set(g
, "A", axis0
, &error
));
99 res
&= DIAG(error
== NULL
);
101 res
&= DIAG(FALSE
== hkl_geometry_axis_set(g
, "B", axis0
, &error
));
102 res
&= DIAG(error
!= NULL
);
106 g_clear_error(&error
);
108 hkl_geometry_free(g
);
111 static void update(void)
114 HklGeometry
*g
= NULL
;
115 HklHolder
*holder
= NULL
;
118 g
= hkl_geometry_new(NULL
);
120 holder
= hkl_geometry_add_holder(g
);
121 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
122 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
124 holder
= hkl_geometry_add_holder(g
);
125 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
126 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
128 axis1
= container_of(hkl_geometry_get_axis_by_name(g
, "B"), HklAxis
, parameter
);
129 res
&= DIAG(hkl_parameter_value_set(&axis1
->parameter
, M_PI_2
, HKL_UNIT_DEFAULT
, NULL
));
130 /* now axis1 is dirty */
131 ok(TRUE
== axis1
->parameter
.changed
, __func__
);
133 hkl_geometry_update(g
);
134 holder
= darray_item(g
->holders
, 0);
135 is_double(1./sqrt(2), holder
->q
.data
[0], HKL_EPSILON
, __func__
);
136 is_double(1./sqrt(2), holder
->q
.data
[1], HKL_EPSILON
, __func__
);
137 is_double(.0, holder
->q
.data
[2], HKL_EPSILON
, __func__
);
138 is_double(.0, holder
->q
.data
[3], HKL_EPSILON
, __func__
);
139 /* now axis1 is clean */
140 res
&= DIAG(FALSE
== axis1
->parameter
.changed
);
144 hkl_geometry_free(g
);
147 static void set(void)
153 HklFactory
*fake_factory
;
155 g
= hkl_geometry_new(NULL
);
156 holder
= hkl_geometry_add_holder(g
);
157 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
158 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
159 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
161 g1
= hkl_geometry_new_copy(g
);
163 /* it is required to use a fake factory, with the public API
164 * geometry contain always a real factory */
165 fake_factory
= (HklFactory
*)0x1;
166 g2
= hkl_geometry_new(fake_factory
);
167 holder
= hkl_geometry_add_holder(g
);
168 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
169 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
171 ok(hkl_geometry_set(g
, g1
), __func__
);
173 hkl_geometry_free(g2
);
174 hkl_geometry_free(g1
);
175 hkl_geometry_free(g
);
178 static void axis_values_get_set(void)
183 static double set_1
[] = {1, 1, 1};
184 static double set_10
[] = {10, 10, 10};
188 g
= hkl_geometry_new(NULL
);
189 holder
= hkl_geometry_add_holder(g
);
190 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
191 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
192 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
194 /* check set DEFAULT unit */
196 ok(TRUE
== hkl_geometry_axis_values_set(g
, set_1
, ARRAY_SIZE(set_1
), HKL_UNIT_DEFAULT
, NULL
), __func__
);
197 ok(TRUE
== hkl_geometry_axis_values_set(g
, set_1
, ARRAY_SIZE(set_1
), HKL_UNIT_DEFAULT
, &error
), __func__
);
198 ok(error
== NULL
, __func__
);
199 for(i
=0; i
<ARRAY_SIZE(set_1
); ++i
)
200 is_double(set_1
[i
], hkl_parameter_value_get(darray_item(g
->axes
, i
), HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
202 /* check get DEFAULT unit */
203 hkl_geometry_axis_values_get(g
, values
, 3, HKL_UNIT_DEFAULT
);
204 for(i
=0; i
<ARRAY_SIZE(set_1
); ++i
)
205 is_double(set_1
[i
], values
[i
], HKL_EPSILON
, __func__
);
207 /* check set USER unit */
208 ok(TRUE
== hkl_geometry_axis_values_set(g
, set_10
, ARRAY_SIZE(set_10
), HKL_UNIT_USER
, NULL
), __func__
);
209 ok(TRUE
== hkl_geometry_axis_values_set(g
, set_10
, ARRAY_SIZE(set_10
), HKL_UNIT_USER
, &error
), __func__
);
210 ok(error
== NULL
, __func__
);
211 for(i
=0; i
<ARRAY_SIZE(set_10
); ++i
)
212 is_double(set_10
[i
] * HKL_DEGTORAD
, hkl_parameter_value_get(darray_item(g
->axes
, i
), HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
214 /* check get USER unit */
215 hkl_geometry_axis_values_get(g
, values
, 3, HKL_UNIT_USER
);
216 for(i
=0; i
<ARRAY_SIZE(set_10
); ++i
)
217 is_double(set_10
[i
], values
[i
], HKL_EPSILON
, __func__
);
219 hkl_geometry_free(g
);
222 static void distance(void)
225 HklGeometry
*g1
= NULL
;
226 HklGeometry
*g2
= NULL
;
227 HklHolder
*holder
= NULL
;
229 g1
= hkl_geometry_new(NULL
);
230 holder
= hkl_geometry_add_holder(g1
);
231 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
232 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
233 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
235 g2
= hkl_geometry_new_copy(g1
);
237 res
&= DIAG(hkl_geometry_set_values_v(g1
, HKL_UNIT_DEFAULT
, NULL
, 0., 0., 0.));
238 res
&= DIAG(hkl_geometry_set_values_v(g2
, HKL_UNIT_DEFAULT
, NULL
, 1., 1., 1.));
239 is_double(3., hkl_geometry_distance(g1
, g2
), HKL_EPSILON
, __func__
);
243 hkl_geometry_free(g1
);
244 hkl_geometry_free(g2
);
247 static void is_valid(void)
250 HklGeometry
*geom
= NULL
;
251 HklHolder
*holder
= NULL
;
253 geom
= hkl_geometry_new(NULL
);
254 holder
= hkl_geometry_add_holder(geom
);
255 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
256 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
257 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
259 res
&= DIAG(hkl_geometry_set_values_v(geom
, HKL_UNIT_DEFAULT
, NULL
, 0., 0., 0.));
260 res
&= DIAG(TRUE
== hkl_geometry_is_valid(geom
));
262 res
&= DIAG(hkl_geometry_set_values_v(geom
, HKL_UNIT_DEFAULT
, NULL
, -181. * HKL_DEGTORAD
, 0., 0.));
263 res
&= DIAG(TRUE
== hkl_geometry_is_valid(geom
));
265 res
&= DIAG(hkl_parameter_min_max_set(darray_item(geom
->axes
, 0),
266 -100 * HKL_DEGTORAD
, 100 * HKL_DEGTORAD
,
267 HKL_UNIT_DEFAULT
, NULL
));
268 res
&= DIAG(FALSE
== hkl_geometry_is_valid(geom
));
272 hkl_geometry_free(geom
);
275 static void wavelength(void)
277 HklGeometry
*geom
= NULL
;
280 geom
= hkl_geometry_new(NULL
);
282 is_double(1.54, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
284 ok(TRUE
== hkl_geometry_wavelength_set(geom
, 2, HKL_UNIT_DEFAULT
, NULL
), __func__
);
285 is_double(2, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
288 ok(TRUE
== hkl_geometry_wavelength_set(geom
, 2, HKL_UNIT_DEFAULT
, &error
), __func__
);
289 ok(error
== NULL
, __func__
);
290 is_double(2, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
292 hkl_geometry_free(geom
);
295 static void xxx_rotation_get(void)
299 HklFactory
**factories
;
300 HklDetector
*detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
301 HklSample
*sample
= hkl_sample_new("test");
303 factories
= hkl_factory_get_all(&n
);
304 for(i
=0; i
<n
&& TRUE
== res
; i
++){
305 HklGeometry
*geometry
= NULL
;
306 HklQuaternion q_ref
= {{1, 0, 0, 0}};
310 geometry
= hkl_factory_create_new_geometry(factories
[i
]);
311 qs
= hkl_geometry_sample_rotation_get(geometry
, sample
);
312 qd
= hkl_geometry_detector_rotation_get(geometry
, detector
);
314 res
&= DIAG(TRUE
== hkl_quaternion_cmp(&q_ref
, &qs
));
315 res
&= DIAG(TRUE
== hkl_quaternion_cmp(&q_ref
, &qd
));
317 hkl_geometry_free(geometry
);
321 hkl_detector_free(detector
);
322 hkl_sample_free(sample
);
325 static void list(void)
330 HklGeometryList
*list
;
331 const HklGeometryListItem
*item
;
333 static double values
[] = {0. * HKL_DEGTORAD
, 10 * HKL_DEGTORAD
, 30 * HKL_DEGTORAD
};
335 g
= hkl_geometry_new(NULL
);
336 holder
= hkl_geometry_add_holder(g
);
337 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
338 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
339 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
341 list
= hkl_geometry_list_new();
343 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[0], 0., 0.));
344 hkl_geometry_list_add(list
, g
);
345 is_int(1, hkl_geometry_list_n_items_get(list
), __func__
);
347 /* can not add two times the same geometry */
348 hkl_geometry_list_add(list
, g
);
349 is_int(1, hkl_geometry_list_n_items_get(list
), __func__
);
351 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[2], 0., 0.));
352 hkl_geometry_list_add(list
, g
);
353 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[1], 0., 0.));
354 hkl_geometry_list_add(list
, g
);
355 is_int(3, hkl_geometry_list_n_items_get(list
), __func__
);
357 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[0], 0., 0.));
358 hkl_geometry_list_sort(list
, g
);
360 HKL_GEOMETRY_LIST_FOREACH(item
, list
){
361 is_double(values
[i
++],
362 hkl_parameter_value_get(darray_item(item
->geometry
->axes
, 0), HKL_UNIT_DEFAULT
),
363 HKL_EPSILON
, __func__
);
368 hkl_geometry_free(g
);
369 hkl_geometry_list_free(list
);
372 static void list_multiply_from_range(void)
376 HklGeometryList
*list
;
378 HklParameter
*axisA
, *axisB
, *axisC
;
380 g
= hkl_geometry_new(NULL
);
381 holder
= hkl_geometry_add_holder(g
);
382 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
383 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
384 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
386 axisA
= hkl_geometry_get_axis_by_name(g
, "A");
387 axisB
= hkl_geometry_get_axis_by_name(g
, "B");
388 axisC
= hkl_geometry_get_axis_by_name(g
, "C");
390 res
&= DIAG(hkl_parameter_min_max_set(axisA
, -190, 190, HKL_UNIT_USER
, NULL
));
391 res
&= DIAG(hkl_parameter_min_max_set(axisB
, -190, 190, HKL_UNIT_USER
, NULL
));
392 res
&= DIAG(hkl_parameter_min_max_set(axisC
, -190, 190, HKL_UNIT_USER
, NULL
));
394 list
= hkl_geometry_list_new();
396 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
397 185. * HKL_DEGTORAD
, -185. * HKL_DEGTORAD
, 190. * HKL_DEGTORAD
));
398 hkl_geometry_list_add(list
, g
);
400 hkl_geometry_list_multiply_from_range(list
);
404 hkl_geometry_free(g
);
405 hkl_geometry_list_free(list
);
408 static void list_remove_invalid(void)
412 HklGeometryList
*list
;
414 HklParameter
*axisA
, *axisB
, *axisC
;
416 g
= hkl_geometry_new(NULL
);
417 holder
= hkl_geometry_add_holder(g
);
418 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
419 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
420 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
422 axisA
= hkl_geometry_get_axis_by_name(g
, "A");
423 axisB
= hkl_geometry_get_axis_by_name(g
, "B");
424 axisC
= hkl_geometry_get_axis_by_name(g
, "C");
426 res
&= DIAG(hkl_parameter_min_max_set(axisA
, -100, 180., HKL_UNIT_USER
, NULL
));
427 res
&= DIAG(hkl_parameter_min_max_set(axisB
, -100., 180., HKL_UNIT_USER
, NULL
));
428 res
&= DIAG(hkl_parameter_min_max_set(axisC
, -100., 180., HKL_UNIT_USER
, NULL
));
430 list
= hkl_geometry_list_new();
432 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
434 -185. * HKL_DEGTORAD
,
435 185. * HKL_DEGTORAD
));
436 hkl_geometry_list_add(list
, g
);
438 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
439 -190. * HKL_DEGTORAD
,
440 -190. * HKL_DEGTORAD
,
441 -190. * HKL_DEGTORAD
));
442 hkl_geometry_list_add(list
, g
);
444 res
&= DIAG(hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
447 180. * HKL_DEGTORAD
));
448 hkl_geometry_list_add(list
, g
);
450 is_int(3, hkl_geometry_list_n_items_get(list
), __func__
);
451 hkl_geometry_list_remove_invalid(list
);
452 is_int(1, hkl_geometry_list_n_items_get(list
), __func__
);
456 hkl_geometry_free(g
);
457 hkl_geometry_list_free(list
);
468 axis_values_get_set();
475 list_multiply_from_range();
476 list_remove_invalid();