35size_t N_POLY_ORDER = 4;
37double TWOPI = 2.0 * M_PI;
40template <
typename R,
typename T>
inline R to(
const T val) {
return static_cast<R
>(val); }
52double integrate(
const std::vector<double> &y,
const double dx) {
57 double sumEven(0.0), sumOdd(0.0);
58 auto itend =
y.end() - 1;
59 for (
auto it =
y.begin() + 1; it != itend;) {
65 return dx * (
y.front() + 4.0 * sumOdd + 2.0 * sumEven +
y.back()) / 3.0;
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 muR =
muRmin() + to<double>(i - 1) * dmuR;
123 const double absFactor = attenuation / (M_PI *
muR *
muR);
125 yabs[i] = 1. / absFactor;
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);
280 return std::make_pair(
muR(flightPath, tmin),
muR(flightPath, tmax));
313 const double sigabs =
m_pars.
sigmaAbs * 2200.0 * tof * 1e-6 / flightPath;
Compute a weighted least-squares polynomial approximations to an arbitrary set of data points.
Evaluate an approximation to a nth order polynomial using a Chebyshev series through Crenshaw's algor...
This implements the the Mersenne Twister 19937 pseudo-random number generator algorithm as a specialz...
Statistics getStatistics(const std::vector< TYPE > &data, const unsigned int flags=StatOptions::AllStats)
Return a statistics object for the given data set.
Controls the computation of statisical data.