Example #1
0
/*
 * this function tries to be a 1:1 C++ reimplementation of the Perl function
 * 'read_mcstas_res' of the McStas 'mcresplot' program
 */
Resolution calc_res(std::vector<vector<t_real>>&& Q_vec,
	const vector<t_real>& Q_avg, const std::vector<t_real>* pp_vec)
{
	vector<t_real> Q_dir = tl::make_vec({Q_avg[0], Q_avg[1], Q_avg[2]});
	Q_dir = Q_dir / norm_2(Q_dir);
	vector<t_real> Q_perp = tl::make_vec({-Q_dir[1], Q_dir[0], Q_dir[2]});
	vector<t_real> vecUp = tl::cross_3(Q_dir, Q_perp);

	/*
	 * transformation from the <Q_x, Q_y, Q_z, E> system
	 * into the <Q_avg, Q_perp, Q_z, E> system,
	 * i.e. rotate by the (ki,Q) angle
	 */
	matrix<t_real> trafo = identity_matrix<t_real>(4);
	tl::set_column(trafo, 0, Q_dir);
	tl::set_column(trafo, 1, Q_perp);
	tl::set_column(trafo, 2, vecUp);
	tl::log_info("Transformation: ", trafo);


	Resolution reso;
	reso.Q_avg_notrafo = Q_avg;
	reso.Q_avg = prod(trans(trafo), Q_avg);
	tl::log_info("Transformed average Q vector: ", reso.Q_avg);

	reso.res.resize(4,4,0);
	reso.cov.resize(4,4,0);

	reso.cov = tl::covariance(Q_vec, pp_vec);
	reso.cov = tl::transform<matrix<t_real>>(reso.cov, trafo, true);

	tl::log_info("Covariance matrix: ", reso.cov);
	if(!(reso.bHasRes = tl::inverse(reso.cov, reso.res)))
		tl::log_err("Covariance matrix could not be inverted!");

	if(reso.bHasRes)
	{
		reso.dQ.resize(4, 0);
		for(int iQ=0; iQ<4; ++iQ)
			reso.dQ[iQ] = tl::get_SIGMA2HWHM<t_real>()/sqrt(reso.res(iQ,iQ));

		tl::log_info("Resolution matrix: ", reso.res);

		std::ostringstream ostrVals;
		ostrVals << "Gaussian HWHM values: ";
		std::copy(reso.dQ.begin(), reso.dQ.end(),
			std::ostream_iterator<t_real>(ostrVals, ", "));

		std::ostringstream ostrElli;
		ostrElli << "Ellipsoid offsets: ";
		std::copy(reso.Q_avg.begin(), reso.Q_avg.end(),
			std::ostream_iterator<t_real>(ostrElli, ", "));

		reso.vecQ = std::move(Q_vec);

		tl::log_info(ostrVals.str());
		tl::log_info(ostrElli.str());
	}

	return reso;
}