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-2016 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 hkl_vector_rotated_quaternion(&n
, &darray_item(geometry
->holders
, 0)->q
);
91 hkl_source_compute_ki(&geometry
->source
, &ki
);
92 incidence
= _incidence(&n
, &ki
);
94 hkl_vector_project_on_plan(&n
, &ki
);
95 azimuth
= hkl_vector_angle(&n
, &Y
);
97 engine_incidence
->incidence
->_value
= incidence
;
98 engine_incidence
->azimuth
->_value
= azimuth
;
103 static int hkl_mode_readonly_set_real(HklMode
*base
,
105 HklGeometry
*geometry
,
106 HklDetector
*detector
,
111 HKL_MODE_INCIDENCE_ERROR
,
112 HKL_MODE_INCIDENCE_ERROR_SET
,
113 "The \"%s\" engine is readonly", base
->info
->name
);
117 HklMode
*hkl_mode_incidence_new(const HklModeInfo
*info
)
119 static const HklModeOperations operations
= {
120 HKL_MODE_OPERATIONS_DEFAULTS
,
121 .capabilities
= HKL_ENGINE_CAPABILITIES_READABLE
,
122 .get
= hkl_mode_incidence_get_real
,
123 .set
= hkl_mode_readonly_set_real
,
125 HklModeIncidence
*self
= HKL_MALLOC(HklModeIncidence
);
127 /* the base constructor; */
128 hkl_mode_init(&self
->parent
,
132 self
->n_x
= register_mode_parameter(&self
->parent
, 0);
133 self
->n_y
= register_mode_parameter(&self
->parent
, 1);
134 self
->n_z
= register_mode_parameter(&self
->parent
, 2);
136 return &self
->parent
;
139 HklEngine
*hkl_engine_incidence_new(HklEngineList
*engines
)
141 HklEngineIncidence
*self
;
142 static const HklParameter incidence
= {
143 HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "incidence",
144 .description
= "incidence of the incomming beam.",
146 static const HklParameter azimuth
= {
147 HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "azimuth",
148 .description
= "azimuth of the sample surface (projection of $\\vec{n}$ on the $yOz$ plan",
150 static const HklParameter
*pseudo_axes
[] = {&incidence
, &azimuth
};
151 static HklEngineInfo info
= {
152 HKL_ENGINE_INFO("incidence",
154 HKL_ENGINE_DEPENDENCIES_AXES
| HKL_ENGINE_DEPENDENCIES_SAMPLE
),
156 static HklEngineOperations operations
= {
157 HKL_ENGINE_OPERATIONS_DEFAULTS
,
160 self
= HKL_MALLOC(HklEngineIncidence
);
162 hkl_engine_init(&self
->engine
, &info
, &operations
, engines
);
164 self
->incidence
= register_pseudo_axis(&self
->engine
, engines
, &incidence
);
165 self
->azimuth
= register_pseudo_axis(&self
->engine
, engines
, &azimuth
);
167 return &self
->engine
;
172 typedef struct _HklEngineEmergence HklEngineEmergence
;
174 struct _HklEngineEmergence
177 HklParameter
*emergence
;
178 HklParameter
*azimuth
;
181 #define HKL_MODE_EMERGENCE_ERROR hkl_mode_emergence_error_quark ()
183 static GQuark
hkl_mode_emergence_error_quark (void)
185 return g_quark_from_static_string ("hkl-mode-emergence-error-quark");
189 HKL_MODE_EMERGENCE_ERROR_GET
, /* can not get the engine */
190 HKL_MODE_EMERGENCE_ERROR_SET
, /* can not set the engine */
191 } HklModeEmergenceError
;
193 static int hkl_mode_emergence_get_real(HklMode
*base
,
194 HklEngine
*engine_base
,
195 HklGeometry
*geometry
,
196 HklDetector
*detector
,
203 static const HklVector X
= {
206 static const HklVector Y
= {
210 if (!base
|| !engine_base
|| !engine_base
->mode
|| !geometry
|| !detector
|| !sample
){
212 HKL_MODE_EMERGENCE_ERROR
,
213 HKL_MODE_EMERGENCE_ERROR_GET
,
217 HklEngineEmergence
*engine
= container_of(engine_base
, HklEngineEmergence
, engine
);
218 const HklModeIncidence
*mode
= container_of(base
, HklModeIncidence
, parent
);
227 /* first check the parameters */
228 if (hkl_vector_is_null(&n
)){
230 HKL_MODE_EMERGENCE_ERROR
,
231 HKL_MODE_EMERGENCE_ERROR_GET
,
232 "Can not compute the emergence when the surface vector is null.");
236 /* compute the orientation of the surface */
237 hkl_vector_rotated_quaternion(&n
, &darray_item(geometry
->holders
, 0)->q
);
239 hkl_detector_compute_kf(detector
, geometry
, &kf
);
240 emergence
= _emergence(&n
, &kf
);
242 hkl_vector_project_on_plan(&n
, &X
);
243 azimuth
= hkl_vector_angle(&n
, &Y
);
245 engine
->emergence
->_value
= emergence
;
246 engine
->azimuth
->_value
= azimuth
;
251 HklMode
*hkl_mode_emergence_new(const HklModeInfo
*info
)
253 static const HklModeOperations operations
= {
254 HKL_MODE_OPERATIONS_DEFAULTS
,
255 .capabilities
= HKL_ENGINE_CAPABILITIES_READABLE
,
256 .get
= hkl_mode_emergence_get_real
,
257 .set
= hkl_mode_readonly_set_real
,
259 HklModeIncidence
*self
= HKL_MALLOC(HklModeIncidence
);
261 /* the base constructor; */
262 hkl_mode_init(&self
->parent
,
266 self
->n_x
= register_mode_parameter(&self
->parent
, 0);
267 self
->n_y
= register_mode_parameter(&self
->parent
, 1);
268 self
->n_z
= register_mode_parameter(&self
->parent
, 2);
270 return &self
->parent
;
273 HklEngine
*hkl_engine_emergence_new(HklEngineList
*engines
)
275 HklEngineEmergence
*self
;
276 static const HklParameter emergence
= {
277 HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "emergence",
278 .description
= "incidence of the outgoing beam.",
280 static const HklParameter azimuth
= {
281 HKL_PARAMETER_DEFAULTS_ANGLE
, .name
= "azimuth",
282 .description
= "azimuth of the sample surface (projection of $\\vec{n}$ on the $yOz$ plan",
284 static const HklParameter
*pseudo_axes
[] = {&emergence
, &azimuth
};
285 static HklEngineInfo info
= {
286 HKL_ENGINE_INFO("emergence",
288 HKL_ENGINE_DEPENDENCIES_AXES
| HKL_ENGINE_DEPENDENCIES_SAMPLE
),
290 static HklEngineOperations operations
= {
291 HKL_ENGINE_OPERATIONS_DEFAULTS
,
294 self
= HKL_MALLOC(HklEngineEmergence
);
296 hkl_engine_init(&self
->engine
, &info
, &operations
, engines
);
298 self
->emergence
= register_pseudo_axis(&self
->engine
, engines
, &emergence
);
299 self
->azimuth
= register_pseudo_axis(&self
->engine
, engines
, &azimuth
);
301 return &self
->engine
;