[hkl] no more hkl_engine_list_add method
[hkl.git] / hkl / hkl-engine-k6c.c
blob224a4d7a0ba04b3c5d1069d27b7aca3c6873d98e
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-2015 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-tth-private.h" // for hkl_engine_tth2_new, etc
30 static void hkl_geometry_list_multiply_k6c_real(HklGeometryList *self,
31 HklGeometryListItem *item)
33 HklGeometry *geometry;
34 HklGeometry *copy;
35 double komega, komegap;
36 double kappa, kappap;
37 double kphi, kphip;
39 geometry = item->geometry;
40 komega = hkl_parameter_value_get(darray_item(geometry->axes, 1), HKL_UNIT_DEFAULT);
41 kappa = hkl_parameter_value_get(darray_item(geometry->axes, 2), HKL_UNIT_DEFAULT);
42 kphi = hkl_parameter_value_get(darray_item(geometry->axes, 3), HKL_UNIT_DEFAULT);
44 kappa_2_kappap(komega, kappa, kphi, 50 * HKL_DEGTORAD, &komegap, &kappap, &kphip);
46 copy = hkl_geometry_new_copy(geometry);
47 /* TODO parameter list for the geometry */
48 hkl_parameter_value_set(darray_item(copy->axes, 1), komegap, HKL_UNIT_DEFAULT, NULL);
49 hkl_parameter_value_set(darray_item(copy->axes, 2), kappap, HKL_UNIT_DEFAULT, NULL);
50 hkl_parameter_value_set(darray_item(copy->axes, 3), kphip, HKL_UNIT_DEFAULT, NULL);
52 hkl_geometry_update(copy);
53 hkl_geometry_list_add(self, copy);
54 hkl_geometry_free(copy);
58 /***********************/
59 /* numerical functions */
60 /***********************/
62 static int _bissector_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
64 const double mu = x->data[0];
65 const double komega = x->data[1];
66 const double kappa = x->data[2];
67 const double gamma = x->data[4];
68 double omega;
70 CHECK_NAN(x->data, x->size);
72 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
74 RUBh_minus_Q(x->data, params, f->data);
75 f->data[3] = fmod(omega, M_PI);
76 f->data[4] = fmod(gamma - 2 * fmod(mu, M_PI), 2*M_PI);
78 return GSL_SUCCESS;
81 static const HklFunction bissector_h_f1 = {
82 .function = _bissector_h_f1,
83 .size = 5,
86 static int _bissector_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
88 const double mu = x->data[0];
89 const double komega = x->data[1];
90 const double kappa = x->data[2];
91 const double gamma = x->data[4];
92 double omega;
94 CHECK_NAN(x->data, x->size);
96 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
98 RUBh_minus_Q(x->data, params, f->data);
99 f->data[3] = fmod(omega, M_PI);
100 f->data[4] = fmod(gamma - 2 * fmod(mu, M_PI), 2*M_PI);
103 return GSL_SUCCESS;
106 static const HklFunction bissector_h_f2 = {
107 .function = _bissector_h_f2,
108 .size = 5,
111 static int _constant_kphi_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
113 const double komega = x->data[1];
114 const double kappa = x->data[2];
115 double omega;
117 CHECK_NAN(x->data, x->size);
119 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
121 RUBh_minus_Q(x->data, params, f->data);
122 f->data[3] = fmod(omega, M_PI);
124 return GSL_SUCCESS;
127 static const HklFunction constant_kphi_h_f1 = {
128 .function = _constant_kphi_h_f1,
129 .size = 4,
132 static int _constant_kphi_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
134 const double komega = x->data[1];
135 const double kappa = x->data[2];
136 double omega;
138 CHECK_NAN(x->data, x->size);
140 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
142 RUBh_minus_Q(x->data, params, f->data);
143 f->data[3] = fmod(omega, M_PI);
145 return GSL_SUCCESS;
148 static const HklFunction constant_kphi_h_f2 = {
149 .function = _constant_kphi_h_f2,
150 .size = 4,
153 static int _constant_phi_h_f1(const gsl_vector *x, void *params, gsl_vector *f)
155 const double komega = x->data[1];
156 const double kappa = x->data[2];
157 const double kphi = x->data[3];
158 double omega, phi, p;
160 CHECK_NAN(x->data, x->size);
162 p = atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD));
163 omega = komega + p - M_PI_2;
164 phi = kphi + p + M_PI_2;
166 RUBh_minus_Q(x->data, params, f->data);
167 f->data[3] = fmod(omega, M_PI);
168 f->data[4] = phi;
170 return GSL_SUCCESS;
173 static const HklFunction constant_phi_h_f1 = {
174 .function = _constant_phi_h_f1,
175 .size = 5,
178 static int _constant_phi_h_f2(const gsl_vector *x, void *params, gsl_vector *f)
180 const double komega = x->data[1];
181 const double kappa = x->data[2];
182 const double kphi = x->data[3];
183 double omega, phi, p;
185 CHECK_NAN(x->data, x->size);
187 p = atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD));
188 omega = komega + p + M_PI_2;
189 phi = kphi + p - M_PI_2;
191 RUBh_minus_Q(x->data, params, f->data);
192 f->data[3] = fmod(omega, M_PI);
193 f->data[4] = phi;
195 return GSL_SUCCESS;
198 static const HklFunction constant_phi_h_f2 = {
199 .function = _constant_phi_h_f2,
200 .size = 5,
203 static int _bissector_v(const gsl_vector *x, void *params, gsl_vector *f)
205 const double komega = x->data[0];
206 const double kappa = x->data[1];
207 const double delta = x->data[3];
208 double omega;
210 CHECK_NAN(x->data, x->size);
212 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
214 RUBh_minus_Q(x->data, params, f->data);
215 f->data[3] = fmod(delta - 2 * fmod(omega, M_PI), 2*M_PI);
217 return GSL_SUCCESS;
220 static const HklFunction bissector_v = {
221 .function = _bissector_v,
222 .size = 4,
225 static int _constant_omega_v(const gsl_vector *x, void *params, gsl_vector *f)
227 const double komega = x->data[0];
228 const double kappa = x->data[1];
229 double omega;
230 HklEngine *engine = params;
231 double omega0 = darray_item(engine->mode->parameters, 0)->_value;
233 CHECK_NAN(x->data, x->size);
235 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
237 RUBh_minus_Q(x->data, params, f->data);
238 f->data[3] = omega0 - omega;
240 return GSL_SUCCESS;
243 static const HklFunction constant_omega_v = {
244 .function = _constant_omega_v,
245 .size = 4,
248 static int _constant_chi_v(const gsl_vector *x, void *params, gsl_vector *f)
250 const double kappa = x->data[1];
251 double chi;
252 HklEngine *engine = params;
253 double chi0 = darray_item(engine->mode->parameters, 0)->_value;
255 CHECK_NAN(x->data, x->size);
257 chi = 2 * asin(sin(kappa/2.) * sin(50 * HKL_DEGTORAD));
259 RUBh_minus_Q(x->data, params, f->data);
260 f->data[3] = chi0 - chi;
262 return GSL_SUCCESS;
265 static const HklFunction constant_chi_v = {
266 .function = _constant_chi_v,
267 .size = 4,
270 static int _constant_phi_v(const gsl_vector *x, void *params, gsl_vector *f)
272 const double kappa = x->data[1];
273 const double kphi = x->data[2];
274 double phi;
275 HklEngine *engine = params;
276 double phi0 = darray_item(engine->mode->parameters, 0)->_value;
278 CHECK_NAN(x->data, x->size);
280 phi = kphi + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
282 RUBh_minus_Q(x->data, params, f->data);
283 f->data[3] = phi0 - phi;
285 return GSL_SUCCESS;
288 static const HklFunction constant_phi_v = {
289 .function = _constant_phi_v,
290 .size = 4,
293 static int _double_diffraction_h(const gsl_vector *x, void *params, gsl_vector *f)
295 const double komega = x->data[1];
296 const double kappa = x->data[2];
297 double omega;
299 CHECK_NAN(x->data, x->size);
301 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
303 _double_diffraction(x->data, params, f->data);
304 f->data[4] = fmod(omega, M_PI);
306 return GSL_SUCCESS;
309 static const HklFunction double_diffraction_h = {
310 .function = _double_diffraction_h,
311 .size = 5,
314 static int _constant_incidence_func(const gsl_vector *x, void *params, gsl_vector *f)
316 static const HklVector Y = {
317 .data = {0, 1, 0},
319 double incidence;
320 double azimuth;
321 HklEngine *engine = params;
322 HklModeAutoWithInit *mode = container_of(engine->mode, HklModeAutoWithInit, mode);
323 HklVector n;
324 double incidence0;
325 double azimuth0;
326 HklVector ki;
328 CHECK_NAN(x->data, x->size);
330 RUBh_minus_Q(x->data, params, f->data);
332 /* get the mode parameters */
333 n.data[0] = darray_item(engine->mode->parameters, 0)->_value;
334 n.data[1] = darray_item(engine->mode->parameters, 1)->_value;
335 n.data[2] = darray_item(engine->mode->parameters, 2)->_value;
336 incidence0 = darray_item(engine->mode->parameters, 3)->_value;
337 azimuth0 = darray_item(engine->mode->parameters, 4)->_value;
339 /* compute the two angles */
342 /* first check that the mode was already initialized if not
343 * the surface is oriented along the nx, ny, nz axis for all
344 * diffractometer angles equal to zero */
345 if(mode->geometry){
346 HklQuaternion q0 = darray_item(mode->geometry->holders, 0)->q;
348 hkl_quaternion_conjugate(&q0);
349 hkl_vector_rotated_quaternion(&n, &q0);
352 hkl_vector_rotated_quaternion(&n, &darray_item(engine->geometry->holders, 0)->q);
354 hkl_source_compute_ki(&engine->geometry->source, &ki);
355 incidence = M_PI_2 - hkl_vector_angle(&n, &ki);
357 hkl_vector_project_on_plan(&n, &ki);
358 azimuth = hkl_vector_angle(&n, &Y);
360 f->data[3] = incidence0 - incidence;
361 f->data[4] = azimuth0 - azimuth;
363 return GSL_SUCCESS;
366 static const HklFunction constant_incidence_func = {
367 .function = _constant_incidence_func,
368 .size = 5,
371 /********/
372 /* mode */
373 /********/
375 static HklMode *bissector_vertical(void)
377 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
378 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
379 static const HklFunction *functions[] = {&bissector_v};
380 static const HklModeAutoInfo info = {
381 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
384 return hkl_mode_auto_new(&info,
385 &hkl_mode_operations,
386 TRUE);
389 static HklMode *constant_omega_vertical(void)
391 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
392 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
393 static const HklFunction *functions[] = {&constant_omega_v};
394 static const HklModeAutoInfo info = {
395 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
396 functions, constant_omega_parameters),
399 return hkl_mode_auto_new(&info,
400 &hkl_mode_operations,
401 TRUE);
404 static HklMode *constant_chi_vertical(void)
406 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
407 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
408 static const HklFunction *functions[] = {&constant_chi_v};
409 static const HklModeAutoInfo info = {
410 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
411 functions, constant_chi_parameters),
414 return hkl_mode_auto_new(&info,
415 &hkl_mode_operations,
416 TRUE);
419 static HklMode *constant_phi_vertical(void)
421 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
422 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
423 static const HklFunction *functions[] = {&constant_phi_v};
424 static const HklModeAutoInfo info = {
425 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
426 functions, constant_phi_parameters),
429 return hkl_mode_auto_new(&info,
430 &hkl_mode_operations,
431 TRUE);
434 static HklMode *lifting_detector_kphi(void)
436 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
437 static const char* axes_w[] = {"kphi", "gamma", "delta"};
438 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
439 static const HklModeAutoInfo info = {
440 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
443 return hkl_mode_auto_new(&info,
444 &hkl_mode_operations,
445 TRUE);
448 static HklMode *lifting_detector_komega(void)
450 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
451 static const char* axes_w[] = {"komega", "gamma", "delta"};
452 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
453 static const HklModeAutoInfo info = {
454 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
457 return hkl_mode_auto_new(&info,
458 &hkl_mode_operations,
459 TRUE);
462 static HklMode *lifting_detector_mu(void)
464 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
465 static const char* axes_w[] = {"mu", "gamma", "delta"};
466 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
467 static const HklModeAutoInfo info = {
468 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
471 return hkl_mode_auto_new(&info,
472 &hkl_mode_operations,
473 TRUE);
476 static HklMode *double_diffraction_vertical(void)
478 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
479 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
480 static const HklFunction *functions[] = {&double_diffraction_func};
481 static const HklModeAutoInfo info = {
482 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
483 functions, double_diffraction_parameters),
486 return hkl_mode_auto_new(&info,
487 &hkl_mode_operations,
488 TRUE);
491 static HklMode *bissector_horizontal(void)
493 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
494 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "gamma"};
495 static const HklFunction *functions[] = {&bissector_h_f1, &bissector_h_f2};
496 static const HklModeAutoInfo info = {
497 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
500 return hkl_mode_auto_new(&info,
501 &hkl_mode_operations,
502 TRUE);
505 static HklMode *constant_phi_horizontal(void)
507 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
508 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "gamma"};
509 static const HklFunction *functions[] = {&constant_phi_h_f1, &constant_phi_h_f2};
510 static const HklModeAutoInfo info = {
511 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
512 functions, constant_phi_parameters),
515 return hkl_mode_auto_new(&info,
516 &hkl_mode_operations,
517 TRUE);
520 static HklMode *constant_kphi_horizontal(void)
522 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
523 static const char* axes_w[] = {"mu", "komega", "kappa", "gamma"};
524 static const HklFunction *functions[] = {&constant_kphi_h_f1, &constant_kphi_h_f2};
525 static const HklModeAutoInfo info = {
526 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
529 return hkl_mode_auto_new(&info,
530 &hkl_mode_operations,
531 TRUE);
534 static HklMode *double_diffraction_horizontal(void)
536 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
537 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "gamma"};
538 static const HklFunction *functions[] = {&double_diffraction_h};
539 static const HklModeAutoInfo info = {
540 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
541 functions, double_diffraction_parameters),
544 return hkl_mode_auto_new(&info,
545 &hkl_mode_operations,
546 TRUE);
549 static HklMode *psi_constant_vertical(void)
551 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
552 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta"};
553 static const HklFunction *functions[] = {&psi_constant_vertical_func};
554 static const HklModeAutoInfo info = {
555 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
556 functions, psi_constant_parameters),
559 return hkl_mode_auto_new(&info,
560 &psi_constant_vertical_mode_operations,
561 TRUE);
564 static HklMode *constant_incidence(void)
566 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
567 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma", "delta"};
568 static const HklFunction *functions[] = {&constant_incidence_func};
569 static const HklModeAutoInfo info = {
570 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
571 functions, constant_incidence_parameters),
574 return hkl_mode_auto_with_init_new(&info,
575 &constant_incidence_mode_operations,
576 TRUE);
579 /**********************/
580 /* pseudo axis engine */
581 /**********************/
583 static HklEngine *hkl_engine_k6c_hkl_new(HklEngineList *engines)
585 HklEngine *self;
586 HklMode *default_mode;
588 self = hkl_engine_hkl_new(engines);
590 default_mode = bissector_vertical();
591 hkl_engine_add_mode(self, default_mode);
592 hkl_engine_mode_set(self, default_mode);
594 hkl_engine_add_mode(self, constant_omega_vertical());
595 hkl_engine_add_mode(self, constant_chi_vertical());
596 hkl_engine_add_mode(self, constant_phi_vertical());
597 hkl_engine_add_mode(self, lifting_detector_kphi());
598 hkl_engine_add_mode(self, lifting_detector_komega());
599 hkl_engine_add_mode(self, lifting_detector_mu());
600 hkl_engine_add_mode(self, double_diffraction_vertical());
601 hkl_engine_add_mode(self, bissector_horizontal());
602 hkl_engine_add_mode(self, constant_phi_horizontal());
603 hkl_engine_add_mode(self, constant_kphi_horizontal());
604 hkl_engine_add_mode(self, double_diffraction_horizontal());
605 hkl_engine_add_mode(self, psi_constant_vertical());
606 hkl_engine_add_mode(self, constant_incidence());
608 return self;
611 /***********************/
612 /* SOLEIL sirius kappa */
613 /***********************/
615 /* mode */
617 static HklMode *bissector_vertical_soleil_sirius_kappa(void)
619 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
620 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma"};
621 static const HklFunction *functions[] = {&bissector_v};
622 static const HklModeAutoInfo info = {
623 HKL_MODE_AUTO_INFO("bissector_vertical", axes_r, axes_w, functions),
626 return hkl_mode_auto_new(&info,
627 &hkl_mode_operations,
628 TRUE);
631 static HklMode *constant_omega_vertical_soleil_sirius_kappa(void)
633 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
634 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma"};
635 static const HklFunction *functions[] = {&constant_omega_v};
636 static const HklModeAutoInfo info = {
637 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_omega_vertical", axes_r, axes_w,
638 functions, constant_omega_parameters),
641 return hkl_mode_auto_new(&info,
642 &hkl_mode_operations,
643 TRUE);
646 static HklMode *constant_chi_vertical_soleil_sirius_kappa(void)
648 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
649 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma"};
650 static const HklFunction *functions[] = {&constant_chi_v};
651 static const HklModeAutoInfo info = {
652 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_chi_vertical", axes_r, axes_w,
653 functions, constant_chi_parameters),
656 return hkl_mode_auto_new(&info,
657 &hkl_mode_operations,
658 TRUE);
661 static HklMode *constant_phi_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_phi_v};
666 static const HklModeAutoInfo info = {
667 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_vertical", axes_r, axes_w,
668 functions, constant_phi_parameters),
671 return hkl_mode_auto_new(&info,
672 &hkl_mode_operations,
673 TRUE);
676 static HklMode *lifting_detector_kphi_soleil_sirius_kappa(void)
678 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
679 static const char* axes_w[] = {"kphi", "delta", "gamma"};
680 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
681 static const HklModeAutoInfo info = {
682 HKL_MODE_AUTO_INFO("lifting_detector_kphi", axes_r, axes_w, functions),
685 return hkl_mode_auto_new(&info,
686 &hkl_mode_operations,
687 TRUE);
690 static HklMode *lifting_detector_komega_soleil_sirius_kappa(void)
692 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
693 static const char* axes_w[] = {"komega", "delta", "gamma"};
694 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
695 static const HklModeAutoInfo info = {
696 HKL_MODE_AUTO_INFO("lifting_detector_komega", axes_r, axes_w, functions),
699 return hkl_mode_auto_new(&info,
700 &hkl_mode_operations,
701 TRUE);
704 static HklMode *lifting_detector_mu_soleil_sirius_kappa(void)
706 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
707 static const char* axes_w[] = {"mu", "delta", "gamma"};
708 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
709 static const HklModeAutoInfo info = {
710 HKL_MODE_AUTO_INFO("lifting_detector_mu", axes_r, axes_w, functions),
713 return hkl_mode_auto_new(&info,
714 &hkl_mode_operations,
715 TRUE);
718 static HklMode *double_diffraction_vertical_soleil_sirius_kappa(void)
720 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
721 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma"};
722 static const HklFunction *functions[] = {&double_diffraction_func};
723 static const HklModeAutoInfo info = {
724 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_vertical", axes_r, axes_w,
725 functions, double_diffraction_parameters),
728 return hkl_mode_auto_new(&info,
729 &hkl_mode_operations,
730 TRUE);
733 static HklMode *bissector_horizontal_soleil_sirius_kappa(void)
735 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
736 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "delta"};
737 static const HklFunction *functions[] = {&bissector_h_f1, &bissector_h_f2};
738 static const HklModeAutoInfo info = {
739 HKL_MODE_AUTO_INFO("bissector_horizontal", axes_r, axes_w, functions),
742 return hkl_mode_auto_new(&info,
743 &hkl_mode_operations,
744 TRUE);
747 static HklMode *constant_phi_horizontal_soleil_sirius_kappa(void)
749 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
750 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "delta"};
751 static const HklFunction *functions[] = {&constant_phi_h_f1, &constant_phi_h_f2};
752 static const HklModeAutoInfo info = {
753 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_horizontal", axes_r, axes_w,
754 functions, constant_phi_parameters),
757 return hkl_mode_auto_new(&info,
758 &hkl_mode_operations,
759 TRUE);
762 static HklMode *constant_kphi_horizontal_soleil_sirius_kappa(void)
764 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
765 static const char* axes_w[] = {"mu", "komega", "kappa", "delta"};
766 static const HklFunction *functions[] = {&constant_kphi_h_f1, &constant_kphi_h_f2};
767 static const HklModeAutoInfo info = {
768 HKL_MODE_AUTO_INFO("constant_kphi_horizontal", axes_r, axes_w, functions),
771 return hkl_mode_auto_new(&info,
772 &hkl_mode_operations,
773 TRUE);
776 static HklMode *double_diffraction_horizontal_soleil_sirius_kappa(void)
778 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
779 static const char* axes_w[] = {"mu", "komega", "kappa", "kphi", "delta"};
780 static const HklFunction *functions[] = {&double_diffraction_h};
781 static const HklModeAutoInfo info = {
782 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_horizontal", axes_r, axes_w,
783 functions, double_diffraction_parameters),
786 return hkl_mode_auto_new(&info,
787 &hkl_mode_operations,
788 TRUE);
791 static HklMode *psi_constant_vertical_soleil_sirius_kappa(void)
793 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
794 static const char* axes_w[] = {"komega", "kappa", "kphi", "gamma"};
795 static const HklFunction *functions[] = {&psi_constant_vertical_func};
796 static const HklModeAutoInfo info = {
797 HKL_MODE_AUTO_INFO_WITH_PARAMS("psi_constant_vertical", axes_r, axes_w,
798 functions, psi_constant_parameters),
801 return hkl_mode_auto_new(&info,
802 &psi_constant_vertical_mode_operations,
803 TRUE);
806 static HklMode *constant_incidence_soleil_sirius_kappa(void)
808 static const char* axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
809 static const char* axes_w[] = {"komega", "kappa", "kphi", "delta", "gamma"};
810 static const HklFunction *functions[] = {&constant_incidence_func};
811 static const HklModeAutoInfo info = {
812 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_incidence", axes_r, axes_w,
813 functions, constant_incidence_parameters),
816 return hkl_mode_auto_with_init_new(&info,
817 &constant_incidence_mode_operations,
818 TRUE);
821 static HklEngine *hkl_engine_soleil_sirius_kappa_hkl_new(HklEngineList *engines)
823 HklEngine *self;
824 HklMode *default_mode;
826 self = hkl_engine_hkl_new(engines);
828 default_mode = bissector_vertical_soleil_sirius_kappa();
829 hkl_engine_add_mode(self, default_mode);
830 hkl_engine_mode_set(self, default_mode);
832 hkl_engine_add_mode(self, constant_omega_vertical_soleil_sirius_kappa());
833 hkl_engine_add_mode(self, constant_chi_vertical_soleil_sirius_kappa());
834 hkl_engine_add_mode(self, constant_phi_vertical_soleil_sirius_kappa());
835 hkl_engine_add_mode(self, lifting_detector_kphi_soleil_sirius_kappa());
836 hkl_engine_add_mode(self, lifting_detector_komega_soleil_sirius_kappa());
837 hkl_engine_add_mode(self, lifting_detector_mu_soleil_sirius_kappa());
838 hkl_engine_add_mode(self, double_diffraction_vertical_soleil_sirius_kappa());
839 hkl_engine_add_mode(self, bissector_horizontal_soleil_sirius_kappa());
840 hkl_engine_add_mode(self, constant_phi_horizontal_soleil_sirius_kappa());
841 hkl_engine_add_mode(self, constant_kphi_horizontal_soleil_sirius_kappa());
842 hkl_engine_add_mode(self, double_diffraction_horizontal_soleil_sirius_kappa());
843 hkl_engine_add_mode(self, psi_constant_vertical_soleil_sirius_kappa());
844 hkl_engine_add_mode(self, constant_incidence_soleil_sirius_kappa());
846 return self;
849 static HklMode *psi_vertical()
851 static const char *axes_r[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
852 static const char *axes_w[] = {"komega", "kappa", "kphi", "delta"};
853 static const HklFunction *functions[] = {&psi_func};
854 static const HklModeAutoInfo info = {
855 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
856 functions, psi_parameters),
859 return hkl_mode_psi_new(&info);
862 static HklEngine *hkl_engine_k6c_psi_new(HklEngineList *engines)
864 HklEngine *self;
865 HklMode *default_mode;
867 self = hkl_engine_psi_new(engines);
869 default_mode = psi_vertical();
870 hkl_engine_add_mode(self, default_mode);
871 hkl_engine_mode_set(self, default_mode);
873 return self;
876 /***********************/
877 /* SOLEIL SIRIUS KAPPA */
878 /***********************/
880 static HklMode *psi_vertical_soleil_sirius_kappa()
882 static const char *axes_r[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
883 static const char *axes_w[] = {"komega", "kappa", "kphi", "gamma"};
884 static const HklFunction *functions[] = {&psi_func};
885 static const HklModeAutoInfo info = {
886 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes_r, axes_w,
887 functions, psi_parameters),
890 return hkl_mode_psi_new(&info);
893 static HklEngine *hkl_engine_soleil_sirius_kappa_psi_new(HklEngineList *engines)
895 HklEngine *self;
896 HklMode *default_mode;
898 self = hkl_engine_psi_new(engines);
900 default_mode = psi_vertical_soleil_sirius_kappa();
901 hkl_engine_add_mode(self, default_mode);
902 hkl_engine_mode_set(self, default_mode);
904 return self;
907 /*******/
908 /* K6C */
909 /*******/
911 #define HKL_GEOMETRY_KAPPA6C_DESCRIPTION \
912 "For this geometry there is a special parameters called :math:`\\alpha` which is the\n" \
913 "angle between the kappa rotation axis and the :math:`\\vec{y}` direction.\n" \
914 "\n" \
915 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
916 "+ 4 axes for the sample\n" \
917 "\n" \
918 " + **mu** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
919 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
920 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
921 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
922 "\n" \
923 "+ 2 axes for the detector\n" \
924 "\n" \
925 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
926 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
928 static const char* hkl_geometry_kappa6C_axes[] = {"mu", "komega", "kappa", "kphi", "gamma", "delta"};
930 static HklGeometry *hkl_geometry_new_kappa6C(const HklFactory *factory)
932 HklGeometry *self = hkl_geometry_new(factory);
933 double alpha = 50 * HKL_DEGTORAD;
934 HklHolder *h;
936 h = hkl_geometry_add_holder(self);
937 hkl_holder_add_rotation_axis(h, "mu", 0, 0, 1);
938 hkl_holder_add_rotation_axis(h, "komega", 0, -1, 0);
939 hkl_holder_add_rotation_axis(h, "kappa", 0, -cos(alpha), -sin(alpha));
940 hkl_holder_add_rotation_axis(h, "kphi", 0, -1, 0);
942 h = hkl_geometry_add_holder(self);
943 hkl_holder_add_rotation_axis(h, "gamma", 0, 0, 1);
944 hkl_holder_add_rotation_axis(h, "delta", 0, -1, 0);
946 return self;
949 static HklEngineList *hkl_engine_list_new_kappa6C(const HklFactory *factory)
951 HklEngineList *self = hkl_engine_list_new();
953 self->geometries->multiply = hkl_geometry_list_multiply_k6c_real;
954 hkl_engine_k6c_hkl_new(self);
955 hkl_engine_eulerians_new(self);
956 hkl_engine_k6c_psi_new(self);
957 hkl_engine_q2_new(self);
958 hkl_engine_qper_qpar_new(self);
959 hkl_engine_tth2_new(self);
961 return self;
964 REGISTER_DIFFRACTOMETER(kappa6C, "K6C", HKL_GEOMETRY_KAPPA6C_DESCRIPTION);
966 /***********************/
967 /* SOLEIL SIRIUS KAPPA */
968 /***********************/
970 #define HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION \
971 "+ xrays source fix along the :math:`\\vec{x}` direction (1, 0, 0)\n" \
972 "+ 4 axes for the sample\n" \
973 "\n" \
974 " + **mu** : rotating around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
975 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
976 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
977 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
978 "\n" \
979 "+ 2 axes for the detector\n" \
980 "\n" \
981 " + **delta** : rotation around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
982 " + **gamma** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
984 static const char* hkl_geometry_soleil_sirius_kappa_axes[] = {"mu", "komega", "kappa", "kphi", "delta", "gamma"};
986 static HklGeometry *hkl_geometry_new_soleil_sirius_kappa(const HklFactory *factory)
988 HklGeometry *self = hkl_geometry_new(factory);
989 double alpha = 50 * HKL_DEGTORAD;
990 HklHolder *h;
992 h = hkl_geometry_add_holder(self);
993 hkl_holder_add_rotation_axis(h, "mu", 0, 0, -1);
994 hkl_holder_add_rotation_axis(h, "komega", 0, -1, 0);
995 hkl_holder_add_rotation_axis(h, "kappa", 0, -cos(alpha), -sin(alpha));
996 hkl_holder_add_rotation_axis(h, "kphi", 0, -1, 0);
998 h = hkl_geometry_add_holder(self);
999 hkl_holder_add_rotation_axis(h, "delta", 0, 0, -1);
1000 hkl_holder_add_rotation_axis(h, "gamma", 0, -1, 0);
1002 return self;
1005 static HklEngineList *hkl_engine_list_new_soleil_sirius_kappa(const HklFactory *factory)
1007 HklEngineList *self = hkl_engine_list_new();
1009 self->geometries->multiply = hkl_geometry_list_multiply_k6c_real;
1010 hkl_engine_soleil_sirius_kappa_hkl_new(self);
1011 hkl_engine_eulerians_new(self);
1012 hkl_engine_soleil_sirius_kappa_psi_new(self);
1013 hkl_engine_q2_new(self);
1014 hkl_engine_qper_qpar_new(self);
1015 hkl_engine_tth2_new(self);
1017 return self;
1020 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION);