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 HklModeAutoInfo info
= {
394 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
395 functions
, constant_omega_parameters
),
398 return hkl_mode_auto_new(&info
,
399 &hkl_mode_operations
,
403 static HklMode
*constant_chi_vertical(void)
405 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
406 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
407 static const HklFunction
*functions
[] = {&constant_chi_v
};
408 static const HklModeAutoInfo info
= {
409 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
410 functions
, constant_chi_parameters
),
413 return hkl_mode_auto_new(&info
,
414 &hkl_mode_operations
,
418 static HklMode
*constant_phi_vertical(void)
420 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
421 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
422 static const HklFunction
*functions
[] = {&constant_phi_v
};
423 static const HklModeAutoInfo info
= {
424 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
425 functions
, constant_phi_parameters
),
428 return hkl_mode_auto_new(&info
,
429 &hkl_mode_operations
,
433 static HklMode
*lifting_detector_kphi(void)
435 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
436 static const char* axes_w
[] = {"kphi", "gamma", "delta"};
437 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
438 static const HklModeAutoInfo info
= {
439 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
442 return hkl_mode_auto_new(&info
,
443 &hkl_mode_operations
,
447 static HklMode
*lifting_detector_komega(void)
449 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
450 static const char* axes_w
[] = {"komega", "gamma", "delta"};
451 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
452 static const HklModeAutoInfo info
= {
453 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
456 return hkl_mode_auto_new(&info
,
457 &hkl_mode_operations
,
461 static HklMode
*lifting_detector_mu(void)
463 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
464 static const char* axes_w
[] = {"mu", "gamma", "delta"};
465 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
466 static const HklModeAutoInfo info
= {
467 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
470 return hkl_mode_auto_new(&info
,
471 &hkl_mode_operations
,
475 static HklMode
*double_diffraction_vertical(void)
477 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
478 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
479 static const HklFunction
*functions
[] = {&double_diffraction_func
};
480 static const HklModeAutoInfo info
= {
481 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
482 functions
, double_diffraction_parameters
),
485 return hkl_mode_auto_new(&info
,
486 &hkl_mode_operations
,
490 static HklMode
*bissector_horizontal(void)
492 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
493 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
494 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
495 static const HklModeAutoInfo info
= {
496 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
499 return hkl_mode_auto_new(&info
,
500 &hkl_mode_operations
,
504 static HklMode
*constant_phi_horizontal(void)
506 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
507 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
508 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
509 static const HklModeAutoInfo info
= {
510 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
511 functions
, constant_phi_parameters
),
514 return hkl_mode_auto_new(&info
,
515 &hkl_mode_operations
,
519 static HklMode
*constant_kphi_horizontal(void)
521 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
522 static const char* axes_w
[] = {"mu", "komega", "kappa", "gamma"};
523 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
524 static const HklModeAutoInfo info
= {
525 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
528 return hkl_mode_auto_new(&info
,
529 &hkl_mode_operations
,
533 static HklMode
*double_diffraction_horizontal(void)
535 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
536 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "gamma"};
537 static const HklFunction
*functions
[] = {&double_diffraction_h
};
538 static const HklModeAutoInfo info
= {
539 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
540 functions
, double_diffraction_parameters
),
543 return hkl_mode_auto_new(&info
,
544 &hkl_mode_operations
,
548 static HklMode
*psi_constant_vertical(void)
550 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
551 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta"};
552 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
553 static const HklModeAutoInfo info
= {
554 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
555 functions
, psi_constant_parameters
),
558 return hkl_mode_auto_new(&info
,
559 &psi_constant_vertical_mode_operations
,
563 static HklMode
*constant_incidence(void)
565 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
566 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma", "delta"};
567 static const HklFunction
*functions
[] = {&constant_incidence_func
};
568 static const HklModeAutoInfo info
= {
569 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
570 functions
, constant_incidence_parameters
),
573 return hkl_mode_auto_with_init_new(&info
,
574 &constant_incidence_mode_operations
,
578 /**********************/
579 /* pseudo axis engine */
580 /**********************/
582 static HklEngine
*hkl_engine_k6c_hkl_new(void)
585 HklMode
*default_mode
;
587 self
= hkl_engine_hkl_new();
589 default_mode
= bissector_vertical();
590 hkl_engine_add_mode(self
, default_mode
);
591 hkl_engine_mode_set(self
, default_mode
);
593 hkl_engine_add_mode(self
, constant_omega_vertical());
594 hkl_engine_add_mode(self
, constant_chi_vertical());
595 hkl_engine_add_mode(self
, constant_phi_vertical());
596 hkl_engine_add_mode(self
, lifting_detector_kphi());
597 hkl_engine_add_mode(self
, lifting_detector_komega());
598 hkl_engine_add_mode(self
, lifting_detector_mu());
599 hkl_engine_add_mode(self
, double_diffraction_vertical());
600 hkl_engine_add_mode(self
, bissector_horizontal());
601 hkl_engine_add_mode(self
, constant_phi_horizontal());
602 hkl_engine_add_mode(self
, constant_kphi_horizontal());
603 hkl_engine_add_mode(self
, double_diffraction_horizontal());
604 hkl_engine_add_mode(self
, psi_constant_vertical());
605 hkl_engine_add_mode(self
, constant_incidence());
610 /***********************/
611 /* SOLEIL sirius kappa */
612 /***********************/
616 static HklMode
*bissector_vertical_soleil_sirius_kappa(void)
618 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
619 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
620 static const HklFunction
*functions
[] = {&bissector_v
};
621 static const HklModeAutoInfo info
= {
622 HKL_MODE_AUTO_INFO("bissector_vertical", axes_r
, axes_w
, functions
),
625 return hkl_mode_auto_new(&info
,
626 &hkl_mode_operations
,
630 static HklMode
*constant_omega_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
[] = {&constant_omega_v
};
635 static const HklModeAutoInfo info
= {
636 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_omega_vertical", axes_r
, axes_w
,
637 functions
, constant_omega_parameters
),
640 return hkl_mode_auto_new(&info
,
641 &hkl_mode_operations
,
645 static HklMode
*constant_chi_vertical_soleil_sirius_kappa(void)
647 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
648 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
649 static const HklFunction
*functions
[] = {&constant_chi_v
};
650 static const HklModeAutoInfo info
= {
651 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_chi_vertical", axes_r
, axes_w
,
652 functions
, constant_chi_parameters
),
655 return hkl_mode_auto_new(&info
,
656 &hkl_mode_operations
,
660 static HklMode
*constant_phi_vertical_soleil_sirius_kappa(void)
662 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
663 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
664 static const HklFunction
*functions
[] = {&constant_phi_v
};
665 static const HklModeAutoInfo info
= {
666 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_vertical", axes_r
, axes_w
,
667 functions
, constant_phi_parameters
),
670 return hkl_mode_auto_new(&info
,
671 &hkl_mode_operations
,
675 static HklMode
*lifting_detector_kphi_soleil_sirius_kappa(void)
677 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
678 static const char* axes_w
[] = {"kphi", "delta", "gamma"};
679 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
680 static const HklModeAutoInfo info
= {
681 HKL_MODE_AUTO_INFO("lifting_detector_kphi", axes_r
, axes_w
, functions
),
684 return hkl_mode_auto_new(&info
,
685 &hkl_mode_operations
,
689 static HklMode
*lifting_detector_komega_soleil_sirius_kappa(void)
691 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
692 static const char* axes_w
[] = {"komega", "delta", "gamma"};
693 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
694 static const HklModeAutoInfo info
= {
695 HKL_MODE_AUTO_INFO("lifting_detector_komega", axes_r
, axes_w
, functions
),
698 return hkl_mode_auto_new(&info
,
699 &hkl_mode_operations
,
703 static HklMode
*lifting_detector_mu_soleil_sirius_kappa(void)
705 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
706 static const char* axes_w
[] = {"mu", "delta", "gamma"};
707 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
708 static const HklModeAutoInfo info
= {
709 HKL_MODE_AUTO_INFO("lifting_detector_mu", axes_r
, axes_w
, functions
),
712 return hkl_mode_auto_new(&info
,
713 &hkl_mode_operations
,
717 static HklMode
*double_diffraction_vertical_soleil_sirius_kappa(void)
719 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
720 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
721 static const HklFunction
*functions
[] = {&double_diffraction_func
};
722 static const HklModeAutoInfo info
= {
723 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_vertical", axes_r
, axes_w
,
724 functions
, double_diffraction_parameters
),
727 return hkl_mode_auto_new(&info
,
728 &hkl_mode_operations
,
732 static HklMode
*bissector_horizontal_soleil_sirius_kappa(void)
734 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
735 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
736 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
737 static const HklModeAutoInfo info
= {
738 HKL_MODE_AUTO_INFO("bissector_horizontal", axes_r
, axes_w
, functions
),
741 return hkl_mode_auto_new(&info
,
742 &hkl_mode_operations
,
746 static HklMode
*constant_phi_horizontal_soleil_sirius_kappa(void)
748 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
749 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
750 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
751 static const HklModeAutoInfo info
= {
752 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_horizontal", axes_r
, axes_w
,
753 functions
, constant_phi_parameters
),
756 return hkl_mode_auto_new(&info
,
757 &hkl_mode_operations
,
761 static HklMode
*constant_kphi_horizontal_soleil_sirius_kappa(void)
763 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
764 static const char* axes_w
[] = {"mu", "komega", "kappa", "delta"};
765 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
766 static const HklModeAutoInfo info
= {
767 HKL_MODE_AUTO_INFO("constant_kphi_horizontal", axes_r
, axes_w
, functions
),
770 return hkl_mode_auto_new(&info
,
771 &hkl_mode_operations
,
775 static HklMode
*double_diffraction_horizontal_soleil_sirius_kappa(void)
777 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
778 static const char* axes_w
[] = {"mu", "komega", "kappa", "kphi", "delta"};
779 static const HklFunction
*functions
[] = {&double_diffraction_h
};
780 static const HklModeAutoInfo info
= {
781 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_horizontal", axes_r
, axes_w
,
782 functions
, double_diffraction_parameters
),
785 return hkl_mode_auto_new(&info
,
786 &hkl_mode_operations
,
790 static HklMode
*psi_constant_vertical_soleil_sirius_kappa(void)
792 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
793 static const char* axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
794 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
795 static const HklModeAutoInfo info
= {
796 HKL_MODE_AUTO_INFO_WITH_PARAMS("psi_constant_vertical", axes_r
, axes_w
,
797 functions
, psi_constant_parameters
),
800 return hkl_mode_auto_new(&info
,
801 &psi_constant_vertical_mode_operations
,
805 static HklMode
*constant_incidence_soleil_sirius_kappa(void)
807 static const char* axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
808 static const char* axes_w
[] = {"komega", "kappa", "kphi", "delta", "gamma"};
809 static const HklFunction
*functions
[] = {&constant_incidence_func
};
810 static const HklModeAutoInfo info
= {
811 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_incidence", axes_r
, axes_w
,
812 functions
, constant_incidence_parameters
),
815 return hkl_mode_auto_with_init_new(&info
,
816 &constant_incidence_mode_operations
,
820 static HklEngine
*hkl_engine_soleil_sirius_kappa_hkl_new(void)
823 HklMode
*default_mode
;
825 self
= hkl_engine_hkl_new();
827 default_mode
= bissector_vertical_soleil_sirius_kappa();
828 hkl_engine_add_mode(self
, default_mode
);
829 hkl_engine_mode_set(self
, default_mode
);
831 hkl_engine_add_mode(self
, constant_omega_vertical_soleil_sirius_kappa());
832 hkl_engine_add_mode(self
, constant_chi_vertical_soleil_sirius_kappa());
833 hkl_engine_add_mode(self
, constant_phi_vertical_soleil_sirius_kappa());
834 hkl_engine_add_mode(self
, lifting_detector_kphi_soleil_sirius_kappa());
835 hkl_engine_add_mode(self
, lifting_detector_komega_soleil_sirius_kappa());
836 hkl_engine_add_mode(self
, lifting_detector_mu_soleil_sirius_kappa());
837 hkl_engine_add_mode(self
, double_diffraction_vertical_soleil_sirius_kappa());
838 hkl_engine_add_mode(self
, bissector_horizontal_soleil_sirius_kappa());
839 hkl_engine_add_mode(self
, constant_phi_horizontal_soleil_sirius_kappa());
840 hkl_engine_add_mode(self
, constant_kphi_horizontal_soleil_sirius_kappa());
841 hkl_engine_add_mode(self
, double_diffraction_horizontal_soleil_sirius_kappa());
842 hkl_engine_add_mode(self
, psi_constant_vertical_soleil_sirius_kappa());
843 hkl_engine_add_mode(self
, constant_incidence_soleil_sirius_kappa());
848 static HklMode
*psi_vertical()
850 static const char *axes_r
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
851 static const char *axes_w
[] = {"komega", "kappa", "kphi", "delta"};
852 static const HklFunction
*functions
[] = {&psi_func
};
853 static const HklModeAutoInfo info
= {
854 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
855 functions
, psi_parameters
),
858 return hkl_mode_psi_new(&info
);
861 static HklEngine
*hkl_engine_k6c_psi_new(void)
864 HklMode
*default_mode
;
866 self
= hkl_engine_psi_new();
868 default_mode
= psi_vertical();
869 hkl_engine_add_mode(self
, default_mode
);
870 hkl_engine_mode_set(self
, default_mode
);
875 /***********************/
876 /* SOLEIL SIRIUS KAPPA */
877 /***********************/
879 static HklMode
*psi_vertical_soleil_sirius_kappa()
881 static const char *axes_r
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
882 static const char *axes_w
[] = {"komega", "kappa", "kphi", "gamma"};
883 static const HklFunction
*functions
[] = {&psi_func
};
884 static const HklModeAutoInfo info
= {
885 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
886 functions
, psi_parameters
),
889 return hkl_mode_psi_new(&info
);
892 static HklEngine
*hkl_engine_soleil_sirius_kappa_psi_new(void)
895 HklMode
*default_mode
;
897 self
= hkl_engine_psi_new();
899 default_mode
= psi_vertical_soleil_sirius_kappa();
900 hkl_engine_add_mode(self
, default_mode
);
901 hkl_engine_mode_set(self
, default_mode
);
910 #define HKL_GEOMETRY_KAPPA6C_DESCRIPTION \
911 "For this geometry there is a special parameters called :math:`\\alpha` which is the\n" \
912 "angle between the kappa rotation axis and the :math:`\\vec{y}` direction.\n" \
914 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
915 "+ 4 axes for the sample\n" \
917 " + **mu** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
918 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
919 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
920 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
922 "+ 2 axes for the detector\n" \
924 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
925 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
927 static const char* hkl_geometry_kappa6C_axes
[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
929 static HklGeometry
*hkl_geometry_new_kappa6C(const HklFactory
*factory
)
931 HklGeometry
*self
= hkl_geometry_new(factory
);
932 double alpha
= 50 * HKL_DEGTORAD
;
935 h
= hkl_geometry_add_holder(self
);
936 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
937 hkl_holder_add_rotation_axis(h
, "komega", 0, -1, 0);
938 hkl_holder_add_rotation_axis(h
, "kappa", 0, -cos(alpha
), -sin(alpha
));
939 hkl_holder_add_rotation_axis(h
, "kphi", 0, -1, 0);
941 h
= hkl_geometry_add_holder(self
);
942 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
943 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
948 static HklEngineList
*hkl_engine_list_new_kappa6C(const HklFactory
*factory
)
950 HklEngineList
*self
= hkl_engine_list_new();
952 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
953 hkl_engine_list_add(self
, hkl_engine_k6c_hkl_new());
954 hkl_engine_list_add(self
, hkl_engine_eulerians_new());
955 hkl_engine_list_add(self
, hkl_engine_k6c_psi_new());
956 hkl_engine_list_add(self
, hkl_engine_q2_new());
957 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
962 REGISTER_DIFFRACTOMETER(kappa6C
, "K6C", HKL_GEOMETRY_KAPPA6C_DESCRIPTION
);
964 /***********************/
965 /* SOLEIL SIRIUS KAPPA */
966 /***********************/
968 #define HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION \
969 "+ xrays source fix along the :math:`\\vec{x}` direction (1, 0, 0)\n" \
970 "+ 4 axes for the sample\n" \
972 " + **mu** : rotating around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
973 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
974 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
975 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
977 "+ 2 axes for the detector\n" \
979 " + **delta** : rotation around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
980 " + **gamma** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
982 static const char* hkl_geometry_soleil_sirius_kappa_axes
[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
984 static HklGeometry
*hkl_geometry_new_soleil_sirius_kappa(const HklFactory
*factory
)
986 HklGeometry
*self
= hkl_geometry_new(factory
);
987 double alpha
= 50 * HKL_DEGTORAD
;
990 h
= hkl_geometry_add_holder(self
);
991 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, -1);
992 hkl_holder_add_rotation_axis(h
, "komega", 0, -1, 0);
993 hkl_holder_add_rotation_axis(h
, "kappa", 0, -cos(alpha
), -sin(alpha
));
994 hkl_holder_add_rotation_axis(h
, "kphi", 0, -1, 0);
996 h
= hkl_geometry_add_holder(self
);
997 hkl_holder_add_rotation_axis(h
, "delta", 0, 0, -1);
998 hkl_holder_add_rotation_axis(h
, "gamma", 0, -1, 0);
1003 static HklEngineList
*hkl_engine_list_new_soleil_sirius_kappa(const HklFactory
*factory
)
1005 HklEngineList
*self
= hkl_engine_list_new();
1007 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
1008 hkl_engine_list_add(self
, hkl_engine_soleil_sirius_kappa_hkl_new());
1009 hkl_engine_list_add(self
, hkl_engine_eulerians_new());
1010 hkl_engine_list_add(self
, hkl_engine_soleil_sirius_kappa_psi_new());
1011 hkl_engine_list_add(self
, hkl_engine_q2_new());
1012 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
1017 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa
, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION
);