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 <gsl/gsl_sys.h> // for gsl_isnan
23 #include "hkl-factory-private.h" // for autodata_factories_, etc
24 #include "hkl-pseudoaxis-common-eulerians-private.h"
25 #include "hkl-pseudoaxis-common-q-private.h" // for hkl_engine_q2_new, etc
26 #include "hkl-pseudoaxis-common-hkl-private.h" // for RUBh_minus_Q, etc
27 #include "hkl-pseudoaxis-common-psi-private.h" // for hkl_engine_psi_new, etc
29 static void hkl_geometry_list_multiply_k6c_real(HklGeometryList
*self
,
30 HklGeometryListItem
*item
)
32 HklGeometry
*geometry
;
34 double komega
, komegap
;
38 geometry
= item
->geometry
;
39 komega
= hkl_parameter_value_get(darray_item(geometry
->axes
, 1), HKL_UNIT_DEFAULT
);
40 kappa
= hkl_parameter_value_get(darray_item(geometry
->axes
, 2), HKL_UNIT_DEFAULT
);
41 kphi
= hkl_parameter_value_get(darray_item(geometry
->axes
, 3), HKL_UNIT_DEFAULT
);
43 kappa_2_kappap(komega
, kappa
, kphi
, 50 * HKL_DEGTORAD
, &komegap
, &kappap
, &kphip
);
45 copy
= hkl_geometry_new_copy(geometry
);
46 /* TODO parameter list for the geometry */
47 hkl_parameter_value_set(darray_item(copy
->axes
, 1), komegap
, HKL_UNIT_DEFAULT
, NULL
);
48 hkl_parameter_value_set(darray_item(copy
->axes
, 2), kappap
, HKL_UNIT_DEFAULT
, NULL
);
49 hkl_parameter_value_set(darray_item(copy
->axes
, 3), kphip
, HKL_UNIT_DEFAULT
, NULL
);
51 hkl_geometry_update(copy
);
52 hkl_geometry_list_add(self
, copy
);
53 hkl_geometry_free(copy
);
57 /***********************/
58 /* numerical functions */
59 /***********************/
61 static int _bissector_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
63 const double mu
= x
->data
[0];
64 const double komega
= x
->data
[1];
65 const double kappa
= x
->data
[2];
66 const double gamma
= x
->data
[4];
69 CHECK_NAN(x
->data
, x
->size
);
71 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
73 RUBh_minus_Q(x
->data
, params
, f
->data
);
74 f
->data
[3] = fmod(omega
, M_PI
);
75 f
->data
[4] = fmod(gamma
- 2 * fmod(mu
, M_PI
), 2*M_PI
);
80 static const HklFunction bissector_h_f1
= {
81 .function
= _bissector_h_f1
,
85 static int _bissector_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
87 const double mu
= x
->data
[0];
88 const double komega
= x
->data
[1];
89 const double kappa
= x
->data
[2];
90 const double gamma
= x
->data
[4];
93 CHECK_NAN(x
->data
, x
->size
);
95 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
97 RUBh_minus_Q(x
->data
, params
, f
->data
);
98 f
->data
[3] = fmod(omega
, M_PI
);
99 f
->data
[4] = fmod(gamma
- 2 * fmod(mu
, M_PI
), 2*M_PI
);
105 static const HklFunction bissector_h_f2
= {
106 .function
= _bissector_h_f2
,
110 static int _constant_kphi_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
112 const double komega
= x
->data
[1];
113 const double kappa
= x
->data
[2];
116 CHECK_NAN(x
->data
, x
->size
);
118 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
120 RUBh_minus_Q(x
->data
, params
, f
->data
);
121 f
->data
[3] = fmod(omega
, M_PI
);
126 static const HklFunction constant_kphi_h_f1
= {
127 .function
= _constant_kphi_h_f1
,
131 static int _constant_kphi_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
133 const double komega
= x
->data
[1];
134 const double kappa
= x
->data
[2];
137 CHECK_NAN(x
->data
, x
->size
);
139 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
141 RUBh_minus_Q(x
->data
, params
, f
->data
);
142 f
->data
[3] = fmod(omega
, M_PI
);
147 static const HklFunction constant_kphi_h_f2
= {
148 .function
= _constant_kphi_h_f2
,
152 static int _constant_phi_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
154 const double komega
= x
->data
[1];
155 const double kappa
= x
->data
[2];
156 const double kphi
= x
->data
[3];
157 double omega
, phi
, p
;
159 CHECK_NAN(x
->data
, x
->size
);
161 p
= atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
));
162 omega
= komega
+ p
- M_PI_2
;
163 phi
= kphi
+ p
+ M_PI_2
;
165 RUBh_minus_Q(x
->data
, params
, f
->data
);
166 f
->data
[3] = fmod(omega
, M_PI
);
172 static const HklFunction constant_phi_h_f1
= {
173 .function
= _constant_phi_h_f1
,
177 static int _constant_phi_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
179 const double komega
= x
->data
[1];
180 const double kappa
= x
->data
[2];
181 const double kphi
= x
->data
[3];
182 double omega
, phi
, p
;
184 CHECK_NAN(x
->data
, x
->size
);
186 p
= atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
));
187 omega
= komega
+ p
+ M_PI_2
;
188 phi
= kphi
+ p
- M_PI_2
;
190 RUBh_minus_Q(x
->data
, params
, f
->data
);
191 f
->data
[3] = fmod(omega
, M_PI
);
197 static const HklFunction constant_phi_h_f2
= {
198 .function
= _constant_phi_h_f2
,
202 static int _bissector_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
204 const double komega
= x
->data
[0];
205 const double kappa
= x
->data
[1];
206 const double delta
= x
->data
[3];
209 CHECK_NAN(x
->data
, x
->size
);
211 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
213 RUBh_minus_Q(x
->data
, params
, f
->data
);
214 f
->data
[3] = fmod(delta
- 2 * fmod(omega
, M_PI
), 2*M_PI
);
219 static const HklFunction bissector_v
= {
220 .function
= _bissector_v
,
224 static int _constant_omega_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
226 const double komega
= x
->data
[0];
227 const double kappa
= x
->data
[1];
229 HklEngine
*engine
= params
;
230 double omega0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
232 CHECK_NAN(x
->data
, x
->size
);
234 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
236 RUBh_minus_Q(x
->data
, params
, f
->data
);
237 f
->data
[3] = omega0
- omega
;
242 static const HklFunction constant_omega_v
= {
243 .function
= _constant_omega_v
,
247 static int _constant_chi_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
249 const double kappa
= x
->data
[1];
251 HklEngine
*engine
= params
;
252 double chi0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
254 CHECK_NAN(x
->data
, x
->size
);
256 chi
= 2 * asin(sin(kappa
/2.) * sin(50 * HKL_DEGTORAD
));
258 RUBh_minus_Q(x
->data
, params
, f
->data
);
259 f
->data
[3] = chi0
- chi
;
264 static const HklFunction constant_chi_v
= {
265 .function
= _constant_chi_v
,
269 static int _constant_phi_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
271 const double kappa
= x
->data
[1];
272 const double kphi
= x
->data
[2];
274 HklEngine
*engine
= params
;
275 double phi0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
277 CHECK_NAN(x
->data
, x
->size
);
279 phi
= kphi
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
281 RUBh_minus_Q(x
->data
, params
, f
->data
);
282 f
->data
[3] = phi0
- phi
;
287 static const HklFunction constant_phi_v
= {
288 .function
= _constant_phi_v
,
292 static int _double_diffraction_h(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
294 const double komega
= x
->data
[1];
295 const double kappa
= x
->data
[2];
298 CHECK_NAN(x
->data
, x
->size
);
300 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
302 _double_diffraction(x
->data
, params
, f
->data
);
303 f
->data
[4] = fmod(omega
, M_PI
);
308 static const HklFunction double_diffraction_h
= {
309 .function
= _double_diffraction_h
,
313 static int _constant_incidence_func(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
315 static const HklVector Y
= {
320 HklEngine
*engine
= params
;
321 HklModeAutoWithInit
*mode
= container_of(engine
->mode
, HklModeAutoWithInit
, mode
);
327 CHECK_NAN(x
->data
, x
->size
);
329 RUBh_minus_Q(x
->data
, params
, f
->data
);
331 /* get the mode parameters */
332 n
.data
[0] = darray_item(engine
->mode
->parameters
, 0)->_value
;
333 n
.data
[1] = darray_item(engine
->mode
->parameters
, 1)->_value
;
334 n
.data
[2] = darray_item(engine
->mode
->parameters
, 2)->_value
;
335 incidence0
= darray_item(engine
->mode
->parameters
, 3)->_value
;
336 azimuth0
= darray_item(engine
->mode
->parameters
, 4)->_value
;
338 /* compute the two angles */
341 /* first check that the mode was already initialized if not
342 * the surface is oriented along the nx, ny, nz axis for all
343 * diffractometer angles equal to zero */
345 HklQuaternion q0
= darray_item(mode
->geometry
->holders
, 0)->q
;
347 hkl_quaternion_conjugate(&q0
);
348 hkl_vector_rotated_quaternion(&n
, &q0
);
351 hkl_vector_rotated_quaternion(&n
, &darray_item(engine
->geometry
->holders
, 0)->q
);
353 hkl_source_compute_ki(&engine
->geometry
->source
, &ki
);
354 incidence
= M_PI_2
- hkl_vector_angle(&n
, &ki
);
356 hkl_vector_project_on_plan(&n
, &ki
);
357 azimuth
= hkl_vector_angle(&n
, &Y
);
359 f
->data
[3] = incidence0
- incidence
;
360 f
->data
[4] = azimuth0
- azimuth
;
365 static const HklFunction constant_incidence_func
= {
366 .function
= _constant_incidence_func
,
374 static HklMode
*bissector_vertical(void)
376 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
377 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
378 static const HklFunction
*functions
[] = {&bissector_v
};
379 static const HklModeAutoInfo info
= {
380 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
383 return hkl_mode_auto_new(&info
,
384 &hkl_mode_operations
,
388 static HklMode
*constant_omega_vertical(void)
390 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
391 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
392 static const HklFunction
*functions
[] = {&constant_omega_v
};
393 static const HklParameter parameters
[] = {
394 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "omega"},
396 static const HklModeAutoInfo info
= {
397 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
, functions
, parameters
),
400 return hkl_mode_auto_new(&info
,
401 &hkl_mode_operations
,
405 static HklMode
*constant_chi_vertical(void)
407 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
408 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
409 static const HklFunction
*functions
[] = {&constant_chi_v
};
410 static const HklParameter parameters
[] = {
411 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "chi"},
413 static const HklModeAutoInfo info
= {
414 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
, functions
, parameters
),
417 return hkl_mode_auto_new(&info
,
418 &hkl_mode_operations
,
422 static HklMode
*constant_phi_vertical(void)
424 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
425 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
426 static const HklFunction
*functions
[] = {&constant_phi_v
};
427 static const HklParameter parameters
[] = {
428 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "phi"},
430 static const HklModeAutoInfo info
= {
431 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
, functions
, parameters
),
434 return hkl_mode_auto_new(&info
,
435 &hkl_mode_operations
,
439 static HklMode
*lifting_detector_kphi(void)
441 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
442 static const char* axes_w
[] = {"kphi", "gamma", "delta"};
443 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
444 static const HklModeAutoInfo info
= {
445 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
448 return hkl_mode_auto_new(&info
,
449 &hkl_mode_operations
,
453 static HklMode
*lifting_detector_komega(void)
455 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
456 static const char* axes_w
[] = {"komega", "gamma", "delta"};
457 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
458 static const HklModeAutoInfo info
= {
459 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
462 return hkl_mode_auto_new(&info
,
463 &hkl_mode_operations
,
467 static HklMode
*lifting_detector_mu(void)
469 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
470 static const char* axes_w
[] = {"mu", "gamma", "delta"};
471 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
472 static const HklModeAutoInfo info
= {
473 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
476 return hkl_mode_auto_new(&info
,
477 &hkl_mode_operations
,
481 static HklMode
*double_diffraction_vertical(void)
483 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
484 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
485 static const HklFunction
*functions
[] = {&double_diffraction_func
};
486 static const HklModeAutoInfo info
= {
487 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
488 functions
, double_diffraction_parameters
),
491 return hkl_mode_auto_new(&info
,
492 &hkl_mode_operations
,
496 static HklMode
*bissector_horizontal(void)
498 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
499 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
500 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
501 static const HklModeAutoInfo info
= {
502 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
505 return hkl_mode_auto_new(&info
,
506 &hkl_mode_operations
,
510 static HklMode
*constant_phi_horizontal(void)
512 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
513 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
514 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
515 static const HklParameter parameters
[] = {
516 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "phi",},
518 static const HklModeAutoInfo info
= {
519 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
, functions
, parameters
),
522 return hkl_mode_auto_new(&info
,
523 &hkl_mode_operations
,
527 static HklMode
*constant_kphi_horizontal(void)
529 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
530 static const char* axes_w
[] = {"mu", "komega", "kappa", "gamma"};
531 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
532 static const HklModeAutoInfo info
= {
533 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
536 return hkl_mode_auto_new(&info
,
537 &hkl_mode_operations
,
541 static HklMode
*double_diffraction_horizontal(void)
543 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
544 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
545 static const HklFunction
*functions
[] = {&double_diffraction_h
};
546 static const HklModeAutoInfo info
= {
547 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
548 functions
, double_diffraction_parameters
),
551 return hkl_mode_auto_new(&info
,
552 &hkl_mode_operations
,
556 static HklMode
*psi_constant_vertical(void)
558 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
559 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
560 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
561 static const HklModeAutoInfo info
= {
562 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
563 functions
, psi_constant_parameters
),
566 return hkl_mode_auto_new(&info
,
567 &psi_constant_vertical_mode_operations
,
571 static HklMode
*constant_incidence(void)
573 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
574 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma", "delta"};
575 static const HklFunction
*functions
[] = {&constant_incidence_func
};
576 static const HklParameter parameters
[] = {
577 {HKL_PARAMETER_DEFAULTS
, .name
= "x", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
578 {HKL_PARAMETER_DEFAULTS
, .name
= "y", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
579 {HKL_PARAMETER_DEFAULTS
, .name
= "z", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
580 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "incidence"},
581 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "azimuth", ._value
= M_PI_2
,},
583 static const HklModeAutoInfo info
= {
584 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
, functions
, parameters
),
587 return hkl_mode_auto_with_init_new(&info
,
588 &constant_incidence_mode_operations
,
592 /**********************/
593 /* pseudo axis engine */
594 /**********************/
596 static HklEngine
*hkl_engine_k6c_hkl_new(void)
599 HklMode
*default_mode
;
601 self
= hkl_engine_hkl_new();
603 default_mode
= bissector_vertical();
604 hkl_engine_add_mode(self
, default_mode
);
605 hkl_engine_mode_set(self
, default_mode
);
607 hkl_engine_add_mode(self
, constant_omega_vertical());
608 hkl_engine_add_mode(self
, constant_chi_vertical());
609 hkl_engine_add_mode(self
, constant_phi_vertical());
610 hkl_engine_add_mode(self
, lifting_detector_kphi());
611 hkl_engine_add_mode(self
, lifting_detector_komega());
612 hkl_engine_add_mode(self
, lifting_detector_mu());
613 hkl_engine_add_mode(self
, double_diffraction_vertical());
614 hkl_engine_add_mode(self
, bissector_horizontal());
615 hkl_engine_add_mode(self
, constant_phi_horizontal());
616 hkl_engine_add_mode(self
, constant_kphi_horizontal());
617 hkl_engine_add_mode(self
, double_diffraction_horizontal());
618 hkl_engine_add_mode(self
, psi_constant_vertical());
619 hkl_engine_add_mode(self
, constant_incidence());
624 /***********************/
625 /* SOLEIL sirius kappa */
626 /***********************/
630 static HklMode
*bissector_vertical_soleil_sirius_kappa(void)
632 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
633 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
634 static const HklFunction
*functions
[] = {&bissector_v
};
635 static const HklModeAutoInfo info
= {
636 HKL_MODE_AUTO_INFO("bissector_vertical", axes_r
, axes_w
, functions
),
639 return hkl_mode_auto_new(&info
,
640 &hkl_mode_operations
,
644 static HklMode
*constant_omega_vertical_soleil_sirius_kappa(void)
646 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
647 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
648 static const HklFunction
*functions
[] = {&constant_omega_v
};
649 static const HklParameter parameters
[] = {
650 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "omega"},
652 static const HklModeAutoInfo info
= {
653 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_omega_vertical", axes_r
, axes_w
, functions
, parameters
),
656 return hkl_mode_auto_new(&info
,
657 &hkl_mode_operations
,
661 static HklMode
*constant_chi_vertical_soleil_sirius_kappa(void)
663 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
664 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
665 static const HklFunction
*functions
[] = {&constant_chi_v
};
666 static const HklParameter parameters
[] = {
667 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "chi"},
669 static const HklModeAutoInfo info
= {
670 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_chi_vertical", axes_r
, axes_w
, functions
, parameters
),
673 return hkl_mode_auto_new(&info
,
674 &hkl_mode_operations
,
678 static HklMode
*constant_phi_vertical_soleil_sirius_kappa(void)
680 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
681 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
682 static const HklFunction
*functions
[] = {&constant_phi_v
};
683 static const HklParameter parameters
[] = {
684 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "phi"},
686 static const HklModeAutoInfo info
= {
687 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_vertical", axes_r
, axes_w
, functions
, parameters
),
690 return hkl_mode_auto_new(&info
,
691 &hkl_mode_operations
,
695 static HklMode
*lifting_detector_kphi_soleil_sirius_kappa(void)
697 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
698 static const char* axes_w
[] = {"kphi", "delta", "gamma"};
699 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
700 static const HklModeAutoInfo info
= {
701 HKL_MODE_AUTO_INFO("lifting_detector_kphi", axes_r
, axes_w
, functions
),
704 return hkl_mode_auto_new(&info
,
705 &hkl_mode_operations
,
709 static HklMode
*lifting_detector_komega_soleil_sirius_kappa(void)
711 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
712 static const char* axes_w
[] = {"komega", "delta", "gamma"};
713 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
714 static const HklModeAutoInfo info
= {
715 HKL_MODE_AUTO_INFO("lifting_detector_komega", axes_r
, axes_w
, functions
),
718 return hkl_mode_auto_new(&info
,
719 &hkl_mode_operations
,
723 static HklMode
*lifting_detector_mu_soleil_sirius_kappa(void)
725 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
726 static const char* axes_w
[] = {"mu", "delta", "gamma"};
727 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
728 static const HklModeAutoInfo info
= {
729 HKL_MODE_AUTO_INFO("lifting_detector_mu", axes_r
, axes_w
, functions
),
732 return hkl_mode_auto_new(&info
,
733 &hkl_mode_operations
,
737 static HklMode
*double_diffraction_vertical_soleil_sirius_kappa(void)
739 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
740 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
741 static const HklFunction
*functions
[] = {&double_diffraction_func
};
742 static const HklModeAutoInfo info
= {
743 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_vertical", axes_r
, axes_w
,
744 functions
, double_diffraction_parameters
),
747 return hkl_mode_auto_new(&info
,
748 &hkl_mode_operations
,
752 static HklMode
*bissector_horizontal_soleil_sirius_kappa(void)
754 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
755 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
756 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
757 static const HklModeAutoInfo info
= {
758 HKL_MODE_AUTO_INFO("bissector_horizontal", axes_r
, axes_w
, functions
),
761 return hkl_mode_auto_new(&info
,
762 &hkl_mode_operations
,
766 static HklMode
*constant_phi_horizontal_soleil_sirius_kappa(void)
768 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
769 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
770 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
771 static const HklParameter parameters
[] = {
772 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "phi",},
774 static const HklModeAutoInfo info
= {
775 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_horizontal", axes_r
, axes_w
, functions
, parameters
),
778 return hkl_mode_auto_new(&info
,
779 &hkl_mode_operations
,
783 static HklMode
*constant_kphi_horizontal_soleil_sirius_kappa(void)
785 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
786 static const char* axes_w
[] = {"mu", "komega", "kappa", "delta"};
787 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
788 static const HklModeAutoInfo info
= {
789 HKL_MODE_AUTO_INFO("constant_kphi_horizontal", axes_r
, axes_w
, functions
),
792 return hkl_mode_auto_new(&info
,
793 &hkl_mode_operations
,
797 static HklMode
*double_diffraction_horizontal_soleil_sirius_kappa(void)
799 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
800 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
801 static const HklFunction
*functions
[] = {&double_diffraction_h
};
802 static const HklModeAutoInfo info
= {
803 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_horizontal", axes_r
, axes_w
,
804 functions
, double_diffraction_parameters
),
807 return hkl_mode_auto_new(&info
,
808 &hkl_mode_operations
,
812 static HklMode
*psi_constant_vertical_soleil_sirius_kappa(void)
814 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
815 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
816 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
817 static const HklModeAutoInfo info
= {
818 HKL_MODE_AUTO_INFO_WITH_PARAMS("psi_constant_vertical", axes_r
, axes_w
,
819 functions
, psi_constant_parameters
),
822 return hkl_mode_auto_new(&info
,
823 &psi_constant_vertical_mode_operations
,
827 static HklMode
*constant_incidence_soleil_sirius_kappa(void)
829 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
830 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta", "gamma"};
831 static const HklFunction
*functions
[] = {&constant_incidence_func
};
832 static const HklParameter parameters
[] = {
833 {HKL_PARAMETER_DEFAULTS
, .name
= "x", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
834 {HKL_PARAMETER_DEFAULTS
, .name
= "y", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
835 {HKL_PARAMETER_DEFAULTS
, .name
= "z", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
836 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "incidence"},
837 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "azimuth", ._value
= M_PI_2
,},
839 static const HklModeAutoInfo info
= {
840 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_incidence", axes_r
, axes_w
, functions
, parameters
),
843 return hkl_mode_auto_with_init_new(&info
,
844 &constant_incidence_mode_operations
,
848 static HklEngine
*hkl_engine_soleil_sirius_kappa_hkl_new(void)
851 HklMode
*default_mode
;
853 self
= hkl_engine_hkl_new();
855 default_mode
= bissector_vertical_soleil_sirius_kappa();
856 hkl_engine_add_mode(self
, default_mode
);
857 hkl_engine_mode_set(self
, default_mode
);
859 hkl_engine_add_mode(self
, constant_omega_vertical_soleil_sirius_kappa());
860 hkl_engine_add_mode(self
, constant_chi_vertical_soleil_sirius_kappa());
861 hkl_engine_add_mode(self
, constant_phi_vertical_soleil_sirius_kappa());
862 hkl_engine_add_mode(self
, lifting_detector_kphi_soleil_sirius_kappa());
863 hkl_engine_add_mode(self
, lifting_detector_komega_soleil_sirius_kappa());
864 hkl_engine_add_mode(self
, lifting_detector_mu_soleil_sirius_kappa());
865 hkl_engine_add_mode(self
, double_diffraction_vertical_soleil_sirius_kappa());
866 hkl_engine_add_mode(self
, bissector_horizontal_soleil_sirius_kappa());
867 hkl_engine_add_mode(self
, constant_phi_horizontal_soleil_sirius_kappa());
868 hkl_engine_add_mode(self
, constant_kphi_horizontal_soleil_sirius_kappa());
869 hkl_engine_add_mode(self
, double_diffraction_horizontal_soleil_sirius_kappa());
870 hkl_engine_add_mode(self
, psi_constant_vertical_soleil_sirius_kappa());
871 hkl_engine_add_mode(self
, constant_incidence_soleil_sirius_kappa());
876 static HklMode
*psi_vertical()
878 static const char *axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
879 static const char *axes_w
[] = {"komega", "kappa", "kphi", "delta"};
880 static const HklFunction
*functions
[] = {&psi_func
};
881 static const HklModeAutoInfo info
= {
882 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
883 functions
, psi_parameters
),
886 return hkl_mode_psi_new(&info
);
889 static HklEngine
*hkl_engine_k6c_psi_new(void)
892 HklMode
*default_mode
;
894 self
= hkl_engine_psi_new();
896 default_mode
= psi_vertical();
897 hkl_engine_add_mode(self
, default_mode
);
898 hkl_engine_mode_set(self
, default_mode
);
903 /***********************/
904 /* SOLEIL SIRIUS KAPPA */
905 /***********************/
907 static HklMode
*psi_vertical_soleil_sirius_kappa()
909 static const char *axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
910 static const char *axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
911 static const HklFunction
*functions
[] = {&psi_func
};
912 static const HklModeAutoInfo info
= {
913 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
914 functions
, psi_parameters
),
917 return hkl_mode_psi_new(&info
);
920 static HklEngine
*hkl_engine_soleil_sirius_kappa_psi_new(void)
923 HklMode
*default_mode
;
925 self
= hkl_engine_psi_new();
927 default_mode
= psi_vertical_soleil_sirius_kappa();
928 hkl_engine_add_mode(self
, default_mode
);
929 hkl_engine_mode_set(self
, default_mode
);
938 #define HKL_GEOMETRY_KAPPA6C_DESCRIPTION \
939 "For this geometry there is a special parameters called :math:`\\alpha` which is the\n" \
940 "angle between the kappa rotation axis and the :math:`\\vec{y}` direction.\n" \
942 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
943 "+ 4 axes for the sample\n" \
945 " + **mu** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
946 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
947 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
948 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
950 "+ 2 axes for the detector\n" \
952 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
953 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
955 static const char* hkl_geometry_kappa6C_axes
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
957 static HklGeometry
*hkl_geometry_new_kappa6C(const HklFactory
*factory
)
959 HklGeometry
*self
= hkl_geometry_new(factory
);
960 double alpha
= 50 * HKL_DEGTORAD
;
963 h
= hkl_geometry_add_holder(self
);
964 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
965 hkl_holder_add_rotation_axis(h
, "komega", 0, -1, 0);
966 hkl_holder_add_rotation_axis(h
, "kappa", 0, -cos(alpha
), -sin(alpha
));
967 hkl_holder_add_rotation_axis(h
, "kphi", 0, -1, 0);
969 h
= hkl_geometry_add_holder(self
);
970 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
971 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
976 static HklEngineList
*hkl_engine_list_new_kappa6C(const HklFactory
*factory
)
978 HklEngineList
*self
= hkl_engine_list_new();
980 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
981 hkl_engine_list_add(self
, hkl_engine_k6c_hkl_new());
982 hkl_engine_list_add(self
, hkl_engine_eulerians_new());
983 hkl_engine_list_add(self
, hkl_engine_k6c_psi_new());
984 hkl_engine_list_add(self
, hkl_engine_q2_new());
985 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
990 REGISTER_DIFFRACTOMETER(kappa6C
, "K6C", HKL_GEOMETRY_KAPPA6C_DESCRIPTION
);
992 /***********************/
993 /* SOLEIL SIRIUS KAPPA */
994 /***********************/
996 #define HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION \
997 "+ xrays source fix along the :math:`\\vec{x}` direction (1, 0, 0)\n" \
998 "+ 4 axes for the sample\n" \
1000 " + **mu** : rotating around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
1001 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
1002 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
1003 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
1005 "+ 2 axes for the detector\n" \
1007 " + **delta** : rotation around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
1008 " + **gamma** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
1010 static const char* hkl_geometry_soleil_sirius_kappa_axes
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
1012 static HklGeometry
*hkl_geometry_new_soleil_sirius_kappa(const HklFactory
*factory
)
1014 HklGeometry
*self
= hkl_geometry_new(factory
);
1015 double alpha
= 50 * HKL_DEGTORAD
;
1018 h
= hkl_geometry_add_holder(self
);
1019 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, -1);
1020 hkl_holder_add_rotation_axis(h
, "komega", 0, -1, 0);
1021 hkl_holder_add_rotation_axis(h
, "kappa", 0, -cos(alpha
), -sin(alpha
));
1022 hkl_holder_add_rotation_axis(h
, "kphi", 0, -1, 0);
1024 h
= hkl_geometry_add_holder(self
);
1025 hkl_holder_add_rotation_axis(h
, "delta", 0, 0, -1);
1026 hkl_holder_add_rotation_axis(h
, "gamma", 0, -1, 0);
1031 static HklEngineList
*hkl_engine_list_new_soleil_sirius_kappa(const HklFactory
*factory
)
1033 HklEngineList
*self
= hkl_engine_list_new();
1035 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
1036 hkl_engine_list_add(self
, hkl_engine_soleil_sirius_kappa_hkl_new());
1037 hkl_engine_list_add(self
, hkl_engine_eulerians_new());
1038 hkl_engine_list_add(self
, hkl_engine_soleil_sirius_kappa_psi_new());
1039 hkl_engine_list_add(self
, hkl_engine_q2_new());
1040 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
1045 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa
, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION
);