create an HklPseudoAxisEngineModeInfo for the Automatic modes.
[hkl.git] / hkl / hkl-pseudoaxis-k4cv-hkl.c
blob2f0ed12d913d5b8ba7649d5170d7397ae81b2543
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-2012 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>
21 * Maria-Teresa Nunez-Pardo-de-Verra <tnunez@mail.desy.de>
22 * Jens Krüger <Jens.Krueger@frm2.tum.de>
24 #include <gsl/gsl_math.h>
25 #include <gsl/gsl_vector.h>
27 #include <ccan/array_size/array_size.h>
29 #include "hkl-pseudoaxis-auto-private.h"
30 #include "hkl-pseudoaxis-common-hkl-private.h"
32 /***********************/
33 /* numerical functions */
34 /***********************/
36 static int _bissector_f1(const gsl_vector *x, void *params, gsl_vector *f)
38 const double komega = x->data[0];
39 const double kappa = x->data[1];
40 const double tth = x->data[3];
41 double omega;
43 CHECK_NAN(x->data, x->size);
45 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
47 RUBh_minus_Q(x->data, params, f->data);
48 f->data[3] = fmod(tth - 2 * fmod(omega, M_PI), 2*M_PI);
50 return GSL_SUCCESS;
53 static const HklFunction bissector_f1 = {
54 .function = _bissector_f1,
55 .size = 4,
58 static int _bissector_f2(const gsl_vector *x, void *params, gsl_vector *f)
60 const double komega = x->data[0];
61 const double kappa = x->data[1];
62 const double tth = x->data[3];
63 double omega;
65 CHECK_NAN(x->data, x->size);
67 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
69 RUBh_minus_Q(x->data, params, f->data);
70 f->data[3] = fmod(tth - 2 * fmod(omega, M_PI), 2*M_PI);
72 return GSL_SUCCESS;
75 static const HklFunction bissector_f2 = {
76 .function = _bissector_f2,
77 .size = 4,
80 static int _constant_omega_f1(const gsl_vector *x, void *params, gsl_vector *f)
82 double const komega = x->data[0];
83 double const kappa = x->data[1];
84 double omega;
85 HklPseudoAxisEngine *engine = params;
86 double omega0 = engine->mode->parameters[0].value;
88 CHECK_NAN(x->data, x->size);
90 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
92 RUBh_minus_Q(x->data, params, f->data);
93 f->data[3] = omega0 - omega;
95 return GSL_SUCCESS;
98 static const HklFunction constant_omega_f1 = {
99 .function = _constant_omega_f1,
100 .size = 4,
103 static int _constant_omega_f2(const gsl_vector *x, void *params, gsl_vector *f)
105 const double komega = x->data[0];
106 const double kappa = x->data[1];
107 double omega;
108 HklPseudoAxisEngine *engine = params;
109 double omega0 = engine->mode->parameters[0].value;
111 CHECK_NAN(x->data, x->size);
113 omega = komega + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
115 RUBh_minus_Q(x->data, params, f->data);
116 f->data[3] = omega0 - omega;
118 return GSL_SUCCESS;
121 static const HklFunction constant_omega_f2 = {
122 .function = _constant_omega_f2,
123 .size = 4,
126 static int _constant_chi_f1(const gsl_vector *x, void *params, gsl_vector *f)
128 const double kappa = x->data[1];
129 double chi;
130 HklPseudoAxisEngine *engine = params;
131 double chi0 = engine->mode->parameters[0].value;
133 CHECK_NAN(x->data, x->size);
135 chi = 2 * asin(sin(kappa/2.) * sin(50 * HKL_DEGTORAD));
137 RUBh_minus_Q(x->data, params, f->data);
138 f->data[3] = chi0 - chi;
140 return GSL_SUCCESS;
143 static const HklFunction constant_chi_f1 = {
144 .function = _constant_chi_f1,
145 .size = 4,
148 static int _constant_chi_f2(const gsl_vector *x, void *params, gsl_vector *f)
150 const double kappa = x->data[1];
151 double chi;
152 HklPseudoAxisEngine *engine = params;
153 double chi0 = engine->mode->parameters[0].value;
155 CHECK_NAN(x->data, x->size);
157 chi = -2 * asin(sin(kappa/2.) * sin(50 * HKL_DEGTORAD));
159 RUBh_minus_Q(x->data, params, f->data);
160 f->data[3] = chi0 - chi;
162 return GSL_SUCCESS;
165 static const HklFunction constant_chi_f2 = {
166 .function = _constant_chi_f2,
167 .size = 4,
170 static int _constant_phi_f1(const gsl_vector *x, void *params, gsl_vector *f)
172 const double kappa = x->data[1];
173 const double kphi = x->data[2];
174 double phi;
175 HklPseudoAxisEngine *engine = params;
176 double phi0 = engine->mode->parameters[0].value;
178 CHECK_NAN(x->data, x->size);
180 phi = kphi + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) + M_PI_2;
182 RUBh_minus_Q(x->data, params, f->data);
183 f->data[3] = phi0 - phi;
185 return GSL_SUCCESS;
188 static const HklFunction constant_phi_f1 = {
189 .function = _constant_phi_f1,
190 .size = 4,
193 static int _constant_phi_f2(const gsl_vector *x, void *params, gsl_vector *f)
195 const double kappa = x->data[1];
196 const double kphi = x->data[2];
197 double phi;
198 HklPseudoAxisEngine *engine = params;
199 double phi0 = engine->mode->parameters[0].value;
201 CHECK_NAN(x->data, x->size);
203 phi = kphi + atan(tan(kappa/2.)*cos(50 * HKL_DEGTORAD)) - M_PI_2;
205 RUBh_minus_Q(x->data, params, f->data);
206 f->data[3] = phi0 - phi;
208 return GSL_SUCCESS;
211 static const HklFunction constant_phi_f2 = {
212 .function = _constant_phi_f2,
213 .size = 4,
216 /********/
217 /* mode */
218 /********/
220 static HklPseudoAxisEngineMode *bissector(void)
222 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
223 static const HklFunction *functions[] = {&bissector_f1, &bissector_f2};
224 static const HklPseudoAxisEngineModeAutoInfo info = {
225 INFO_AUTO(__func__, axes, functions),
228 return hkl_pseudo_axis_engine_mode_auto_new(&info,
229 &hkl_mode_operations);
232 static HklPseudoAxisEngineMode *constant_omega(void)
234 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
235 static const HklFunction *functions[] = {&constant_omega_f1, &constant_omega_f2};
236 static const HklParameter parameters[] = {
237 {HKL_PARAMETER_DEFAULTS_ANGLE, .name = "omega"},
239 static const HklPseudoAxisEngineModeAutoInfo info = {
240 INFO_AUTO_WITH_PARAMS(__func__, axes, functions, parameters),
243 return hkl_pseudo_axis_engine_mode_auto_new(&info,
244 &hkl_mode_operations);
247 static HklPseudoAxisEngineMode *constant_chi(void)
249 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
250 static const HklFunction *functions[] = {&constant_chi_f1, &constant_chi_f2};
251 static const HklParameter parameters[] = {
252 {HKL_PARAMETER_DEFAULTS_ANGLE, .name = "chi"},
254 static const HklPseudoAxisEngineModeAutoInfo info = {
255 INFO_AUTO_WITH_PARAMS(__func__, axes, functions, parameters),
258 return hkl_pseudo_axis_engine_mode_auto_new(&info,
259 &hkl_mode_operations);
262 static HklPseudoAxisEngineMode *constant_phi(void)
264 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
265 static const HklFunction *functions[] = {&constant_phi_f1, &constant_phi_f2};
266 static const HklParameter parameters[] = {
267 {HKL_PARAMETER_DEFAULTS_ANGLE, .name = "phi"},
269 static const HklPseudoAxisEngineModeAutoInfo info = {
270 INFO_AUTO_WITH_PARAMS(__func__, axes, functions, parameters),
273 return hkl_pseudo_axis_engine_mode_auto_new(&info,
274 &hkl_mode_operations);
277 static HklPseudoAxisEngineMode *double_diffraction(void)
279 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
280 static const HklFunction *functions[] = {&double_diffraction_func};
281 static const HklParameter parameters[] = {
282 {HKL_PARAMETER_DEFAULTS, .name = "h2", .range = {.min=-1, .max=1}, .value = 1,},
283 {HKL_PARAMETER_DEFAULTS, .name = "k2", .range = {.min=-1, .max=1}, .value = 1,},
284 {HKL_PARAMETER_DEFAULTS, .name = "l2", .range = {.min=-1, .max=1}, .value = 1,},
286 static const HklPseudoAxisEngineModeAutoInfo info = {
287 INFO_AUTO_WITH_PARAMS(__func__, axes, functions, parameters),
290 return hkl_pseudo_axis_engine_mode_auto_new(&info,
291 &hkl_mode_operations);
294 static HklPseudoAxisEngineMode *psi_constant(void)
296 static const char* axes[] = {"komega", "kappa", "kphi", "tth"};
297 static const HklFunction *functions[] = {&psi_constant_vertical_func};
298 static const HklParameter parameters[] = {
299 {HKL_PARAMETER_DEFAULTS, .name = "h2", .range = {.min=-1, .max=1}, .value = 1,},
300 {HKL_PARAMETER_DEFAULTS, .name = "k2", .range = {.min=-1, .max=1}, .value = 0,},
301 {HKL_PARAMETER_DEFAULTS, .name = "l2", .range = {.min=-1, .max=1}, .value = 0,},
302 {HKL_PARAMETER_DEFAULTS_ANGLE, .name = "psi"},
304 static const HklPseudoAxisEngineModeAutoInfo info = {
305 INFO_AUTO_WITH_PARAMS(__func__, axes, functions, parameters),
308 return hkl_pseudo_axis_engine_mode_auto_new(&info,
309 &psi_constant_vertical_mode_operations);
312 /**********************/
313 /* pseudo axis engine */
314 /**********************/
316 HklPseudoAxisEngine *hkl_pseudo_axis_engine_k4cv_hkl_new(void)
318 HklPseudoAxisEngine *self;
319 HklPseudoAxisEngineMode *default_mode;
321 self = hkl_pseudo_axis_engine_hkl_new();
323 default_mode = bissector();
324 hkl_pseudo_axis_engine_add_mode(self, default_mode);
325 hkl_pseudo_axis_engine_select_mode(self, default_mode);
327 hkl_pseudo_axis_engine_add_mode(self, constant_omega());
328 hkl_pseudo_axis_engine_add_mode(self, constant_chi());
329 hkl_pseudo_axis_engine_add_mode(self, constant_phi());
330 hkl_pseudo_axis_engine_add_mode(self, double_diffraction());
331 hkl_pseudo_axis_engine_add_mode(self, psi_constant());
333 return self;