[hkl] fix the test suite due to binoculars new projection signature.
[hkl.git] / hkl / hkl-pseudoaxis-common-readonly.c
blobdd0809ecdff648c0ed9c2c7efc64b25d8f661918
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-2019, 2022 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 "hkl-pseudoaxis-common-readonly-private.h"
23 #include "hkl-pseudoaxis-private.h"
25 /* incidence */
27 typedef struct _HklEngineIncidence HklEngineIncidence;
29 struct _HklEngineIncidence
31 HklEngine engine;
32 HklParameter *incidence;
33 HklParameter *azimuth;
36 #define HKL_MODE_INCIDENCE_ERROR hkl_mode_incidence_error_quark ()
38 static GQuark hkl_mode_incidence_error_quark (void)
40 return g_quark_from_static_string ("hkl-mode-incidence-error-quark");
43 typedef enum {
44 HKL_MODE_INCIDENCE_ERROR_GET, /* can not get the engine */
45 HKL_MODE_INCIDENCE_ERROR_SET, /* can not set the engine */
46 } HklModeIncidenceError;
48 static int hkl_mode_incidence_get_real(HklMode *base,
49 HklEngine *engine,
50 HklGeometry *geometry,
51 HklDetector *detector,
52 HklSample *sample,
53 GError **error)
55 HklVector ki;
56 double incidence;
57 double azimuth;
58 static const HklVector Y = {
59 .data = {0, 1, 0},
62 if (!base || !engine || !engine->mode || !geometry || !detector || !sample){
63 g_set_error(error,
64 HKL_MODE_INCIDENCE_ERROR,
65 HKL_MODE_INCIDENCE_ERROR_GET,
66 "internal error");
67 return FALSE;
69 HklEngineIncidence *engine_incidence = container_of(engine, HklEngineIncidence, engine);
70 const HklModeIncidence *mode = container_of(base, HklModeIncidence, parent);
71 HklVector n = {
72 .data = {
73 mode->n_x->_value,
74 mode->n_y->_value,
75 mode->n_z->_value,
79 /* first check the parameters */
80 if (hkl_vector_is_null(&n)){
81 g_set_error(error,
82 HKL_MODE_INCIDENCE_ERROR,
83 HKL_MODE_INCIDENCE_ERROR_GET,
84 "can not compute the incidence when the surface vector is null.");
85 return FALSE;
88 /* compute the orientation of the surface */
89 const HklHolder *sample_holder = hkl_geometry_sample_holder_get(geometry, sample);
90 hkl_vector_rotated_quaternion(&n, &sample_holder->q);
92 ki = hkl_geometry_ki_get(geometry);
93 incidence = _incidence(&n, &ki);
95 hkl_vector_project_on_plan(&n, &ki);
96 azimuth = hkl_vector_angle(&n, &Y);
98 engine_incidence->incidence->_value = incidence;
99 engine_incidence->azimuth->_value = azimuth;
101 return TRUE;
104 static int hkl_mode_readonly_set_real(HklMode *base,
105 HklEngine *engine,
106 HklGeometry *geometry,
107 HklDetector *detector,
108 HklSample *sample,
109 GError **error)
111 g_set_error(error,
112 HKL_MODE_INCIDENCE_ERROR,
113 HKL_MODE_INCIDENCE_ERROR_SET,
114 "The \"%s\" engine is readonly", base->info->name);
115 return FALSE;
118 HklMode *hkl_mode_incidence_new(const HklModeInfo *info)
120 static const HklModeOperations operations = {
121 HKL_MODE_OPERATIONS_DEFAULTS,
122 .capabilities = HKL_ENGINE_CAPABILITIES_READABLE,
123 .get = hkl_mode_incidence_get_real,
124 .set = hkl_mode_readonly_set_real,
126 HklModeIncidence *self = g_new(HklModeIncidence, 1);
128 /* the base constructor; */
129 hkl_mode_init(&self->parent,
130 info,
131 &operations, TRUE);
133 self->n_x = register_mode_parameter(&self->parent, 0);
134 self->n_y = register_mode_parameter(&self->parent, 1);
135 self->n_z = register_mode_parameter(&self->parent, 2);
137 return &self->parent;
140 static void hkl_engine_incidence_free_real(HklEngine *base)
142 HklEngineIncidence *self=container_of(base, HklEngineIncidence, engine);
143 hkl_engine_release(&self->engine);
144 free(self);
147 HklEngine *hkl_engine_incidence_new(HklEngineList *engines)
149 HklEngineIncidence *self;
150 static const HklParameter incidence = {
151 HKL_PARAMETER_DEFAULTS_ANGLE, .name = "incidence",
152 .description = "incidence of the incomming beam.",
154 static const HklParameter azimuth = {
155 HKL_PARAMETER_DEFAULTS_ANGLE, .name = "azimuth",
156 .description = "azimuth of the sample surface (projection of $\\vec{n}$ on the $yOz$ plan",
158 static const HklParameter *pseudo_axes[] = {&incidence, &azimuth};
159 static HklEngineInfo info = {
160 HKL_ENGINE_INFO("incidence",
161 pseudo_axes,
162 HKL_ENGINE_DEPENDENCIES_AXES | HKL_ENGINE_DEPENDENCIES_SAMPLE),
164 static HklEngineOperations operations = {
165 HKL_ENGINE_OPERATIONS_DEFAULTS,
166 .free=hkl_engine_incidence_free_real,
169 self = g_new(HklEngineIncidence, 1);
171 hkl_engine_init(&self->engine, &info, &operations, engines);
173 self->incidence = register_pseudo_axis(&self->engine, engines, &incidence);
174 self->azimuth = register_pseudo_axis(&self->engine, engines, &azimuth);
176 return &self->engine;
179 /* emergence */
181 typedef struct _HklEngineEmergence HklEngineEmergence;
183 struct _HklEngineEmergence
185 HklEngine engine;
186 HklParameter *emergence;
187 HklParameter *azimuth;
190 #define HKL_MODE_EMERGENCE_ERROR hkl_mode_emergence_error_quark ()
192 static GQuark hkl_mode_emergence_error_quark (void)
194 return g_quark_from_static_string ("hkl-mode-emergence-error-quark");
197 typedef enum {
198 HKL_MODE_EMERGENCE_ERROR_GET, /* can not get the engine */
199 HKL_MODE_EMERGENCE_ERROR_SET, /* can not set the engine */
200 } HklModeEmergenceError;
202 static int hkl_mode_emergence_get_real(HklMode *base,
203 HklEngine *engine_base,
204 HklGeometry *geometry,
205 HklDetector *detector,
206 HklSample *sample,
207 GError **error)
209 HklVector kf;
210 double emergence;
211 double azimuth;
212 static const HklVector X = {
213 .data = {1, 0, 0},
215 static const HklVector Y = {
216 .data = {0, 1, 0},
219 if (!base || !engine_base || !engine_base->mode || !geometry || !detector || !sample){
220 g_set_error(error,
221 HKL_MODE_EMERGENCE_ERROR,
222 HKL_MODE_EMERGENCE_ERROR_GET,
223 "internal error");
224 return FALSE;
226 HklEngineEmergence *engine = container_of(engine_base, HklEngineEmergence, engine);
227 const HklModeIncidence *mode = container_of(base, HklModeIncidence, parent);
228 HklVector n = {
229 .data = {
230 mode->n_x->_value,
231 mode->n_y->_value,
232 mode->n_z->_value,
236 /* first check the parameters */
237 if (hkl_vector_is_null(&n)){
238 g_set_error(error,
239 HKL_MODE_EMERGENCE_ERROR,
240 HKL_MODE_EMERGENCE_ERROR_GET,
241 "Can not compute the emergence when the surface vector is null.");
242 return FALSE;
245 /* compute the orientation of the surface */
246 const HklHolder *sample_holder = hkl_geometry_sample_holder_get(geometry, sample);
247 hkl_vector_rotated_quaternion(&n, &sample_holder->q);
249 kf = hkl_geometry_kf_get(geometry, detector);
250 emergence = _emergence(&n, &kf);
252 hkl_vector_project_on_plan(&n, &X);
253 azimuth = hkl_vector_angle(&n, &Y);
255 engine->emergence->_value = emergence;
256 engine->azimuth->_value = azimuth;
258 return TRUE;
261 HklMode *hkl_mode_emergence_new(const HklModeInfo *info)
263 static const HklModeOperations operations = {
264 HKL_MODE_OPERATIONS_DEFAULTS,
265 .capabilities = HKL_ENGINE_CAPABILITIES_READABLE,
266 .get = hkl_mode_emergence_get_real,
267 .set = hkl_mode_readonly_set_real,
269 HklModeIncidence *self = g_new(HklModeIncidence, 1);
271 /* the base constructor; */
272 hkl_mode_init(&self->parent,
273 info,
274 &operations, TRUE);
276 self->n_x = register_mode_parameter(&self->parent, 0);
277 self->n_y = register_mode_parameter(&self->parent, 1);
278 self->n_z = register_mode_parameter(&self->parent, 2);
280 return &self->parent;
283 static void hkl_engine_emergence_free_real(HklEngine *base)
285 HklEngineEmergence *self=container_of(base, HklEngineEmergence, engine);
286 hkl_engine_release(&self->engine);
287 free(self);
290 HklEngine *hkl_engine_emergence_new(HklEngineList *engines)
292 HklEngineEmergence *self = g_new(HklEngineEmergence, 1);
294 static const HklParameter emergence = {
295 HKL_PARAMETER_DEFAULTS_ANGLE, .name = "emergence",
296 .description = "incidence of the outgoing beam.",
298 static const HklParameter azimuth = {
299 HKL_PARAMETER_DEFAULTS_ANGLE, .name = "azimuth",
300 .description = "azimuth of the sample surface (projection of $\\vec{n}$ on the $yOz$ plan",
302 static const HklParameter *pseudo_axes[] = {&emergence, &azimuth};
303 static HklEngineInfo info = {
304 HKL_ENGINE_INFO("emergence",
305 pseudo_axes,
306 HKL_ENGINE_DEPENDENCIES_AXES | HKL_ENGINE_DEPENDENCIES_SAMPLE),
308 static HklEngineOperations operations = {
309 HKL_ENGINE_OPERATIONS_DEFAULTS,
310 .free=hkl_engine_emergence_free_real,
314 hkl_engine_init(&self->engine, &info, &operations, engines);
316 self->emergence = register_pseudo_axis(&self->engine, engines, &emergence);
317 self->azimuth = register_pseudo_axis(&self->engine, engines, &azimuth);
319 return &self->engine;