95 const std::vector<double> binParams =
getProperty(
"OutputBinning");
98 const auto xLength =
static_cast<int>(iqWS->x(0).size());
99 std::vector<double> XNorm(xLength - 1, 0.0);
107 thetaWS->setSharedX(0, iqWS->sharedX(0));
108 auto &ThetaY = thetaWS->mutableY(0);
114 tofWS->setSharedX(0, iqWS->sharedX(0));
115 auto &TOFY = tofWS->mutableY(0);
118 HistogramData::HistogramDx DxOut(xLength - 1, 0.0);
120 const auto numberOfSpectra =
static_cast<int>(reducedWS->getNumberHistograms());
123 const auto &spectrumInfo = reducedWS->spectrumInfo();
124 const double L1 = spectrumInfo.l1();
127 for (
int i = 0; i < numberOfSpectra; i++) {
129 if (!spectrumInfo.hasDetectors(i)) {
130 g_log.
warning() <<
"Workspace index " << i <<
" has no detector assigned to it - discarding\n";
134 if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
137 const double L2 = spectrumInfo.l2(i);
141 const double theta = spectrumInfo.twoTheta(i);
142 const double factor = 4.0 * M_PI * sin(0.5 * theta);
144 const auto &XIn = reducedWS->x(i);
145 const auto &YIn = reducedWS->y(i);
146 const auto wlLength =
static_cast<int>(XIn.size());
148 std::vector<double> _dx(xLength - 1, 0.0);
149 std::vector<double> _norm(xLength - 1, 0.0);
150 std::vector<double> _tofy(xLength - 1, 0.0);
151 std::vector<double> _thetay(xLength - 1, 0.0);
153 for (
int j = 0; j < wlLength - 1; j++) {
154 const double wl = (XIn[j + 1] + XIn[j]) / 2.0;
155 const double wl_bin = XIn[j + 1] - XIn[j];
156 if (!
isEmpty(min_wl) && wl < min_wl)
158 if (!
isEmpty(max_wl) && wl > max_wl)
160 const double q = factor / wl;
166 if (binParams[1] > 0.0) {
167 iq =
static_cast<int>(floor((q - binParams[0]) / binParams[1]));
169 iq =
static_cast<int>(floor(log(q / binParams[0]) / log(1.0 - binParams[1])));
172 const double src_to_pixel = L1 + L2;
173 const double dTheta2 =
174 (3.0 * R1 * R1 / (L1 * L1) + 3.0 * R2 * R2 * src_to_pixel * src_to_pixel / (L1 * L1 * L2 * L2) +
175 2.0 * (pixel_size_x * pixel_size_x + pixel_size_y * pixel_size_y) / (L2 * L2)) /
179 const double dwl_over_wl = 3.9560 *
getTOFResolution(wl) / (1000.0 * (L1 + L2) * wl);
181 const double wl_bin_over_wl = wl_bin / wl;
182 const double dq_over_q =
183 std::sqrt(dTheta2 / (theta * theta) + dwl_over_wl * dwl_over_wl + wl_bin_over_wl * wl_bin_over_wl);
188 if (iq >= 0 && iq < xLength - 1 && !std::isnan(dq_over_q) && dq_over_q > 0 && YIn[j] > 0) {
189 _dx[iq] += q * dq_over_q * YIn[j];
191 _tofy[iq] += q * std::fabs(dwl_over_wl) * YIn[j];
192 _thetay[iq] += q * std::sqrt(dTheta2) / theta * YIn[j];
199 for (
int iq = 0; iq < xLength - 1; iq++) {
200 DxOut[iq] += _dx[iq];
201 XNorm[iq] += _norm[iq];
202 TOFY[iq] += _tofy[iq];
203 ThetaY[iq] += _thetay[iq];
206 progress.report(
"Computing Q resolution");
213 for (
int i = 0; i < xLength - 1; i++) {
216 DxOut[i] /= XNorm[i];
218 ThetaY[i] /= XNorm[i];
220 iqWS->setPointStandardDeviations(0, std::move(DxOut));