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/hkl-tap.h>
26 #include "hkl-axis-private.h" /* temporary */
28 #define CHECK_AXIS_VALUE(geometry, axis, value) fabs((value) - hkl_parameter_value_get(hkl_geometry_axis_get(geometry, axis, NULL), HKL_UNIT_DEFAULT)) < HKL_EPSILON
31 static int hkl_geometry_list_check_geometry_unit(const HklGeometryList
*self
,
39 const HklGeometryListItem
*item
;
42 HKL_GEOMETRY_LIST_FOREACH(item
, self
){
43 const HklGeometry
*geometry
;
45 geometry
= hkl_geometry_list_item_geometry_get(item
);
48 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "mu", mu
* HKL_DEGTORAD
));
49 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "omega", omega
* HKL_DEGTORAD
));
50 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "chi", chi
* HKL_DEGTORAD
));
51 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "phi", phi
* HKL_DEGTORAD
));
52 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "gamma", gamma
* HKL_DEGTORAD
));
53 res
&= DIAG(CHECK_AXIS_VALUE(geometry
, "delta", delta
* HKL_DEGTORAD
));
61 static void getter(void)
64 HklEngineList
*engines
;
66 const HklFactory
*factory
;
67 HklGeometry
*geometry
;
68 HklDetector
*detector
;
71 factory
= hkl_factory_get_by_name("E6C", NULL
);
72 geometry
= hkl_factory_create_new_geometry(factory
);
73 sample
= hkl_sample_new("test");
75 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
77 engines
= hkl_factory_create_new_engine_list(factory
);
78 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
80 engine
= hkl_engine_list_engine_get_by_name(engines
, "hkl", NULL
);
82 /* geometry -> pseudo */
83 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 30., 0., 0., 0., 60.);
84 res
&= DIAG(check_pseudoaxes_v(engine
, 0., 0., 1.));
86 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 30., 0., 90., 0., 60.);
87 res
&= DIAG(check_pseudoaxes_v(engine
, 1., 0., 0.));
89 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 30., 0., -90., 0., 60.);
90 res
&= DIAG(check_pseudoaxes_v(engine
, -1., 0., 0.));
92 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 30., 0., 180., 0., 60.);
93 res
&= DIAG(check_pseudoaxes_v(engine
, 0., 0., -1.));
95 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 45., 0., 135., 0., 90.);
96 res
&= DIAG(check_pseudoaxes_v(engine
, 1., 0., -1.));
98 ok(res
== TRUE
, "getter");
100 hkl_engine_list_free(engines
);
101 hkl_detector_free(detector
);
102 hkl_sample_free(sample
);
103 hkl_geometry_free(geometry
);
106 static void degenerated(void)
109 HklEngineList
*engines
;
111 const darray_string
*modes
;
113 const HklFactory
*factory
;
114 HklGeometry
*geometry
;
115 HklDetector
*detector
;
117 static double hkl
[] = {0, 0, 1};
119 factory
= hkl_factory_get_by_name("E6C", NULL
);
120 geometry
= hkl_factory_create_new_geometry(factory
);
121 sample
= hkl_sample_new("test");
123 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
125 engines
= hkl_factory_create_new_engine_list(factory
);
126 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
128 engine
= hkl_engine_list_engine_get_by_name(engines
, "hkl", NULL
);
129 modes
= hkl_engine_modes_names_get(engine
);
131 darray_foreach(mode
, *modes
) {
132 const darray_string
*parameters
;
133 HklGeometryList
*geometries
;
136 hkl_engine_current_mode_set(engine
, *mode
, NULL
);
137 parameters
= hkl_engine_parameters_names_get(engine
);
138 n_params
= darray_size(*parameters
);
140 double params
[n_params
];
142 hkl_engine_parameters_values_get(engine
, params
, n_params
, HKL_UNIT_DEFAULT
);
144 hkl_engine_parameters_values_set(engine
, params
, n_params
, HKL_UNIT_DEFAULT
, NULL
);
147 /* studdy this degenerated case */
148 geometries
= hkl_engine_pseudo_axes_values_set(engine
,
149 hkl
, ARRAY_SIZE(hkl
),
150 HKL_UNIT_DEFAULT
, NULL
);
152 const HklGeometryListItem
*item
;
154 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
155 hkl_geometry_set(geometry
,
156 hkl_geometry_list_item_geometry_get(item
));
157 res
&= DIAG(check_pseudoaxes(engine
, hkl
, 3));
159 hkl_geometry_list_free(geometries
);
163 ok(res
== TRUE
, "degenerated");
165 hkl_engine_list_free(engines
);
166 hkl_detector_free(detector
);
167 hkl_sample_free(sample
);
168 hkl_geometry_free(geometry
);
174 HklEngineList
*engines
;
177 const darray_string
*modes
;
178 const HklFactory
*factory
;
179 HklGeometry
*geometry
;
180 HklDetector
*detector
;
183 factory
= hkl_factory_get_by_name("E6C", NULL
);
184 geometry
= hkl_factory_create_new_geometry(factory
);
185 sample
= hkl_sample_new("test");
187 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
189 engines
= hkl_factory_create_new_engine_list(factory
);
190 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
192 engine
= hkl_engine_list_engine_get_by_name(engines
, "q2", NULL
);
193 modes
= hkl_engine_modes_names_get(engine
);
196 hkl_geometry_set_values_v(geometry
, HKL_UNIT_USER
, NULL
, 0., 30., 0., 0., 0., 60.);
197 hkl_engine_initialized_set(engine
, TRUE
, NULL
);
200 darray_foreach(mode
, *modes
){
203 hkl_engine_current_mode_set(engine
, *mode
, NULL
);
204 for(q
=0.1; q
<1.; q
+= 0.1)
205 for(alpha
= -M_PI
; alpha
<M_PI
; alpha
+= M_PI
/180.){
206 double values
[] = {q
, alpha
};
207 HklGeometryList
*geometries
;
209 geometries
= hkl_engine_pseudo_axes_values_set(engine
,
210 values
, ARRAY_SIZE(values
),
211 HKL_UNIT_DEFAULT
, NULL
);
213 const HklGeometryListItem
*item
;
215 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
216 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
217 res
&= DIAG(check_pseudoaxes(engine
, values
, 2));
219 hkl_geometry_list_free(geometries
);
224 ok(res
== TRUE
, "q2");
226 hkl_engine_list_free(engines
);
227 hkl_detector_free(detector
);
228 hkl_sample_free(sample
);
229 hkl_geometry_free(geometry
);
232 static void petra3(void)
234 static double hkl_v
[] = {1, 1, 0};
235 static double hkl_p
[] = {0, 0, 1, 90 * HKL_DEGTORAD
};
236 static double psi_p
[] = {0, 0, 1};
238 HklEngineList
*engines
;
241 const HklFactory
*factory
;
242 HklGeometry
*geometry
;
243 HklGeometryList
*geometries
;
244 HklDetector
*detector
;
249 factory
= hkl_factory_get_by_name("E6C", NULL
);
250 geometry
= hkl_factory_create_new_geometry(factory
);
251 hkl_geometry_wavelength_set(geometry
, 2.033, HKL_UNIT_DEFAULT
, NULL
);
253 sample
= hkl_sample_new("test");
254 lattice
= hkl_lattice_new(7.813, 7.813, 7.813,
255 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
,
257 hkl_sample_lattice_set(sample
, lattice
);
258 hkl_lattice_free(lattice
);
260 U
= hkl_matrix_new_euler(-112.5 * HKL_DEGTORAD
,
261 -87.84 * HKL_DEGTORAD
,
262 157.48 * HKL_DEGTORAD
);
263 hkl_sample_U_set(sample
, U
, NULL
);
266 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
268 engines
= hkl_factory_create_new_engine_list(factory
);
269 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
271 /* set the psi pseudo axis */
272 psi
= hkl_engine_list_engine_get_by_name(engines
, "psi", NULL
);
273 hkl_engine_current_mode_set(psi
, "psi_constant_vertical", NULL
);
274 /* set the mode parameters 0, 0, 1 */
275 hkl_engine_parameters_values_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), HKL_UNIT_DEFAULT
, NULL
);
277 /* Compute the hkl [1, 1, 0] in psi_constant_vertical mode with */
278 /* h2,k2,l2= [0, 0,1] and psi = 90 */
279 /* set the hkl pseudo axis in psi_constant_vertical */
280 hkl
= hkl_engine_list_engine_get_by_name(engines
, "hkl", NULL
);
281 hkl_engine_current_mode_set(hkl
, "psi_constant_vertical", NULL
);
282 /* set the mode parameters 0, 0, 1, 90. */
283 hkl_engine_parameters_values_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), HKL_UNIT_DEFAULT
, NULL
);
284 geometries
= hkl_engine_pseudo_axes_values_set(hkl
, hkl_v
, ARRAY_SIZE(hkl_v
),
285 HKL_UNIT_DEFAULT
, NULL
);
287 const HklGeometryListItem
*item
;
289 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
290 double PSI
= hkl_p
[3];
293 hkl_geometry_set(geometry
,
294 hkl_geometry_list_item_geometry_get(item
));
295 hkl_engine_initialized_set(psi
, TRUE
, NULL
);
296 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1,
297 HKL_UNIT_DEFAULT
, NULL
);
298 res
&= DIAG(fabs(PSI
- current
) < HKL_EPSILON
);
300 hkl_geometry_list_free(geometries
);
303 ok(res
== TRUE
, "petra3");
305 hkl_engine_list_free(engines
);
306 hkl_detector_free(detector
);
307 hkl_sample_free(sample
);
308 hkl_geometry_free(geometry
);
311 /* Problem observed with the psi_constant_vertical mode */
312 static void petra3_2(void)
315 HklEngineList
*engines
;
318 const HklFactory
*factory
;
319 const HklGeometryListItem
*item
;
320 HklGeometry
*geometry
;
321 HklGeometryList
*geometries
;
322 HklDetector
*detector
;
330 /* Wavelength 1.0332035 */
331 /* Mode psi_constant_vertical */
332 /* UB11 0.000 UB12 1.232 UB13 0.000 */
333 /* UB21 0.000 UB22 -0.000 UB23 1.232 */
334 /* UB31 1.232 UB32 -0.000 UB33 -0.000 */
335 /* Ux -90 Uy 6.84979352816457e-15 Uz -90 */
336 /* A 5.1 B 5.1 C 5.1 */
337 /* Alpha 90 Beta 90 Gamma 90 */
339 factory
= hkl_factory_get_by_name("E6C", NULL
);
340 geometry
= hkl_factory_create_new_geometry(factory
);
341 hkl_geometry_wavelength_set(geometry
, 1.0332035, HKL_UNIT_DEFAULT
, NULL
);
343 sample
= hkl_sample_new("test");
344 lattice
= hkl_lattice_new(5.1, 5.1, 5.1,
345 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
,
347 hkl_sample_lattice_set(sample
, lattice
);
348 hkl_lattice_free(lattice
);
349 U
= hkl_matrix_new_euler(-90.0 * HKL_DEGTORAD
,
351 -90.0 * HKL_DEGTORAD
);
352 hkl_sample_U_set(sample
, U
, NULL
);
355 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
357 engines
= hkl_factory_create_new_engine_list(factory
);
358 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
360 /* set the hkl pseudo axis in psi_constant_vertical */
361 hkl
= hkl_engine_list_engine_get_by_name(engines
, "hkl", NULL
);
362 hkl_engine_current_mode_set(hkl
, "psi_constant_vertical", NULL
);
363 /* set the psi pseudo engine to read the psi value */
364 psi
= hkl_engine_list_engine_get_by_name(engines
, "psi", NULL
);
367 /* freeze 0; ca 0 0 2 */
373 hkl_engine_parameters_values_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), HKL_UNIT_DEFAULT
, NULL
);
378 hkl_engine_parameters_values_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), HKL_UNIT_DEFAULT
, NULL
);
380 /* freeze 0; ca 0 0 2 */
381 geometries
= hkl_engine_set_values_v(hkl
, 0., 0., 2.);
384 /* 23.37668 11.68835 90 -90 */
386 /* -2.384186e-09 -1.182388e-14 */
387 /* the -90 value of phi is problematic, the right value is 0 */
389 res
&= DIAG(hkl_geometry_list_check_geometry_unit(geometries
, 0., 11.688393153063114, 90., 0., 0., 23.376786185344031));
391 /* check that all solution gives the right psi */
392 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
395 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
396 hkl_engine_initialized_set(psi
, TRUE
, NULL
);
397 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1,
398 HKL_UNIT_DEFAULT
, NULL
);
399 res
&= DIAG(fabs(PSI
- current
) < HKL_EPSILON
);
401 hkl_geometry_list_free(geometries
);
404 /* freeze 45; ca 0 0 2 */
405 hkl_p
[3] = PSI
= 45.0 * HKL_DEGTORAD
;
406 hkl_engine_parameters_values_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), HKL_UNIT_DEFAULT
, NULL
);
407 geometries
= hkl_engine_set_values_v(hkl
, 0., 0., 2.);
410 /* 23.3768 11.68831 90 -135 */
412 /* -2.384186e-09 -1.182388e-14 */
413 /* -135 n'est pas bon il faudrait plutôt -45 */
415 res
&= DIAG(hkl_geometry_list_check_geometry_unit(geometries
, 0., 11.688393153063114, 90., -45., 0., 23.376786185344031));
417 /* check that all solution gives the right psi */
418 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
) {
421 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
422 hkl_engine_initialized_set(psi
, TRUE
, NULL
);
423 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1,
424 HKL_UNIT_DEFAULT
, NULL
);
425 res
&= DIAG(fabs(PSI
- current
) < HKL_EPSILON
);
427 hkl_geometry_list_free(geometries
);
431 /* freeze 0; ca 0 0 2 */
437 hkl_engine_parameters_values_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), HKL_UNIT_DEFAULT
, NULL
);
438 geometries
= hkl_engine_set_values_v(hkl
, 0., 0., 2.);
444 hkl_engine_parameters_values_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), HKL_UNIT_DEFAULT
, NULL
);
447 /* 23.37681 11.68839 90 -90 */
449 /* -2.384186e-09 -1.182388e-14 */
450 /* phi is wrong it should be -45 */
452 res
&= DIAG(hkl_geometry_list_check_geometry_unit(geometries
, 0, 11.688393153063114, 90, -45, 0, 23.376786185344031));
454 /* check that all solution gives the right psi */
455 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
458 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
459 hkl_engine_initialized_set(psi
, TRUE
, NULL
);
460 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1,
461 HKL_UNIT_DEFAULT
, NULL
);
462 res
&= DIAG(fabs(PSI
- current
) < HKL_EPSILON
);
464 hkl_geometry_list_free(geometries
);
467 /* freeze 45; ca 0 0 2 */
468 hkl_p
[3] = PSI
= 45 * HKL_DEGTORAD
;
470 hkl_engine_parameters_values_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), HKL_UNIT_DEFAULT
, NULL
);
471 geometries
= hkl_engine_set_values_v(hkl
, 0., 0., 2.);
474 /* 23.37666 11.68837 90 -135 */
476 /* -2.384186e-09 -1.182388e-14 */
477 /* phi is wrong it should be -90 */
479 res
&= DIAG(hkl_geometry_list_check_geometry_unit(geometries
, 0, 11.688393153063114, 90, -90, 0, 23.376786185344031));
481 /* check that all solution gives the right psi */
482 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
485 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
486 hkl_engine_initialized_set(psi
, TRUE
, NULL
);
487 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1,
488 HKL_UNIT_DEFAULT
, NULL
);
489 res
&= DIAG(fabs(PSI
- current
) < HKL_EPSILON
);
491 hkl_geometry_list_free(geometries
);
494 ok(res
== TRUE
, __func__
);
496 hkl_engine_list_free(engines
);
497 hkl_detector_free(detector
);
498 hkl_sample_free(sample
);
499 hkl_geometry_free(geometry
);
502 int main(int argc
, char** argv
)