1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2016 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
22 #include <gsl/gsl_sys.h> // for gsl_isnan
23 #include "hkl-factory-private.h" // for autodata_factories_, etc
24 #include "hkl-pseudoaxis-common-eulerians-private.h"
25 #include "hkl-pseudoaxis-common-hkl-private.h" // for RUBh_minus_Q, etc
26 #include "hkl-pseudoaxis-common-psi-private.h" // for hkl_engine_psi_new, etc
27 #include "hkl-pseudoaxis-common-q-private.h" // for hkl_engine_q2_new, etc
28 #include "hkl-pseudoaxis-common-readonly-private.h"
29 #include "hkl-pseudoaxis-common-tth-private.h" // for hkl_engine_tth2_new, etc
32 #define KOMEGA "komega"
38 static void hkl_geometry_list_multiply_k6c_real(HklGeometryList
*self
,
39 HklGeometryListItem
*item
)
41 HklGeometry
*geometry
;
43 double komega
, komegap
;
47 geometry
= item
->geometry
;
48 komega
= hkl_parameter_value_get(darray_item(geometry
->axes
, 1), HKL_UNIT_DEFAULT
);
49 kappa
= hkl_parameter_value_get(darray_item(geometry
->axes
, 2), HKL_UNIT_DEFAULT
);
50 kphi
= hkl_parameter_value_get(darray_item(geometry
->axes
, 3), HKL_UNIT_DEFAULT
);
52 kappa_2_kappap(komega
, kappa
, kphi
, 50 * HKL_DEGTORAD
, &komegap
, &kappap
, &kphip
);
54 copy
= hkl_geometry_new_copy(geometry
);
55 /* TODO parameter list for the geometry */
56 hkl_parameter_value_set(darray_item(copy
->axes
, 1), komegap
, HKL_UNIT_DEFAULT
, NULL
);
57 hkl_parameter_value_set(darray_item(copy
->axes
, 2), kappap
, HKL_UNIT_DEFAULT
, NULL
);
58 hkl_parameter_value_set(darray_item(copy
->axes
, 3), kphip
, HKL_UNIT_DEFAULT
, NULL
);
60 hkl_geometry_update(copy
);
61 hkl_geometry_list_add(self
, copy
);
62 hkl_geometry_free(copy
);
66 /***********************/
67 /* numerical functions */
68 /***********************/
70 static int _bissector_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
72 const double mu
= x
->data
[0];
73 const double komega
= x
->data
[1];
74 const double kappa
= x
->data
[2];
75 const double gamma
= x
->data
[4];
78 CHECK_NAN(x
->data
, x
->size
);
80 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
82 RUBh_minus_Q(x
->data
, params
, f
->data
);
83 f
->data
[3] = fmod(omega
, M_PI
);
84 f
->data
[4] = fmod(gamma
- 2 * fmod(mu
, M_PI
), 2*M_PI
);
89 static const HklFunction bissector_h_f1
= {
90 .function
= _bissector_h_f1
,
94 static int _bissector_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
96 const double mu
= x
->data
[0];
97 const double komega
= x
->data
[1];
98 const double kappa
= x
->data
[2];
99 const double gamma
= x
->data
[4];
102 CHECK_NAN(x
->data
, x
->size
);
104 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
106 RUBh_minus_Q(x
->data
, params
, f
->data
);
107 f
->data
[3] = fmod(omega
, M_PI
);
108 f
->data
[4] = fmod(gamma
- 2 * fmod(mu
, M_PI
), 2*M_PI
);
114 static const HklFunction bissector_h_f2
= {
115 .function
= _bissector_h_f2
,
119 static int _constant_kphi_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
121 const double komega
= x
->data
[1];
122 const double kappa
= x
->data
[2];
125 CHECK_NAN(x
->data
, x
->size
);
127 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
129 RUBh_minus_Q(x
->data
, params
, f
->data
);
130 f
->data
[3] = fmod(omega
, M_PI
);
135 static const HklFunction constant_kphi_h_f1
= {
136 .function
= _constant_kphi_h_f1
,
140 static int _constant_kphi_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
142 const double komega
= x
->data
[1];
143 const double kappa
= x
->data
[2];
146 CHECK_NAN(x
->data
, x
->size
);
148 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
150 RUBh_minus_Q(x
->data
, params
, f
->data
);
151 f
->data
[3] = fmod(omega
, M_PI
);
156 static const HklFunction constant_kphi_h_f2
= {
157 .function
= _constant_kphi_h_f2
,
161 static int _constant_phi_h_f1(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
163 const double komega
= x
->data
[1];
164 const double kappa
= x
->data
[2];
165 const double kphi
= x
->data
[3];
166 double omega
, phi
, p
;
168 CHECK_NAN(x
->data
, x
->size
);
170 p
= atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
));
171 omega
= komega
+ p
- M_PI_2
;
172 phi
= kphi
+ p
+ M_PI_2
;
174 RUBh_minus_Q(x
->data
, params
, f
->data
);
175 f
->data
[3] = fmod(omega
, M_PI
);
181 static const HklFunction constant_phi_h_f1
= {
182 .function
= _constant_phi_h_f1
,
186 static int _constant_phi_h_f2(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
188 const double komega
= x
->data
[1];
189 const double kappa
= x
->data
[2];
190 const double kphi
= x
->data
[3];
191 double omega
, phi
, p
;
193 CHECK_NAN(x
->data
, x
->size
);
195 p
= atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
));
196 omega
= komega
+ p
+ M_PI_2
;
197 phi
= kphi
+ p
- M_PI_2
;
199 RUBh_minus_Q(x
->data
, params
, f
->data
);
200 f
->data
[3] = fmod(omega
, M_PI
);
206 static const HklFunction constant_phi_h_f2
= {
207 .function
= _constant_phi_h_f2
,
211 static int _bissector_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
213 const double komega
= x
->data
[0];
214 const double kappa
= x
->data
[1];
215 const double delta
= x
->data
[3];
218 CHECK_NAN(x
->data
, x
->size
);
220 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
222 RUBh_minus_Q(x
->data
, params
, f
->data
);
223 f
->data
[3] = fmod(delta
- 2 * fmod(omega
, M_PI
), 2*M_PI
);
228 static const HklFunction bissector_v
= {
229 .function
= _bissector_v
,
233 static int _constant_omega_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
235 const double komega
= x
->data
[0];
236 const double kappa
= x
->data
[1];
238 HklEngine
*engine
= params
;
239 double omega0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
241 CHECK_NAN(x
->data
, x
->size
);
243 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
245 RUBh_minus_Q(x
->data
, params
, f
->data
);
246 f
->data
[3] = omega0
- omega
;
251 static const HklFunction constant_omega_v
= {
252 .function
= _constant_omega_v
,
256 static int _constant_chi_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
258 const double kappa
= x
->data
[1];
260 HklEngine
*engine
= params
;
261 double chi0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
263 CHECK_NAN(x
->data
, x
->size
);
265 chi
= 2 * asin(sin(kappa
/2.) * sin(50 * HKL_DEGTORAD
));
267 RUBh_minus_Q(x
->data
, params
, f
->data
);
268 f
->data
[3] = chi0
- chi
;
273 static const HklFunction constant_chi_v
= {
274 .function
= _constant_chi_v
,
278 static int _constant_phi_v(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
280 const double kappa
= x
->data
[1];
281 const double kphi
= x
->data
[2];
283 HklEngine
*engine
= params
;
284 double phi0
= darray_item(engine
->mode
->parameters
, 0)->_value
;
286 CHECK_NAN(x
->data
, x
->size
);
288 phi
= kphi
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) + M_PI_2
;
290 RUBh_minus_Q(x
->data
, params
, f
->data
);
291 f
->data
[3] = phi0
- phi
;
296 static const HklFunction constant_phi_v
= {
297 .function
= _constant_phi_v
,
301 static int _double_diffraction_h(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
303 const double komega
= x
->data
[1];
304 const double kappa
= x
->data
[2];
307 CHECK_NAN(x
->data
, x
->size
);
309 omega
= komega
+ atan(tan(kappa
/2.)*cos(50 * HKL_DEGTORAD
)) - M_PI_2
;
311 _double_diffraction(x
->data
, params
, f
->data
);
312 f
->data
[4] = fmod(omega
, M_PI
);
317 static const HklFunction double_diffraction_h
= {
318 .function
= _double_diffraction_h
,
322 static int _constant_incidence_func(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
324 static const HklVector Y
= {
329 HklEngine
*engine
= params
;
330 HklModeAutoWithInit
*mode
= container_of(engine
->mode
, HklModeAutoWithInit
, mode
);
336 CHECK_NAN(x
->data
, x
->size
);
338 RUBh_minus_Q(x
->data
, params
, f
->data
);
340 /* get the mode parameters */
341 n
.data
[0] = darray_item(engine
->mode
->parameters
, 0)->_value
;
342 n
.data
[1] = darray_item(engine
->mode
->parameters
, 1)->_value
;
343 n
.data
[2] = darray_item(engine
->mode
->parameters
, 2)->_value
;
344 incidence0
= darray_item(engine
->mode
->parameters
, 3)->_value
;
345 azimuth0
= darray_item(engine
->mode
->parameters
, 4)->_value
;
347 /* compute the two angles */
350 /* first check that the mode was already initialized if not
351 * the surface is oriented along the nx, ny, nz axis for all
352 * diffractometer angles equal to zero */
354 HklQuaternion q0
= darray_item(mode
->geometry
->holders
, 0)->q
;
356 hkl_quaternion_conjugate(&q0
);
357 hkl_vector_rotated_quaternion(&n
, &q0
);
360 hkl_vector_rotated_quaternion(&n
, &darray_item(engine
->geometry
->holders
, 0)->q
);
362 hkl_source_compute_ki(&engine
->geometry
->source
, &ki
);
363 incidence
= _incidence(&n
, &ki
);
365 hkl_vector_project_on_plan(&n
, &ki
);
366 azimuth
= hkl_vector_angle(&n
, &Y
);
368 f
->data
[3] = incidence0
- incidence
;
369 f
->data
[4] = azimuth0
- azimuth
;
374 static const HklFunction constant_incidence_func
= {
375 .function
= _constant_incidence_func
,
387 static HklMode
*bissector_vertical(void)
389 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
390 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
391 static const HklFunction
*functions
[] = {&bissector_v
};
392 static const HklModeAutoInfo info
= {
393 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
396 return hkl_mode_auto_new(&info
,
397 &hkl_mode_operations
,
401 static HklMode
*constant_omega_vertical(void)
403 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
404 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
405 static const HklFunction
*functions
[] = {&constant_omega_v
};
406 static const HklModeAutoInfo info
= {
407 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
408 functions
, constant_omega_parameters
),
411 return hkl_mode_auto_new(&info
,
412 &hkl_mode_operations
,
416 static HklMode
*constant_chi_vertical(void)
418 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
419 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
420 static const HklFunction
*functions
[] = {&constant_chi_v
};
421 static const HklModeAutoInfo info
= {
422 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
423 functions
, constant_chi_parameters
),
426 return hkl_mode_auto_new(&info
,
427 &hkl_mode_operations
,
431 static HklMode
*constant_phi_vertical(void)
433 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
434 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
435 static const HklFunction
*functions
[] = {&constant_phi_v
};
436 static const HklModeAutoInfo info
= {
437 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
438 functions
, constant_phi_parameters
),
441 return hkl_mode_auto_new(&info
,
442 &hkl_mode_operations
,
446 static HklMode
*lifting_detector_kphi(void)
448 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
449 static const char* axes_w
[] = {KPHI
, GAMMA
, DELTA
};
450 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
451 static const HklModeAutoInfo info
= {
452 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
455 return hkl_mode_auto_new(&info
,
456 &hkl_mode_operations
,
460 static HklMode
*lifting_detector_komega(void)
462 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
463 static const char* axes_w
[] = {KOMEGA
, GAMMA
, DELTA
};
464 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
465 static const HklModeAutoInfo info
= {
466 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
469 return hkl_mode_auto_new(&info
,
470 &hkl_mode_operations
,
474 static HklMode
*lifting_detector_mu(void)
476 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
477 static const char* axes_w
[] = {MU
, GAMMA
, DELTA
};
478 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
479 static const HklModeAutoInfo info
= {
480 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
483 return hkl_mode_auto_new(&info
,
484 &hkl_mode_operations
,
488 static HklMode
*double_diffraction_vertical(void)
490 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
491 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
492 static const HklFunction
*functions
[] = {&double_diffraction_func
};
493 static const HklModeAutoInfo info
= {
494 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
495 functions
, double_diffraction_parameters
),
498 return hkl_mode_auto_new(&info
,
499 &hkl_mode_operations
,
503 static HklMode
*bissector_horizontal(void)
505 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
506 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
};
507 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
508 static const HklModeAutoInfo info
= {
509 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
512 return hkl_mode_auto_new(&info
,
513 &hkl_mode_operations
,
517 static HklMode
*constant_phi_horizontal(void)
519 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
520 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
};
521 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
522 static const HklModeAutoInfo info
= {
523 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
524 functions
, constant_phi_parameters
),
527 return hkl_mode_auto_new(&info
,
528 &hkl_mode_operations
,
532 static HklMode
*constant_kphi_horizontal(void)
534 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
535 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, GAMMA
};
536 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
537 static const HklModeAutoInfo info
= {
538 HKL_MODE_AUTO_INFO(__func__
, axes_r
, axes_w
, functions
),
541 return hkl_mode_auto_new(&info
,
542 &hkl_mode_operations
,
546 static HklMode
*double_diffraction_horizontal(void)
548 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
549 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
};
550 static const HklFunction
*functions
[] = {&double_diffraction_h
};
551 static const HklModeAutoInfo info
= {
552 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
553 functions
, double_diffraction_parameters
),
556 return hkl_mode_auto_new(&info
,
557 &hkl_mode_operations
,
561 static HklMode
*psi_constant_vertical(void)
563 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
564 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
565 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
566 static const HklModeAutoInfo info
= {
567 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
568 functions
, psi_constant_parameters
),
571 return hkl_mode_auto_new(&info
,
572 &psi_constant_vertical_mode_operations
,
576 static HklMode
*constant_incidence(void)
578 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
579 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
580 static const HklFunction
*functions
[] = {&constant_incidence_func
};
581 static const HklModeAutoInfo info
= {
582 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
583 functions
, constant_incidence_parameters
),
586 return hkl_mode_auto_with_init_new(&info
,
587 &constant_incidence_mode_operations
,
591 static HklEngine
*hkl_engine_k6c_hkl_new(HklEngineList
*engines
)
594 HklMode
*default_mode
;
596 self
= hkl_engine_hkl_new(engines
);
598 default_mode
= bissector_vertical();
599 hkl_engine_add_mode(self
, default_mode
);
600 hkl_engine_mode_set(self
, default_mode
);
602 hkl_engine_add_mode(self
, constant_omega_vertical());
603 hkl_engine_add_mode(self
, constant_chi_vertical());
604 hkl_engine_add_mode(self
, constant_phi_vertical());
605 hkl_engine_add_mode(self
, lifting_detector_kphi());
606 hkl_engine_add_mode(self
, lifting_detector_komega());
607 hkl_engine_add_mode(self
, lifting_detector_mu());
608 hkl_engine_add_mode(self
, double_diffraction_vertical());
609 hkl_engine_add_mode(self
, bissector_horizontal());
610 hkl_engine_add_mode(self
, constant_phi_horizontal());
611 hkl_engine_add_mode(self
, constant_kphi_horizontal());
612 hkl_engine_add_mode(self
, double_diffraction_horizontal());
613 hkl_engine_add_mode(self
, psi_constant_vertical());
614 hkl_engine_add_mode(self
, constant_incidence());
623 static HklMode
*psi_vertical(void)
625 static const char *axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
626 static const char *axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
};
627 static const HklFunction
*functions
[] = {&psi_func
};
628 static const HklModeAutoInfo info
= {
629 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
630 functions
, psi_parameters
),
633 return hkl_mode_psi_new(&info
);
636 static HklEngine
*hkl_engine_k6c_psi_new(HklEngineList
*engines
)
639 HklMode
*default_mode
;
641 self
= hkl_engine_psi_new(engines
);
643 default_mode
= psi_vertical();
644 hkl_engine_add_mode(self
, default_mode
);
645 hkl_engine_mode_set(self
, default_mode
);
654 REGISTER_READONLY_INCIDENCE(hkl_engine_k6c_incidence_new
,
655 P99_PROTECT({MU
, KOMEGA
, KAPPA
, KPHI
}),
656 surface_parameters_y
);
658 REGISTER_READONLY_EMERGENCE(hkl_engine_k6c_emergence_new
,
659 P99_PROTECT({MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
}),
660 surface_parameters_y
);
662 #define HKL_GEOMETRY_KAPPA6C_DESCRIPTION \
663 "For this geometry there is a special parameters called :math:`\\alpha` which is the\n" \
664 "angle between the kappa rotation axis and the :math:`\\vec{y}` direction.\n" \
666 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
667 "+ 4 axes for the sample\n" \
669 " + **mu** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
670 " + **komega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
671 " + **kappa** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
672 " + **kphi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
674 "+ 2 axes for the detector\n" \
676 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
677 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
679 static const char* hkl_geometry_kappa6C_axes
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, GAMMA
, DELTA
};
681 static HklGeometry
*hkl_geometry_new_kappa6C(const HklFactory
*factory
)
683 HklGeometry
*self
= hkl_geometry_new(factory
);
684 double alpha
= 50 * HKL_DEGTORAD
;
687 h
= hkl_geometry_add_holder(self
);
688 hkl_holder_add_rotation_axis(h
, MU
, 0, 0, 1);
689 hkl_holder_add_rotation_axis(h
, KOMEGA
, 0, -1, 0);
690 hkl_holder_add_rotation_axis(h
, KAPPA
, 0, -cos(alpha
), -sin(alpha
));
691 hkl_holder_add_rotation_axis(h
, KPHI
, 0, -1, 0);
693 h
= hkl_geometry_add_holder(self
);
694 hkl_holder_add_rotation_axis(h
, GAMMA
, 0, 0, 1);
695 hkl_holder_add_rotation_axis(h
, DELTA
, 0, -1, 0);
700 static HklEngineList
*hkl_engine_list_new_kappa6C(const HklFactory
*factory
)
702 HklEngineList
*self
= hkl_engine_list_new();
704 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
705 hkl_engine_k6c_hkl_new(self
);
706 hkl_engine_eulerians_new(self
);
707 hkl_engine_k6c_psi_new(self
);
708 hkl_engine_q2_new(self
);
709 hkl_engine_qper_qpar_new(self
);
710 hkl_engine_k6c_incidence_new(self
);
711 hkl_engine_tth2_new(self
);
712 hkl_engine_k6c_emergence_new(self
);
717 REGISTER_DIFFRACTOMETER(kappa6C
, "K6C", HKL_GEOMETRY_KAPPA6C_DESCRIPTION
);
719 /***********************/
720 /* SOLEIL sirius kappa */
721 /***********************/
725 static HklMode
*bissector_vertical_soleil_sirius_kappa(void)
727 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
728 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
729 static const HklFunction
*functions
[] = {&bissector_v
};
730 static const HklModeAutoInfo info
= {
731 HKL_MODE_AUTO_INFO("bissector_vertical", axes_r
, axes_w
, functions
),
734 return hkl_mode_auto_new(&info
,
735 &hkl_mode_operations
,
739 static HklMode
*constant_omega_vertical_soleil_sirius_kappa(void)
741 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
742 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
743 static const HklFunction
*functions
[] = {&constant_omega_v
};
744 static const HklModeAutoInfo info
= {
745 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_omega_vertical", axes_r
, axes_w
,
746 functions
, constant_omega_parameters
),
749 return hkl_mode_auto_new(&info
,
750 &hkl_mode_operations
,
754 static HklMode
*constant_chi_vertical_soleil_sirius_kappa(void)
756 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
757 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
758 static const HklFunction
*functions
[] = {&constant_chi_v
};
759 static const HklModeAutoInfo info
= {
760 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_chi_vertical", axes_r
, axes_w
,
761 functions
, constant_chi_parameters
),
764 return hkl_mode_auto_new(&info
,
765 &hkl_mode_operations
,
769 static HklMode
*constant_phi_vertical_soleil_sirius_kappa(void)
771 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
772 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
773 static const HklFunction
*functions
[] = {&constant_phi_v
};
774 static const HklModeAutoInfo info
= {
775 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_vertical", axes_r
, axes_w
,
776 functions
, constant_phi_parameters
),
779 return hkl_mode_auto_new(&info
,
780 &hkl_mode_operations
,
784 static HklMode
*lifting_detector_kphi_soleil_sirius_kappa(void)
786 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
787 static const char* axes_w
[] = {KPHI
, DELTA
, GAMMA
};
788 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
789 static const HklModeAutoInfo info
= {
790 HKL_MODE_AUTO_INFO("lifting_detector_kphi", axes_r
, axes_w
, functions
),
793 return hkl_mode_auto_new(&info
,
794 &hkl_mode_operations
,
798 static HklMode
*lifting_detector_komega_soleil_sirius_kappa(void)
800 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
801 static const char* axes_w
[] = {KOMEGA
, DELTA
, GAMMA
};
802 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
803 static const HklModeAutoInfo info
= {
804 HKL_MODE_AUTO_INFO("lifting_detector_komega", axes_r
, axes_w
, functions
),
807 return hkl_mode_auto_new(&info
,
808 &hkl_mode_operations
,
812 static HklMode
*lifting_detector_mu_soleil_sirius_kappa(void)
814 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
815 static const char* axes_w
[] = {MU
, DELTA
, GAMMA
};
816 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
817 static const HklModeAutoInfo info
= {
818 HKL_MODE_AUTO_INFO("lifting_detector_mu", axes_r
, axes_w
, functions
),
821 return hkl_mode_auto_new(&info
,
822 &hkl_mode_operations
,
826 static HklMode
*double_diffraction_vertical_soleil_sirius_kappa(void)
828 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
829 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
830 static const HklFunction
*functions
[] = {&double_diffraction_func
};
831 static const HklModeAutoInfo info
= {
832 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_vertical", axes_r
, axes_w
,
833 functions
, double_diffraction_parameters
),
836 return hkl_mode_auto_new(&info
,
837 &hkl_mode_operations
,
841 static HklMode
*bissector_horizontal_soleil_sirius_kappa(void)
843 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
844 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
};
845 static const HklFunction
*functions
[] = {&bissector_h_f1
, &bissector_h_f2
};
846 static const HklModeAutoInfo info
= {
847 HKL_MODE_AUTO_INFO("bissector_horizontal", axes_r
, axes_w
, functions
),
850 return hkl_mode_auto_new(&info
,
851 &hkl_mode_operations
,
855 static HklMode
*constant_phi_horizontal_soleil_sirius_kappa(void)
857 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
858 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
};
859 static const HklFunction
*functions
[] = {&constant_phi_h_f1
, &constant_phi_h_f2
};
860 static const HklModeAutoInfo info
= {
861 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_phi_horizontal", axes_r
, axes_w
,
862 functions
, constant_phi_parameters
),
865 return hkl_mode_auto_new(&info
,
866 &hkl_mode_operations
,
870 static HklMode
*constant_kphi_horizontal_soleil_sirius_kappa(void)
872 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
873 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, DELTA
};
874 static const HklFunction
*functions
[] = {&constant_kphi_h_f1
, &constant_kphi_h_f2
};
875 static const HklModeAutoInfo info
= {
876 HKL_MODE_AUTO_INFO("constant_kphi_horizontal", axes_r
, axes_w
, functions
),
879 return hkl_mode_auto_new(&info
,
880 &hkl_mode_operations
,
884 static HklMode
*double_diffraction_horizontal_soleil_sirius_kappa(void)
886 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
887 static const char* axes_w
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
};
888 static const HklFunction
*functions
[] = {&double_diffraction_h
};
889 static const HklModeAutoInfo info
= {
890 HKL_MODE_AUTO_INFO_WITH_PARAMS("double_diffraction_horizontal", axes_r
, axes_w
,
891 functions
, double_diffraction_parameters
),
894 return hkl_mode_auto_new(&info
,
895 &hkl_mode_operations
,
899 static HklMode
*psi_constant_vertical_soleil_sirius_kappa(void)
901 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
902 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
903 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
904 static const HklModeAutoInfo info
= {
905 HKL_MODE_AUTO_INFO_WITH_PARAMS("psi_constant_vertical", axes_r
, axes_w
,
906 functions
, psi_constant_parameters
),
909 return hkl_mode_auto_new(&info
,
910 &psi_constant_vertical_mode_operations
,
914 static HklMode
*constant_incidence_soleil_sirius_kappa(void)
916 static const char* axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
917 static const char* axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
918 static const HklFunction
*functions
[] = {&constant_incidence_func
};
919 static const HklModeAutoInfo info
= {
920 HKL_MODE_AUTO_INFO_WITH_PARAMS("constant_incidence", axes_r
, axes_w
,
921 functions
, constant_incidence_parameters
),
924 return hkl_mode_auto_with_init_new(&info
,
925 &constant_incidence_mode_operations
,
929 static HklEngine
*hkl_engine_soleil_sirius_kappa_hkl_new(HklEngineList
*engines
)
932 HklMode
*default_mode
;
934 self
= hkl_engine_hkl_new(engines
);
936 default_mode
= bissector_vertical_soleil_sirius_kappa();
937 hkl_engine_add_mode(self
, default_mode
);
938 hkl_engine_mode_set(self
, default_mode
);
940 hkl_engine_add_mode(self
, constant_omega_vertical_soleil_sirius_kappa());
941 hkl_engine_add_mode(self
, constant_chi_vertical_soleil_sirius_kappa());
942 hkl_engine_add_mode(self
, constant_phi_vertical_soleil_sirius_kappa());
943 hkl_engine_add_mode(self
, lifting_detector_kphi_soleil_sirius_kappa());
944 hkl_engine_add_mode(self
, lifting_detector_komega_soleil_sirius_kappa());
945 hkl_engine_add_mode(self
, lifting_detector_mu_soleil_sirius_kappa());
946 hkl_engine_add_mode(self
, double_diffraction_vertical_soleil_sirius_kappa());
947 hkl_engine_add_mode(self
, bissector_horizontal_soleil_sirius_kappa());
948 hkl_engine_add_mode(self
, constant_phi_horizontal_soleil_sirius_kappa());
949 hkl_engine_add_mode(self
, constant_kphi_horizontal_soleil_sirius_kappa());
950 hkl_engine_add_mode(self
, double_diffraction_horizontal_soleil_sirius_kappa());
951 hkl_engine_add_mode(self
, psi_constant_vertical_soleil_sirius_kappa());
952 hkl_engine_add_mode(self
, constant_incidence_soleil_sirius_kappa());
959 static HklMode
*psi_vertical_soleil_sirius_kappa()
961 static const char *axes_r
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
962 static const char *axes_w
[] = {KOMEGA
, KAPPA
, KPHI
, GAMMA
};
963 static const HklFunction
*functions
[] = {&psi_func
};
964 static const HklModeAutoInfo info
= {
965 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__
, axes_r
, axes_w
,
966 functions
, psi_parameters
),
969 return hkl_mode_psi_new(&info
);
972 static HklEngine
*hkl_engine_soleil_sirius_kappa_psi_new(HklEngineList
*engines
)
975 HklMode
*default_mode
;
977 self
= hkl_engine_psi_new(engines
);
979 default_mode
= psi_vertical_soleil_sirius_kappa();
980 hkl_engine_add_mode(self
, default_mode
);
981 hkl_engine_mode_set(self
, default_mode
);
986 /* SOLEIL SIRIUS KAPPA */
988 #define HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION \
989 "+ xrays source fix along the :math:`\\vec{x}` direction (1, 0, 0)\n" \
990 "+ 4 axes for the sample\n" \
992 " + **" MU "** : rotating around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
993 " + **" KOMEGA "** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
994 " + **" KAPPA "** : rotating around the :math:`\\vec{x}` direction (0, :math:`-\\cos\\alpha`, :math:`-\\sin\\alpha`)\n" \
995 " + **" KPHI "** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
997 "+ 2 axes for the detector\n" \
999 " + **" DELTA "** : rotation around the :math:`-\\vec{z}` direction (0, 0, -1)\n" \
1000 " + **" GAMMA "** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
1002 static const char* hkl_geometry_soleil_sirius_kappa_axes
[] = {MU
, KOMEGA
, KAPPA
, KPHI
, DELTA
, GAMMA
};
1004 static HklGeometry
*hkl_geometry_new_soleil_sirius_kappa(const HklFactory
*factory
)
1006 HklGeometry
*self
= hkl_geometry_new(factory
);
1007 double alpha
= 50 * HKL_DEGTORAD
;
1010 h
= hkl_geometry_add_holder(self
);
1011 hkl_holder_add_rotation_axis(h
, MU
, 0, 0, -1);
1012 hkl_holder_add_rotation_axis(h
, KOMEGA
, 0, -1, 0);
1013 hkl_holder_add_rotation_axis(h
, KAPPA
, 0, -cos(alpha
), -sin(alpha
));
1014 hkl_holder_add_rotation_axis(h
, KPHI
, 0, -1, 0);
1016 h
= hkl_geometry_add_holder(self
);
1017 hkl_holder_add_rotation_axis(h
, DELTA
, 0, 0, -1);
1018 hkl_holder_add_rotation_axis(h
, GAMMA
, 0, -1, 0);
1023 static HklEngineList
*hkl_engine_list_new_soleil_sirius_kappa(const HklFactory
*factory
)
1025 HklEngineList
*self
= hkl_engine_list_new();
1027 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
1028 hkl_engine_soleil_sirius_kappa_hkl_new(self
);
1029 hkl_engine_eulerians_new(self
);
1030 hkl_engine_soleil_sirius_kappa_psi_new(self
);
1031 hkl_engine_q2_new(self
);
1032 hkl_engine_qper_qpar_new(self
);
1033 hkl_engine_tth2_new(self
);
1034 hkl_engine_k6c_incidence_new(self
);
1035 hkl_engine_k6c_emergence_new(self
);
1040 REGISTER_DIFFRACTOMETER(soleil_sirius_kappa
, "SOLEIL SIRIUS KAPPA", HKL_GEOMETRY_TYPE_SOLEIL_SIRIUS_KAPPA_DESCRIPTION
);