Mantid
Loading...
Searching...
No Matches
SofQWNormalisedPolygon.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
25#include "MantidIndexing/IndexInfo.h"
27#include "MantidTypes/SpectrumDefinition.h"
28
29#include <boost/math/special_functions/pow.hpp>
30
31using boost::math::pow;
33
34namespace {
44double twoThetaFromLocalPoint(const Mantid::Geometry::DetectorInfo &detInfo, const size_t detInfoIndex,
45 const Mantid::Kernel::V3D &samplePos, const Mantid::Kernel::V3D &beamDir,
46 Mantid::Kernel::V3D point) {
47 const auto rotation = detInfo.rotation(detInfoIndex);
48 const auto position = detInfo.position(detInfoIndex);
49 rotation.rotate(point);
50 point += position;
51 point -= samplePos;
52 const auto twoTheta = point.angle(beamDir);
53 return twoTheta;
54}
55
66std::pair<double, double> cuboidTwoThetaRange(const Mantid::Geometry::DetectorInfo &detInfo, const size_t detInfoIndex,
67 const Mantid::Kernel::V3D &samplePos, const Mantid::Kernel::V3D &beamDir,
69 const auto back = geometry.leftBackBottom - geometry.leftFrontBottom;
70 const auto up = geometry.leftFrontTop - geometry.leftFrontBottom;
71 const auto right = geometry.rightFrontBottom - geometry.leftFrontBottom;
72 const std::array<Mantid::Kernel::V3D, 8> capRing{{geometry.leftFrontBottom, geometry.leftFrontBottom + back * 0.5,
73 geometry.leftBackBottom, geometry.leftBackBottom + up * 0.5,
74 geometry.leftBackBottom + up, geometry.leftFrontTop + back * 0.5,
75 geometry.leftFrontTop, geometry.leftFrontBottom + up * 0.5}};
76 double minTwoTheta{std::numeric_limits<double>::max()};
77 double maxTwoTheta{std::numeric_limits<double>::lowest()};
78 for (int width = 0; width < 2; ++width) {
79 const auto offset = right * static_cast<double>(width);
80 for (const auto &pointInRing : capRing) {
81 auto point = pointInRing;
82 if (width != 0) {
83 point += offset;
84 }
85 const auto current = twoThetaFromLocalPoint(detInfo, detInfoIndex, samplePos, beamDir, point);
86 minTwoTheta = std::min(minTwoTheta, current);
87 maxTwoTheta = std::max(maxTwoTheta, current);
88 }
89 }
90 const auto beltOffset = right * 0.5;
91 for (size_t beltIndex = 0; beltIndex < capRing.size(); beltIndex += 2) {
92 const auto point = capRing[beltIndex] + beltOffset;
93 const auto current = twoThetaFromLocalPoint(detInfo, detInfoIndex, samplePos, beamDir, point);
94 minTwoTheta = std::min(minTwoTheta, current);
95 maxTwoTheta = std::max(maxTwoTheta, current);
96 }
97 return std::make_pair(minTwoTheta, maxTwoTheta);
98}
99
111std::pair<double, double> cylinderTwoThetaRange(const Mantid::Geometry::DetectorInfo &detInfo,
112 const size_t detInfoIndex, const Mantid::Kernel::V3D &samplePos,
113 const Mantid::Kernel::V3D &beamDir,
115 Mantid::Kernel::V3D basis1{1., 0., 0.};
116 if (geometry.axis.X() != 0. && geometry.axis.Z() != 0) {
117 const auto inverseXZSumSq = 1. / (pow<2>(geometry.axis.X()) + pow<2>(geometry.axis.Z()));
118 basis1.setX(std::sqrt(1. - pow<2>(geometry.axis.X()) * inverseXZSumSq));
119 basis1.setY(geometry.axis.X() * std::sqrt(inverseXZSumSq));
120 }
121 const Mantid::Kernel::V3D basis2 = geometry.axis.cross_prod(basis1);
122 const std::array<double, 8> angles{
123 {0., 0.25 * M_PI, 0.5 * M_PI, 0.75 * M_PI, M_PI, 1.25 * M_PI, 1.5 * M_PI, 1.75 * M_PI}};
124 double minTwoTheta{std::numeric_limits<double>::max()};
125 double maxTwoTheta{std::numeric_limits<double>::lowest()};
126 for (const double &angle : angles) {
127 const auto basePoint =
128 geometry.centreOfBottomBase + (basis1 * std::cos(angle) + basis2 * std::sin(angle)) * geometry.radius;
129 for (int i = 0; i < 3; ++i) {
130 const auto point = basePoint + geometry.axis * (0.5 * geometry.height * static_cast<double>(i));
131 const auto current = twoThetaFromLocalPoint(detInfo, detInfoIndex, samplePos, beamDir, point);
132 minTwoTheta = std::min(minTwoTheta, current);
133 maxTwoTheta = std::max(maxTwoTheta, current);
134 }
135 }
136 return std::make_pair(minTwoTheta, maxTwoTheta);
137}
138
148double twoThetaFromBoundingBox(const Mantid::Geometry::DetectorInfo &detInfo, const size_t detInfoIndex,
149 const Mantid::Kernel::V3D &samplePos, const Mantid::Kernel::V3D &beamDir,
150 const Mantid::Kernel::V3D &sideDir) {
151 const auto shape = detInfo.detector(detInfoIndex).shape();
152 const Mantid::Geometry::BoundingBox bbox = shape->getBoundingBox();
153 const auto maxPoint = bbox.maxPoint();
154 auto side = maxPoint * sideDir;
155 return twoThetaFromLocalPoint(detInfo, detInfoIndex, samplePos, beamDir, side);
156}
157
167std::pair<double, double> generalTwoThetaRange(const Mantid::Geometry::DetectorInfo &detInfo, const size_t detInfoIndex,
168 const Mantid::Kernel::V3D &samplePos,
169 const Mantid::Kernel::V3D &beamDir) {
170 double minTwoTheta{std::numeric_limits<double>::max()};
171 double maxTwoTheta{std::numeric_limits<double>::lowest()};
172 const std::array<Mantid::Kernel::V3D, 6> dirs{
173 {Mantid::Kernel::V3D{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}, {-1., 0., 0.}, {0., -1., 0.}, {0., 0., -1.}}};
174 for (const auto &dir : dirs) {
175 const auto current = twoThetaFromBoundingBox(detInfo, detInfoIndex, samplePos, beamDir, dir);
176 minTwoTheta = std::min(minTwoTheta, current);
177 maxTwoTheta = std::max(maxTwoTheta, current);
178 }
179 return std::make_pair(minTwoTheta, maxTwoTheta);
180}
181
191std::pair<double, double> minMaxTwoTheta(const Mantid::Geometry::DetectorInfo &detInfo, const size_t detInfoIndex,
192 const Mantid::Kernel::V3D &samplePos, const Mantid::Kernel::V3D &beamDir) {
193 const auto shape = detInfo.detector(detInfoIndex).shape();
194 const Mantid::Geometry::CSGObject *csgShape;
195 switch (shape->shape()) {
197 csgShape = dynamic_cast<const Mantid::Geometry::CSGObject *>(shape.get());
198 assert(csgShape);
199 return cylinderTwoThetaRange(detInfo, detInfoIndex, samplePos, beamDir, csgShape->shapeInfo().cylinderGeometry());
201 csgShape = dynamic_cast<const Mantid::Geometry::CSGObject *>(shape.get());
202 assert(csgShape);
203 return cuboidTwoThetaRange(detInfo, detInfoIndex, samplePos, beamDir, csgShape->shapeInfo().cuboidGeometry());
204 default:
205 return generalTwoThetaRange(detInfo, detInfoIndex, samplePos, beamDir);
206 }
207}
208
216std::pair<double, double> twoThetasFromTable(const Mantid::detid_t detID, const std::vector<int> &detectorIDs,
217 const std::vector<double> &lowers, const std::vector<double> &uppers) {
218 const auto range = std::equal_range(detectorIDs.cbegin(), detectorIDs.cend(), static_cast<int>(detID));
219 if (std::distance(range.first, range.second) > 1) {
220 throw std::invalid_argument("Duplicate detector IDs in 'DetectorTwoThetaRanges'.");
221 }
222 if (range.first == detectorIDs.cend()) {
223 throw std::invalid_argument("No min/max 2thetas found for detector ID " + std::to_string(detID));
224 }
225 const auto index = std::distance(detectorIDs.cbegin(), range.first);
226 const auto minmax = std::make_pair(lowers[index], uppers[index]);
227 if (minmax.first <= 0) {
228 throw std::invalid_argument("Non-positive min 2theta for detector ID " + std::to_string(detID));
229 }
230 if (minmax.first > M_PI) {
231 throw std::invalid_argument("Min 2theta greater than pi for detector ID " + std::to_string(detID));
232 }
233 if (minmax.second > M_PI) {
234 throw std::invalid_argument("Max 2theta greater than pi for detector ID" + std::to_string(detID));
235 }
236 if (minmax.first >= minmax.second) {
237 throw std::invalid_argument("Min 2theta larger than max for detector ID " + std::to_string(detID));
238 }
239 return minmax;
240}
241} // namespace
242
243namespace Mantid::Algorithms {
244// Setup typedef for later use
245using SpectraDistanceMap = std::map<specnum_t, Mantid::Kernel::V3D>;
247
248// Register the algorithm into the AlgorithmFactory
250
251using namespace Mantid::Kernel;
252using namespace Mantid::Geometry;
253using namespace Mantid::API;
254using namespace Mantid::DataObjects;
255
259const std::string SofQWNormalisedPolygon::name() const { return "SofQWNormalisedPolygon"; }
260
264int SofQWNormalisedPolygon::version() const { return 1; }
265
269const std::string SofQWNormalisedPolygon::category() const { return "Inelastic\\SofQW"; }
270
275
280std::map<std::string, std::string> SofQWNormalisedPolygon::validateInputs() {
281 std::map<std::string, std::string> result;
282 API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
283 if (!inputWS) {
284 result["InputWorkspace"] = "InputWorkspace is of Incorrect type. Please "
285 "provide a MatrixWorkspace as the "
286 "InputWorkspace";
287 }
288 TableWorkspace_sptr tableWS = getProperty("DetectorTwoThetaRanges");
289 if (tableWS) {
290 // The table should have three columns
291 if (tableWS->columnCount() != 3) {
292 result["DetectorTwoThetaRanges"] = "DetectorTwoThetaRanges requires 3 columns";
293 }
294 // The first column should be of type int
295 else if (!tableWS->getColumn(0)->isType<int>()) {
296 result["DetectorTwoThetaRanges"] = "The first column of DetectorTwoThetaRanges should be of type int";
297 }
298 // The second column should be of type double
299 else if (!tableWS->getColumn(1)->isType<double>()) {
300 result["DetectorTwoThetaRanges"] = "The second column of DetectorTwoThetaRanges should be of type "
301 "double";
302 }
303 // The third column should be of type double.
304 else if (!tableWS->getColumn(2)->isType<double>()) {
305 result["DetectorTwoThetaRanges"] = "The third column of DetectorTwoThetaRanges should be of type double";
306 }
307 // Table and workspace should have the same number of detectors.
308 else if (tableWS->rowCount() != inputWS->getNumberHistograms()) {
309 result["DetectorTwoThetaRanges"] = "The table and workspace do not have the same number of detectors";
310 }
311 }
312 return result;
313}
314
319 MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
320 // Compute input caches
321 m_EmodeProperties.initCachedValues(*inputWS, this);
322
323 RebinnedOutput_sptr outputWS = SofQW::setUpOutputWorkspace<RebinnedOutput>(
324 *inputWS, getProperty("QAxisBinning"), m_Qout, getProperty("EAxisBinning"), m_EmodeProperties);
325 g_log.debug() << "Workspace type: " << outputWS->id() << '\n';
326 setProperty("OutputWorkspace", outputWS);
327 const size_t nEnergyBins = inputWS->blocksize();
328 const size_t nHistos = inputWS->getNumberHistograms();
329
330 // Holds the spectrum-detector mapping
331 std::vector<SpectrumDefinition> detIDMapping(outputWS->getNumberHistograms());
332
333 // Progress reports & cancellation
334 const size_t nreports(nHistos * nEnergyBins);
335 m_progress = std::make_unique<API::Progress>(this, 0.0, 1.0, nreports);
336
337 // Index theta cache
338 TableWorkspace_sptr twoThetaTable = getProperty("DetectorTwoThetaRanges");
339 if (twoThetaTable) {
340 initAngularCachesTable(*inputWS, *twoThetaTable);
341 } else {
342 std::vector<double> par = inputWS->getInstrument()->getNumberParameter("detector-neighbour-offset");
343 if (par.empty()) {
344 this->initAngularCachesNonPSD(*inputWS);
345 } else {
346 g_log.debug() << "Offset: " << par[0] << '\n';
347 this->m_detNeighbourOffset = static_cast<int>(par[0]);
348 this->initAngularCachesPSD(*inputWS);
349 }
350 }
351 const auto &X = inputWS->x(0);
352
353 const auto &inputIndices = inputWS->indexInfo();
354 const auto &spectrumInfo = inputWS->spectrumInfo();
355
356 PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
357 for (int64_t i = 0; i < static_cast<int64_t>(nHistos); ++i) {
359
360 if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
361 continue;
362 }
363 const auto *det = m_EmodeProperties.m_emode == 1 ? nullptr : &spectrumInfo.detector(i);
364
365 const double thetaLower = m_twoThetaLowers[i];
366 const double thetaUpper = m_twoThetaUppers[i];
367
368 const auto specNo = static_cast<specnum_t>(inputIndices.spectrumNumber(i));
369 std::stringstream logStream;
370 for (size_t j = 0; j < nEnergyBins; ++j) {
371 m_progress->report("Computing polygon intersections");
372 // For each input polygon test where it intersects with
373 // the output grid and assign the appropriate weights of Y/E
374 const double dE_j = X[j];
375 const double dE_jp1 = X[j + 1];
376
377 const double lrQ = m_EmodeProperties.q(dE_jp1, thetaLower, det);
378
379 const V2D ll(dE_j, m_EmodeProperties.q(dE_j, thetaLower, det));
380 const V2D lr(dE_jp1, lrQ);
381 const V2D ur(dE_jp1, m_EmodeProperties.q(dE_jp1, thetaUpper, det));
382 const V2D ul(dE_j, m_EmodeProperties.q(dE_j, thetaUpper, det));
383 if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
384 logStream << "Spectrum=" << specNo << ", lower theta=" << thetaLower * rad2deg
385 << ", upper theta=" << thetaUpper * rad2deg << ". QE polygon: ll=" << ll << ", lr=" << lr
386 << ", ur=" << ur << ", ul=" << ul << "\n";
387 }
388
390 rebinToFractionalOutput(Quadrilateral(ll, lr, ur, ul), inputWS, i, j, *outputWS, m_Qout);
391
392 // Find which q bin this point lies in
393 const MantidVec::difference_type qIndex = std::upper_bound(m_Qout.begin(), m_Qout.end(), lrQ) - m_Qout.begin();
394 if (qIndex != 0 && qIndex < static_cast<int>(m_Qout.size())) {
395 // Add this spectra-detector pair to the mapping
396 PARALLEL_CRITICAL(SofQWNormalisedPolygon_spectramap) {
397 // Could do a more complete merge of spectrum definitions here, but
398 // historically only the ID of the first detector in the spectrum is
399 // used, so I am keeping that for now.
400 detIDMapping[qIndex - 1].add(spectrumInfo.spectrumDefinition(i)[0].first);
401 }
402 }
403 }
404 if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
405 g_log.debug(logStream.str());
406 }
407
409 }
411
413 outputWS->finalize();
414 FractionalRebinning::normaliseOutput(outputWS, inputWS, m_progress.get());
415
416 // Set the output spectrum-detector mapping
417 auto outputIndices = outputWS->indexInfo();
418 outputIndices.setSpectrumDefinitions(std::move(detIDMapping));
419 outputWS->setIndexInfo(outputIndices);
420
421 // Replace any NaNs in outputWorkspace with zeroes
422 if (this->getProperty("ReplaceNaNs")) {
423 auto replaceNans = this->createChildAlgorithm("ReplaceSpecialValues");
424 replaceNans->setChild(true);
425 replaceNans->initialize();
426 replaceNans->setProperty("InputWorkspace", outputWS);
427 replaceNans->setProperty("OutputWorkspace", outputWS);
428 replaceNans->setProperty("NaNValue", 0.0);
429 replaceNans->setProperty("InfinityValue", 0.0);
430 replaceNans->setProperty("BigNumberThreshold", DBL_MAX);
431 replaceNans->execute();
432 }
433}
434
444 const size_t nhist = workspace.getNumberHistograms();
445 constexpr double skipDetector{-1.};
446 m_twoThetaLowers = std::vector<double>(nhist, skipDetector);
447 m_twoThetaUppers = std::vector<double>(nhist, skipDetector);
448
449 auto inst = workspace.getInstrument();
450 const auto referenceFrame = inst->getReferenceFrame();
451 const auto beamDir = referenceFrame->vecPointingAlongBeam();
452
453 const auto &detectorInfo = workspace.detectorInfo();
454 const auto &spectrumInfo = workspace.spectrumInfo();
455 const auto samplePos = spectrumInfo.samplePosition();
456 for (size_t i = 0; i < nhist; ++i) {
457 m_progress->report("Calculating detector angles");
458
459 // If no detector found, skip onto the next spectrum
460 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i)) {
461 continue;
462 }
463
464 const auto &det = spectrumInfo.detector(i);
465 // Check to see if there is an EFixed, if not skip it
466 try {
468 } catch (std::runtime_error &) {
469 continue;
470 }
471
472 double minTwoTheta{spectrumInfo.twoTheta(i)};
473 double maxTwoTheta{minTwoTheta};
474 if (spectrumInfo.hasUniqueDetector(i)) {
475 const auto detInfoIndex = detectorInfo.indexOf(det.getID());
476 std::tie(minTwoTheta, maxTwoTheta) = minMaxTwoTheta(detectorInfo, detInfoIndex, samplePos, beamDir);
477 } else {
478 const auto &group = dynamic_cast<const DetectorGroup &>(det);
479 const auto ids = group.getDetectorIDs();
480 for (const auto id : ids) {
481 const auto detInfoIndex = detectorInfo.indexOf(id);
482 const auto current = minMaxTwoTheta(detectorInfo, detInfoIndex, samplePos, beamDir);
483 minTwoTheta = std::min(minTwoTheta, current.first);
484 maxTwoTheta = std::max(maxTwoTheta, current.second);
485 }
486 }
487 m_twoThetaLowers[i] = minTwoTheta;
488 m_twoThetaUppers[i] = maxTwoTheta;
489 if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
490 g_log.debug() << "Detector at spectrum = " << workspace.getSpectrum(i).getSpectrumNo()
491 << ", lower 2theta = " << m_twoThetaLowers[i] * rad2deg
492 << ", upper 2theta = " << m_twoThetaUppers[i] * rad2deg << " degrees\n";
493 }
494 }
495}
496
504 const size_t nHistos = workspace.getNumberHistograms();
505
506 bool ignoreMasked = true;
507 const int numNeighbours = 4;
508 WorkspaceNearestNeighbourInfo neighbourInfo(workspace, ignoreMasked, numNeighbours);
509
510 m_twoThetaLowers.resize(nHistos);
511 m_twoThetaUppers.resize(nHistos);
512
513 const auto &spectrumInfo = workspace.spectrumInfo();
514
515 for (size_t i = 0; i < nHistos; ++i) {
516 m_progress->report("Calculating detector angular widths");
517
518 // If no detector found, skip onto the next spectrum
519 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i)) {
520 continue;
521 }
522
523 const specnum_t inSpec = workspace.getSpectrum(i).getSpectrumNo();
524 const SpectraDistanceMap neighbours = neighbourInfo.getNeighboursExact(inSpec);
525
526 // Convert from spectrum numbers to workspace indices
527 double thetaWidth = std::numeric_limits<double>::lowest();
528
529 // Find theta and phi widths
530 const double theta = spectrumInfo.twoTheta(i);
531
532 const specnum_t deltaPlus1 = inSpec + 1;
533 const specnum_t deltaMinus1 = inSpec - 1;
534 const specnum_t deltaPlusT = inSpec + this->m_detNeighbourOffset;
535 const specnum_t deltaMinusT = inSpec - this->m_detNeighbourOffset;
536
537 for (auto &neighbour : neighbours) {
538 specnum_t spec = neighbour.first;
539 if (spec == deltaPlus1 || spec == deltaMinus1 || spec == deltaPlusT || spec == deltaMinusT) {
540 const double theta_n = spectrumInfo.twoTheta(spec - 1) * 0.5;
541
542 const double dTheta = std::abs(theta - theta_n);
543 thetaWidth = std::max(thetaWidth, dTheta);
544 }
545 }
546 m_twoThetaLowers[i] = theta - thetaWidth / 2.;
547 m_twoThetaUppers[i] = theta + thetaWidth / 2.;
548 if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
549 g_log.debug() << "Detector at spectrum = " << inSpec << ", width = " << thetaWidth * rad2deg << " degrees\n";
550 }
551 }
552}
553
555 const TableWorkspace &angleTable) {
556 constexpr double skipDetector{-1.};
557 const size_t nhist = workspace.getNumberHistograms();
558 m_twoThetaLowers = std::vector<double>(nhist, skipDetector);
559 m_twoThetaUppers = std::vector<double>(nhist, skipDetector);
560 const auto &detIDs = angleTable.getColVector<int>("Detector ID");
561 const auto &lowers = angleTable.getColVector<double>("Min two theta");
562 const auto &uppers = angleTable.getColVector<double>("Max two theta");
563 const auto &spectrumInfo = workspace.spectrumInfo();
564 for (size_t i = 0; i < nhist; ++i) {
565 m_progress->report("Reading detector angles");
566 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i)) {
567 continue;
568 }
569 const auto &det = spectrumInfo.detector(i);
570 try {
572 } catch (std::runtime_error &) {
573 continue;
574 }
575
576 if (spectrumInfo.hasUniqueDetector(i)) {
577 const auto twoThetas = twoThetasFromTable(det.getID(), detIDs, lowers, uppers);
578 m_twoThetaLowers[i] = twoThetas.first;
579 m_twoThetaUppers[i] = twoThetas.second;
580 } else {
581 const auto &group = dynamic_cast<const DetectorGroup &>(det);
582 const auto ids = group.getDetectorIDs();
583 double minTwoTheta{spectrumInfo.twoTheta(i)};
584 double maxTwoTheta{minTwoTheta};
585 for (const auto id : ids) {
586 const auto twoThetas = twoThetasFromTable(id, detIDs, lowers, uppers);
587 minTwoTheta = std::min(minTwoTheta, twoThetas.first);
588 maxTwoTheta = std::max(maxTwoTheta, twoThetas.second);
589 }
590 m_twoThetaLowers[i] = minTwoTheta;
591 m_twoThetaUppers[i] = maxTwoTheta;
592 }
593 if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
594 g_log.debug() << "Detector at spectrum = " << workspace.getSpectrum(i).getSpectrumNo()
595 << ", lower 2theta = " << m_twoThetaLowers[i] * rad2deg
596 << ", upper 2theta = " << m_twoThetaUppers[i] * rad2deg << " degrees\n";
597 }
598 }
599}
600} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double position
Definition: GetAllEi.cpp:154
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
double right
Definition: LineProfile.cpp:81
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
Definition: MultiThreaded.h:94
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Definition: Algorithm.cpp:842
Kernel::Logger & g_log
Definition: Algorithm.h:451
Base MatrixWorkspace Abstract Class.
WorkspaceNearestNeighbourInfo provides easy access to nearest-neighbour information for a workspace.
std::map< specnum_t, Kernel::V3D > getNeighboursExact(specnum_t spec) const
Queries the WorkspaceNearestNeighbours object for the selected spectrum number.
std::unique_ptr< API::Progress > m_progress
Progress reporter.
Definition: Rebin2D.h:41
Converts a 2D workspace that has axes of energy transfer against spectrum number to one that gives in...
std::vector< double > m_twoThetaLowers
Array for the lower 2theta angles, in radians.
int m_detNeighbourOffset
Offset for finding neighbor in nearest tube.
std::map< std::string, std::string > validateInputs() override
validate the inputs
void initAngularCachesNonPSD(const API::MatrixWorkspace &workspace)
Init the theta index.
std::vector< double > m_twoThetaUppers
Array for the upper 2theta angles, in radians.
void initAngularCachesPSD(const API::MatrixWorkspace &workspace)
Get angles and calculate angular widths.
int version() const override
Algorithm's version for identification.
void init() override
Initialize the algorithm.
const std::string category() const override
Algorithm's category for identification.
const std::string name() const override
Algorithm's name for identification.
void initAngularCachesTable(const API::MatrixWorkspace &workspace, const DataObjects::TableWorkspace &widthTable)
std::vector< double > m_Qout
Output Q axis.
static void createCommonInputProperties(API::Algorithm &alg)
Create the input properties on the given algorithm object.
Definition: SofQW.cpp:69
TableWorkspace is an implementation of Workspace in which the data are organised in columns of same s...
std::vector< T > & getColVector(size_t index)
get access to column vector for index i.
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition: BoundingBox.h:34
const Kernel::V3D & maxPoint() const
Returns the min point of the box.
Definition: BoundingBox.h:92
Constructive Solid Geometry object.
Definition: CSGObject.h:51
const detail::ShapeInfo & shapeInfo() const override
Definition: CSGObject.cpp:2232
Holds a collection of detectors.
Definition: DetectorGroup.h:28
std::vector< detid_t > getDetectorIDs() const
What detectors are contained in the group?
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
Definition: DetectorInfo.h:49
Kernel::Quat rotation(const size_t index) const
Returns the rotation of the detector with given index.
Kernel::V3D position(const size_t index) const
Returns the position of the detector with given index.
const Geometry::IDetector & detector(const size_t index) const
Return a const reference to the detector with given index.
virtual const std::shared_ptr< const IObject > shape() const =0
Returns the shape of the Object.
A ConvexPolygon with only 4 vertices.
Definition: Quadrilateral.h:24
CylinderGeometry cylinderGeometry() const
Definition: ShapeInfo.cpp:53
CuboidGeometry cuboidGeometry() const
Definition: ShapeInfo.cpp:38
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
bool is(int level) const
Returns true if at least the given log level is set.
Definition: Logger.cpp:146
void rotate(V3D &) const
Rotate a vector.
Definition: Quat.cpp:397
Implements a 2-dimensional vector embedded in a 3D space, i.e.
Definition: V2D.h:29
Class for 3D vectors.
Definition: V3D.h:34
constexpr double X() const noexcept
Get x.
Definition: V3D.h:232
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
Definition: V3D.h:278
double angle(const V3D &) const
Angle between this and another vector.
Definition: V3D.cpp:165
void setX(const double xx) noexcept
Set is x position.
Definition: V3D.h:218
constexpr double Z() const noexcept
Get z.
Definition: V3D.h:234
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
Geometry::IDetector_const_sptr DetConstPtr
std::map< specnum_t, Mantid::Kernel::V3D > SpectraDistanceMap
MANTID_DATAOBJECTS_DLL void normaliseOutput(const API::MatrixWorkspace_sptr &outputWS, const API::MatrixWorkspace_const_sptr &inputWS, API::Progress *progress=nullptr)
Compute sqrt of errors and put back in bin width division if necessary.
MANTID_DATAOBJECTS_DLL void rebinToFractionalOutput(const Geometry::Quadrilateral &inputQ, const API::MatrixWorkspace_const_sptr &inputWS, const size_t i, const size_t j, DataObjects::RebinnedOutput &outputWS, const std::vector< double > &verticalAxis, const DataObjects::RebinnedOutput_const_sptr &inputRB=nullptr)
Rebin the input quadrilateral to to output grid.
MANTID_DATAOBJECTS_DLL void finalizeFractionalRebin(DataObjects::RebinnedOutput &outputWS)
Set finalize flag after fractional rebinning loop.
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< RebinnedOutput > RebinnedOutput_sptr
shared pointer to the RebinnedOutput class
constexpr double rad2deg
Radians to degrees conversion factor.
Definition: AngleUnits.h:23
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
Definition: IDetector.h:102
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
Definition: MultiThreaded.h:22
int32_t detid_t
Typedef for a detector ID.
Definition: SpectrumInfo.h:21
int32_t specnum_t
Typedef for a spectrum Number.
Definition: IDTypes.h:16
std::string to_string(const wide_integer< Bits, Signed > &n)
double getEFixed(const Geometry::IDetector &det) const
Get the efixed value for the given detector.
Definition: SofQCommon.cpp:72
double q(const double deltaE, const double twoTheta, const Geometry::IDetector *det) const
Calculate the Q value.
Definition: SofQCommon.cpp:101
void initCachedValues(const API::MatrixWorkspace &workspace, API::Algorithm *const hostAlgorithm)
The procedure analyses emode and efixed properties provided to the algorithm and identify the energy ...
Definition: SofQCommon.cpp:25