static void to_matrix(void) { HklQuaternion q_ref = {{1./sqrt(2), 0, 0, 1./sqrt(2)}}; HklMatrix *m_ref = hkl_matrix_new_full(0,-1, 0, 1, 0, 0, 0, 0, 1); HklMatrix *m = hkl_matrix_new(); hkl_quaternion_to_matrix(&q_ref, m); is_matrix(m_ref, m, __func__); hkl_matrix_free(m_ref); hkl_matrix_free(m); }
static int hkl_pseudo_axis_engine_mode_init_psi_real(HklPseudoAxisEngineMode *base, HklPseudoAxisEngine *engine, HklGeometry *geometry, HklDetector *detector, HklSample *sample, HklError **error) { int status = HKL_SUCCESS; HklVector ki; HklMatrix RUB; HklPseudoAxisEngineModePsi *self = (HklPseudoAxisEngineModePsi *)base; HklHolder *holder; status = hkl_pseudo_axis_engine_init_func(base, engine, geometry, detector, sample); if (status == HKL_FAIL) return status; /* update the geometry internals */ hkl_geometry_update(geometry); /* R * UB */ /* for now the 0 holder is the sample holder. */ holder = &geometry->holders[0]; hkl_quaternion_to_matrix(&holder->q, &RUB); hkl_matrix_times_matrix(&RUB, &sample->UB); /* kf - ki = Q0 */ hkl_source_compute_ki(&geometry->source, &ki); hkl_detector_compute_kf(detector, geometry, &self->Q0); hkl_vector_minus_vector(&self->Q0, &ki); if (hkl_vector_is_null(&self->Q0)) status = HKL_FAIL; else /* compute hkl0 */ hkl_matrix_solve(&RUB, &self->hkl0, &self->Q0); return status; }
static int psi_func(const gsl_vector *x, void *params, gsl_vector *f) { HklVector dhkl0, hkl1; HklVector ki, kf, Q, n; HklMatrix RUB; HklPseudoAxisEngine *engine; HklPseudoAxisEngineModePsi *modepsi; HklPseudoAxis *psi; HklHolder *holder; size_t i; size_t len; double const *x_data = gsl_vector_const_ptr(x, 0); double *f_data = gsl_vector_ptr(f, 0); engine = params; modepsi = (HklPseudoAxisEngineModePsi *)engine->mode; psi = engine->pseudoAxes[0]; /* update the workspace from x; */ len = HKL_LIST_LEN(engine->axes); for(i=0; i<len; ++i) hkl_axis_set_value(engine->axes[i], x_data[i]); hkl_geometry_update(engine->geometry); /* kf - ki = Q */ hkl_source_compute_ki(&engine->geometry->source, &ki); hkl_detector_compute_kf(engine->detector, engine->geometry, &kf); Q = kf; hkl_vector_minus_vector(&Q, &ki); if (hkl_vector_is_null(&Q)){ f_data[0] = 1; f_data[1] = 1; f_data[2] = 1; f_data[3] = 1; }else{ /* R * UB */ /* for now the 0 holder is the sample holder. */ holder = &engine->geometry->holders[0]; hkl_quaternion_to_matrix(&holder->q, &RUB); hkl_matrix_times_matrix(&RUB, &engine->sample->UB); /* compute dhkl0 */ hkl_matrix_solve(&RUB, &dhkl0, &Q); hkl_vector_minus_vector(&dhkl0, &modepsi->hkl0); /* compute the intersection of the plan P(kf, ki) and PQ (normal Q) */ /* * now that dhkl0 have been computed we can use a * normalized Q to compute n and psi */ hkl_vector_normalize(&Q); n = kf; hkl_vector_vectorial_product(&n, &ki); hkl_vector_vectorial_product(&n, &Q); /* compute hkl1 in the laboratory referentiel */ /* for now the 0 holder is the sample holder. */ hkl1.data[0] = engine->mode->parameters[0].value; hkl1.data[1] = engine->mode->parameters[1].value; hkl1.data[2] = engine->mode->parameters[2].value; hkl_vector_times_matrix(&hkl1, &engine->sample->UB); hkl_vector_rotated_quaternion(&hkl1, &engine->geometry->holders[0].q); /* project hkl1 on the plan of normal Q */ hkl_vector_project_on_plan(&hkl1, &Q); if (hkl_vector_is_null(&hkl1)){ /* hkl1 colinear with Q */ f_data[0] = dhkl0.data[0]; f_data[1] = dhkl0.data[1]; f_data[2] = dhkl0.data[2]; f_data[3] = 1; }else{ f_data[0] = dhkl0.data[0]; f_data[1] = dhkl0.data[1]; f_data[2] = dhkl0.data[2]; f_data[3] = psi->parent.value - hkl_vector_oriented_angle(&n, &hkl1, &Q); } } return GSL_SUCCESS; }