void MultivariateGaussianComptonProfile::massProfile( double *result, const size_t nData, const double amplitude) const { std::vector<double> s2Cache; buildS2Cache(s2Cache); const double sigmaX(getParameter(SIGMA_X_PARAM)); const double sigmaY(getParameter(SIGMA_Y_PARAM)); const double sigmaZ(getParameter(SIGMA_Z_PARAM)); const double prefactorJ = (1.0 / (sqrt(2.0 * M_PI) * sigmaX * sigmaY * sigmaZ)) * (2.0 / M_PI); const double prefactorFSE = (pow(sigmaX, 4) + pow(sigmaY, 4) + pow(sigmaZ, 4)) / (9.0 * sqrt(2.0 * M_PI) * sigmaX * sigmaY * sigmaZ); const auto &yspace = ySpace(); const auto &modq = modQ(); for (size_t i = 0; i < nData; i++) { const double y(yspace[i]); const double q(modq[i]); double j = prefactorJ * calculateJ(s2Cache, y); double fse = (prefactorFSE / q) * calculateFSE(s2Cache, y); result[i] = amplitude * (j + fse); } }
/** * Uses a Gaussian approximation for the mass and convolutes it with the Voigt * instrument resolution function * @param result An pre-sized output vector that should be filled with the results * @param lorentzFWHM The lorentz width for the resolution * @param resolutionFWHM The sum-squared value of the resolution errors */ void GaussianComptonProfile::massProfile(std::vector<double> & result,const double lorentzFWHM, const double resolutionFWHM) const { double lorentzPos(0.0), gaussWidth(getParameter(0)), amplitude(getParameter(1)); double gaussFWHM = std::sqrt(std::pow(resolutionFWHM,2) + std::pow(2.0*STDDEV_TO_HWHM*gaussWidth,2)); const auto & yspace = ySpace(); // Gaussian already folded into Voigt voigtApprox(result, yspace, lorentzPos, amplitude, lorentzFWHM, gaussFWHM); std::vector<double> voigtDiffResult(yspace.size()); voigtApproxDiff(voigtDiffResult, yspace, lorentzPos, amplitude, lorentzFWHM, gaussFWHM); const auto & modq = modQ(); const size_t nData(result.size()); for(size_t j = 0; j < nData; ++j) { const double factor = std::pow(gaussWidth,4.0)/(3.0*modq[j]); result[j] -= factor*voigtDiffResult[j]; } }