upgrading copyright year from 2015 to 2016
[hkl.git] / hkl / hkl-engine-k6c.c
blobf5862449c1e06c0698b23d4835f6426f4b096ac7
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-2016 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-hkl-private.h" // for RUBh_minus_Q, etc
26 #include "hkl-pseudoaxis-common-psi-private.h" // for hkl_engine_psi_new, etc
27 #include "hkl-pseudoaxis-common-q-private.h" // for hkl_engine_q2_new, etc
28 #include "hkl-pseudoaxis-common-readonly-private.h"
29 #include "hkl-pseudoaxis-common-tth-private.h" // for hkl_engine_tth2_new, etc
31 #define MU "mu"
32 #define KOMEGA "komega"
33 #define KAPPA "kappa"
34 #define KPHI "kphi"
35 #define GAMMA "gamma"
36 #define DELTA "delta"
38 static void hkl_geometry_list_multiply_k6c_real(HklGeometryList *self,
39 HklGeometryListItem *item)
41 HklGeometry *geometry;
42 HklGeometry *copy;
43 double komega, komegap;
44 double kappa, kappap;
45 double kphi, kphip;
47 geometry = item->geometry;
48 komega = hkl_parameter_value_get(darray_item(geometry->axes, 1), HKL_UNIT_DEFAULT);
49 kappa = hkl_parameter_value_get(darray_item(geometry->axes, 2), HKL_UNIT_DEFAULT);
50 kphi = hkl_parameter_value_get(darray_item(geometry->axes, 3), HKL_UNIT_DEFAULT);
52 kappa_2_kappap(komega, kappa, kphi, 50 * HKL_DEGTORAD, &komegap, &kappap, &kphip);
54 copy = hkl_geometry_new_copy(geometry);
55 /* TODO parameter list for the geometry */
56 hkl_parameter_value_set(darray_item(copy->axes, 1), komegap, HKL_UNIT_DEFAULT, NULL);
57 hkl_parameter_value_set(darray_item(copy->axes, 2), kappap, HKL_UNIT_DEFAULT, NULL);
58 hkl_parameter_value_set(darray_item(copy->axes, 3), kphip, HKL_UNIT_DEFAULT, NULL);
60 hkl_geometry_update(copy);
61 hkl_geometry_list_add(self, copy);
62 hkl_geometry_free(copy);
66 /***********************/
67 /* numerical functions */
68 /***********************/
70 static int _bissector_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
72 const double mu = x->data[0];
73 const double komega = x->data[1];
74 const double kappa = x->data[2];
75 const double gamma = x->data[4];
76 double omega;
78 CHECK_NAN(x->data, x->size);
80 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
82 RUBh_minus_Q(x->data, params, f->data);
83 f->data[3] = fmod(omega, M_PI);
84 f->data[4] = fmod(gamma - 2 * fmod(mu, M_PI), 2*M_PI);
86 return GSL_SUCCESS;
89 static const HklFunction bissector_h_f1 = {
90 .function = _bissector_h_f1,
91 .size = 5,
94 static int _bissector_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
96 const double mu = x->data[0];
97 const double komega = x->data[1];
98 const double kappa = x->data[2];
99 const double gamma = x->data[4];
100 double omega;
102 CHECK_NAN(x->data, x->size);
104 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
106 RUBh_minus_Q(x->data, params, f->data);
107 f->data[3] = fmod(omega, M_PI);
108 f->data[4] = fmod(gamma - 2 * fmod(mu, M_PI), 2*M_PI);
111 return GSL_SUCCESS;
114 static const HklFunction bissector_h_f2 = {
115 .function = _bissector_h_f2,
116 .size = 5,
119 static int _constant_kphi_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
121 const double komega = x->data[1];
122 const double kappa = x->data[2];
123 double omega;
125 CHECK_NAN(x->data, x->size);
127 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
129 RUBh_minus_Q(x->data, params, f->data);
130 f->data[3] = fmod(omega, M_PI);
132 return GSL_SUCCESS;
135 static const HklFunction constant_kphi_h_f1 = {
136 .function = _constant_kphi_h_f1,
137 .size = 4,
140 static int _constant_kphi_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
142 const double komega = x->data[1];
143 const double kappa = x->data[2];
144 double omega;
146 CHECK_NAN(x->data, x->size);
148 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
150 RUBh_minus_Q(x->data, params, f->data);
151 f->data[3] = fmod(omega, M_PI);
153 return GSL_SUCCESS;
156 static const HklFunction constant_kphi_h_f2 = {
157 .function = _constant_kphi_h_f2,
158 .size = 4,
161 static int _constant_phi_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
163 const double komega = x->data[1];
164 const double kappa = x->data[2];
165 const double kphi = x->data[3];
166 double omega, phi, p;
168 CHECK_NAN(x->data, x->size);
170 p = atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD));
171 omega = komega + p - M_PI_2;
172 phi = kphi + p + M_PI_2;
174 RUBh_minus_Q(x->data, params, f->data);
175 f->data[3] = fmod(omega, M_PI);
176 f->data[4] = phi;
178 return GSL_SUCCESS;
181 static const HklFunction constant_phi_h_f1 = {
182 .function = _constant_phi_h_f1,
183 .size = 5,
186 static int _constant_phi_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
188 const double komega = x->data[1];
189 const double kappa = x->data[2];
190 const double kphi = x->data[3];
191 double omega, phi, p;
193 CHECK_NAN(x->data, x->size);
195 p = atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD));
196 omega = komega + p + M_PI_2;
197 phi = kphi + p - M_PI_2;
199 RUBh_minus_Q(x->data, params, f->data);
200 f->data[3] = fmod(omega, M_PI);
201 f->data[4] = phi;
203 return GSL_SUCCESS;
206 static const HklFunction constant_phi_h_f2 = {
207 .function = _constant_phi_h_f2,
208 .size = 5,
211 static int _bissector_v(const gsl_vector *x, void *params, gsl_vector *f)
213 const double komega = x->data[0];
214 const double kappa = x->data[1];
215 const double delta = x->data[3];
216 double omega;
218 CHECK_NAN(x->data, x->size);
220 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
222 RUBh_minus_Q(x->data, params, f->data);
223 f->data[3] = fmod(delta - 2 * fmod(omega, M_PI), 2*M_PI);
225 return GSL_SUCCESS;
228 static const HklFunction bissector_v = {
229 .function = _bissector_v,
230 .size = 4,
233 static int _constant_omega_v(const gsl_vector *x, void *params, gsl_vector *f)
235 const double komega = x->data[0];
236 const double kappa = x->data[1];
237 double omega;
238 HklEngine *engine = params;
239 double omega0 = darray_item(engine->mode->parameters, 0)->_value;
241 CHECK_NAN(x->data, x->size);
243 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
245 RUBh_minus_Q(x->data, params, f->data);
246 f->data[3] = omega0 - omega;
248 return GSL_SUCCESS;
251 static const HklFunction constant_omega_v = {
252 .function = _constant_omega_v,
253 .size = 4,
256 static int _constant_chi_v(const gsl_vector *x, void *params, gsl_vector *f)
258 const double kappa = x->data[1];
259 double chi;
260 HklEngine *engine = params;
261 double chi0 = darray_item(engine->mode->parameters, 0)->_value;
263 CHECK_NAN(x->data, x->size);
265 chi = 2 * asin(sin(kappa/2.) * sin(50 * HKL_DEGTORAD));
267 RUBh_minus_Q(x->data, params, f->data);
268 f->data[3] = chi0 - chi;
270 return GSL_SUCCESS;
273 static const HklFunction constant_chi_v = {
274 .function = _constant_chi_v,
275 .size = 4,
278 static int _constant_phi_v(const gsl_vector *x, void *params, gsl_vector *f)
280 const double kappa = x->data[1];
281 const double kphi = x->data[2];
282 double phi;
283 HklEngine *engine = params;
284 double phi0 = darray_item(engine->mode->parameters, 0)->_value;
286 CHECK_NAN(x->data, x->size);
288 phi = kphi + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
290 RUBh_minus_Q(x->data, params, f->data);
291 f->data[3] = phi0 - phi;
293 return GSL_SUCCESS;
296 static const HklFunction constant_phi_v = {
297 .function = _constant_phi_v,
298 .size = 4,
301 static int _double_diffraction_h(const gsl_vector *x, void *params, gsl_vector *f)
303 const double komega = x->data[1];
304 const double kappa = x->data[2];
305 double omega;
307 CHECK_NAN(x->data, x->size);
309 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
311 _double_diffraction(x->data, params, f->data);
312 f->data[4] = fmod(omega, M_PI);
314 return GSL_SUCCESS;
317 static const HklFunction double_diffraction_h = {
318 .function = _double_diffraction_h,
319 .size = 5,
322 static int _constant_incidence_func(const gsl_vector *x, void *params, gsl_vector *f)
324 static const HklVector Y = {
325 .data = {0, 1, 0},
327 double incidence;
328 double azimuth;
329 HklEngine *engine = params;
330 HklModeAutoWithInit *mode = container_of(engine->mode, HklModeAutoWithInit, mode);
331 HklVector n;
332 double incidence0;
333 double azimuth0;
334 HklVector ki;
336 CHECK_NAN(x->data, x->size);
338 RUBh_minus_Q(x->data, params, f->data);
340 /* get the mode parameters */
341 n.data[0] = darray_item(engine->mode->parameters, 0)->_value;
342 n.data[1] = darray_item(engine->mode->parameters, 1)->_value;
343 n.data[2] = darray_item(engine->mode->parameters, 2)->_value;
344 incidence0 = darray_item(engine->mode->parameters, 3)->_value;
345 azimuth0 = darray_item(engine->mode->parameters, 4)->_value;
347 /* compute the two angles */
350 /* first check that the mode was already initialized if not
351 * the surface is oriented along the nx, ny, nz axis for all
352 * diffractometer angles equal to zero */
353 if(mode->geometry){
354 HklQuaternion q0 = darray_item(mode->geometry->holders, 0)->q;
356 hkl_quaternion_conjugate(&q0);
357 hkl_vector_rotated_quaternion(&n, &q0);
360 hkl_vector_rotated_quaternion(&n, &darray_item(engine->geometry->holders, 0)->q);
362 hkl_source_compute_ki(&engine->geometry->source, &ki);
363 incidence = _incidence(&n, &ki);
365 hkl_vector_project_on_plan(&n, &ki);
366 azimuth = hkl_vector_angle(&n, &Y);
368 f->data[3] = incidence0 - incidence;
369 f->data[4] = azimuth0 - azimuth;
371 return GSL_SUCCESS;
374 static const HklFunction constant_incidence_func = {
375 .function = _constant_incidence_func,
376 .size = 5,
379 /*******/
380 /* K6C */
381 /*******/
383 /************/
384 /* hkl mode */
385 /************/
387 static HklMode *bissector_vertical(void)
389 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
390 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
391 static const HklFunction *functions[] = {&bissector_v};
392 static const HklModeAutoInfo info = {
393 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
396 return hkl_mode_auto_new(&info,
397 &hkl_mode_operations,
398 TRUE);
401 static HklMode *constant_omega_vertical(void)
403 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
404 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
405 static const HklFunction *functions[] = {&constant_omega_v};
406 static const HklModeAutoInfo info = {
407 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
408 functions, constant_omega_parameters),
411 return hkl_mode_auto_new(&info,
412 &hkl_mode_operations,
413 TRUE);
416 static HklMode *constant_chi_vertical(void)
418 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
419 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
420 static const HklFunction *functions[] = {&constant_chi_v};
421 static const HklModeAutoInfo info = {
422 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
423 functions, constant_chi_parameters),
426 return hkl_mode_auto_new(&info,
427 &hkl_mode_operations,
428 TRUE);
431 static HklMode *constant_phi_vertical(void)
433 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
434 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
435 static const HklFunction *functions[] = {&constant_phi_v};
436 static const HklModeAutoInfo info = {
437 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
438 functions, constant_phi_parameters),
441 return hkl_mode_auto_new(&info,
442 &hkl_mode_operations,
443 TRUE);
446 static HklMode *lifting_detector_kphi(void)
448 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
449 static const char* axes_w[] = {KPHI, GAMMA, DELTA};
450 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
451 static const HklModeAutoInfo info = {
452 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
455 return hkl_mode_auto_new(&info,
456 &hkl_mode_operations,
457 TRUE);
460 static HklMode *lifting_detector_komega(void)
462 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
463 static const char* axes_w[] = {KOMEGA, GAMMA, DELTA};
464 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
465 static const HklModeAutoInfo info = {
466 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
469 return hkl_mode_auto_new(&info,
470 &hkl_mode_operations,
471 TRUE);
474 static HklMode *lifting_detector_mu(void)
476 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
477 static const char* axes_w[] = {MU, GAMMA, DELTA};
478 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
479 static const HklModeAutoInfo info = {
480 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
483 return hkl_mode_auto_new(&info,
484 &hkl_mode_operations,
485 TRUE);
488 static HklMode *double_diffraction_vertical(void)
490 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
491 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
492 static const HklFunction *functions[] = {&double_diffraction_func};
493 static const HklModeAutoInfo info = {
494 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
495 functions, double_diffraction_parameters),
498 return hkl_mode_auto_new(&info,
499 &hkl_mode_operations,
500 TRUE);
503 static HklMode *bissector_horizontal(void)
505 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
506 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA};
507 static const HklFunction *functions[] = {&bissector_h_f1, &bissector_h_f2};
508 static const HklModeAutoInfo info = {
509 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
512 return hkl_mode_auto_new(&info,
513 &hkl_mode_operations,
514 TRUE);
517 static HklMode *constant_phi_horizontal(void)
519 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
520 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA};
521 static const HklFunction *functions[] = {&constant_phi_h_f1, &constant_phi_h_f2};
522 static const HklModeAutoInfo info = {
523 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
524 functions, constant_phi_parameters),
527 return hkl_mode_auto_new(&info,
528 &hkl_mode_operations,
529 TRUE);
532 static HklMode *constant_kphi_horizontal(void)
534 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
535 static const char* axes_w[] = {MU, KOMEGA, KAPPA, GAMMA};
536 static const HklFunction *functions[] = {&constant_kphi_h_f1, &constant_kphi_h_f2};
537 static const HklModeAutoInfo info = {
538 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
541 return hkl_mode_auto_new(&info,
542 &hkl_mode_operations,
543 TRUE);
546 static HklMode *double_diffraction_horizontal(void)
548 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
549 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA};
550 static const HklFunction *functions[] = {&double_diffraction_h};
551 static const HklModeAutoInfo info = {
552 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
553 functions, double_diffraction_parameters),
556 return hkl_mode_auto_new(&info,
557 &hkl_mode_operations,
558 TRUE);
561 static HklMode *psi_constant_vertical(void)
563 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
564 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
565 static const HklFunction *functions[] = {&psi_constant_vertical_func};
566 static const HklModeAutoInfo info = {
567 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
568 functions, psi_constant_parameters),
571 return hkl_mode_auto_new(&info,
572 &psi_constant_vertical_mode_operations,
573 TRUE);
576 static HklMode *constant_incidence(void)
578 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
579 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
580 static const HklFunction *functions[] = {&constant_incidence_func};
581 static const HklModeAutoInfo info = {
582 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
583 functions, constant_incidence_parameters),
586 return hkl_mode_auto_with_init_new(&info,
587 &constant_incidence_mode_operations,
588 TRUE);
591 static HklEngine *hkl_engine_k6c_hkl_new(HklEngineList *engines)
593 HklEngine *self;
594 HklMode *default_mode;
596 self = hkl_engine_hkl_new(engines);
598 default_mode = bissector_vertical();
599 hkl_engine_add_mode(self, default_mode);
600 hkl_engine_mode_set(self, default_mode);
602 hkl_engine_add_mode(self, constant_omega_vertical());
603 hkl_engine_add_mode(self, constant_chi_vertical());
604 hkl_engine_add_mode(self, constant_phi_vertical());
605 hkl_engine_add_mode(self, lifting_detector_kphi());
606 hkl_engine_add_mode(self, lifting_detector_komega());
607 hkl_engine_add_mode(self, lifting_detector_mu());
608 hkl_engine_add_mode(self, double_diffraction_vertical());
609 hkl_engine_add_mode(self, bissector_horizontal());
610 hkl_engine_add_mode(self, constant_phi_horizontal());
611 hkl_engine_add_mode(self, constant_kphi_horizontal());
612 hkl_engine_add_mode(self, double_diffraction_horizontal());
613 hkl_engine_add_mode(self, psi_constant_vertical());
614 hkl_engine_add_mode(self, constant_incidence());
616 return self;
619 /************/
620 /* psi mode */
621 /************/
623 static HklMode *psi_vertical(void)
625 static const char *axes_r[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
626 static const char *axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA};
627 static const HklFunction *functions[] = {&psi_func};
628 static const HklModeAutoInfo info = {
629 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
630 functions, psi_parameters),
633 return hkl_mode_psi_new(&info);
636 static HklEngine *hkl_engine_k6c_psi_new(HklEngineList *engines)
638 HklEngine *self;
639 HklMode *default_mode;
641 self = hkl_engine_psi_new(engines);
643 default_mode = psi_vertical();
644 hkl_engine_add_mode(self, default_mode);
645 hkl_engine_mode_set(self, default_mode);
647 return self;
650 /*****************/
651 /* mode readonly */
652 /*****************/
654 REGISTER_READONLY_INCIDENCE(hkl_engine_k6c_incidence_new,
655 P99_PROTECT({MU, KOMEGA, KAPPA, KPHI}),
656 surface_parameters_y);
658 REGISTER_READONLY_EMERGENCE(hkl_engine_k6c_emergence_new,
659 P99_PROTECT({MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA}),
660 surface_parameters_y);
662 #define HKL_GEOMETRY_KAPPA6C_DESCRIPTION \
663 "For this geometry there is a special parameters called :math:`\\alpha` which is the\n" \
664 "angle between the kappa rotation axis and the :math:`\\vec{y}` direction.\n" \
665 "\n" \
666 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
667 "+ 4 axes for the sample\n" \
668 "\n" \
669 " + **mu** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
670 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
671 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
672 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
673 "\n" \
674 "+ 2 axes for the detector\n" \
675 "\n" \
676 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
677 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
679 static const char* hkl_geometry_kappa6C_axes[] = {MU, KOMEGA, KAPPA, KPHI, GAMMA, DELTA};
681 static HklGeometry *hkl_geometry_new_kappa6C(const HklFactory *factory)
683 HklGeometry *self = hkl_geometry_new(factory);
684 double alpha = 50 * HKL_DEGTORAD;
685 HklHolder *h;
687 h = hkl_geometry_add_holder(self);
688 hkl_holder_add_rotation_axis(h, MU, 0, 0, 1);
689 hkl_holder_add_rotation_axis(h, KOMEGA, 0, -1, 0);
690 hkl_holder_add_rotation_axis(h, KAPPA, 0, -cos(alpha), -sin(alpha));
691 hkl_holder_add_rotation_axis(h, KPHI, 0, -1, 0);
693 h = hkl_geometry_add_holder(self);
694 hkl_holder_add_rotation_axis(h, GAMMA, 0, 0, 1);
695 hkl_holder_add_rotation_axis(h, DELTA, 0, -1, 0);
697 return self;
700 static HklEngineList *hkl_engine_list_new_kappa6C(const HklFactory *factory)
702 HklEngineList *self = hkl_engine_list_new();
704 self->geometries->multiply = hkl_geometry_list_multiply_k6c_real;
705 hkl_engine_k6c_hkl_new(self);
706 hkl_engine_eulerians_new(self);
707 hkl_engine_k6c_psi_new(self);
708 hkl_engine_q2_new(self);
709 hkl_engine_qper_qpar_new(self);
710 hkl_engine_k6c_incidence_new(self);
711 hkl_engine_tth2_new(self);
712 hkl_engine_k6c_emergence_new(self);
714 return self;
717 REGISTER_DIFFRACTOMETER(kappa6C, "K6C", HKL_GEOMETRY_KAPPA6C_DESCRIPTION);
719 /***********************/
720 /* SOLEIL sirius kappa */
721 /***********************/
723 /* hkl mode */
725 static HklMode *bissector_vertical_soleil_sirius_kappa(void)
727 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
728 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
729 static const HklFunction *functions[] = {&bissector_v};
730 static const HklModeAutoInfo info = {
731 HKL_MODE_AUTO_INFO("bissector_vertical", axes_r, axes_w, functions),
734 return hkl_mode_auto_new(&info,
735 &hkl_mode_operations,
736 TRUE);
739 static HklMode *constant_omega_vertical_soleil_sirius_kappa(void)
741 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
742 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
743 static const HklFunction *functions[] = {&constant_omega_v};
744 static const HklModeAutoInfo info = {
745 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_omega_vertical", axes_r, axes_w,
746 functions, constant_omega_parameters),
749 return hkl_mode_auto_new(&info,
750 &hkl_mode_operations,
751 TRUE);
754 static HklMode *constant_chi_vertical_soleil_sirius_kappa(void)
756 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
757 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
758 static const HklFunction *functions[] = {&constant_chi_v};
759 static const HklModeAutoInfo info = {
760 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_chi_vertical", axes_r, axes_w,
761 functions, constant_chi_parameters),
764 return hkl_mode_auto_new(&info,
765 &hkl_mode_operations,
766 TRUE);
769 static HklMode *constant_phi_vertical_soleil_sirius_kappa(void)
771 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
772 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
773 static const HklFunction *functions[] = {&constant_phi_v};
774 static const HklModeAutoInfo info = {
775 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_vertical", axes_r, axes_w,
776 functions, constant_phi_parameters),
779 return hkl_mode_auto_new(&info,
780 &hkl_mode_operations,
781 TRUE);
784 static HklMode *lifting_detector_kphi_soleil_sirius_kappa(void)
786 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
787 static const char* axes_w[] = {KPHI, DELTA, GAMMA};
788 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
789 static const HklModeAutoInfo info = {
790 HKL_MODE_AUTO_INFO("lifting_detector_kphi", axes_r, axes_w, functions),
793 return hkl_mode_auto_new(&info,
794 &hkl_mode_operations,
795 TRUE);
798 static HklMode *lifting_detector_komega_soleil_sirius_kappa(void)
800 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
801 static const char* axes_w[] = {KOMEGA, DELTA, GAMMA};
802 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
803 static const HklModeAutoInfo info = {
804 HKL_MODE_AUTO_INFO("lifting_detector_komega", axes_r, axes_w, functions),
807 return hkl_mode_auto_new(&info,
808 &hkl_mode_operations,
809 TRUE);
812 static HklMode *lifting_detector_mu_soleil_sirius_kappa(void)
814 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
815 static const char* axes_w[] = {MU, DELTA, GAMMA};
816 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
817 static const HklModeAutoInfo info = {
818 HKL_MODE_AUTO_INFO("lifting_detector_mu", axes_r, axes_w, functions),
821 return hkl_mode_auto_new(&info,
822 &hkl_mode_operations,
823 TRUE);
826 static HklMode *double_diffraction_vertical_soleil_sirius_kappa(void)
828 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
829 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
830 static const HklFunction *functions[] = {&double_diffraction_func};
831 static const HklModeAutoInfo info = {
832 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_vertical", axes_r, axes_w,
833 functions, double_diffraction_parameters),
836 return hkl_mode_auto_new(&info,
837 &hkl_mode_operations,
838 TRUE);
841 static HklMode *bissector_horizontal_soleil_sirius_kappa(void)
843 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
844 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, DELTA};
845 static const HklFunction *functions[] = {&bissector_h_f1, &bissector_h_f2};
846 static const HklModeAutoInfo info = {
847 HKL_MODE_AUTO_INFO("bissector_horizontal", axes_r, axes_w, functions),
850 return hkl_mode_auto_new(&info,
851 &hkl_mode_operations,
852 TRUE);
855 static HklMode *constant_phi_horizontal_soleil_sirius_kappa(void)
857 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
858 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, DELTA};
859 static const HklFunction *functions[] = {&constant_phi_h_f1, &constant_phi_h_f2};
860 static const HklModeAutoInfo info = {
861 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_horizontal", axes_r, axes_w,
862 functions, constant_phi_parameters),
865 return hkl_mode_auto_new(&info,
866 &hkl_mode_operations,
867 TRUE);
870 static HklMode *constant_kphi_horizontal_soleil_sirius_kappa(void)
872 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
873 static const char* axes_w[] = {MU, KOMEGA, KAPPA, DELTA};
874 static const HklFunction *functions[] = {&constant_kphi_h_f1, &constant_kphi_h_f2};
875 static const HklModeAutoInfo info = {
876 HKL_MODE_AUTO_INFO("constant_kphi_horizontal", axes_r, axes_w, functions),
879 return hkl_mode_auto_new(&info,
880 &hkl_mode_operations,
881 TRUE);
884 static HklMode *double_diffraction_horizontal_soleil_sirius_kappa(void)
886 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
887 static const char* axes_w[] = {MU, KOMEGA, KAPPA, KPHI, DELTA};
888 static const HklFunction *functions[] = {&double_diffraction_h};
889 static const HklModeAutoInfo info = {
890 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_horizontal", axes_r, axes_w,
891 functions, double_diffraction_parameters),
894 return hkl_mode_auto_new(&info,
895 &hkl_mode_operations,
896 TRUE);
899 static HklMode *psi_constant_vertical_soleil_sirius_kappa(void)
901 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
902 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
903 static const HklFunction *functions[] = {&psi_constant_vertical_func};
904 static const HklModeAutoInfo info = {
905 HKL_MODE_AUTO_INFO_WITH_PARAMS("psi_constant_vertical", axes_r, axes_w,
906 functions, psi_constant_parameters),
909 return hkl_mode_auto_new(&info,
910 &psi_constant_vertical_mode_operations,
911 TRUE);
914 static HklMode *constant_incidence_soleil_sirius_kappa(void)
916 static const char* axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
917 static const char* axes_w[] = {KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
918 static const HklFunction *functions[] = {&constant_incidence_func};
919 static const HklModeAutoInfo info = {
920 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_incidence", axes_r, axes_w,
921 functions, constant_incidence_parameters),
924 return hkl_mode_auto_with_init_new(&info,
925 &constant_incidence_mode_operations,
926 TRUE);
929 static HklEngine *hkl_engine_soleil_sirius_kappa_hkl_new(HklEngineList *engines)
931 HklEngine *self;
932 HklMode *default_mode;
934 self = hkl_engine_hkl_new(engines);
936 default_mode = bissector_vertical_soleil_sirius_kappa();
937 hkl_engine_add_mode(self, default_mode);
938 hkl_engine_mode_set(self, default_mode);
940 hkl_engine_add_mode(self, constant_omega_vertical_soleil_sirius_kappa());
941 hkl_engine_add_mode(self, constant_chi_vertical_soleil_sirius_kappa());
942 hkl_engine_add_mode(self, constant_phi_vertical_soleil_sirius_kappa());
943 hkl_engine_add_mode(self, lifting_detector_kphi_soleil_sirius_kappa());
944 hkl_engine_add_mode(self, lifting_detector_komega_soleil_sirius_kappa());
945 hkl_engine_add_mode(self, lifting_detector_mu_soleil_sirius_kappa());
946 hkl_engine_add_mode(self, double_diffraction_vertical_soleil_sirius_kappa());
947 hkl_engine_add_mode(self, bissector_horizontal_soleil_sirius_kappa());
948 hkl_engine_add_mode(self, constant_phi_horizontal_soleil_sirius_kappa());
949 hkl_engine_add_mode(self, constant_kphi_horizontal_soleil_sirius_kappa());
950 hkl_engine_add_mode(self, double_diffraction_horizontal_soleil_sirius_kappa());
951 hkl_engine_add_mode(self, psi_constant_vertical_soleil_sirius_kappa());
952 hkl_engine_add_mode(self, constant_incidence_soleil_sirius_kappa());
954 return self;
957 /* psi mode */
959 static HklMode *psi_vertical_soleil_sirius_kappa()
961 static const char *axes_r[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
962 static const char *axes_w[] = {KOMEGA, KAPPA, KPHI, GAMMA};
963 static const HklFunction *functions[] = {&psi_func};
964 static const HklModeAutoInfo info = {
965 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
966 functions, psi_parameters),
969 return hkl_mode_psi_new(&info);
972 static HklEngine *hkl_engine_soleil_sirius_kappa_psi_new(HklEngineList *engines)
974 HklEngine *self;
975 HklMode *default_mode;
977 self = hkl_engine_psi_new(engines);
979 default_mode = psi_vertical_soleil_sirius_kappa();
980 hkl_engine_add_mode(self, default_mode);
981 hkl_engine_mode_set(self, default_mode);
983 return self;
986 /* SOLEIL SIRIUS KAPPA */
988 #define HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION \
989 "+ xrays source fix along the :math:`\\vec{x}` direction (1, 0, 0)\n" \
990 "+ 4 axes for the sample\n" \
991 "\n" \
992 " + **" MU "** : rotating around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
993 " + **" KOMEGA "** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
994 " + **" KAPPA "** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
995 " + **" KPHI "** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
996 "\n" \
997 "+ 2 axes for the detector\n" \
998 "\n" \
999 " + **" DELTA "** : rotation around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
1000 " + **" GAMMA "** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
1002 static const char* hkl_geometry_soleil_sirius_kappa_axes[] = {MU, KOMEGA, KAPPA, KPHI, DELTA, GAMMA};
1004 static HklGeometry *hkl_geometry_new_soleil_sirius_kappa(const HklFactory *factory)
1006 HklGeometry *self = hkl_geometry_new(factory);
1007 double alpha = 50 * HKL_DEGTORAD;
1008 HklHolder *h;
1010 h = hkl_geometry_add_holder(self);
1011 hkl_holder_add_rotation_axis(h, MU, 0, 0, -1);
1012 hkl_holder_add_rotation_axis(h, KOMEGA, 0, -1, 0);
1013 hkl_holder_add_rotation_axis(h, KAPPA, 0, -cos(alpha), -sin(alpha));
1014 hkl_holder_add_rotation_axis(h, KPHI, 0, -1, 0);
1016 h = hkl_geometry_add_holder(self);
1017 hkl_holder_add_rotation_axis(h, DELTA, 0, 0, -1);
1018 hkl_holder_add_rotation_axis(h, GAMMA, 0, -1, 0);
1020 return self;
1023 static HklEngineList *hkl_engine_list_new_soleil_sirius_kappa(const HklFactory *factory)
1025 HklEngineList *self = hkl_engine_list_new();
1027 self->geometries->multiply = hkl_geometry_list_multiply_k6c_real;
1028 hkl_engine_soleil_sirius_kappa_hkl_new(self);
1029 hkl_engine_eulerians_new(self);
1030 hkl_engine_soleil_sirius_kappa_psi_new(self);
1031 hkl_engine_q2_new(self);
1032 hkl_engine_qper_qpar_new(self);
1033 hkl_engine_tth2_new(self);
1034 hkl_engine_k6c_incidence_new(self);
1035 hkl_engine_k6c_emergence_new(self);
1037 return self;
1040 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION);