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"
27 typedef struct _HklEngineIncidence HklEngineIncidence
;
29 struct _HklEngineIncidence
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");
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
,
50 HklGeometry
*geometry
,
51 HklDetector
*detector
,
58 static const HklVector Y
= {
62 if (!base
|| !engine
|| !engine
->mode
|| !geometry
|| !detector
|| !sample
){
64 HKL_MODE_INCIDENCE_ERROR
,
65 HKL_MODE_INCIDENCE_ERROR_GET
,
69 HklEngineIncidence
*engine_incidence
= container_of(engine
, HklEngineIncidence
, engine
);
70 const HklModeIncidence
*mode
= container_of(base
, HklModeIncidence
, parent
);
79 /* first check the parameters */
80 if (hkl_vector_is_null(&n
)){
82 HKL_MODE_INCIDENCE_ERROR
,
83 HKL_MODE_INCIDENCE_ERROR_GET
,
84 "can not compute the incidence when the surface vector is null.");
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
;
104 static int hkl_mode_readonly_set_real(HklMode
*base
,
106 HklGeometry
*geometry
,
107 HklDetector
*detector
,
112 HKL_MODE_INCIDENCE_ERROR
,
113 HKL_MODE_INCIDENCE_ERROR_SET
,
114 "The \"%s\" engine is readonly", base
->info
->name
);
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
,
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
);
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",
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
;
181 typedef struct _HklEngineEmergence HklEngineEmergence
;
183 struct _HklEngineEmergence
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");
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
,
212 static const HklVector X
= {
215 static const HklVector Y
= {
219 if (!base
|| !engine_base
|| !engine_base
->mode
|| !geometry
|| !detector
|| !sample
){
221 HKL_MODE_EMERGENCE_ERROR
,
222 HKL_MODE_EMERGENCE_ERROR_GET
,
226 HklEngineEmergence
*engine
= container_of(engine_base
, HklEngineEmergence
, engine
);
227 const HklModeIncidence
*mode
= container_of(base
, HklModeIncidence
, parent
);
236 /* first check the parameters */
237 if (hkl_vector_is_null(&n
)){
239 HKL_MODE_EMERGENCE_ERROR
,
240 HKL_MODE_EMERGENCE_ERROR_GET
,
241 "Can not compute the emergence when the surface vector is null.");
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
;
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
,
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
);
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",
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
;