From 351a62de880fcaceb9e684cb75f0a7a23e63f167 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric-Emmanuel=20PICCA?= Date: Wed, 5 Sep 2012 17:34:12 +0200 Subject: [PATCH] add the qperqpar pseudo axis Conflicts: hkl/hkl-pseudoaxis-common-q.c hkl/hkl-pseudoaxis-common-q.h test/hkl/bench-t.c --- Documentation/sphinx/source/pseudo.rst | 23 ++++++- hkl/hkl-pseudoaxis-auto.c | 4 +- hkl/hkl-pseudoaxis-common-q.c | 113 +++++++++++++++++++++++++++++++++ hkl/hkl-pseudoaxis-common-q.h | 7 +- hkl/hkl-pseudoaxis-factory.c | 5 ++ test/bench.c | 15 +++++ 6 files changed, 162 insertions(+), 5 deletions(-) diff --git a/Documentation/sphinx/source/pseudo.rst b/Documentation/sphinx/source/pseudo.rst index c855fb6d..592238f0 100644 --- a/Documentation/sphinx/source/pseudo.rst +++ b/Documentation/sphinx/source/pseudo.rst @@ -60,13 +60,13 @@ or 2nd one \begin{eqnarray*} \omega & = & \kappa_\omega + p + \frac{\pi}{2} \\ \chi & = & -2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\ - \phi & = & \kappa_\phi + p - \frac{\pi}{2}; + \phi & = & \kappa_\phi + p - \frac{\pi}{2} \end{eqnarray*} where .. math:: - p = \arctan\left(\tan\frac{\kappa}{2} \cos\alpha\right); + p = \arctan\left(\tan\frac{\kappa}{2} \cos\alpha\right) .. figure:: ../../figures/e2k_1.png @@ -92,3 +92,22 @@ where :width: 8cm :math:`\omega = 0`, :math:`\chi = 90`, :math:`\phi = 0`, 2nd solution + +Qper and Qpar +************* + +this pseudo axis engine compute the perpendicular +(:math:`\left|\left|\vec{q_\text{per}}\right|\right|`) and parallel +(:math:`\left|\left|\vec{q_\text{par}}\right|\right|`) contribution of +:math:`\vec{Q}` relatively to the surface of the sample defined by the +:math:`\vec{n}` vector. + +.. math:: + :nowrap: + + \begin{eqnarray*} + \vec{q} & = & \vec{k_\text{f}} - \vec{k_\text{i}} \\ + \vec{q} & = & \vec{q_\text{per}} + \vec{q_\text{par}} \\ + \vec{q_\text{per}} & = & \frac{\vec{q} \cdot \vec{n}}{\left|\left|\vec{n}\right|\right|} \frac{\vec{n}}{\left|\left|\vec{n}\right|\right|} + \end{eqnarray*} + diff --git a/hkl/hkl-pseudoaxis-auto.c b/hkl/hkl-pseudoaxis-auto.c index de75bcf5..6d60a911 100644 --- a/hkl/hkl-pseudoaxis-auto.c +++ b/hkl/hkl-pseudoaxis-auto.c @@ -124,7 +124,7 @@ static int find_first_geometry(HklPseudoAxisEngine *self, do { ++iter; status = gsl_multiroot_fsolver_iterate(s); - if (status || iter % 100 == 0) { + if (status || iter % 300 == 0) { /* Restart from another point. */ for(i=0; if, HKL_EPSILON); - } while (status == GSL_CONTINUE && iter < 1000); + } while (status == GSL_CONTINUE && iter < 2000); #ifdef DEBUG fprintf(stdout, "\nstatus : %d iter : %d", status, iter); diff --git a/hkl/hkl-pseudoaxis-common-q.c b/hkl/hkl-pseudoaxis-common-q.c index ca6c63d4..19493b05 100644 --- a/hkl/hkl-pseudoaxis-common-q.c +++ b/hkl/hkl-pseudoaxis-common-q.c @@ -243,3 +243,116 @@ HklPseudoAxisEngine *hkl_pseudo_axis_engine_q2_new(void) return self; } + +/************/ +/* QperQpar */ +/************/ + +static void _qper_qpar(HklPseudoAxisEngine *engine, + HklGeometry *geometry, HklDetector *detector, + double *qper, double *qpar) +{ + HklVector ki; + HklVector q; + HklVector n; + HklVector qper_v; + HklVector qpar_v; + + /* compute q */ + hkl_source_compute_ki(&geometry->source, &ki); + hkl_detector_compute_kf(detector, geometry, &q); + hkl_vector_minus_vector(&q, &ki); + + /* compute the real orientation of n */ + hkl_vector_init(&n, + engine->mode->parameters[0].value, + engine->mode->parameters[1].value, + engine->mode->parameters[2].value); + + hkl_vector_rotated_quaternion(&n, &geometry->holders[0].q); + hkl_vector_normalize(&n); + + qper_v = n; + hkl_vector_times_double(&qper_v, hkl_vector_scalar_product(&q, &n)); + + qpar_v = q; + hkl_vector_minus_vector(&qpar_v, &qper_v); + + *qper = hkl_vector_norm2(&qper_v); + *qpar = hkl_vector_norm2(&qpar_v); +} + +static int _qper_qpar_func(const gsl_vector *x, void *params, gsl_vector *f) +{ + unsigned int i; + HklPseudoAxisEngine *engine = params; + double qper; + double qpar; + + /* update the workspace from x */ + for(i=0; iaxes); ++i) + hkl_axis_set_value(engine->axes[i], x->data[i]); + hkl_geometry_update(engine->geometry); + + + _qper_qpar(engine, engine->geometry, engine->detector, + &qper, &qpar); + + f->data[0] = engine->pseudoAxes[0]->parent.value - qper; + f->data[1] = engine->pseudoAxes[1]->parent.value - qpar; + + return GSL_SUCCESS; +} + +static int get_qper_qpar_real(HklPseudoAxisEngineMode *self, + HklPseudoAxisEngine *engine, + HklGeometry *geometry, + HklDetector *detector, + HklSample *sample, + HklError **error) +{ + _qper_qpar(engine, geometry, detector, + &engine->pseudoAxes[0]->parent.value, + &engine->pseudoAxes[1]->parent.value); + + return HKL_TRUE; +} + +HklPseudoAxisEngine *hkl_pseudo_axis_engine_qper_qpar_new(void) +{ + HklPseudoAxisEngine *self; + HklPseudoAxisEngineMode *mode; + + self = hkl_pseudo_axis_engine_new("qper_qpar", 2, "qper", "qpar"); + + /* qper */ + hkl_parameter_init((HklParameter *)self->pseudoAxes[0], + "qper", + 0., 0., 1, + HKL_TRUE, HKL_TRUE, + NULL, NULL); + + /* qpar */ + hkl_parameter_init((HklParameter *)self->pseudoAxes[0], + "qpar", + 0., 0., 1, + HKL_TRUE, HKL_TRUE, + NULL, NULL); + + + /* qper_qpar */ + mode = hkl_pseudo_axis_engine_mode_new( + "qper_qpar", + NULL, + get_qper_qpar_real, + hkl_pseudo_axis_engine_mode_set_real, + 1, _qper_qpar_func, + (size_t)0, + (size_t)2, "gamma", "delta"); + hkl_pseudo_axis_engine_add_mode(self, mode); + + + hkl_pseudo_axis_engine_select_mode(self, 0); + + return self; +} diff --git a/hkl/hkl-pseudoaxis-common-q.h b/hkl/hkl-pseudoaxis-common-q.h index dd94e4be..c56c1f5d 100644 --- a/hkl/hkl-pseudoaxis-common-q.h +++ b/hkl/hkl-pseudoaxis-common-q.h @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with the hkl library. If not, see . * - * Copyright (C) 2003-2010 Synchrotron SOLEIL + * Copyright (C) 2003-2012 Synchrotron SOLEIL * L'Orme des Merisiers Saint-Aubin * BP 48 91192 GIF-sur-YVETTE CEDEX * @@ -24,7 +24,12 @@ #include +HKL_BEGIN_DECLS + extern HklPseudoAxisEngine *hkl_pseudo_axis_engine_q_new(void); extern HklPseudoAxisEngine *hkl_pseudo_axis_engine_q2_new(void); +extern HklPseudoAxisEngine *hkl_pseudo_axis_engine_qper_qpar_new(void); + +HKL_END_DECLS #endif diff --git a/hkl/hkl-pseudoaxis-factory.c b/hkl/hkl-pseudoaxis-factory.c index 5db12ac6..cad9b379 100644 --- a/hkl/hkl-pseudoaxis-factory.c +++ b/hkl/hkl-pseudoaxis-factory.c @@ -126,6 +126,7 @@ HklPseudoAxisEngineList *hkl_pseudo_axis_engine_list_factory(const HklGeometryCo hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_e6c_hkl_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_e6c_psi_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_q2_new()); + hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_qper_qpar_new()); break; case HKL_GEOMETRY_TYPE_KAPPA6C: self->geometries->multiply = hkl_geometry_list_multiply_k6c_real; @@ -133,18 +134,22 @@ HklPseudoAxisEngineList *hkl_pseudo_axis_engine_list_factory(const HklGeometryCo hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_eulerians_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_k6c_psi_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_q2_new()); + hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_qper_qpar_new()); break; case HKL_GEOMETRY_TYPE_ZAXIS: hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_zaxis_hkl_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_q2_new()); + hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_qper_qpar_new()); break; case HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_2_2: hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_soleil_sixs_med_2_2_hkl_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_q2_new()); + hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_qper_qpar_new()); break; case HKL_GEOMETRY_TYPE_SOLEIL_SIXS_MED_1_2: hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_soleil_sixs_med_1_2_hkl_new()); hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_q2_new()); + hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_qper_qpar_new()); break; case HKL_GEOMETRY_TYPE_PETRA3_P09_EH2: hkl_pseudo_axis_engine_list_add(self, hkl_pseudo_axis_engine_petra3_p09_eh2_hkl_new()); diff --git a/test/bench.c b/test/bench.c index 1f2ed158..176447fd 100644 --- a/test/bench.c +++ b/test/bench.c @@ -114,6 +114,20 @@ static void hkl_test_bench_q2_real(HklPseudoAxisEngineList *engines, HklGeometry hkl_test_bench_run(engine, geometry, n); } +static void hkl_test_bench_qper_qpar_real(HklPseudoAxisEngineList *engines, HklGeometry *geometry, + char const *name, int n, + double qper, double qpar) +{ + HklPseudoAxisEngine *engine; + + engine = hkl_pseudo_axis_engine_list_get_by_name(engines, name); + + ((HklParameter *)engine->pseudoAxes[0])->value = qper; + ((HklParameter *)engine->pseudoAxes[1])->value = qpar; + + hkl_test_bench_run(engine, geometry, n); +} + static void hkl_test_bench_k6c(void) { HklPseudoAxisEngineList *engines; @@ -140,6 +154,7 @@ static void hkl_test_bench_k6c(void) hkl_test_bench_eulerians_real(engines, geom, "eulerians", 1000, 0, 90*HKL_DEGTORAD, 0 ); hkl_test_bench_psi_real(engines, geom, "psi", 1000, 10*HKL_DEGTORAD); hkl_test_bench_q2_real(engines, geom, "q2", 1000, 1, 10*HKL_DEGTORAD); + hkl_test_bench_qper_qpar_real(engines, geom, "qper_qpar", 1000, .5, .5); hkl_pseudo_axis_engine_list_free(engines); hkl_sample_free(sample); -- 2.11.4.GIT