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
;
35 double komega
, komegap
;
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];
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
);
81 static const HklFunction bissector_h_f1
= {
82 .function
= _bissector_h_f1
,
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];
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
);
106 static const HklFunction bissector_h_f2
= {
107 .function
= _bissector_h_f2
,
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];
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
);
127 static const HklFunction constant_kphi_h_f1
= {
128 .function
= _constant_kphi_h_f1
,
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];
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
);
148 static const HklFunction constant_kphi_h_f2
= {
149 .function
= _constant_kphi_h_f2
,
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
);
173 static const HklFunction constant_phi_h_f1
= {
174 .function
= _constant_phi_h_f1
,
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
);
198 static const HklFunction constant_phi_h_f2
= {
199 .function
= _constant_phi_h_f2
,
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];
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
);
220 static const HklFunction bissector_v
= {
221 .function
= _bissector_v
,
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];
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
;
243 static const HklFunction constant_omega_v
= {
244 .function
= _constant_omega_v
,
248 static int _constant_chi_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
250 const double kappa
= x
->data
[1];
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
;
265 static const HklFunction constant_chi_v
= {
266 .function
= _constant_chi_v
,
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];
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
;
288 static const HklFunction constant_phi_v
= {
289 .function
= _constant_phi_v
,
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];
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
);
309 static const HklFunction double_diffraction_h
= {
310 .function
= _double_diffraction_h
,
314 static int _constant_incidence_func(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
316 static const HklVector Y
= {
321 HklEngine
*engine
= params
;
322 HklModeAutoWithInit
*mode
= container_of(engine
->mode
, HklModeAutoWithInit
, mode
);
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 */
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
;
366 static const HklFunction constant_incidence_func
= {
367 .function
= _constant_incidence_func
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
579 /**********************/
580 /* pseudo axis engine */
581 /**********************/
583 static HklEngine
*hkl_engine_k6c_hkl_new(HklEngineList
*engines
)
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());
611 /***********************/
612 /* SOLEIL sirius kappa */
613 /***********************/
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
821 static HklEngine
*hkl_engine_soleil_sirius_kappa_hkl_new(HklEngineList
*engines
)
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());
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
)
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
);
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
)
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
);
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" \
915 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
916 "+ 4 axes for the sample\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" \
923 "+ 2 axes for the detector\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
;
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);
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
);
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" \
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" \
979 "+ 2 axes for the detector\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
;
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);
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
);
1020 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa
, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION
);