[contrib] use (*~~) and (/~~) instead of from/toAngles
[hkl.git] / hkl / hkl-engine-k6c.c
blobf99b095230927e2e99b4f1cf12b41aba6bdeb1a6
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 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,
400 TRUE);
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,
415 TRUE);
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,
430 TRUE);
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,
444 TRUE);
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,
458 TRUE);
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,
472 TRUE);
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,
487 TRUE);
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,
501 TRUE);
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,
516 TRUE);
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,
530 TRUE);
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,
545 TRUE);
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,
560 TRUE);
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,
575 TRUE);
578 /**********************/
579 /* pseudo axis engine */
580 /**********************/
582 static HklEngine *hkl_engine_k6c_hkl_new(void)
584 HklEngine *self;
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());
607 return self;
610 /***********************/
611 /* SOLEIL sirius kappa */
612 /***********************/
614 /* mode */
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,
627 TRUE);
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,
642 TRUE);
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,
657 TRUE);
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,
672 TRUE);
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,
686 TRUE);
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,
700 TRUE);
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,
714 TRUE);
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,
729 TRUE);
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,
743 TRUE);
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,
758 TRUE);
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,
772 TRUE);
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,
787 TRUE);
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,
802 TRUE);
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,
817 TRUE);
820 static HklEngine *hkl_engine_soleil_sirius_kappa_hkl_new(void)
822 HklEngine *self;
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());
845 return self;
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)
863 HklEngine *self;
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);
872 return self;
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)
894 HklEngine *self;
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);
903 return self;
906 /*******/
907 /* K6C */
908 /*******/
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" \
913 "\n" \
914 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
915 "+ 4 axes for the sample\n" \
916 "\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" \
921 "\n" \
922 "+ 2 axes for the detector\n" \
923 "\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;
933 HklHolder *h;
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);
945 return self;
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());
959 return self;
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" \
971 "\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" \
976 "\n" \
977 "+ 2 axes for the detector\n" \
978 "\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;
988 HklHolder *h;
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);
1000 return self;
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());
1014 return self;
1017 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION);