* add the axis source test
[hkl.git] / src / eulerian4C_vertical_mode.cpp
blob8deb80ce1a81f5d520e0284b2b939512833f1a49
1 #include "eulerian4C_vertical_mode.h"
2 #include "value.h"
3 #include "smatrix.h"
4 #include "parameter.h"
6 namespace hkl
9 namespace eulerian4C
12 namespace vertical
15 namespace mode
18 Bissector::Bissector(const std::string & name, const std::string & description, hkl::eulerian4C::vertical::Geometry & geometry) :
19 ModeTemp<hkl::eulerian4C::vertical::Geometry>(name, description, geometry)
23 Bissector::~Bissector()
27 /**
28 * @brief The main function to get a sample of angles from (h,k,l).
29 * @param h The scaterring vector first coordinate.
30 * @param k The scaterring vector second coordinate.
31 * @param l The scaterring vector third coordinate.
32 * @param UB The product of the orientation matrix U by the crystal matrix B.
35 void Bissector::computeAngles(const hkl::Value & h, const hkl::Value & k, const hkl::Value & l, hkl_smatrix const * UB) const
37 if (this->_parametersAreOk(h, k, l, UB))
39 double theta;
40 hkl_svector hphi;
41 this->_computeThetaAndHphi(h, k, l, UB, theta, &hphi);
43 // Calcule de Omega
44 double omega = theta;
46 // Calcule de Chi
47 double s_chi = hphi.data[Y];
48 double c_chi = hphi.data[X] * hphi.data[X] + hphi.data[Z] * hphi.data[Z];
49 if (c_chi < 0.)
50 HKLEXCEPTION("Unreachable reflection.",
51 "Change h k l values");
52 else
53 c_chi = sqrt(c_chi);
54 double chi = convenience::atan2(s_chi, c_chi);
56 // Calcule de Phi
57 double s_phi = hphi.data[X];
58 double c_phi = hphi.data[Z];
59 double phi = convenience::atan2(s_phi, c_phi);
61 _geometry.omega()->set_consign(omega);
62 _geometry.chi()->set_consign(chi);
63 _geometry.phi()->set_consign(phi);
64 _geometry.tth()->set_consign(2.*theta);
68 Delta_Theta::Delta_Theta(const std::string & name, const std::string & description, hkl::eulerian4C::vertical::Geometry & geometry) :
69 ModeTemp<hkl::eulerian4C::vertical::Geometry>(name, description, geometry)
71 _dtheta = new Parameter("delta theta", "The omega offset relatively to theta.",
72 0 * HKL_DEGTORAD, 0 * HKL_DEGTORAD, 180 * HKL_DEGTORAD);
73 _parameters.add(_dtheta);
76 Delta_Theta::~Delta_Theta()
78 delete _dtheta;
81 /**
82 * @brief The main function to get a sample of angles from (h,k,l).
83 * @param h The scaterring vector first coordinate.
84 * @param k The scaterring vector second coordinate.
85 * @param l The scaterring vector third coordinate.
86 * @param UB The product of the orientation matrix U by the crystal matrix B.
89 void Delta_Theta::computeAngles(const hkl::Value & h, const hkl::Value & k, const hkl::Value & l, hkl_smatrix const * UB) const
91 if (this->_parametersAreOk(h, k, l, UB))
93 double theta;
94 hkl_svector hphi;
95 this->_computeThetaAndHphi(h, k, l, UB, theta, &hphi);
97 // Calcule de Omega
98 // By definition in 4C omega constant mode.
99 double dtheta = _dtheta->get_current().get_value();
100 double omega = theta + dtheta;
102 // Calcule de Chi
103 double s_chi = hphi.data[Y];
104 double c_chi = hphi.data[X] * hphi.data[X] - hphi.data[Y] * hphi.data[Y] * tan(dtheta) * tan(dtheta) + hphi.data[Z] * hphi.data[Z];
105 if (c_chi < 0.)
106 HKLEXCEPTION("Unreachable reflection.", "Change h k l values");
107 else
108 c_chi = sqrt(c_chi) * cos(dtheta);
109 double chi = convenience::atan2(s_chi, c_chi);
111 // Calcule de Phi
112 double s_phi = hphi.data[X] * cos(dtheta) * cos(chi) - hphi.data[Z] * sin(dtheta);
113 double c_phi = hphi.data[Z] * cos(dtheta) * cos(chi) + hphi.data[X] * sin(dtheta);
114 double phi = convenience::atan2(s_phi, c_phi);
116 _geometry.omega()->set_consign(omega);
117 _geometry.chi()->set_consign(chi);
118 _geometry.phi()->set_consign(phi);
119 _geometry.tth()->set_consign(2.*theta);
123 Constant_Omega::Constant_Omega(const std::string & name, const std::string & description, hkl::eulerian4C::vertical::Geometry & geometry) :
124 ModeTemp<hkl::eulerian4C::vertical::Geometry>(name, description, geometry)
126 _omega = new Parameter("omega", "The fix value of omega.",
127 0 * HKL_DEGTORAD, 0 * HKL_DEGTORAD, 180 * HKL_DEGTORAD);
128 _parameters.add(_omega);
131 Constant_Omega::~Constant_Omega()
133 delete _omega;
137 * @brief The main function to get a sample of angles from (h,k,l).
138 * @param h The scaterring vector first coordinate.
139 * @param k The scaterring vector second coordinate.
140 * @param l The scaterring vector third coordinate.
141 * @param UB The product of the orientation matrix U by the crystal matrix B.
144 void Constant_Omega::computeAngles(const hkl::Value & h, const hkl::Value & k, const hkl::Value & l, hkl_smatrix const * UB) const
146 if (this->_parametersAreOk(h, k, l, UB))
148 double theta;
149 hkl_svector hphi;
150 this->_computeThetaAndHphi(h, k, l, UB, theta, &hphi);
152 // La définition de omega dans ce mode.
153 double omega = _omega->get_current().get_value();
155 // calcule de Chi.
156 double s_chi = hphi.data[Y];
157 double c_chi = (hphi.data[X]*hphi.data[X] + hphi.data[Z]*hphi.data[Z])*cos(omega-theta)*cos(omega-theta)-hphi.data[Y]*hphi.data[Y]*sin(omega-theta)*sin(omega-theta);
158 if (c_chi < 0.)
159 HKLEXCEPTION("Unreachable reflection.", "Change h k l values");
160 else
161 c_chi = sqrt(c_chi);
162 double chi = convenience::atan2(s_chi, c_chi);
164 // Calcule de Phi
165 double s_phi = hphi.data[X] * cos(chi) * cos(omega - theta) - hphi.data[Z] * sin(omega - theta);
166 double c_phi = hphi.data[X] * sin(omega - theta) + hphi.data[Z] * cos(chi) * cos(omega - theta);
167 double phi = convenience::atan2(s_phi, c_phi);
169 _geometry.omega()->set_consign(omega);
170 _geometry.chi()->set_consign(chi);
171 _geometry.phi()->set_consign(phi);
172 _geometry.tth()->set_consign(2.*theta);
176 Constant_Chi::Constant_Chi(const std::string & name, const std::string & description, hkl::eulerian4C::vertical::Geometry & geometry) :
177 ModeTemp<hkl::eulerian4C::vertical::Geometry>(name, description, geometry)
179 _chi = new Parameter("chi", "The fix value of chi.",
180 0 * HKL_DEGTORAD, 0 * HKL_DEGTORAD, 180 * HKL_DEGTORAD);
181 _parameters.add(_chi);
184 Constant_Chi::~Constant_Chi()
186 delete _chi;
190 * @brief The main function to get a sample of angles from (h,k,l).
191 * @param h The scaterring vector first coordinate.
192 * @param k The scaterring vector second coordinate.
193 * @param l The scaterring vector third coordinate.
194 * @param UB The product of the orientation matrix U by the crystal matrix B.
197 void Constant_Chi::computeAngles(const hkl::Value & h, const hkl::Value & k, const hkl::Value & l, hkl_smatrix const * UB) const
199 if (this->_parametersAreOk(h, k, l, UB))
201 double theta;
202 hkl_svector hphi;
203 this->_computeThetaAndHphi(h, k, l, UB, theta, &hphi);
205 // La définition de chi dans ce mode.
206 double chi = _chi->get_current().get_value();
207 //! \todo traiter le cas C=0;
209 // calcule de Omega.
210 double s_omega_theta = (hphi.data[X]*hphi.data[X] + hphi.data[Z]*hphi.data[Z])*sin(chi)*sin(chi) - hphi.data[Y]*hphi.data[Y]*cos(chi)*cos(chi);
211 double c_omega_theta = hphi.data[Y];
212 if (s_omega_theta < 0.)
213 HKLEXCEPTION("Unreachable reflection.", "Change h k l values");
214 else
215 s_omega_theta = sqrt(s_omega_theta);
216 double omega = convenience::atan2(s_omega_theta, c_omega_theta) + theta;
218 // Calcule de Phi
219 double s_phi = hphi.data[X] * cos(chi) * cos(omega - theta) - hphi.data[Z] * sin(omega - theta);
220 double c_phi = hphi.data[X] * sin(omega - theta) + hphi.data[Z] * cos(chi) * cos(omega - theta);
221 double phi = convenience::atan2(s_phi, c_phi);
223 _geometry.omega()->set_consign(omega);
224 _geometry.chi()->set_consign(chi);
225 _geometry.phi()->set_consign(phi);
226 _geometry.tth()->set_consign(2.*theta);
230 Constant_Phi::Constant_Phi(const std::string & name, const std::string & description, hkl::eulerian4C::vertical::Geometry & geometry) :
231 ModeTemp<hkl::eulerian4C::vertical::Geometry>(name, description, geometry)
233 _phi = new Parameter("phi", "The fix value of phi.",
234 0 * HKL_DEGTORAD, 0 * HKL_DEGTORAD, 180 * HKL_DEGTORAD);
235 _parameters.add(_phi);
238 Constant_Phi::~Constant_Phi()
240 delete _phi;
244 * @brief The main function to get a sample of angles from (h,k,l).
245 * @param h The scaterring vector first coordinate.
246 * @param k The scaterring vector second coordinate.
247 * @param l The scaterring vector third coordinate.
248 * @param UB The product of the orientation matrix U by the crystal matrix B.
251 void Constant_Phi::computeAngles(const hkl::Value & h, const hkl::Value & k, const hkl::Value & l, hkl_smatrix const * UB) const
253 if (this->_parametersAreOk(h, k, l, UB))
255 double theta;
256 hkl_svector hphi;
257 this->_computeThetaAndHphi(h, k, l, UB, theta, &hphi);
259 // La définition de chi dans ce mode.
260 double phi = _phi->get_current().get_value();
262 // calcule de Omega.
263 double s_omega_theta = hphi.data[X] * cos(phi) - hphi.data[Z] * sin(phi);
264 double c_omega_theta = hphi.data[X] * hphi.data[X] * sin(phi) * sin(phi) + hphi.data[Y] * hphi.data[Y] + hphi.data[Z] * hphi.data[Z] * cos(phi) * cos(phi) + hphi.data[X] * hphi.data[Z] * cos(phi) * sin(phi);
265 if (c_omega_theta < 0.)
266 HKLEXCEPTION("Unreachable reflection.", "Change h k l values");
267 else
268 c_omega_theta = sqrt(c_omega_theta);
269 double omega = convenience::atan2(s_omega_theta, c_omega_theta) + theta;
271 // Calcule de Chi
272 double s_chi = hphi.data[Y];
273 double c_chi = hphi.data[X] * sin(phi) + hphi.data[Z] * cos(phi);
274 double chi = convenience::atan2(s_chi, c_chi);
276 _geometry.omega()->set_consign(omega);
277 _geometry.chi()->set_consign(chi);
278 _geometry.phi()->set_consign(phi);
279 _geometry.tth()->set_consign(2.*theta);
284 } // namespace hkl::eulerian4C::vertical::mode
286 } // namespace hkl::eulerian4C::vertical
288 } // namespace hkl::eulerian4C
290 } // namespace hkl