add an --enable-logging to activate the logging in the hkl library
[hkl.git] / tests / hkl-pseudoaxis-t.c
blobef9ea0134bae0519e32e25a2bf3dce6ac8c43dc5
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>
22 #include <alloca.h>
23 #include <string.h>
24 #include "hkl.h"
25 #include <tap/basic.h>
26 #include <tap/hkl-tap.h>
28 #define DEBUG
31 typedef int (* test_func) (HklEngine *engine, HklEngineList *engine_list, unsigned int n);
33 static int __test(unsigned int nb_iter, test_func f, int foreach_mode)
35 HklFactory **factories;
36 unsigned int i, j, n;
37 HklGeometry *geometry = NULL;
38 HklDetector *detector = hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D);
39 HklSample *sample = hkl_sample_new("test");
40 HklEngineList *engines;
41 int res = TRUE;
42 const char **mode;
44 factories = hkl_factory_get_all(&n);
45 for(i=0; i<n && TRUE == res; i++){
46 HklEngine **engine;
48 geometry = hkl_factory_create_new_geometry(factories[i]);
49 engines = hkl_factory_create_new_engine_list(factories[i]);
50 hkl_engine_list_init(engines, geometry, detector, sample);
51 darray_foreach(engine, *hkl_engine_list_engines_get(engines)){
52 const darray_string *modes = hkl_engine_modes_names_get(*engine);
53 if (foreach_mode){
54 darray_foreach(mode, *modes){
55 res &= DIAG(hkl_engine_current_mode_set(*engine, *mode, NULL));
56 for(j=0; j<nb_iter; ++j){
57 res &= DIAG(f(*engine, engines, nb_iter));
58 if(!res){
59 diag("failed at factory: \"%s\" engine: \"%s\" mode: \"%s\"",
60 hkl_geometry_name_get(geometry),
61 hkl_engine_name_get(*engine), *mode);
62 break;
65 if(!res)
66 break;
68 }else{
69 for(j=0; j<nb_iter; ++j){
70 res &= DIAG(f(*engine, engines, nb_iter));
71 if(!res)
72 break;
75 if(!res)
76 break;
78 hkl_geometry_free(geometry);
79 hkl_engine_list_free(engines);
81 hkl_detector_free(detector);
82 hkl_sample_free(sample);
84 return res;
87 #define TEST(_nb_iter, _f) __test(_nb_iter, _f, 0)
88 #define TEST_FOREACH_MODE(_nb_iter, _f) __test(_nb_iter, _f, 1)
90 static void factories(void)
92 int res = TRUE;
93 uint i, n;
94 HklEngineList *engines;
95 HklFactory **factories;
97 factories = hkl_factory_get_all(&n);
98 for(i=0;i<n; i++){
99 engines = hkl_factory_create_new_engine_list(factories[i]);
100 hkl_engine_list_free(engines);
103 ok(res == TRUE, "factories");
106 static int _get(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
108 uint i;
109 GError *error;
110 int res = TRUE;
111 HklGeometry *geometry = hkl_engine_list_geometry_get(engine_list);
112 const darray_string *pseudo_axes = hkl_engine_pseudo_axes_names_get(engine);
113 const size_t n_pseudo_axes = darray_size(*pseudo_axes);
114 double targets[n_pseudo_axes];
115 double currents[n_pseudo_axes];
117 /* randomize the geometry */
118 hkl_geometry_randomize(geometry);
120 /* randomize the pseudoAxes values */
121 hkl_tap_engine_pseudo_axes_randomize(engine,
122 targets, n_pseudo_axes,
123 HKL_UNIT_DEFAULT);
125 /* randomize the parameters */
126 hkl_tap_engine_parameters_randomize(engine);
128 /* pseudo -> geometry */
129 if(HKL_ENGINE_CAPABILITIES_INITIALIZABLE & hkl_engine_capabilities_get(engine))
130 res &= DIAG(hkl_engine_initialized_set(engine, TRUE, NULL));
131 res &= DIAG(hkl_engine_pseudo_axes_values_get(engine, currents, n_pseudo_axes,
132 HKL_UNIT_DEFAULT, NULL));
134 /* idem with error management */
135 error = NULL;
136 res &= DIAG(hkl_engine_pseudo_axes_values_get(engine, currents, n_pseudo_axes,
137 HKL_UNIT_DEFAULT, &error));
138 res &= DIAG(NULL == error);
139 for(i=0; i<n_pseudo_axes; ++i)
140 res &= DIAG(targets[i] != currents[i]); /* TODO this test is almost true, need a real check */
142 return res;
145 static void get()
147 ok(TRUE == TEST_FOREACH_MODE(1, _get), __func__);
150 static int _set(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
152 uint i;
153 GError *error = NULL;
154 int unreachable = 0;
155 int res = TRUE;
156 HklGeometry *geometry = hkl_engine_list_geometry_get(engine_list);
157 const darray_string *pseudo_axes = hkl_engine_pseudo_axes_names_get(engine);
158 const size_t n_pseudo_axes = darray_size(*pseudo_axes);
159 double targets[n_pseudo_axes];
160 double currents[n_pseudo_axes];
162 /* randomize the geometry */
163 hkl_geometry_randomize(geometry);
165 /* for now skip the eulerians check */
166 if(!strcmp(hkl_engine_current_mode_get(engine), "eulerians"))
167 return TRUE;
169 size_t j;
170 HklParameter **pseudo_axis;
171 HklGeometryList *solutions;
173 /* randomize the pseudoAxes values */
174 hkl_tap_engine_pseudo_axes_randomize(engine,
175 targets, n_pseudo_axes,
176 HKL_UNIT_DEFAULT);
178 /* randomize the parameters */
179 hkl_tap_engine_parameters_randomize(engine);
181 /* pseudo -> geometry */
182 res &= DIAG(hkl_engine_initialized_set(engine, TRUE, &error));
184 /* geometry -> pseudo */
185 solutions = hkl_engine_pseudo_axes_values_set(engine,
186 targets, n_pseudo_axes,
187 HKL_UNIT_DEFAULT, &error);
188 if(solutions) {
189 const HklGeometryListItem *item;
191 HKL_GEOMETRY_LIST_FOREACH(item, solutions){
192 hkl_geometry_set(geometry,
193 hkl_geometry_list_item_geometry_get(item));
195 res &= DIAG(hkl_engine_pseudo_axes_values_get(engine, currents, n_pseudo_axes, HKL_UNIT_DEFAULT, &error));
196 for(j=0; j<n_pseudo_axes; ++j)
197 res &= DIAG(fabs(targets[j] - currents[j]) < HKL_EPSILON);
199 }else{
200 res &= DIAG(error != NULL);
201 g_clear_error(&error);
202 unreachable++;
204 #if 0
205 fprintf(stderr, " unreachable : %d/%d", unreachable, i);
206 if(!res){
207 fprintf(stderr, " ko");
208 /* print the hkl internals if the test failed */
209 fprintf(stderr, "\n expected : ");
210 for(uint j=0; j<n_pseudo_axes; ++j)
211 fprintf(stderr, " %f", targets[j]);
212 fprintf(stderr, " obtained : ");
213 for(uint j=0; j<n_pseudo_axes; ++j)
214 fprintf(stderr, " %f", currents[j]);
215 hkl_engine_fprintf(stderr, engine);
216 exit(0);
217 }else{
218 fprintf(stderr, " ok");
220 #endif
222 return res;
226 static void set(int nb_iter)
228 ok(TRUE == TEST_FOREACH_MODE(nb_iter, _set), __func__);
232 static int _pseudo_axis_get(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
234 static const char *bad = "_bad_name_";
235 const darray_string *pseudo_axes_names = hkl_engine_pseudo_axes_names_get(engine);
236 const char **pseudo_axis_name;
237 const HklParameter *pseudo_axis;
238 int res = TRUE;
239 GError *error;
241 darray_foreach(pseudo_axis_name, *pseudo_axes_names){
242 pseudo_axis = hkl_engine_pseudo_axis_get(engine, *pseudo_axis_name, NULL);
243 res &= DIAG(NULL != pseudo_axis);
245 error = NULL;
246 pseudo_axis = hkl_engine_pseudo_axis_get(engine, *pseudo_axis_name, &error);
247 res &= DIAG(NULL != pseudo_axis);
248 res &= DIAG(NULL == error);
251 /* error */
252 pseudo_axis = hkl_engine_pseudo_axis_get(engine, bad, NULL);
253 res &= DIAG(NULL == pseudo_axis);
255 error = NULL;
256 pseudo_axis = hkl_engine_pseudo_axis_get(engine, bad, &error);
257 res &= DIAG(NULL == pseudo_axis);
258 res &= DIAG(error != NULL);
259 g_clear_error(&error);
261 return res;
264 static void pseudo_axis_get(void)
266 ok(TRUE == TEST(1, _pseudo_axis_get), __func__);
269 static int _capabilities(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
271 int res = TRUE;
272 const unsigned long capabilities = hkl_engine_capabilities_get(engine);
274 /* all motors must have the read/write capabilities */
275 res &= DIAG((capabilities & HKL_ENGINE_CAPABILITIES_READABLE) != 0);
276 res &= DIAG((capabilities & HKL_ENGINE_CAPABILITIES_WRITABLE) != 0);
278 /* all psi engines must be initialisable */
279 if(!strcmp("psi", hkl_engine_name_get(engine)))
280 res &= DIAG((capabilities & HKL_ENGINE_CAPABILITIES_INITIALIZABLE) != 0);
282 return res;
285 static void capabilities(void)
287 ok(TRUE == TEST_FOREACH_MODE(1, _capabilities), __func__);
290 static int _initialized(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
292 int res = TRUE;
293 GError *error = NULL;
294 const unsigned long capabilities = hkl_engine_capabilities_get(engine);
296 if(HKL_ENGINE_CAPABILITIES_INITIALIZABLE & capabilities){
297 int tmp;
299 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, FALSE, NULL));
300 res &= DIAG(FALSE == hkl_engine_initialized_get(engine));
301 tmp = hkl_engine_initialized_set(engine, TRUE, NULL);
302 res &= DIAG(tmp == hkl_engine_initialized_get(engine));
304 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, FALSE, &error));
305 res &= DIAG(FALSE == hkl_engine_initialized_get(engine));
306 res &= DIAG(NULL == error);
307 tmp = hkl_engine_initialized_set(engine, TRUE, &error);
308 res &= DIAG(tmp == hkl_engine_initialized_get(engine));
309 if(tmp)
310 res &= DIAG(NULL == error);
311 else{
312 res &= DIAG(NULL != error);
313 g_clear_error(&error);
315 }else{
316 /* non-initializable engine should not produce an error */
317 res &= DIAG(TRUE == hkl_engine_initialized_get(engine));
318 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, TRUE, NULL));
319 res &= DIAG(TRUE == hkl_engine_initialized_get(engine));
320 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, FALSE, NULL));
321 res &= DIAG(TRUE == hkl_engine_initialized_get(engine));
323 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, TRUE, &error));
324 res &= DIAG(TRUE == hkl_engine_initialized_get(engine));
325 res &= DIAG(NULL == error);
326 res &= DIAG(TRUE == hkl_engine_initialized_set(engine, FALSE, &error));
327 res &= DIAG(TRUE == hkl_engine_initialized_get(engine));
328 res &= DIAG(NULL == error);
331 return res;
334 static void initialized(void)
336 ok(TRUE == TEST_FOREACH_MODE(1, _initialized), __func__);
339 HKLAPI int hkl_engine_initialized_set(HklEngine *self, int initialized,
340 GError **error) HKL_ARG_NONNULL(1) HKL_WARN_UNUSED_RESULT;
342 static int _modes(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
344 static const char *bad = "__bad_mode_name__";
345 int res = TRUE;
346 int ok;
347 const darray_string *modes;
348 const char **mode;
349 const char *current_mode;
350 GError *error = NULL;
352 modes = hkl_engine_modes_names_get(engine);
354 /* check that the current mode is available in the mode list. */
355 current_mode = hkl_engine_current_mode_get(engine);
356 ok = FALSE;
357 darray_foreach(mode, *modes){
358 if(!strcmp(current_mode, *mode))
359 ok = TRUE;
361 res &= DIAG(TRUE == ok);
363 /* check that all modes can be set */
364 darray_foreach(mode, *modes){
365 res &= DIAG(TRUE == hkl_engine_current_mode_set(engine, *mode, NULL));
367 res &= DIAG(TRUE == hkl_engine_current_mode_set(engine, *mode, &error));
368 res &= DIAG(NULL == error);
371 /* check for bad mode name */
372 res &= DIAG(FALSE == hkl_engine_current_mode_set(engine, bad, NULL));
374 res &= DIAG(FALSE == hkl_engine_current_mode_set(engine, bad, &error));
375 res &= DIAG(NULL != error);
376 g_clear_error(&error);
378 return res;
381 static void modes(void)
383 ok(TRUE == TEST(1, _modes), __func__);
386 static int _check_axes(const darray_string *axes, const darray_string *refs)
388 int ko = TRUE;
389 const char **axis;
390 const char **ref;
392 darray_foreach(axis, *axes){
393 darray_foreach(ref, *refs){
394 if(!strcmp(*axis, *ref))
395 ko = FALSE;
397 if(ko)
398 break;
399 ko = TRUE;
401 return ko;
404 static int _axes_names(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
406 int res = TRUE;
407 HklGeometry *geometry;
408 const darray_string *all_axes;
409 const darray_string *axes_r;
410 const darray_string *axes_w;
412 geometry = hkl_engine_list_geometry_get(engine_list);
413 all_axes = hkl_geometry_axes_names_get(geometry);
415 /* check consistency of the engines, all axes should be in the
416 * list of the geometry axes */
417 axes_r = hkl_engine_axes_names_get(engine,
418 HKL_ENGINE_AXES_NAMES_GET_READ);
420 axes_w = hkl_engine_axes_names_get(engine,
421 HKL_ENGINE_AXES_NAMES_GET_WRITE);
423 res &= DIAG(axes_r != NULL);
424 res &= DIAG(axes_w != NULL);
425 res &= DIAG(_check_axes(axes_r, all_axes));
426 res &= DIAG(_check_axes(axes_w, all_axes));
429 static void axes_names(void)
431 ok(TRUE == TEST_FOREACH_MODE(1, _axes_names), __func__);
436 static int _parameters(HklEngine *engine, HklEngineList *engine_list, unsigned int n)
438 static const char *bad = "__bad_parameer_name__";
439 int res = TRUE;
440 GError *error = NULL;
441 const char **parameter;
442 const darray_string *parameters = hkl_engine_parameters_names_get(engine);
443 const HklParameter *param;
444 int n_values = darray_size(*parameters);
445 double values[n_values];
447 /* can not get a bad parameter */
448 param = hkl_engine_parameter_get(engine, bad, NULL);
449 res &= DIAG(NULL == param);
451 param = hkl_engine_parameter_get(engine, bad, &error);
452 res &= DIAG(NULL == param);
453 res &= DIAG(NULL != error);
454 g_clear_error(&error);
456 /* it is possible to get and set all the parameters */
457 darray_foreach(parameter, *parameters){
458 /* get */
459 param = hkl_engine_parameter_get(engine, *parameter, NULL);
460 res &= DIAG(NULL != param);
462 param = hkl_engine_parameter_get(engine, *parameter, &error);
463 res &= DIAG(NULL != param);
464 res &= DIAG(NULL == error);
466 /* set */
467 res &= DIAG(TRUE == hkl_engine_parameter_set(engine, *parameter, param, NULL));
468 res &= DIAG(TRUE == hkl_engine_parameter_set(engine, *parameter, param, &error));
469 res &= DIAG(NULL == error);
471 res &= DIAG(FALSE == hkl_engine_parameter_set(engine, bad, param, &error));
472 res &= DIAG(NULL != error);
473 g_clear_error(&error);
476 hkl_engine_parameters_values_get(engine, values, n_values, HKL_UNIT_USER);
478 res &= DIAG(TRUE == hkl_engine_parameters_values_set(engine, values, n_values, HKL_UNIT_DEFAULT, NULL));
479 res &= DIAG(TRUE == hkl_engine_parameters_values_set(engine, values, n_values, HKL_UNIT_DEFAULT, &error));
480 res &= DIAG(NULL == error);
482 res &= DIAG(TRUE == hkl_engine_parameters_values_set(engine, values, n_values, HKL_UNIT_USER, NULL));
483 res &= DIAG(TRUE == hkl_engine_parameters_values_set(engine, values, n_values, HKL_UNIT_USER, &error));
484 res &= DIAG(NULL == error);
486 return res;
489 static void parameters(void)
491 ok(TRUE == TEST_FOREACH_MODE(1, _parameters), __func__);
495 int main(int argc, char** argv)
497 double n;
499 plan(9);
501 if (argc > 1)
502 n = atoi(argv[1]);
503 else
504 n = 10;
506 factories();
507 get();
508 set(n);
509 pseudo_axis_get();
510 capabilities();
511 initialized();
512 modes();
513 axes_names();
514 parameters();
516 return 0;