post release commit
[hkl.git] / tests / hkl-geometry-t.c
blob6b4e74c4aaa73c856066e847aa0c413e2e405420
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>
22 #include "hkl.h"
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__);
54 hkl_geometry_free(g);
57 static void get_axis(void)
59 int res = TRUE;
60 HklGeometry *g = NULL;
61 HklHolder *holder = NULL;
62 const HklParameter *axis0;
63 GError *error;
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 */
82 /* get */
83 res &= DIAG(NULL != hkl_geometry_axis_get(g, "A", NULL));
84 res &= DIAG(NULL == hkl_geometry_axis_get(g, "D", NULL));
85 error = 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);
92 /* set */
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));
97 error = 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);
104 ok(res, __func__);
106 g_clear_error(&error);
108 hkl_geometry_free(g);
111 static void update(void)
113 int res = TRUE;
114 HklGeometry *g = NULL;
115 HklHolder *holder = NULL;
116 HklAxis *axis1;
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);
142 ok(res, __func__);
144 hkl_geometry_free(g);
147 static void set(void)
149 HklGeometry *g;
150 HklGeometry *g1;
151 HklGeometry *g2;
152 HklHolder *holder;
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)
180 unsigned int i;
181 HklGeometry *g;
182 HklHolder *holder;
183 static double set_1[] = {1, 1, 1};
184 static double set_10[] = {10, 10, 10};
185 double values[3];
186 GError *error;
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 */
195 error = NULL;
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)
224 int res = TRUE;
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__);
241 ok(res, __func__);
243 hkl_geometry_free(g1);
244 hkl_geometry_free(g2);
247 static void is_valid(void)
249 int res = TRUE;
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));
270 ok(res, __func__);
272 hkl_geometry_free(geom);
275 static void wavelength(void)
277 HklGeometry *geom = NULL;
278 GError *error;
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__);
287 error = NULL;
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)
297 int res = TRUE;
298 size_t i, n;
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}};
307 HklQuaternion qs;
308 HklQuaternion qd;
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);
319 ok(res, __func__);
321 hkl_detector_free(detector);
322 hkl_sample_free(sample);
325 static void list(void)
327 int i = 0;
328 int res = TRUE;
329 HklGeometry *g;
330 HklGeometryList *list;
331 const HklGeometryListItem *item;
332 HklHolder *holder;
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__);
366 ok(res, __func__);
368 hkl_geometry_free(g);
369 hkl_geometry_list_free(list);
372 static void list_multiply_from_range(void)
374 int res = TRUE;
375 HklGeometry *g;
376 HklGeometryList *list;
377 HklHolder *holder;
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);
402 ok(res, __func__);
404 hkl_geometry_free(g);
405 hkl_geometry_list_free(list);
408 static void list_remove_invalid(void)
410 int res = TRUE;
411 HklGeometry *g;
412 HklGeometryList *list;
413 HklHolder *holder;
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,
433 185. * HKL_DEGTORAD,
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,
445 180. * HKL_DEGTORAD,
446 180. * HKL_DEGTORAD,
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__);
454 ok(res, __func__);
456 hkl_geometry_free(g);
457 hkl_geometry_list_free(list);
460 int main(void)
462 plan(51);
464 add_holder();
465 get_axis();
466 update();
467 set();
468 axis_values_get_set();
469 distance();
470 is_valid();
471 wavelength();
472 xxx_rotation_get();
474 list();
475 list_multiply_from_range();
476 list_remove_invalid();
478 return 0;