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-2014 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>
26 /* BEWARE THESE TESTS ARE DEALING WITH HKL INTERNALS WHICH EXPOSE A
27 * NON PUBLIC API WHICH ALLOW TO SHOOT YOURSELF IN YOUR FOOT */
29 #include "hkl/ccan/container_of/container_of.h"
30 #include "hkl-axis-private.h" /* temporary */
31 #include "hkl-geometry-private.h"
33 static void add_holder(void)
35 HklGeometry
*g
= NULL
;
36 HklHolder
*holder
= NULL
;
38 g
= hkl_geometry_new(NULL
);
39 is_int(0, darray_size(g
->holders
), __func__
);
41 holder
= hkl_geometry_add_holder(g
);
42 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
43 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
44 is_int(1, darray_size(g
->holders
), __func__
);
46 holder
= hkl_geometry_add_holder(g
);
47 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
48 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
49 is_int(2, darray_size(g
->holders
), __func__
);
51 ok(holder
== darray_item(g
->holders
, 1), __func__
);
56 static void get_axis(void)
58 HklGeometry
*g
= NULL
;
59 HklHolder
*holder
= NULL
;
60 const HklParameter
*axis0
, *axis1
, *axis2
;
63 g
= hkl_geometry_new(NULL
);
65 holder
= hkl_geometry_add_holder(g
);
66 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
67 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
69 holder
= hkl_geometry_add_holder(g
);
70 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
71 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
73 /* check the private API */
74 ok(0 == !hkl_geometry_get_axis_by_name(g
, "A"), __func__
);
75 ok(0 == !hkl_geometry_get_axis_by_name(g
, "B"), __func__
);
76 ok(0 == !hkl_geometry_get_axis_by_name(g
, "C"), __func__
);
77 ok(1 == !hkl_geometry_get_axis_by_name(g
, "D"), __func__
);
79 /* check the public API */
81 ok(NULL
!= hkl_geometry_axis_get(g
, "A", NULL
), __func__
);
82 ok(NULL
== hkl_geometry_axis_get(g
, "D", NULL
), __func__
);
84 hkl_geometry_axis_get(g
, "A", &error
);
85 ok(error
== NULL
, __func__
);
86 hkl_geometry_axis_get(g
, "D", &error
);
87 ok(error
!= NULL
, __func__
);
88 g_clear_error(&error
);
91 axis0
= hkl_geometry_axis_get(g
, "A", NULL
);
92 ok(TRUE
== hkl_geometry_axis_set(g
, "A", axis0
, NULL
), __func__
);
93 ok(FALSE
== hkl_geometry_axis_set(g
, "B", axis0
, NULL
), __func__
);
96 hkl_geometry_axis_set(g
, "A", axis0
, &error
);
97 ok(error
== NULL
, __func__
);
99 ok(FALSE
== hkl_geometry_axis_set(g
, "B", axis0
, &error
), __func__
);
100 ok(error
!= NULL
, __func__
);
101 g_clear_error(&error
);
103 hkl_geometry_free(g
);
106 static void update(void)
108 HklGeometry
*g
= NULL
;
109 HklHolder
*holder
= NULL
;
110 HklAxis
*axis0
, *axis1
, *axis2
;
112 g
= hkl_geometry_new(NULL
);
114 holder
= hkl_geometry_add_holder(g
);
115 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
116 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
118 holder
= hkl_geometry_add_holder(g
);
119 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
120 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
122 axis1
= container_of(hkl_geometry_get_axis_by_name(g
, "B"), HklAxis
, parameter
);
123 hkl_parameter_value_set(&axis1
->parameter
, M_PI_2
, HKL_UNIT_DEFAULT
, NULL
);
124 /* now axis1 is dirty */
125 ok(TRUE
== axis1
->parameter
.changed
, __func__
);
127 hkl_geometry_update(g
);
128 holder
= darray_item(g
->holders
, 0);
129 is_double(1./sqrt(2), holder
->q
.data
[0], HKL_EPSILON
, __func__
);
130 is_double(1./sqrt(2), holder
->q
.data
[1], HKL_EPSILON
, __func__
);
131 is_double(.0, holder
->q
.data
[2], HKL_EPSILON
, __func__
);
132 is_double(.0, holder
->q
.data
[3], HKL_EPSILON
, __func__
);
133 /* now axis1 is clean */
134 ok(FALSE
== axis1
->parameter
.changed
, __func__
);
136 hkl_geometry_free(g
);
139 static void set(void)
147 HklFactory
*fake_factory
;
149 g
= hkl_geometry_new(NULL
);
150 holder
= hkl_geometry_add_holder(g
);
151 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
152 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
153 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
155 g1
= hkl_geometry_new_copy(g
);
157 /* it is required to use a fake factory, with the public API
158 * geometry contain always a real factory */
159 fake_factory
= (HklFactory
*)0x1;
160 g2
= hkl_geometry_new(fake_factory
);
161 holder
= hkl_geometry_add_holder(g
);
162 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
163 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
165 ok(hkl_geometry_set(g
, g1
), __func__
);
167 hkl_geometry_free(g2
);
168 hkl_geometry_free(g1
);
169 hkl_geometry_free(g
);
172 static void axes_values_get_set(void)
177 static double set_1
[] = {1, 1, 1};
178 static double set_10
[] = {10, 10, 10};
182 g
= hkl_geometry_new(NULL
);
183 holder
= hkl_geometry_add_holder(g
);
184 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
185 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
186 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
188 /* check set DEFAULT unit */
190 ok(TRUE
== hkl_geometry_axes_values_set(g
, set_1
, ARRAY_SIZE(set_1
), HKL_UNIT_DEFAULT
, NULL
), __func__
);
191 ok(TRUE
== hkl_geometry_axes_values_set(g
, set_1
, ARRAY_SIZE(set_1
), HKL_UNIT_DEFAULT
, &error
), __func__
);
192 ok(error
== NULL
, __func__
);
193 for(i
=0; i
<ARRAY_SIZE(set_1
); ++i
)
194 is_double(set_1
[i
], hkl_parameter_value_get(darray_item(g
->axes
, i
), HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
196 /* check get DEFAULT unit */
197 hkl_geometry_axes_values_get(g
, values
, 3, HKL_UNIT_DEFAULT
);
198 for(i
=0; i
<ARRAY_SIZE(set_1
); ++i
)
199 is_double(set_1
[i
], values
[i
], HKL_EPSILON
, __func__
);
201 /* check set USER unit */
202 ok(TRUE
== hkl_geometry_axes_values_set(g
, set_10
, ARRAY_SIZE(set_10
), HKL_UNIT_USER
, NULL
), __func__
);
203 ok(TRUE
== hkl_geometry_axes_values_set(g
, set_10
, ARRAY_SIZE(set_10
), HKL_UNIT_USER
, &error
), __func__
);
204 ok(error
== NULL
, __func__
);
205 for(i
=0; i
<ARRAY_SIZE(set_10
); ++i
)
206 is_double(set_10
[i
] * HKL_DEGTORAD
, hkl_parameter_value_get(darray_item(g
->axes
, i
), HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
208 /* check get USER unit */
209 hkl_geometry_axes_values_get(g
, values
, 3, HKL_UNIT_USER
);
210 for(i
=0; i
<ARRAY_SIZE(set_10
); ++i
)
211 is_double(set_10
[i
], values
[i
], HKL_EPSILON
, __func__
);
213 hkl_geometry_free(g
);
216 static void distance(void)
218 HklGeometry
*g1
= NULL
;
219 HklGeometry
*g2
= NULL
;
220 HklHolder
*holder
= NULL
;
222 g1
= hkl_geometry_new(NULL
);
223 holder
= hkl_geometry_add_holder(g1
);
224 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
225 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
226 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
228 g2
= hkl_geometry_new_copy(g1
);
230 hkl_geometry_set_values_v(g1
, HKL_UNIT_DEFAULT
, NULL
, 0., 0., 0.);
231 hkl_geometry_set_values_v(g2
, HKL_UNIT_DEFAULT
, NULL
, 1., 1., 1.);
232 is_double(3., hkl_geometry_distance(g1
, g2
), HKL_EPSILON
, __func__
);
234 hkl_geometry_free(g1
);
235 hkl_geometry_free(g2
);
238 static void is_valid(void)
240 HklGeometry
*geom
= NULL
;
241 HklHolder
*holder
= NULL
;
243 geom
= hkl_geometry_new(NULL
);
244 holder
= hkl_geometry_add_holder(geom
);
245 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
246 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
247 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
249 hkl_geometry_set_values_v(geom
, HKL_UNIT_DEFAULT
, NULL
, 0., 0., 0.);
250 ok(TRUE
== hkl_geometry_is_valid(geom
), __func__
);
252 hkl_geometry_set_values_v(geom
, HKL_UNIT_DEFAULT
, NULL
, -181. * HKL_DEGTORAD
, 0., 0.);
253 ok(TRUE
== hkl_geometry_is_valid(geom
), __func__
);
255 hkl_parameter_min_max_set(darray_item(geom
->axes
, 0),
256 -100 * HKL_DEGTORAD
, 100 * HKL_DEGTORAD
,
257 HKL_UNIT_DEFAULT
, NULL
);
258 ok(FALSE
== hkl_geometry_is_valid(geom
), __func__
);
260 hkl_geometry_free(geom
);
263 static void wavelength(void)
265 HklGeometry
*geom
= NULL
;
266 HklHolder
*holder
= NULL
;
269 geom
= hkl_geometry_new(NULL
);
271 is_double(1.54, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
273 ok(TRUE
== hkl_geometry_wavelength_set(geom
, 2, HKL_UNIT_DEFAULT
, NULL
), __func__
);
274 is_double(2, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
277 ok(TRUE
== hkl_geometry_wavelength_set(geom
, 2, HKL_UNIT_DEFAULT
, &error
), __func__
);
278 ok(error
== NULL
, __func__
);
279 is_double(2, hkl_geometry_wavelength_get(geom
, HKL_UNIT_DEFAULT
), HKL_EPSILON
, __func__
);
281 hkl_geometry_free(geom
);
284 static void list(void)
288 HklGeometryList
*list
;
289 const HklGeometryListItem
*item
;
291 static double values
[] = {0. * HKL_DEGTORAD
, 10 * HKL_DEGTORAD
, 30 * HKL_DEGTORAD
};
293 g
= hkl_geometry_new(NULL
);
294 holder
= hkl_geometry_add_holder(g
);
295 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
296 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
297 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
299 list
= hkl_geometry_list_new();
301 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[0], 0., 0.);
302 hkl_geometry_list_add(list
, g
);
303 is_int(1, hkl_geometry_list_n_items_get(list
), __func__
);
305 /* can not add two times the same geometry */
306 hkl_geometry_list_add(list
, g
);
307 is_int(1, hkl_geometry_list_n_items_get(list
), __func__
);
309 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[2], 0., 0.);
310 hkl_geometry_list_add(list
, g
);
311 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[1], 0., 0.);
312 hkl_geometry_list_add(list
, g
);
313 is_int(3, hkl_geometry_list_n_items_get(list
), __func__
);
315 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
, values
[0], 0., 0.);
316 hkl_geometry_list_sort(list
, g
);
318 HKL_GEOMETRY_LIST_FOREACH(item
, list
){
319 is_double(values
[i
++],
320 hkl_parameter_value_get(darray_item(item
->geometry
->axes
, 0), HKL_UNIT_DEFAULT
),
321 HKL_EPSILON
, __func__
);
324 hkl_geometry_free(g
);
325 hkl_geometry_list_free(list
);
328 static void list_multiply_from_range(void)
331 HklGeometryList
*list
;
333 HklParameter
*axisA
, *axisB
, *axisC
;
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 axisA
= hkl_geometry_get_axis_by_name(g
, "A");
342 axisB
= hkl_geometry_get_axis_by_name(g
, "B");
343 axisC
= hkl_geometry_get_axis_by_name(g
, "C");
345 hkl_parameter_min_max_set(axisA
, -190, 190, HKL_UNIT_USER
, NULL
);
346 hkl_parameter_min_max_set(axisB
, -190, 190, HKL_UNIT_USER
, NULL
);
347 hkl_parameter_min_max_set(axisC
, -190, 190, HKL_UNIT_USER
, NULL
);
349 list
= hkl_geometry_list_new();
351 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
352 185. * HKL_DEGTORAD
, -185. * HKL_DEGTORAD
, 190. * HKL_DEGTORAD
);
353 hkl_geometry_list_add(list
, g
);
355 hkl_geometry_list_multiply_from_range(list
);
357 hkl_geometry_free(g
);
358 hkl_geometry_list_free(list
);
361 static void list_remove_invalid(void)
364 HklGeometryList
*list
;
366 HklParameter
*axisA
, *axisB
, *axisC
;
368 g
= hkl_geometry_new(NULL
);
369 holder
= hkl_geometry_add_holder(g
);
370 hkl_holder_add_rotation_axis(holder
, "A", 1., 0., 0.);
371 hkl_holder_add_rotation_axis(holder
, "B", 1., 0., 0.);
372 hkl_holder_add_rotation_axis(holder
, "C", 1., 0., 0.);
374 axisA
= hkl_geometry_get_axis_by_name(g
, "A");
375 axisB
= hkl_geometry_get_axis_by_name(g
, "B");
376 axisC
= hkl_geometry_get_axis_by_name(g
, "C");
378 hkl_parameter_min_max_set(axisA
, -100, 180., HKL_UNIT_USER
, NULL
);
379 hkl_parameter_min_max_set(axisB
, -100., 180., HKL_UNIT_USER
, NULL
);
380 hkl_parameter_min_max_set(axisC
, -100., 180., HKL_UNIT_USER
, NULL
);
382 list
= hkl_geometry_list_new();
384 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
387 185. * HKL_DEGTORAD
);
388 hkl_geometry_list_add(list
, g
);
390 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
391 -190. * HKL_DEGTORAD
,
393 -190.* HKL_DEGTORAD
);
394 hkl_geometry_list_add(list
, g
);
396 hkl_geometry_set_values_v(g
, HKL_UNIT_DEFAULT
, NULL
,
400 hkl_geometry_list_add(list
, g
);
402 is_int(3, hkl_geometry_list_n_items_get(list
), __func__
);
403 hkl_geometry_list_remove_invalid(list
);
404 is_int(2, hkl_geometry_list_n_items_get(list
), __func__
);
406 hkl_geometry_free(g
);
407 hkl_geometry_list_free(list
);
410 int main(int argc
, char** argv
)
418 axes_values_get_set();
424 list_multiply_from_range();
425 list_remove_invalid();