81 HistogramData::Histogram inputHist)
82 : m_pars(
std::move(params)), m_histogram(
std::move(inputHist)), m_tofVals(m_histogram.points()),
83 m_histoYSize(m_histogram.size()), m_muRrange(calculateMuRange()), m_rng(
std::make_unique<
MersenneTwister>(1)) {
86 if (!(xVals.front() < xVals.back())) {
87 throw std::invalid_argument(
"TOF values are expected to be monotonically increasing");
106 std::vector<double> xmur(N_MUR_PTS + 1, 0.0), yabs(N_MUR_PTS + 1, 1.0),
107 wabs(N_MUR_PTS + 1, 1.0),
111 yms.resize(N_MUR_PTS + 1, 0.0);
112 wms.resize(N_MUR_PTS + 1, 100.0);
117 const double dmuR = (
muRmax() -
muRmin()) / to<double>(N_MUR_PTS - 1);
118 for (
size_t i = 1; i < N_MUR_PTS + 1; ++i) {
119 const double muRValue =
muRmin() + to<double>(i - 1) * dmuR;
123 const double absFactor = attenuation / (M_PI * muRValue * muRValue);
125 yabs[i] = 1. / absFactor;
129 auto mscat =
calculateMS(i, muRValue, attenuation);
130 yms[i] = mscat.first;
131 wms[i] = mscat.second;
137 auto absCoeffs = polyfit(xmur, yabs, wabs);
138 decltype(absCoeffs) msCoeffs(0);
140 msCoeffs = polyfit(xmur, yms, wms);
143 const double muMin(xmur.front()), muMax(xmur.back()), flightPath(
m_pars.
l1 +
m_pars.
l2);
148 auto &sigOut = outputHistogram.mutableY();
149 auto &errOut = outputHistogram.mutableE();
159 const double rmu =
muR(sigt);
161 const double xcap = ((rmu - muMin) - (muMax - rmu)) / (muMax - muMin);
162 double corrfact = chebyPoly(absCoeffs, xcap);
164 const double msVal = chebyPoly(msCoeffs, xcap);
166 corrfact *= (1.0 - beta);
170 sigOut[i] = yin * corrfact;
171 errOut[i] = sigOut[i] * ein / yin;
173 return outputHistogram;
184 const double dyr =
muR / to<double>(N_RAD - 1);
185 const double dyth = TWOPI / to<double>(N_THETA - 1);
186 const double muRSq =
muR *
muR;
190 std::vector<double> yr(N_RAD), yth(N_THETA);
191 for (
size_t i = 0; i < N_RAD; ++i) {
192 const double r0 = to<double>(i) * dyr;
194 for (
size_t j = 0; j < N_THETA; ++j) {
195 const double theta = to<double>(j) * dyth;
197 double fact1 = muRSq - std::pow(r0 * sin(theta), 2);
201 const double mul1 = sqrt(fact1) + r0 * cos(theta);
203 double fact2 = muRSq - std::pow(r0 * sin(
m_pars.
twoTheta - theta), 2);
206 const double mul2 = (sqrt(fact2) - r0 * cos(
m_pars.
twoTheta - theta)) / cosaz;
207 yth[j] = exp(-mul1 - mul2);
210 yr[i] = r0 * integrate(yth, dyth);
212 return integrate(yr, dyr);
227 const double radDistPower = 1. / 3.;
238 const double r1 = pow(
m_rng->nextValue(), radDistPower) *
muR;
239 const double r2 = pow(
m_rng->nextValue(), radDistPower) *
muR;
240 const double z1 =
m_rng->nextValue() * muH;
241 const double z2 =
m_rng->nextValue() * muH;
242 const double th1 =
m_rng->nextValue() * TWOPI;
243 const double th2 =
m_rng->nextValue() * TWOPI;
244 double fact1 = pow(
muR, 2) - std::pow(r1 * sin(th1), 2);
248 const double mul1 = sqrt(fact1) + r1 * cos(th1);
253 const double mul2 = (sqrt(fact2) - r2 * cos(
m_pars.
twoTheta - th2)) / cosaz;
256 sqrt(pow(r1 * cos(th1) - r2 * cos(th2), 2) + pow(r1 * sin(th1) - r2 * sin(th2), 2) + pow(z1 - z2, 2));
259 sum += exp(-(mul1 + mul2 + mul12)) / pow(mul12, 2);
262 const double delta = 0.25 * beta / (M_PI * abs * muH);
266 return std::make_pair(stats.mean, stats.mean / stats.standard_deviation);