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-2011 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>
23 #include <gsl/gsl_sf.h>
25 #include <hkl/hkl-pseudoaxis-factory.h>
26 #include <hkl/hkl-pseudoaxis-common-eulerians.h>
27 #include <hkl/hkl-pseudoaxis-common-q.h>
28 #include <hkl/hkl-pseudoaxis-e4cv.h>
29 #include <hkl/hkl-pseudoaxis-k4cv.h>
30 #include <hkl/hkl-pseudoaxis-e6c.h>
31 #include <hkl/hkl-pseudoaxis-k6c.h>
32 #include <hkl/hkl-pseudoaxis-zaxis.h>
33 #include <hkl/hkl-pseudoaxis-soleil-sixs-med.h>
34 #include <hkl/hkl-pseudoaxis-petra3.h>
36 static void kappa_2_kappap(double komega
, double kappa
, double kphi
, double alpha
,
37 double *komegap
, double *kappap
, double *kphip
)
43 p
= atan(tan(kappa
/2.) * cos(alpha
));
44 omega
= komega
+ p
- M_PI_2
;
45 phi
= kphi
+ p
+ M_PI_2
;
47 *komegap
= gsl_sf_angle_restrict_symm(2*omega
- komega
);
49 *kphip
= gsl_sf_angle_restrict_symm(2*phi
- kphi
);
53 static void hkl_geometry_list_multiply_k4c_real(HklGeometryList
*self
, size_t idx
)
55 HklGeometry
*geometry
;
57 double komega
, komegap
;
61 geometry
= self
->items
[idx
]->geometry
;
62 komega
= hkl_axis_get_value(&geometry
->axes
[0]);
63 kappa
= hkl_axis_get_value(&geometry
->axes
[1]);
64 kphi
= hkl_axis_get_value(&geometry
->axes
[2]);
66 kappa_2_kappap(komega
, kappa
, kphi
, 50 * HKL_DEGTORAD
, &komegap
, &kappap
, &kphip
);
68 copy
= hkl_geometry_new_copy(geometry
);
69 hkl_axis_set_value(©
->axes
[0], komegap
);
70 hkl_axis_set_value(©
->axes
[1], kappap
);
71 hkl_axis_set_value(©
->axes
[2], kphip
);
73 hkl_geometry_update(copy
);
74 hkl_geometry_list_add(self
, copy
);
75 hkl_geometry_free(copy
);
78 static void hkl_geometry_list_multiply_k6c_real(HklGeometryList
*self
, size_t idx
)
80 HklGeometry
*geometry
;
82 double komega
, komegap
;
86 geometry
= self
->items
[idx
]->geometry
;
87 komega
= hkl_axis_get_value(&geometry
->axes
[1]);
88 kappa
= hkl_axis_get_value(&geometry
->axes
[2]);
89 kphi
= hkl_axis_get_value(&geometry
->axes
[3]);
91 kappa_2_kappap(komega
, kappa
, kphi
, 50 * HKL_DEGTORAD
, &komegap
, &kappap
, &kphip
);
93 copy
= hkl_geometry_new_copy(geometry
);
94 hkl_axis_set_value(©
->axes
[1], komegap
);
95 hkl_axis_set_value(©
->axes
[2], kappap
);
96 hkl_axis_set_value(©
->axes
[3], kphip
);
98 hkl_geometry_update(copy
);
99 hkl_geometry_list_add(self
, copy
);
100 hkl_geometry_free(copy
);
103 HklPseudoAxisEngineList
*hkl_pseudo_axis_engine_list_factory(const HklGeometryConfig
*config
)
105 HklPseudoAxisEngineList
*self
= NULL
;
107 self
= hkl_pseudo_axis_engine_list_new();
109 switch(config
->type
){
110 case HKL_GEOMETRY_TYPE_TWOC_VERTICAL
:
112 case HKL_GEOMETRY_TYPE_EULERIAN4C_VERTICAL
:
113 case HKL_GEOMETRY_TYPE_SOLEIL_MARS
:
114 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_e4cv_hkl_new());
115 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_e4cv_psi_new());
116 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q_new());
118 case HKL_GEOMETRY_TYPE_KAPPA4C_VERTICAL
:
119 self
->geometries
->multiply
= hkl_geometry_list_multiply_k4c_real
;
120 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_k4cv_hkl_new());
121 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_eulerians_new());
122 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_k4cv_psi_new());
123 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q_new());
125 case HKL_GEOMETRY_TYPE_EULERIAN6C
:
126 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_e6c_hkl_new());
127 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_e6c_psi_new());
128 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q2_new());
130 case HKL_GEOMETRY_TYPE_KAPPA6C
:
131 self
->geometries
->multiply
= hkl_geometry_list_multiply_k6c_real
;
132 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_k6c_hkl_new());
133 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_eulerians_new());
134 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_k6c_psi_new());
135 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q2_new());
137 case HKL_GEOMETRY_TYPE_ZAXIS
:
138 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_zaxis_hkl_new());
139 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q2_new());
141 case HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_2
:
142 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_soleil_sixs_med_2_2_hkl_new());
143 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q2_new());
145 case HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_1_2
:
146 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_soleil_sixs_med_1_2_hkl_new());
147 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_q2_new());
149 case HKL_GEOMETRY_TYPE_PETRA3_P09_EH2
:
150 hkl_pseudo_axis_engine_list_add(self
, hkl_pseudo_axis_engine_petra3_p09_eh2_hkl_new());