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-2014 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 <gsl/gsl_sf_trig.h> // for gsl_sf_angle_restrict_symm
23 #include <math.h> // for cos, sin, M_PI_2, atan, tan
24 #include <string.h> // for NULL, strcmp
25 #include "hkl-factory-private.h" // for autodata_factories_, etc
26 #include "hkl-geometry-private.h"
27 #include "hkl-pseudoaxis-common-eulerians-private.h"
28 #include "hkl-pseudoaxis-common-q-private.h" // for hkl_engine_q2_new, etc
29 #include "hkl-pseudoaxis-private.h" // for hkl_engine_list_add, etc
30 #include "hkl-pseudoaxis-soleil-sixs-med-private.h"
31 #include "hkl-pseudoaxis-zaxis-private.h" // for hkl_engine_zaxis_hkl_new
32 #include "hkl.h" // for HklFactory, HklGeometry, etc
33 #include "hkl/ccan/autodata/autodata.h" // for AUTODATA, autodata_get
34 #include "hkl/ccan/darray/darray.h" // for darray_item
36 HklFactory
**hkl_factory_get_all(unsigned int *n
)
38 return autodata_get(factories
, n
);
41 HklFactory
*hkl_factory_get_by_name(const char *name
, GError
**error
)
44 HklFactory
**factories
;
46 factories
= autodata_get(factories
, &n
);
48 if (!strcmp(name
, factories
[i
]->name
))
54 const char *hkl_factory_name_get(const HklFactory
*self
)
59 HklGeometry
*hkl_factory_create_new_geometry(const HklFactory
*self
)
61 return self
->create_new_geometry(self
);
64 HklEngineList
*hkl_factory_create_new_engine_list(const HklFactory
*self
)
66 return self
->create_new_engine_list(self
);
73 #define HKL_GEOMETRY_TYPE_ZAXIS_DESCRIPTION \
74 "For this geometry the **mu** axis is common to the sample and the detector.\n" \
76 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
77 "+ 2 axes for the sample\n" \
79 " + **mu** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
80 " + **omega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
82 "+ 3 axis for the detector\n" \
84 " + **mu** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
85 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
86 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n"
88 static const char* hkl_geometry_zaxis_axes
[] = {"mu", "omega", "delta", "gamma"};
90 static HklGeometry
*hkl_geometry_new_zaxis(const HklFactory
*factory
)
92 HklGeometry
*self
= hkl_geometry_new(factory
);
95 h
= hkl_geometry_add_holder(self
);
96 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
97 hkl_holder_add_rotation_axis(h
, "omega", 0, -1, 0);
99 h
= hkl_geometry_add_holder(self
);
100 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
101 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
102 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
107 static HklEngineList
*hkl_engine_list_new_zaxis(const HklFactory
*factory
)
109 HklEngineList
*self
= hkl_engine_list_new();
111 hkl_engine_list_add(self
, hkl_engine_zaxis_hkl_new());
112 hkl_engine_list_add(self
, hkl_engine_q2_new());
113 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
118 REGISTER_DIFFRACTOMETER(zaxis
, "ZAXIS", HKL_GEOMETRY_TYPE_ZAXIS_DESCRIPTION
);
120 /***********************/
121 /* SOLEIL SIXS MED 2+2 */
122 /***********************/
124 #define HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_2_DESCRIPTION \
125 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
126 "+ 3 axes for the sample\n" \
128 " + **beta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
129 " + **mu** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
130 " + **omega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
132 "+ 3 axis for the detector\n" \
134 " + **beta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
135 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
136 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
138 static const char* hkl_geometry_soleil_sixs_med_2_2_axes
[] = {"beta", "mu", "omega", "gamma", "delta"};
140 static HklGeometry
*hkl_geometry_new_soleil_sixs_med_2_2(const HklFactory
*factory
)
142 HklGeometry
*self
= hkl_geometry_new(factory
);
145 h
= hkl_geometry_add_holder(self
);
146 hkl_holder_add_rotation_axis(h
, "beta", 0, -1, 0);
147 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
148 hkl_holder_add_rotation_axis(h
, "omega", 0, -1, 0);
150 h
= hkl_geometry_add_holder(self
);
151 hkl_holder_add_rotation_axis(h
, "beta", 0, -1, 0);
152 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
153 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
158 static HklEngineList
*hkl_engine_list_new_soleil_sixs_med_2_2(const HklFactory
*factory
)
160 HklEngineList
*self
= hkl_engine_list_new();
162 hkl_engine_list_add(self
, hkl_engine_soleil_sixs_med_2_2_hkl_new());
163 hkl_engine_list_add(self
, hkl_engine_q2_new());
164 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
169 REGISTER_DIFFRACTOMETER(soleil_sixs_med_2_2
,"SOLEIL SIXS MED2+2", HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_2_DESCRIPTION
);
171 /***********************/
172 /* SOLEIL SIXS MED 1+2 */
173 /***********************/
175 #define HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_1_2_DESCRIPTION \
176 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
177 "+ 2 axes for the sample\n" \
179 " + **pitch** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
180 " + **mu** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
182 "+ 3 axis for the detector\n" \
184 " + **pitch** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
185 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
186 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n"
188 static const char* hkl_geometry_soleil_sixs_med_1_2_axes
[] = {"pitch", "mu", "gamma", "delta"};
190 static HklGeometry
*hkl_geometry_new_soleil_sixs_med_1_2(const HklFactory
*factory
)
192 HklGeometry
*self
= hkl_geometry_new(factory
);
195 h
= hkl_geometry_add_holder(self
);
196 hkl_holder_add_rotation_axis(h
, "pitch", 0, -1, 0);
197 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
199 h
= hkl_geometry_add_holder(self
);
200 hkl_holder_add_rotation_axis(h
, "pitch", 0, -1, 0);
201 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
202 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
207 static HklEngineList
*hkl_engine_list_new_soleil_sixs_med_1_2(const HklFactory
*factory
)
209 HklEngineList
*self
= hkl_engine_list_new();
211 hkl_engine_list_add(self
, hkl_engine_soleil_sixs_med_1_2_hkl_new());
212 hkl_engine_list_add(self
, hkl_engine_q2_new());
213 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
218 REGISTER_DIFFRACTOMETER(soleil_sixs_med_1_2
, "SOLEIL SIXS MED1+2", HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_1_2_DESCRIPTION
);
221 /***********************/
222 /* SOLEIL SIXS MED 2+3 */
223 /***********************/
225 #define HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_3_DESCRIPTION \
226 "+ xrays source fix allong the :math:`\\vec{x}` direction (1, 0, 0)\n" \
227 "+ 3 axes for the sample\n" \
229 " + **beta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
230 " + **mu** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
231 " + **omega** : rotating around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
233 "+ 4 axis for the detector\n" \
235 " + **beta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
236 " + **gamma** : rotation around the :math:`\\vec{z}` direction (0, 0, 1)\n" \
237 " + **delta** : rotation around the :math:`-\\vec{y}` direction (0, -1, 0)\n" \
238 " + **eta_a** : rotation around the :math:`-\\vec{x}` direction (-1, 0, 0)\n"
240 static const char* hkl_geometry_soleil_sixs_med_2_3_axes
[] = {"beta", "mu", "omega", "gamma", "delta", "eta_a"};
242 static HklGeometry
*hkl_geometry_new_soleil_sixs_med_2_3(const HklFactory
*factory
)
244 HklGeometry
*self
= hkl_geometry_new(factory
);
247 h
= hkl_geometry_add_holder(self
);
248 hkl_holder_add_rotation_axis(h
, "beta", 0, -1, 0);
249 hkl_holder_add_rotation_axis(h
, "mu", 0, 0, 1);
250 hkl_holder_add_rotation_axis(h
, "omega", 0, -1, 0);
252 h
= hkl_geometry_add_holder(self
);
253 hkl_holder_add_rotation_axis(h
, "beta", 0, -1, 0);
254 hkl_holder_add_rotation_axis(h
, "gamma", 0, 0, 1);
255 hkl_holder_add_rotation_axis(h
, "delta", 0, -1, 0);
256 hkl_holder_add_rotation_axis(h
, "eta_a", -1, 0, 0);
261 static HklEngineList
*hkl_engine_list_new_soleil_sixs_med_2_3(const HklFactory
*factory
)
263 HklEngineList
*self
= hkl_engine_list_new();
265 self
->geometries
->multiply
= hkl_geometry_list_multiply_soleil_sixs_med_2_3
;
266 hkl_engine_list_add(self
, hkl_engine_soleil_sixs_med_2_3_hkl_new());
267 hkl_engine_list_add(self
, hkl_engine_q2_new());
268 hkl_engine_list_add(self
, hkl_engine_qper_qpar_new());
273 REGISTER_DIFFRACTOMETER(soleil_sixs_med_2_3
, "SOLEIL SIXS MED2+3", HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_3_DESCRIPTION
);