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-2013 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))) < 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
&= CHECK_AXIS_VALUE(geometry
, "mu", mu
* HKL_DEGTORAD
);
49 res
&= CHECK_AXIS_VALUE(geometry
, "omega", omega
* HKL_DEGTORAD
);
50 res
&= CHECK_AXIS_VALUE(geometry
, "chi", chi
* HKL_DEGTORAD
);
51 res
&= CHECK_AXIS_VALUE(geometry
, "phi", phi
* HKL_DEGTORAD
);
52 res
&= CHECK_AXIS_VALUE(geometry
, "gamma", gamma
* HKL_DEGTORAD
);
53 res
&= 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");
72 geometry
= hkl_factory_create_new_geometry(factory
);
73 sample
= hkl_sample_new("test");
75 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
76 hkl_detector_idx_set(detector
, 1);
78 engines
= hkl_factory_create_new_engine_list(factory
);
79 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
81 engine
= hkl_engine_list_engine_get_by_name(engines
, "hkl");
83 /* geometry -> pseudo */
84 hkl_geometry_set_values_unit_v(geometry
, 0., 30., 0., 0., 0., 60.);
85 hkl_engine_get(engine
, NULL
);
86 res
&= check_pseudoaxes_v(engine
, 0., 0., 1.);
88 hkl_geometry_set_values_unit_v(geometry
, 0., 30., 0., 90., 0., 60.);
89 hkl_engine_get(engine
, NULL
);
90 res
&= check_pseudoaxes_v(engine
, 1., 0., 0.);
92 hkl_geometry_set_values_unit_v(geometry
, 0., 30., 0., -90., 0., 60.);
93 hkl_engine_get(engine
, NULL
);
94 res
&= check_pseudoaxes_v(engine
, -1., 0., 0.);
96 hkl_geometry_set_values_unit_v(geometry
, 0., 30., 0., 180., 0., 60.);
97 hkl_engine_get(engine
, NULL
);
98 res
&= check_pseudoaxes_v(engine
, 0., 0., -1.);
100 hkl_geometry_set_values_unit_v(geometry
, 0., 45., 0., 135., 0., 90.);
101 hkl_engine_get(engine
, NULL
);
102 res
&= check_pseudoaxes_v(engine
, 1., 0., -1.);
104 ok(res
== HKL_TRUE
, "getter");
106 hkl_engine_list_free(engines
);
107 hkl_detector_free(detector
);
108 hkl_sample_free(sample
);
109 hkl_geometry_free(geometry
);
112 static void degenerated(void)
115 HklEngineList
*engines
;
117 const darray_string
*modes
;
119 const HklFactory
*factory
;
120 HklGeometry
*geometry
;
121 const HklGeometryList
*geometries
;
122 HklDetector
*detector
;
124 static double hkl
[] = {0, 0, 1};
126 factory
= hkl_factory_get_by_name("E6C");
127 geometry
= hkl_factory_create_new_geometry(factory
);
128 sample
= hkl_sample_new("test");
130 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
131 hkl_detector_idx_set(detector
, 1);
133 engines
= hkl_factory_create_new_engine_list(factory
);
134 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
135 geometries
= hkl_engine_list_geometries_get(engines
);
137 engine
= hkl_engine_list_engine_get_by_name(engines
, "hkl");
138 modes
= hkl_engine_modes_get(engine
);
140 darray_foreach(mode
, *modes
) {
141 const darray_string
*parameters
;
143 hkl_engine_select_mode(engine
, *mode
);
144 parameters
= hkl_engine_parameters_get(engine
);
145 if (darray_size(*parameters
)){
146 HklParameter
*p
= hkl_parameter_new_copy(hkl_engine_parameter_get(engine
,
147 darray_item(*parameters
, 0)));
148 hkl_parameter_value_set(p
, 0, NULL
);
149 hkl_engine_parameter_set(engine
, p
);
150 hkl_parameter_free(p
);
153 /* studdy this degenerated case */
154 hkl_engine_pseudo_axes_values_set(engine
,
155 hkl
, ARRAY_SIZE(hkl
),
157 if (hkl_engine_set(engine
, NULL
)){
158 const HklGeometryListItem
*item
;
160 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
161 static double null
[] = {0, 0, 0};
163 hkl_engine_pseudo_axes_values_set(engine
,
164 null
, ARRAY_SIZE(null
),
166 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
167 hkl_engine_get(engine
, NULL
);
168 res
&= check_pseudoaxes(engine
, hkl
, 3);
173 ok(res
== HKL_TRUE
, "degenerated");
175 hkl_engine_list_free(engines
);
176 hkl_detector_free(detector
);
177 hkl_sample_free(sample
);
178 hkl_geometry_free(geometry
);
184 HklEngineList
*engines
;
187 const darray_string
*modes
;
188 const HklFactory
*factory
;
189 HklGeometry
*geometry
;
190 const HklGeometryList
*geometries
;
191 HklDetector
*detector
;
194 factory
= hkl_factory_get_by_name("E6C");
195 geometry
= hkl_factory_create_new_geometry(factory
);
196 sample
= hkl_sample_new("test");
198 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
199 hkl_detector_idx_set(detector
, 1);
201 engines
= hkl_factory_create_new_engine_list(factory
);
202 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
203 geometries
= hkl_engine_list_geometries_get(engines
);
205 engine
= hkl_engine_list_engine_get_by_name(engines
, "q2");
206 modes
= hkl_engine_modes_get(engine
);
209 hkl_geometry_set_values_unit_v(geometry
, 0., 30., 0., 0., 0., 60.);
210 hkl_engine_initialize(engine
, NULL
);
213 darray_foreach(mode
, *modes
){
216 hkl_engine_select_mode(engine
, *mode
);
217 for(q
=0.1; q
<1.; q
+= 0.1)
218 for(alpha
= -M_PI
; alpha
<M_PI
; alpha
+= M_PI
/180.){
219 double values
[] = {q
, alpha
};
221 hkl_engine_pseudo_axes_values_set(engine
,
222 values
, ARRAY_SIZE(values
),
224 if(hkl_engine_set(engine
, NULL
)){
225 const HklGeometryListItem
*item
;
227 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
228 static double null
[] = {0, 0};
230 hkl_engine_pseudo_axes_values_set(engine
,
231 null
, ARRAY_SIZE(null
),
233 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
234 hkl_engine_get(engine
, NULL
);
235 res
&= check_pseudoaxes(engine
, values
, 2);
241 ok(res
== HKL_TRUE
, "q2");
243 hkl_engine_list_free(engines
);
244 hkl_detector_free(detector
);
245 hkl_sample_free(sample
);
246 hkl_geometry_free(geometry
);
249 static void petra3(void)
251 static double values
[] = {1, 1, 0};
252 static double hkl_p
[] = {0, 0, 1, 90 * HKL_DEGTORAD
};
253 static double psi_p
[] = {0, 0, 1};
255 HklEngineList
*engines
;
258 const HklFactory
*factory
;
259 HklGeometry
*geometry
;
260 const HklGeometryList
*geometries
;
261 HklDetector
*detector
;
266 factory
= hkl_factory_get_by_name("E6C");
267 geometry
= hkl_factory_create_new_geometry(factory
);
268 hkl_geometry_wavelength_set(geometry
, 2.033);
270 sample
= hkl_sample_new("test");
271 lattice
= hkl_lattice_new(7.813, 7.813, 7.813,
272 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
);
273 hkl_sample_lattice_set(sample
, lattice
);
274 hkl_lattice_free(lattice
);
276 U
= hkl_matrix_new_euler(-112.5 * HKL_DEGTORAD
,
277 -87.84 * HKL_DEGTORAD
,
278 157.48 * HKL_DEGTORAD
);
279 hkl_sample_U_set(sample
, U
);
282 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
283 hkl_detector_idx_set(detector
, 1);
285 engines
= hkl_factory_create_new_engine_list(factory
);
286 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
287 geometries
= hkl_engine_list_geometries_get(engines
);
289 /* set the hkl pseudo axis in psi_constant_vertical */
290 hkl
= hkl_engine_list_engine_get_by_name(engines
, "hkl");
291 hkl_engine_select_mode(hkl
, "psi_constant_vertical");
292 hkl_engine_set_values_v(hkl
, 1, 1, 0);
293 /* set the mode parameters 0, 0, 1, 90. */
294 hkl_engine_parameters_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), NULL
);
296 /* set the psi pseudo axis */
297 psi
= hkl_engine_list_engine_get_by_name(engines
, "psi");
298 hkl_engine_select_mode(psi
, "psi_constant_vertical");
299 /* set the mode parameters 0, 0, 1 */
300 hkl_engine_parameters_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), NULL
);
302 /* Compute the hkl [1, 1, 0] in psi_constant_vertical mode with */
303 /* h2,k2,l2= [0, 0,1] and psi = 90 */
304 if(hkl_engine_set(hkl
, NULL
)){
305 const HklGeometryListItem
*item
;
307 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
308 double PSI
= hkl_p
[3];
311 hkl_geometry_set(geometry
,
312 hkl_geometry_list_item_geometry_get(item
));
313 hkl_engine_initialize(psi
, NULL
);
314 hkl_engine_list_get(engines
);
315 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1);
316 res
&= fabs(PSI
- current
) < HKL_EPSILON
;
320 ok(res
== HKL_TRUE
, "petra3");
322 hkl_engine_list_free(engines
);
323 hkl_detector_free(detector
);
324 hkl_sample_free(sample
);
325 hkl_geometry_free(geometry
);
328 /* Problem observed with the psi_constant_vertical mode */
329 static void petra3_2(void)
332 HklEngineList
*engines
;
335 const HklFactory
*factory
;
336 const HklGeometryListItem
*item
;
337 HklGeometry
*geometry
;
338 const HklGeometryList
*geometries
;
339 HklDetector
*detector
;
347 /* Wavelength 1.0332035 */
348 /* Mode psi_constant_vertical */
349 /* UB11 0.000 UB12 1.232 UB13 0.000 */
350 /* UB21 0.000 UB22 -0.000 UB23 1.232 */
351 /* UB31 1.232 UB32 -0.000 UB33 -0.000 */
352 /* Ux -90 Uy 6.84979352816457e-15 Uz -90 */
353 /* A 5.1 B 5.1 C 5.1 */
354 /* Alpha 90 Beta 90 Gamma 90 */
356 factory
= hkl_factory_get_by_name("E6C");
357 geometry
= hkl_factory_create_new_geometry(factory
);
358 hkl_geometry_wavelength_set(geometry
, 1.0332035);
360 sample
= hkl_sample_new("test");
361 lattice
= hkl_lattice_new(5.1, 5.1, 5.1,
362 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
, 90*HKL_DEGTORAD
);
363 hkl_sample_lattice_set(sample
, lattice
);
364 hkl_lattice_free(lattice
);
365 U
= hkl_matrix_new_euler(-90.0 * HKL_DEGTORAD
,
367 -90.0 * HKL_DEGTORAD
);
368 hkl_sample_U_set(sample
, U
);
371 detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
372 hkl_detector_idx_set(detector
, 1);
374 engines
= hkl_factory_create_new_engine_list(factory
);
375 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
376 geometries
= hkl_engine_list_geometries_get(engines
);
378 /* set the hkl pseudo axis in psi_constant_vertical */
379 hkl
= hkl_engine_list_engine_get_by_name(engines
, "hkl");
380 hkl_engine_select_mode(hkl
, "psi_constant_vertical");
381 /* set the psi pseudo engine to read the psi value */
382 psi
= hkl_engine_list_engine_get_by_name(engines
, "psi");
385 /* freeze 0; ca 0 0 2 */
391 hkl_engine_parameters_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), NULL
);
396 hkl_engine_parameters_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), NULL
);
398 /* freeze 0; ca 0 0 2 */
399 hkl_engine_set_values_v(hkl
, 0., 0., 2.);
402 /* 23.37668 11.68835 90 -90 */
404 /* -2.384186e-09 -1.182388e-14 */
405 /* the -90 value of phi is problematic, the right value is 0 */
406 if(hkl_engine_set(hkl
, NULL
)){
407 res
&= hkl_geometry_list_check_geometry_unit(
409 0., 11.688393153063114, 90., 0., 0., 23.376786185344031);
411 /* check that all solution gives the right psi */
412 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
415 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
416 hkl_engine_initialize(psi
, NULL
);
417 hkl_engine_list_get(engines
);
418 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1);
419 res
&= fabs(PSI
- current
) < HKL_EPSILON
;
423 /* freeze 45; ca 0 0 2 */
424 hkl_p
[3] = PSI
= 45.0 * HKL_DEGTORAD
;
425 hkl_engine_parameters_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), NULL
);
426 hkl_engine_set_values_v(hkl
, 0., 0., 2.);
429 /* 23.3768 11.68831 90 -135 */
431 /* -2.384186e-09 -1.182388e-14 */
432 /* -135 n'est pas bon il faudrait plutôt -45 */
433 if(hkl_engine_set(hkl
, NULL
)){
434 res
&= hkl_geometry_list_check_geometry_unit(
436 0., 11.688393153063114, 90., -45., 0., 23.376786185344031);
438 /* check that all solution gives the right psi */
439 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
) {
442 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
443 hkl_engine_initialize(psi
, NULL
);
444 hkl_engine_list_get(engines
);
445 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1);
446 res
&= fabs(PSI
- current
) < HKL_EPSILON
;
451 /* freeze 0; ca 0 0 2 */
457 hkl_engine_parameters_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), NULL
);
458 hkl_engine_set_values_v(hkl
, 0., 0., 2.);
464 hkl_engine_parameters_set(psi
, psi_p
, ARRAY_SIZE(psi_p
), NULL
);
467 /* 23.37681 11.68839 90 -90 */
469 /* -2.384186e-09 -1.182388e-14 */
470 /* phi is wrong it should be -45 */
471 if(hkl_engine_set(hkl
, NULL
)){
472 res
&= hkl_geometry_list_check_geometry_unit(
474 0, 11.688393153063114, 90, -45, 0, 23.376786185344031);
476 /* check that all solution gives the right psi */
477 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
480 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
481 hkl_engine_initialize(psi
, NULL
);
482 hkl_engine_list_get(engines
);
483 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1);
484 res
&= fabs(PSI
- current
) < HKL_EPSILON
;
488 /* freeze 45; ca 0 0 2 */
489 hkl_p
[3] = PSI
= 45 * HKL_DEGTORAD
;
491 hkl_engine_parameters_set(hkl
, hkl_p
, ARRAY_SIZE(hkl_p
), NULL
);
492 hkl_engine_set_values_v(hkl
, 0., 0., 2.);
495 /* 23.37666 11.68837 90 -135 */
497 /* -2.384186e-09 -1.182388e-14 */
498 /* phi is wrong it should be -90 */
499 if(hkl_engine_set(hkl
, NULL
)){
500 res
&= hkl_geometry_list_check_geometry_unit(
502 0, 11.688393153063114, 90, -90, 0, 23.376786185344031);
504 /* check that all solution gives the right psi */
505 HKL_GEOMETRY_LIST_FOREACH(item
, geometries
){
508 hkl_geometry_set(geometry
, hkl_geometry_list_item_geometry_get(item
));
509 hkl_engine_initialize(psi
, NULL
);
510 hkl_engine_list_get(engines
);
511 hkl_engine_pseudo_axes_values_get(psi
, ¤t
, 1);
512 res
&= fabs(PSI
- current
) < HKL_EPSILON
;
516 ok(res
== HKL_TRUE
, __func__
);
518 hkl_engine_list_free(engines
);
519 hkl_detector_free(detector
);
520 hkl_sample_free(sample
);
521 hkl_geometry_free(geometry
);
524 int main(int argc
, char** argv
)