88 std::optional<Mantid::Kernel::SpecialCoordinateSystem> coordinateSystem = converter(m_inputWS.get());
90 std::stringstream errmsg;
91 errmsg <<
"Input MDWorkspace's coordinate system is not HKL.";
92 throw std::invalid_argument(errmsg.str());
99 const int neighborPts =
getProperty(
"NeighborPoints");
102 if (peakWS != inPeakWS)
103 peakWS = inPeakWS->clone();
110 int npeaks = peakWS->getNumberPeaks();
112 auto prog = std::make_unique<Progress>(
this, 0.3, 1.0, npeaks);
114 for (
int i = 0; i < npeaks; i++) {
117 IPeak &p = peakWS->getPeak(i);
119 int h =
static_cast<int>(boost::math::iround(p.getH()));
120 int k =
static_cast<int>(boost::math::iround(p.getK()));
121 int l =
static_cast<int>(boost::math::iround(p.getL()));
124 histoBox =
cropHisto(h, k, l, box, m_histoWS);
125 }
else if (sa && flux) {
126 histoBox =
normalize(h, k, l, box, gridPts, flux, sa, m_eventWS);
128 histoBox =
binEvent(h, k, l, box, gridPts, m_eventWS);
130 double intensity = 0.0;
131 double errorSquared = 0.0;
132 integratePeak(neighborPts, histoBox, intensity, errorSquared);
133 p.setIntensity(intensity);
134 p.setSigmaIntensity(sqrt(errorSquared));
147 normAlg->setProperty(
"InputWorkspace", ws);
148 normAlg->setProperty(
"AlignedDim0",
"[H,0,0]," + boost::lexical_cast<std::string>(h - box) +
"," +
149 boost::lexical_cast<std::string>(h + box) +
"," +
std::to_string(gridPts));
150 normAlg->setProperty(
"AlignedDim1",
"[0,K,0]," + boost::lexical_cast<std::string>(k - box) +
"," +
151 boost::lexical_cast<std::string>(k + box) +
"," +
std::to_string(gridPts));
152 normAlg->setProperty(
"AlignedDim2",
"[0,0,L]," + boost::lexical_cast<std::string>(l - box) +
"," +
153 boost::lexical_cast<std::string>(l + box) +
"," +
std::to_string(gridPts));
154 normAlg->setProperty(
"FluxWorkspace", flux);
155 normAlg->setProperty(
"SolidAngleWorkspace", sa);
156 normAlg->setProperty(
"OutputWorkspace",
"mdout");
157 normAlg->setProperty(
"OutputNormalizationWorkspace",
"mdnorm");
158 normAlg->executeAsChildAlg();
160 Workspace_sptr mdnorm = normAlg->getProperty(
"OutputNormalizationWorkspace");
163 alg->setProperty(
"LHSWorkspace", mdout);
164 alg->setProperty(
"RHSWorkspace", mdnorm);
165 alg->setPropertyValue(
"OutputWorkspace",
"out");
168 return std::dynamic_pointer_cast<MDHistoWorkspace>(out);
172 double &errorSquared) {
173 std::vector<int> gridPts;
175 double BackgroundOuterRadius2 =
getProperty(
"BackgroundOuterRadius");
176 if (BackgroundOuterRadius2 !=
EMPTY_DBL())
177 BackgroundOuterRadius2 = pow(BackgroundOuterRadius2, 2.0);
179 double BackgroundInnerRadius2 =
getProperty(
"BackgroundInnerRadius");
180 if (BackgroundInnerRadius2 !=
EMPTY_DBL())
181 BackgroundInnerRadius2 = pow(BackgroundInnerRadius2, 2.0);
182 const size_t dimensionality = out->getNumDims();
183 for (
size_t i = 0; i < dimensionality; ++i) {
184 gridPts.emplace_back(
static_cast<int>(out->getDimension(i)->getNBins()));
187 const auto F = out->getSignalArray();
189 double Fmin = std::numeric_limits<double>::max();
190 for (
int i = 0; i < gridPts[0] * gridPts[1] * gridPts[2]; i++) {
191 if (std::isnormal(F[i])) {
192 Fmin = std::min(Fmin, F[i]);
193 Fmax = std::max(Fmax, F[i]);
196 const auto SqError = out->getErrorSquaredArray();
198 double minIntensity = Fmin + 0.01 * (Fmax - Fmin);
199 int measuredPoints = 0;
201 double peakSum = 0.0;
202 double measuredSum = 0.0;
203 double errSqSum = 0.0;
204 double measuredErrSqSum = 0.0;
205 int backgroundPoints = 0;
206 double backgroundSum = 0.0;
207 double backgroundErrSqSum = 0.0;
208 double Hcenter = gridPts[0] * 0.5;
209 double Kcenter = gridPts[1] * 0.5;
210 double Lcenter = gridPts[2] * 0.5;
212 for (
int Hindex = 0; Hindex < gridPts[0]; Hindex++) {
213 for (
int Kindex = 0; Kindex < gridPts[1]; Kindex++) {
214 for (
int Lindex = 0; Lindex < gridPts[2]; Lindex++) {
215 int iHKL = Hindex + gridPts[0] * (Kindex + gridPts[1] * Lindex);
216 if (BackgroundOuterRadius2 !=
EMPTY_DBL()) {
217 double radius2 = pow((
double(Hindex) - Hcenter) / gridPts[0], 2) +
218 pow((
double(Kindex) - Kcenter) / gridPts[1], 2) +
219 pow((
double(Lindex) - Lcenter) / gridPts[2], 2);
220 if (radius2 < BackgroundOuterRadius2 && BackgroundInnerRadius2 < radius2) {
221 backgroundPoints = backgroundPoints + 1;
222 backgroundSum = backgroundSum + F[iHKL];
223 backgroundErrSqSum = backgroundErrSqSum + SqError[iHKL];
226 if (std::isfinite(F[iHKL])) {
227 measuredPoints = measuredPoints + 1;
228 measuredSum = measuredSum + F[iHKL];
229 measuredErrSqSum = measuredErrSqSum + SqError[iHKL];
230 if (F[iHKL] > minIntensity) {
231 int neighborPoints = 0;
232 for (
int Hj = -2; Hj < 3; Hj++) {
233 for (
int Kj = -2; Kj < 3; Kj++) {
234 for (
int Lj = -2; Lj < 3; Lj++) {
235 int jHKL = Hindex + Hj + gridPts[0] * (Kindex + Kj + gridPts[1] * (Lindex + Lj));
236 if (Lindex + Lj >= 0 && Lindex + Lj < gridPts[2] && Kindex + Kj >= 0 && Kindex + Kj < gridPts[1] &&
237 Hindex + Hj >= 0 && Hindex + Hj < gridPts[0] && F[jHKL] > minIntensity) {
238 neighborPoints = neighborPoints + 1;
243 if (neighborPoints >= neighborPts) {
244 peakPoints = peakPoints + 1;
245 peakSum = peakSum + F[iHKL];
246 errSqSum = errSqSum + SqError[iHKL];
250 double minR = sqrt(std::pow(
float(Hindex) /
float(gridPts[0]) - 0.5, 2) +
251 std::pow(
float(Kindex) /
float(gridPts[1]) - 0.5, 2) +
252 std::pow(
float(Lindex) /
float(gridPts[0]) - 0.5, 2));
262 if (BackgroundOuterRadius2 !=
EMPTY_DBL()) {
264 if (backgroundPoints > 0) {
265 ratio = float(peakPoints) / float(backgroundPoints);
267 intensity = peakSum - ratio * (backgroundSum);
268 errorSquared = errSqSum + ratio * ratio * (backgroundErrSqSum);
270 double ratio = float(peakPoints) / float(measuredPoints - peakPoints);
271 intensity = peakSum - ratio * (measuredSum - peakSum);
272 errorSquared = errSqSum + ratio * ratio * (measuredErrSqSum - errSqSum);
285 binMD->setProperty(
"InputWorkspace", ws);
286 binMD->setProperty(
"AlignedDim0",
"[H,0,0]," + boost::lexical_cast<std::string>(h - box) +
"," +
287 boost::lexical_cast<std::string>(h + box) +
"," +
std::to_string(gridPts));
288 binMD->setProperty(
"AlignedDim1",
"[0,K,0]," + boost::lexical_cast<std::string>(k - box) +
"," +
289 boost::lexical_cast<std::string>(k + box) +
"," +
std::to_string(gridPts));
290 binMD->setProperty(
"AlignedDim2",
"[0,0,L]," + boost::lexical_cast<std::string>(l - box) +
"," +
291 boost::lexical_cast<std::string>(l + box) +
"," +
std::to_string(gridPts));
292 binMD->setPropertyValue(
"AxisAligned",
"1");
293 binMD->setPropertyValue(
"OutputWorkspace",
"out");
294 binMD->executeAsChildAlg();
296 return std::dynamic_pointer_cast<MDHistoWorkspace>(outputWS);
306 cropMD->setProperty(
"InputWorkspace", ws);
308 cropMD->setProperty(
"P1Bin",
309 boost::lexical_cast<std::string>(h - box) +
",0," + boost::lexical_cast<std::string>(h + box));
310 cropMD->setProperty(
"P2Bin",
311 boost::lexical_cast<std::string>(k - box) +
",0," + boost::lexical_cast<std::string>(k + box));
312 cropMD->setProperty(
"P3Bin",
313 boost::lexical_cast<std::string>(l - box) +
",0," + boost::lexical_cast<std::string>(l + box));
315 cropMD->setPropertyValue(
"OutputWorkspace",
"out");
316 cropMD->executeAsChildAlg();
318 return std::dynamic_pointer_cast<MDHistoWorkspace>(outputWS);