add a few scripts to clean the files and indent using emacs.
[hkl.git] / hkl / hkl-pseudoaxis-common-eulerians.c
blob043c2ea66cdc5f284a5677ec389bff0997142fe5
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 <gsl/gsl_sf_trig.h>
24 #include <hkl/hkl-pseudoaxis-auto.h>
25 #include <hkl/hkl-pseudoaxis-common-eulerians.h>
27 static int kappa_to_eulerian(double komega, double kappa, double kphi,
28 double *omega, double *chi, double *phi,
29 double alpha, int solution)
31 double Kappa = gsl_sf_angle_restrict_symm(kappa);
32 double p = atan(tan(Kappa/2.) * cos(alpha));
34 if (solution){
35 *omega = komega + p - M_PI_2;
36 *chi = 2 * asin(sin(Kappa/2.) * sin(alpha));
37 *phi = kphi + p + M_PI_2;
38 }else{
39 *omega = komega + p + M_PI_2;
40 *chi = -2 * asin(sin(Kappa/2.) * sin(alpha));
41 *phi = kphi + p - M_PI_2;
44 return HKL_SUCCESS;
47 static int eulerian_to_kappa(double omega, double chi, double phi,
48 double *komega, double *kappa, double *kphi,
49 double alpha, double solution)
51 int status = HKL_SUCCESS;
53 if (fabs(chi) <= alpha * 2){
54 double p = asin(tan(chi/2.)/tan(alpha));
56 if (solution){
57 *komega = omega - p + M_PI_2;
58 *kappa = 2 * asin(sin(chi/2.)/sin(alpha));
59 *kphi = phi - p - M_PI_2;
60 }else{
61 *komega = omega + p - M_PI_2;
62 *kappa = -2 * asin(sin(chi/2.)/sin(alpha));
63 *kphi = phi + p + M_PI_2;
65 }else
66 status = HKL_FAIL;
68 return status;
71 static int hkl_pseudo_axis_engine_mode_get_eulerians_real(HklPseudoAxisEngineMode *self,
72 HklPseudoAxisEngine *engine,
73 HklGeometry *geometry,
74 HklDetector *detector,
75 HklSample *sample,
76 HklError **error)
78 double komega, kappa, kphi;
79 int solution;
81 hkl_geometry_update(geometry);
83 solution = (int)self->parameters[0].value;
85 komega = ((HklParameter *)hkl_geometry_get_axis_by_name(geometry, "komega"))->value;
86 kappa = ((HklParameter *)hkl_geometry_get_axis_by_name(geometry, "kappa"))->value;
87 kphi = ((HklParameter *)hkl_geometry_get_axis_by_name(geometry, "kphi"))->value;
89 return kappa_to_eulerian(komega, kappa, kphi,
90 &((HklParameter *)engine->pseudoAxes[0])->value,
91 &((HklParameter *)engine->pseudoAxes[1])->value,
92 &((HklParameter *)engine->pseudoAxes[2])->value,
93 50 * HKL_DEGTORAD, solution);
96 static int hkl_pseudo_axis_engine_mode_set_eulerians_real(HklPseudoAxisEngineMode *self,
97 HklPseudoAxisEngine *engine,
98 HklGeometry *geometry,
99 HklDetector *detector,
100 HklSample *sample,
101 HklError **error)
103 int status = HKL_SUCCESS;
104 int solution;
106 double angles[3];
108 solution = (int)self->parameters[0].value;
110 status |= eulerian_to_kappa(((HklParameter *)engine->pseudoAxes[0])->value,
111 ((HklParameter *)engine->pseudoAxes[1])->value,
112 ((HklParameter *)engine->pseudoAxes[2])->value,
113 &angles[0], &angles[1], &angles[2],
114 50 * HKL_DEGTORAD, solution);
116 if (status == HKL_SUCCESS)
117 hkl_pseudo_axis_engine_add_geometry(engine, angles);
119 return status;
122 HklPseudoAxisEngine *hkl_pseudo_axis_engine_eulerians_new(void)
124 HklPseudoAxisEngine *self;
125 HklPseudoAxisEngineMode *mode;
126 HklParameter parameter = {"solution", {0, 1}, 1., NULL, NULL, 0, 0};
128 self = hkl_pseudo_axis_engine_new("eulerians", 3, "omega", "chi", "phi");
130 /* omega */
131 hkl_parameter_init((HklParameter *)self->pseudoAxes[0],
132 "omega",
133 -M_PI, 0., M_PI,
134 HKL_TRUE, HKL_TRUE,
135 &hkl_unit_angle_rad, &hkl_unit_angle_deg);
136 /* chi */
137 hkl_parameter_init((HklParameter *)self->pseudoAxes[1],
138 "chi",
139 -M_PI, 0., M_PI,
140 HKL_TRUE, HKL_TRUE,
141 &hkl_unit_angle_rad, &hkl_unit_angle_deg);
142 /* phi */
143 hkl_parameter_init((HklParameter *)self->pseudoAxes[2],
144 "phi",
145 -M_PI, 0., M_PI,
146 HKL_TRUE, HKL_TRUE,
147 &hkl_unit_angle_rad, &hkl_unit_angle_deg);
149 /* eulerians */
150 mode = hkl_pseudo_axis_engine_mode_new(
151 "eulerians",
152 NULL,
153 hkl_pseudo_axis_engine_mode_get_eulerians_real,
154 hkl_pseudo_axis_engine_mode_set_eulerians_real,
156 (size_t)1, parameter,
157 (size_t)3, "komega", "kappa", "kphi");
158 hkl_pseudo_axis_engine_add_mode(self, mode);
160 hkl_pseudo_axis_engine_select_mode(self, 0);
162 return self;