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-parameter-private.h"
30 #include "hkl-pseudoaxis-auto-private.h"
31 #include "hkl-pseudoaxis-common-hkl-private.h"
33 /***********************/
34 /* numerical functions */
35 /***********************/
37 static int _bissector_horizontal_func(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
39 const double mu
= x
->data
[0];
40 const double omega
= x
->data
[1];
41 const double gamma
= x
->data
[4];
43 CHECK_NAN(x
->data
, x
->size
);
45 RUBh_minus_Q(x
->data
, params
, f
->data
);
46 f
->data
[3] = fmod(omega
, M_PI
);
47 f
->data
[4] = gamma
- 2 * fmod(mu
, M_PI
);
52 static const HklFunction bissector_horizontal_func
= {
53 .function
= _bissector_horizontal_func
,
57 static int _bissector_vertical_func(const gsl_vector
*x
, void *params
, gsl_vector
*f
)
59 const double omega
= x
->data
[0];
60 const double tth
= x
->data
[3];
62 CHECK_NAN(x
->data
, x
->size
);
64 RUBh_minus_Q(x
->data
, params
, f
->data
);
65 f
->data
[3] = tth
- 2 * fmod(omega
,M_PI
);
70 static const HklFunction bissector_vertical_func
= {
71 .function
= _bissector_vertical_func
,
79 static HklMode
*bissector_vertical(void)
81 static const char* axes
[] = {"omega", "chi", "phi", "delta"};
82 static const HklFunction
*functions
[] = {&bissector_vertical_func
};
83 static const HklModeAutoInfo info
= {
84 INFO_AUTO(__func__
, axes
, functions
),
87 return hkl_mode_auto_new(&info
,
88 &hkl_mode_operations
);
91 static HklMode
*constant_omega_vertical(void)
93 static const char* axes
[] = {"chi", "phi", "delta"};
94 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
95 static const HklModeAutoInfo info
= {
96 INFO_AUTO(__func__
, axes
, functions
),
99 return hkl_mode_auto_new(&info
,
100 &hkl_mode_operations
);
103 static HklMode
*constant_chi_vertical(void)
105 static const char* axes
[] = {"omega", "phi", "delta"};
106 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
107 static const HklModeAutoInfo info
= {
108 INFO_AUTO(__func__
, axes
, functions
),
111 return hkl_mode_auto_new(&info
,
112 &hkl_mode_operations
);
115 static HklMode
*constant_phi_vertical(void)
117 static const char* axes
[] = {"omega", "chi", "delta"};
118 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
119 static const HklModeAutoInfo info
= {
120 INFO_AUTO(__func__
, axes
, functions
),
123 return hkl_mode_auto_new(&info
,
124 &hkl_mode_operations
);
127 static HklMode
*lifting_detector_phi(void)
129 static const char* axes
[] = {"phi", "gamma", "delta"};
130 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
131 static const HklModeAutoInfo info
= {
132 INFO_AUTO(__func__
, axes
, functions
),
135 return hkl_mode_auto_new(&info
,
136 &hkl_mode_operations
);
139 static HklMode
*lifting_detector_omega(void)
141 static const char* axes
[] = {"omega", "gamma", "delta"};
142 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
143 static const HklModeAutoInfo info
= {
144 INFO_AUTO(__func__
, axes
, functions
),
147 return hkl_mode_auto_new(&info
,
148 &hkl_mode_operations
);
151 static HklMode
*lifting_detector_mu(void)
153 static const char* axes
[] = {"mu", "gamma", "delta"};
154 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
155 static const HklModeAutoInfo info
= {
156 INFO_AUTO(__func__
, axes
, functions
),
159 return hkl_mode_auto_new(&info
,
160 &hkl_mode_operations
);
163 static HklMode
*double_diffraction_vertical(void)
165 static const char* axes
[] = {"omega", "chi", "phi", "delta"};
166 static const HklFunction
*functions
[] = {&double_diffraction_func
};
167 static const HklParameter parameters
[] = {
168 {HKL_PARAMETER_DEFAULTS
, .name
= "h2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
169 {HKL_PARAMETER_DEFAULTS
, .name
= "k2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
170 {HKL_PARAMETER_DEFAULTS
, .name
= "l2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
172 static const HklModeAutoInfo info
= {
173 INFO_AUTO_WITH_PARAMS(__func__
, axes
, functions
, parameters
),
176 return hkl_mode_auto_new(&info
,
177 &hkl_mode_operations
);
180 static HklMode
*bissector_horizontal(void)
182 static const char* axes
[] = {"mu", "omega", "chi", "phi", "gamma"};
183 static const HklFunction
*functions
[] = {&bissector_horizontal_func
};
184 static const HklModeAutoInfo info
= {
185 INFO_AUTO(__func__
, axes
, functions
),
188 return hkl_mode_auto_new(&info
,
189 &hkl_mode_operations
);
192 static HklMode
*double_diffraction_horizontal(void)
194 static const char* axes
[] = {"mu", "chi", "phi", "gamma"};
195 static const HklFunction
*functions
[] = {&double_diffraction_func
};
196 static const HklParameter parameters
[] = {
197 {HKL_PARAMETER_DEFAULTS
, .name
= "h2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
198 {HKL_PARAMETER_DEFAULTS
, .name
= "k2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
199 {HKL_PARAMETER_DEFAULTS
, .name
= "l2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
201 static const HklModeAutoInfo info
= {
202 INFO_AUTO_WITH_PARAMS(__func__
, axes
, functions
, parameters
),
205 return hkl_mode_auto_new(&info
,
206 &hkl_mode_operations
);
209 static HklMode
*psi_constant_vertical(void)
211 static const char* axes
[] = {"omega", "chi", "phi", "delta"};
212 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
213 static const HklParameter parameters
[] = {
214 {HKL_PARAMETER_DEFAULTS
, .name
= "h2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
215 {HKL_PARAMETER_DEFAULTS
, .name
= "k2", .range
= {.min
=-1, .max
=1}, ._value
= 0,},
216 {HKL_PARAMETER_DEFAULTS
, .name
= "l2", .range
= {.min
=-1, .max
=1}, ._value
= 0,},
217 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "psi"},
219 static const HklModeAutoInfo info
= {
220 INFO_AUTO_WITH_PARAMS(__func__
, axes
, functions
, parameters
),
223 return hkl_mode_auto_new(&info
,
224 &psi_constant_vertical_mode_operations
);
227 static HklMode
*psi_constant_horizontal(void)
229 static const char* axes
[] = {"omega", "chi", "phi", "gamma"};
230 static const HklFunction
*functions
[] = {&psi_constant_vertical_func
};
231 static const HklParameter parameters
[] = {
232 {HKL_PARAMETER_DEFAULTS
, .name
= "h2", .range
= {.min
=-1, .max
=1}, ._value
= 1,},
233 {HKL_PARAMETER_DEFAULTS
, .name
= "k2", .range
= {.min
=-1, .max
=1}, ._value
= 0,},
234 {HKL_PARAMETER_DEFAULTS
, .name
= "l2", .range
= {.min
=-1, .max
=1}, ._value
= 0,},
235 {HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "psi"},
237 static const HklModeAutoInfo info
= {
238 INFO_AUTO_WITH_PARAMS(__func__
, axes
, functions
, parameters
),
241 return hkl_mode_auto_new(&info
,
242 &psi_constant_vertical_mode_operations
);
245 static HklMode
*constant_mu_horizontal(void)
247 static const char* axes
[] = {"chi", "phi", "gamma"};
248 static const HklFunction
*functions
[] = {&RUBh_minus_Q_func
};
249 static const HklModeAutoInfo info
= {
250 INFO_AUTO(__func__
, axes
, functions
),
253 return hkl_mode_auto_new(&info
,
254 &hkl_full_mode_operations
);
257 /***********************/
258 /* E6C PseudoAxeEngine */
259 /***********************/
261 HklEngine
*hkl_engine_e6c_hkl_new(void)
264 HklMode
*default_mode
;
266 self
= hkl_engine_hkl_new();
268 default_mode
= bissector_vertical();
269 hkl_engine_add_mode(self
, default_mode
);
270 hkl_engine_select_mode(self
, default_mode
);
272 hkl_engine_add_mode(self
, constant_omega_vertical());
273 hkl_engine_add_mode(self
, constant_chi_vertical());
274 hkl_engine_add_mode(self
, constant_phi_vertical());
275 hkl_engine_add_mode(self
, lifting_detector_phi());
276 hkl_engine_add_mode(self
, lifting_detector_omega());
277 hkl_engine_add_mode(self
, lifting_detector_mu());
278 hkl_engine_add_mode(self
, double_diffraction_vertical());
279 hkl_engine_add_mode(self
, bissector_horizontal());
280 hkl_engine_add_mode(self
, double_diffraction_horizontal());
281 hkl_engine_add_mode(self
, psi_constant_vertical());
282 hkl_engine_add_mode(self
, psi_constant_horizontal());
283 hkl_engine_add_mode(self
, constant_mu_horizontal());