49 auto inputValidator = std::make_shared<Kernel::CompositeValidator>();
50 inputValidator->add(std::make_shared<API::WorkspaceHasDxValidator>());
51 constexpr bool acceptHistograms{
false};
52 inputValidator->add(std::make_shared<API::HistogramValidator>(acceptHistograms));
55 "An input workspace with Dx values.");
57 "The grouped workspace.");
58 auto positive = std::make_shared<Kernel::BoundedValidator<double>>();
59 positive->setLower(0.);
60 positive->setLowerExclusive(
true);
61 declareProperty(Prop::FRACTION, 0.2, positive,
"A fraction of Dx to group the points to.");
76 using boost::math::pow;
78 double const groupingFraction =
getProperty(Prop::FRACTION);
79 HistogramData::Histogram
h(HistogramData::Histogram::XMode::Points, HistogramData::Histogram::YMode::Counts);
80 auto const &inXs = inWS->x(0);
81 auto const &inYs = inWS->y(0);
82 auto const &inEs = inWS->e(0);
83 auto const &inDxs = inWS->dx(0);
84 std::vector<double> outXs;
85 outXs.reserve(inXs.size());
86 std::vector<double> outYs;
87 outYs.reserve(inXs.size());
88 std::vector<double> outEs;
89 outEs.reserve(inXs.size());
90 std::vector<double> outDxs;
91 outDxs.reserve(inXs.size());
93 double begin = inXs.front();
95 auto const Dx = inDxs[pointIndex];
97 throw std::out_of_range(
"Nonpositive DX value in the workspace.");
99 auto const width = groupingFraction * Dx;
100 auto const end = inXs[pointIndex] + width;
101 auto const beginXIterator = std::lower_bound(inXs.cbegin(), inXs.cend(), begin);
102 auto const endXIterator = std::lower_bound(inXs.cbegin(), inXs.cend(), end);
103 auto const pickSize =
static_cast<size_t>(std::distance(beginXIterator, endXIterator));
105 auto const offset =
static_cast<size_t>(std::distance(inXs.cbegin(), beginXIterator));
108 double eSquaredSum{0.};
109 for (
size_t pickIndex = offset; pickIndex < offset + pickSize; ++pickIndex) {
110 xSum += inXs[pickIndex];
111 ySum += inYs[pickIndex];
112 eSquaredSum += pow<2>(inEs[pickIndex]);
114 outXs.emplace_back(xSum /
static_cast<double>(pickSize));
115 outYs.emplace_back(ySum /
static_cast<double>(pickSize));
116 outEs.emplace_back(std::sqrt(eSquaredSum) /
static_cast<double>(pickSize));
117 auto const groupedXWidth = *std::prev(endXIterator) - *beginXIterator;
118 outDxs.emplace_back(std::sqrt(pow<2>(inDxs[pointIndex]) + pow<2>(FWHM_GAUSSIAN_EQUIVALENT * groupedXWidth)));
120 throw std::out_of_range(
"Failed to group. Is the X data sorted in ascending order?");
123 if (begin > inXs.back()) {
126 pointIndex += pickSize;
128 HistogramData::HistogramBuilder constructionYard;
129 constructionYard.setX(std::move(outXs));
130 constructionYard.setY(std::move(outYs));
131 constructionYard.setE(std::move(outEs));
132 constructionYard.setDx(std::move(outDxs));
133 constructionYard.setDistribution(
false);