[hkl] factorize the psi_parameters for the psi engine.
[hkl.git] / hkl / hkl-engine-k6c.c
blobbcda99fb1cd5ab159f389d9ad859c28679d01e5c
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;
33 HklGeometry *copy;
34 double komega, komegap;
35 double kappa, kappap;
36 double kphi, kphip;
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];
67 double omega;
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);
77 return GSL_SUCCESS;
80 static const HklFunction bissector_h_f1 = {
81 .function = _bissector_h_f1,
82 .size = 5,
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];
91 double omega;
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);
102 return GSL_SUCCESS;
105 static const HklFunction bissector_h_f2 = {
106 .function = _bissector_h_f2,
107 .size = 5,
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];
114 double omega;
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);
123 return GSL_SUCCESS;
126 static const HklFunction constant_kphi_h_f1 = {
127 .function = _constant_kphi_h_f1,
128 .size = 4,
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];
135 double omega;
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);
144 return GSL_SUCCESS;
147 static const HklFunction constant_kphi_h_f2 = {
148 .function = _constant_kphi_h_f2,
149 .size = 4,
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);
167 f->data[4] = phi;
169 return GSL_SUCCESS;
172 static const HklFunction constant_phi_h_f1 = {
173 .function = _constant_phi_h_f1,
174 .size = 5,
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);
192 f->data[4] = phi;
194 return GSL_SUCCESS;
197 static const HklFunction constant_phi_h_f2 = {
198 .function = _constant_phi_h_f2,
199 .size = 5,
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];
207 double omega;
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);
216 return GSL_SUCCESS;
219 static const HklFunction bissector_v = {
220 .function = _bissector_v,
221 .size = 4,
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];
228 double omega;
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;
239 return GSL_SUCCESS;
242 static const HklFunction constant_omega_v = {
243 .function = _constant_omega_v,
244 .size = 4,
247 static int _constant_chi_v(const gsl_vector *x, void *params, gsl_vector *f)
249 const double kappa = x->data[1];
250 double chi;
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;
261 return GSL_SUCCESS;
264 static const HklFunction constant_chi_v = {
265 .function = _constant_chi_v,
266 .size = 4,
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];
273 double phi;
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;
284 return GSL_SUCCESS;
287 static const HklFunction constant_phi_v = {
288 .function = _constant_phi_v,
289 .size = 4,
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];
296 double omega;
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);
305 return GSL_SUCCESS;
308 static const HklFunction double_diffraction_h = {
309 .function = _double_diffraction_h,
310 .size = 5,
313 static int _constant_incidence_func(const gsl_vector *x, void *params, gsl_vector *f)
315 static const HklVector Y = {
316 .data = {0, 1, 0},
318 double incidence;
319 double azimuth;
320 HklEngine *engine = params;
321 HklModeAutoWithInit *mode = container_of(engine->mode, HklModeAutoWithInit, mode);
322 HklVector n;
323 double incidence0;
324 double azimuth0;
325 HklVector ki;
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 */
344 if(mode->geometry){
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;
362 return GSL_SUCCESS;
365 static const HklFunction constant_incidence_func = {
366 .function = _constant_incidence_func,
367 .size = 5,
370 /********/
371 /* mode */
372 /********/
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,
385 TRUE);
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,
402 TRUE);
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,
419 TRUE);
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,
436 TRUE);
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,
450 TRUE);
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,
464 TRUE);
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,
478 TRUE);
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,
493 TRUE);
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,
507 TRUE);
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,
524 TRUE);
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,
538 TRUE);
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,
553 TRUE);
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,
568 TRUE);
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,
589 TRUE);
592 /**********************/
593 /* pseudo axis engine */
594 /**********************/
596 static HklEngine *hkl_engine_k6c_hkl_new(void)
598 HklEngine *self;
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());
621 return self;
624 /***********************/
625 /* SOLEIL sirius kappa */
626 /***********************/
628 /* mode */
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,
641 TRUE);
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,
658 TRUE);
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,
675 TRUE);
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,
692 TRUE);
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,
706 TRUE);
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,
720 TRUE);
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,
734 TRUE);
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,
749 TRUE);
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,
763 TRUE);
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,
780 TRUE);
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,
794 TRUE);
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,
809 TRUE);
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,
824 TRUE);
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,
845 TRUE);
848 static HklEngine *hkl_engine_soleil_sirius_kappa_hkl_new(void)
850 HklEngine *self;
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());
873 return self;
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)
891 HklEngine *self;
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);
900 return self;
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)
922 HklEngine *self;
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);
931 return self;
934 /*******/
935 /* K6C */
936 /*******/
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" \
941 "\n" \
942 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
943 "+ 4 axes for the sample\n" \
944 "\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" \
949 "\n" \
950 "+ 2 axes for the detector\n" \
951 "\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;
961 HklHolder *h;
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);
973 return self;
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());
987 return self;
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" \
999 "\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" \
1004 "\n" \
1005 "+ 2 axes for the detector\n" \
1006 "\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;
1016 HklHolder *h;
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);
1028 return self;
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());
1042 return self;
1045 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION);