Exemple #1
0
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;
}