fix all the references
[hkl.git] / hkl / hkl-engine-e4c.c
blob21637b87c876d6591a98fa0a0a0a8ba0294511c8
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-2014 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-q-private.h" // for hkl_engine_q2_new, etc
25 #include "hkl-pseudoaxis-common-hkl-private.h" // for hkl_mode_operations, etc
26 #include "hkl-pseudoaxis-common-psi-private.h" // for hkl_engine_psi_new, etc
28 /* bissector */
30 static int _bissector_func(const gsl_vector *x, void *params, gsl_vector *f)
32 const double omega = x->data[0];
33 const double tth = x->data[3];
35 CHECK_NAN(x->data, x->size);
37 RUBh_minus_Q(x->data, params, f->data);
38 f->data[3] = tth - 2 * fmod(omega,M_PI);
40 return GSL_SUCCESS;
43 static const HklFunction bissector_func = {
44 .function = _bissector_func,
45 .size = 4,
48 static HklMode *bissector(void)
50 static const char* axes[] = {"omega", "chi", "phi", "tth"};
51 static const HklFunction *functions[] = {&bissector_func};
52 static const HklModeAutoInfo info = {
53 HKL_MODE_AUTO_INFO(__func__, axes, axes, functions),
56 return hkl_mode_auto_new(&info,
57 &hkl_mode_operations,
58 TRUE);
61 static HklMode *constant_omega(void)
63 static const char* axes_r[] = {"omega", "chi", "phi", "tth"};
64 static const char* axes_w[] = {"chi", "phi", "tth"};
65 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
66 static const HklModeAutoInfo info = {
67 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
70 return hkl_mode_auto_new(&info,
71 &hkl_mode_operations,
72 TRUE);
75 static HklMode *constant_chi(void)
77 static const char* axes_r[] = {"omega", "chi", "phi", "tth"};
78 static const char* axes_w[] = {"omega", "phi", "tth"};
79 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
80 static const HklModeAutoInfo info = {
81 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
84 return hkl_mode_auto_new(&info,
85 &hkl_mode_operations,
86 TRUE);
89 static HklMode *constant_phi(void)
91 static const char* axes_r[] = {"omega", "chi", "phi", "tth"};
92 static const char* axes_w[] = {"omega", "chi", "tth"};
93 static const HklFunction *functions[] = {&RUBh_minus_Q_func};
94 static const HklModeAutoInfo info = {
95 HKL_MODE_AUTO_INFO(__func__, axes_r, axes_w, functions),
98 return hkl_mode_auto_new(&info,
99 &hkl_mode_operations,
100 TRUE);
103 static HklMode *double_diffraction(void)
105 static const char* axes[] = {"omega", "chi", "phi", "tth"};
106 static const HklFunction *functions[] = {&double_diffraction_func};
107 static const HklParameter parameters[] = {
108 {HKL_PARAMETER_DEFAULTS, .name = "h2", .range = {.min=-1, .max=1}, ._value = 1,},
109 {HKL_PARAMETER_DEFAULTS, .name = "k2", .range = {.min=-1, .max=1}, ._value = 1,},
110 {HKL_PARAMETER_DEFAULTS, .name = "l2", .range = {.min=-1, .max=1}, ._value = 1,},
112 static const HklModeAutoInfo info = {
113 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes, axes, functions,
114 parameters),
117 return hkl_mode_auto_new(&info,
118 &hkl_mode_operations,
119 TRUE);
122 static HklMode *psi_constant(void)
124 static const char* axes[] = {"omega", "chi", "phi", "tth"};
125 static const HklFunction *functions[] = {&psi_constant_vertical_func};
126 static const HklParameter parameters[] = {
127 {HKL_PARAMETER_DEFAULTS, .name = "h2", .range = {.min=-1, .max=1}, ._value = 1,},
128 {HKL_PARAMETER_DEFAULTS, .name = "k2", .range = {.min=-1, .max=1}, ._value = 1,},
129 {HKL_PARAMETER_DEFAULTS, .name = "l2", .range = {.min=-1, .max=1}, ._value = 1,},
130 {HKL_PARAMETER_DEFAULTS_ANGLE, .name = "psi"},
132 static const HklModeAutoInfo info = {
133 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes, axes, functions,
134 parameters),
137 return hkl_mode_auto_new(&info,
138 &psi_constant_vertical_mode_operations,
139 TRUE);
142 /***********************/
143 /* pseudo axes engines */
144 /***********************/
146 static HklEngine *hkl_engine_e4c_hkl_new(void)
148 HklEngine *self;
149 HklMode *default_mode;
151 self = hkl_engine_hkl_new();
153 default_mode = bissector();
154 hkl_engine_add_mode(self, default_mode);
155 hkl_engine_mode_set(self, default_mode);
157 hkl_engine_add_mode(self, constant_omega());
158 hkl_engine_add_mode(self, constant_chi());
159 hkl_engine_add_mode(self, constant_phi());
160 hkl_engine_add_mode(self, double_diffraction());
161 hkl_engine_add_mode(self, psi_constant());
163 return self;
166 static HklMode *psi(void)
168 static const char *axes[] = {"omega", "chi", "phi", "tth"};
169 static const HklFunction *functions[] = {&psi_func};
170 static const HklParameter parameters[] = {
171 {HKL_PARAMETER_DEFAULTS, .name = "h1", .range = {.min=-1, .max=1}, ._value=1,},
172 {HKL_PARAMETER_DEFAULTS, .name = "k1", .range = {.min=-1, .max=1}, ._value=1,},
173 {HKL_PARAMETER_DEFAULTS, .name = "l1", .range = {.min=-1, .max=1}, ._value=1,},
175 static const HklModeAutoInfo info = {
176 HKL_MODE_AUTO_INFO_WITH_PARAMS(__func__, axes, axes, functions, parameters),
179 return hkl_mode_psi_new(&info);
182 static HklEngine *hkl_engine_e4c_psi_new(void)
184 HklEngine *self;
185 HklMode *default_mode;
187 self = hkl_engine_psi_new();
189 default_mode = psi();
190 hkl_engine_add_mode(self, default_mode);
191 hkl_engine_mode_set(self, default_mode);
193 return self;
196 /********/
197 /* E4CV */
198 /********/
200 #define HKL_GEOMETRY_EULERIAN4C_VERTICAL_DESCRIPTION \
201 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
202 "+ 3 axes for the sample\n" \
203 "\n" \
204 " + **omega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
205 " + **chi** : rotating around the :math:`\\vec{x}` direction (1, 0, 0)\n" \
206 " + **phi** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
207 "\n" \
208 "+ 1 axis for the detector\n" \
209 "\n" \
210 " + **tth** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
212 static const char* hkl_geometry_eulerian4C_vertical_axes[] = {"omega", "chi", "phi", "tth"};
214 static HklGeometry *hkl_geometry_new_eulerian4C_vertical(const HklFactory *factory)
216 HklGeometry *self = hkl_geometry_new(factory);
217 HklHolder *h;
219 h = hkl_geometry_add_holder(self);
220 hkl_holder_add_rotation_axis(h, "omega", 0, -1, 0);
221 hkl_holder_add_rotation_axis(h, "chi", 1, 0, 0);
222 hkl_holder_add_rotation_axis(h, "phi", 0, -1, 0);
224 h = hkl_geometry_add_holder(self);
225 hkl_holder_add_rotation_axis(h, "tth", 0, -1, 0);
227 return self;
230 static HklEngineList *hkl_engine_list_new_eulerian4C_vertical(const HklFactory *factory)
232 HklEngineList *self = hkl_engine_list_new();
234 hkl_engine_list_add(self, hkl_engine_e4c_hkl_new());
235 hkl_engine_list_add(self, hkl_engine_e4c_psi_new());
236 hkl_engine_list_add(self, hkl_engine_q_new());
238 return self;
241 REGISTER_DIFFRACTOMETER(eulerian4C_vertical, "E4CV", HKL_GEOMETRY_EULERIAN4C_VERTICAL_DESCRIPTION);
244 /***************/
245 /* SOLEIL MARS */
246 /***************/
248 #define HKL_GEOMETRY_TYPE_SOLEIL_MARS_DESCRIPTION \
249 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
250 "+ 3 axes for the sample\n" \
251 "\n" \
252 " + **omega** : rotating around the :math:`\\vec{z}` direction (0, -1, 0)\n" \
253 " + **chi** : rotating around the :math:`\\vec{x}` direction (-1, 0, 0)\n" \
254 " + **phi** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
255 "\n" \
256 "+ 1 axis for the detector\n" \
257 "\n" \
258 " + **tth** : rotation around the :math:`\\vec{z}` direction (0, -1, 0)\n"
260 static const char* hkl_geometry_soleil_mars_axes[] = {"omega", "chi", "phi", "tth"};
262 static HklGeometry *hkl_geometry_new_soleil_mars(const HklFactory *factory)
264 HklGeometry *self = hkl_geometry_new(factory);
265 HklHolder *h;
267 h = hkl_geometry_add_holder(self);
268 hkl_holder_add_rotation_axis(h, "omega", 0, -1, 0);
269 hkl_holder_add_rotation_axis(h, "chi", -1, 0, 0);
270 hkl_holder_add_rotation_axis(h, "phi", 0, 0, 1);
272 h = hkl_geometry_add_holder(self);
273 hkl_holder_add_rotation_axis(h, "tth", 0, -1, 0);
275 return self;
278 static HklEngineList *hkl_engine_list_new_soleil_mars(const HklFactory *factory)
280 HklEngineList *self = hkl_engine_list_new();
282 hkl_engine_list_add(self, hkl_engine_e4c_hkl_new());
283 hkl_engine_list_add(self, hkl_engine_e4c_psi_new());
284 hkl_engine_list_add(self, hkl_engine_q_new());
286 return self;
289 REGISTER_DIFFRACTOMETER(soleil_mars, "SOLEIL MARS", HKL_GEOMETRY_TYPE_SOLEIL_MARS_DESCRIPTION);
291 /********/
292 /* E4CH */
293 /********/
295 #define HKL_GEOMETRY_TYPE_EULERIAN4C_HORIZONTAL_DESCRIPTION \
296 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
297 "+ 3 axes for the sample\n" \
298 "\n" \
299 " + **omega** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
300 " + **chi** : rotating around the :math:`\\vec{x}` direction (1, 0, 0)\n" \
301 " + **phi** : rotating around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
302 "\n" \
303 "+ 1 axis for the detector\n" \
304 "\n" \
305 " + **tth** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n"
307 static const char* hkl_geometry_eulerian4C_horizontal_axes[] = {"omega", "chi", "phi", "tth"};
309 static HklGeometry *hkl_geometry_new_eulerian4C_horizontal(const HklFactory *factory)
311 HklGeometry *self = hkl_geometry_new(factory);
312 HklHolder *h;
314 h = hkl_geometry_add_holder(self);
315 hkl_holder_add_rotation_axis(h, "omega", 0, 0, 1);
316 hkl_holder_add_rotation_axis(h, "chi", 1, 0, 0);
317 hkl_holder_add_rotation_axis(h, "phi", 0, 0, 1);
319 h = hkl_geometry_add_holder(self);
320 hkl_holder_add_rotation_axis(h, "tth", 0, 0, 1);
322 return self;
325 static HklEngineList *hkl_engine_list_new_eulerian4C_horizontal(const HklFactory *factory)
327 HklEngineList *self = hkl_engine_list_new();
329 hkl_engine_list_add(self, hkl_engine_e4c_hkl_new());
330 hkl_engine_list_add(self, hkl_engine_e4c_psi_new());
331 hkl_engine_list_add(self, hkl_engine_q_new());
333 return self;
336 REGISTER_DIFFRACTOMETER(eulerian4C_horizontal, "E4CH", HKL_GEOMETRY_TYPE_EULERIAN4C_HORIZONTAL_DESCRIPTION);