add a few scripts to clean the files and indent using emacs.
[hkl.git] / hkl / hkl-pseudoaxis-common-q.c
blobca6c63d4f3fe4fe53ed94f13c0766a9ef87330eb
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-2010 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 * Jens Krüger <Jens.Krueger@frm2.tum.de>
23 #include <string.h>
24 #include <hkl/hkl-pseudoaxis.h>
25 #include <hkl/hkl-pseudoaxis-common.h>
26 #include <hkl/hkl-pseudoaxis-common-q.h>
27 #include <hkl/hkl-pseudoaxis-auto.h>
28 #include <gsl/gsl_sf_trig.h>
30 /*****/
31 /* q */
32 /*****/
34 static int q(const gsl_vector *x, void *params, gsl_vector *f)
36 size_t i;
37 double q;
38 double q0;
39 double tth;
40 double const *x_data;
41 double *f_data;
42 HklPseudoAxisEngine *engine;
44 x_data = gsl_vector_const_ptr(x, 0);
45 f_data = gsl_vector_ptr(f, 0);
46 engine = params;
48 /* update the workspace from x */
49 for(i=0; i<HKL_LIST_LEN(engine->axes); ++i)
50 hkl_axis_set_value(engine->axes[i], x_data[i]);
51 hkl_geometry_update(engine->geometry);
53 q0 = ((HklParameter *)engine->pseudoAxes[0])->value;
55 tth = gsl_sf_angle_restrict_symm(x_data[0]);
56 q = 2 * HKL_TAU / hkl_source_get_wavelength(&engine->geometry->source) * sin(tth/2.);
58 f_data[0] = q0 - q;
60 return GSL_SUCCESS;
63 static int hkl_pseudo_axis_engine_mode_get_q_real(HklPseudoAxisEngineMode *self,
64 HklPseudoAxisEngine *engine,
65 HklGeometry *geometry,
66 HklDetector *detector,
67 HklSample *sample,
68 HklError **error)
70 double wavelength;
71 double theta;
72 double q;
73 HklInterval range = {0, 0};
74 HklVector ki, kf;
75 HklParameter *parameter;
77 wavelength = hkl_source_get_wavelength(&geometry->source);
78 hkl_source_compute_ki(&geometry->source, &ki);
79 hkl_detector_compute_kf(detector, geometry, &kf);
80 theta = hkl_vector_angle(&ki, &kf) / 2.;
82 hkl_vector_vectorial_product(&ki, &kf);
83 if(ki.data[1] > 0)
84 theta = -theta;
86 q = 2 * HKL_TAU / wavelength * sin(theta);
88 /* update q */
89 parameter = (HklParameter *)(engine->pseudoAxes[0]);
90 hkl_parameter_set_value(parameter, q);
91 hkl_parameter_set_range(parameter, range.min, range.max);
93 return HKL_SUCCESS;
96 HklPseudoAxisEngine *hkl_pseudo_axis_engine_q_new(void)
98 HklPseudoAxisEngine *self;
99 HklPseudoAxisEngineMode *mode;
101 self = hkl_pseudo_axis_engine_new("q", 1, "q");
103 /* q */
104 hkl_parameter_init((HklParameter *)self->pseudoAxes[0],
105 "q",
106 -1, 0., 1,
107 HKL_TRUE, HKL_TRUE,
108 NULL, NULL);
109 /* q */
110 mode = hkl_pseudo_axis_engine_mode_new(
111 "q",
112 NULL,
113 hkl_pseudo_axis_engine_mode_get_q_real,
114 hkl_pseudo_axis_engine_mode_set_real,
115 1, q,
116 (size_t)0,
117 (size_t)1, "tth");
118 hkl_pseudo_axis_engine_add_mode(self, mode);
121 hkl_pseudo_axis_engine_select_mode(self, 0);
123 return self;
126 /******/
127 /* q2 */
128 /******/
130 static int q2(const gsl_vector *x, void *params, gsl_vector *f)
132 size_t i;
133 double q0, q;
134 double alpha0, alpha;
135 double wavelength, theta;
136 double const *x_data;
137 double *f_data;
138 HklPseudoAxisEngine *engine;
139 HklVector kf, ki;
140 HklVector X = {{1, 0, 0}};
142 x_data = gsl_vector_const_ptr(x, 0);
143 f_data = gsl_vector_ptr(f, 0);
144 engine = params;
146 /* update the workspace from x */
147 for(i=0; i<HKL_LIST_LEN(engine->axes); ++i)
148 hkl_axis_set_value(engine->axes[i], x_data[i]);
149 hkl_geometry_update(engine->geometry);
151 q0 = ((HklParameter *)engine->pseudoAxes[0])->value;
152 alpha0 = ((HklParameter *)engine->pseudoAxes[1])->value;
154 wavelength = hkl_source_get_wavelength(&engine->geometry->source);
155 hkl_source_compute_ki(&engine->geometry->source, &ki);
156 hkl_detector_compute_kf(engine->detector, engine->geometry, &kf);
157 theta = hkl_vector_angle(&ki, &kf) / 2.;
159 q = 2 * HKL_TAU / wavelength * sin(theta);
161 /* project kf on the x plan to compute alpha */
162 hkl_vector_project_on_plan(&kf, &X);
163 alpha = atan2(kf.data[2], kf.data[1]);
165 f_data[0] = q0 - q;
166 f_data[1] = alpha0 - alpha;
168 return GSL_SUCCESS;
172 static int hkl_pseudo_axis_engine_mode_get_q2_real(HklPseudoAxisEngineMode *self,
173 HklPseudoAxisEngine *engine,
174 HklGeometry *geometry,
175 HklDetector *detector,
176 HklSample *sample,
177 HklError **error)
179 double wavelength;
180 double theta;
181 double q, alpha;
182 HklVector x = {{1, 0, 0}};
183 HklVector ki, kf;
184 HklParameter *parameter;
186 wavelength = hkl_source_get_wavelength(&geometry->source);
187 hkl_source_compute_ki(&geometry->source, &ki);
188 hkl_detector_compute_kf(detector, geometry, &kf);
189 theta = hkl_vector_angle(&ki, &kf) / 2.;
191 q = 2 * HKL_TAU / wavelength * sin(theta);
193 /* project kf on the x plan to compute alpha */
194 hkl_vector_project_on_plan(&kf, &x);
195 alpha = atan2(kf.data[2], kf.data[1]);
197 /* update q */
198 parameter = (HklParameter *)(engine->pseudoAxes[0]);
199 hkl_parameter_set_value(parameter, q);
201 /* update alpha */
202 parameter = (HklParameter *)(engine->pseudoAxes[1]);
203 hkl_parameter_set_value(parameter, alpha);
204 hkl_parameter_set_range(parameter, -M_PI, M_PI);
206 return HKL_SUCCESS;
209 HklPseudoAxisEngine *hkl_pseudo_axis_engine_q2_new(void)
211 HklPseudoAxisEngine *self;
212 HklPseudoAxisEngineMode *mode;
214 self = hkl_pseudo_axis_engine_new("q2", 2, "q", "alpha");
216 /* q */
217 hkl_parameter_init((HklParameter *)self->pseudoAxes[0],
218 "q",
219 0., 0., 1,
220 HKL_TRUE, HKL_TRUE,
221 NULL, NULL);
223 /* alpha */
224 hkl_parameter_init((HklParameter *)self->pseudoAxes[1],
225 "alpha",
226 -M_PI, 0., M_PI,
227 HKL_TRUE, HKL_TRUE,
228 &hkl_unit_angle_rad, &hkl_unit_angle_deg);
230 /* q */
231 mode = hkl_pseudo_axis_engine_mode_new(
232 "q2",
233 NULL,
234 hkl_pseudo_axis_engine_mode_get_q2_real,
235 hkl_pseudo_axis_engine_mode_set_real,
236 1, q2,
237 (size_t)0,
238 (size_t)2, "gamma", "delta");
239 hkl_pseudo_axis_engine_add_mode(self, mode);
242 hkl_pseudo_axis_engine_select_mode(self, 0);
244 return self;