Mantid
Loading...
Searching...
No Matches
ConvertUnits.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 +
9#include "MantidAPI/Axis.h"
10#include "MantidAPI/Run.h"
18#include "MantidHistogramData/Histogram.h"
23
24#include <numeric>
25
26namespace Mantid::Algorithms {
27
28// Register with the algorithm factory
29DECLARE_ALGORITHM(ConvertUnits)
30
31using namespace Kernel;
32using namespace API;
33using namespace DataObjects;
34using namespace HistogramData;
35
38 auto wsValidator = std::make_shared<CompositeValidator>();
39 wsValidator->add<WorkspaceUnitValidator>();
41 std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("InputWorkspace", "", Direction::Input, wsValidator),
42 "Name of the input workspace");
43 declareProperty(std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("OutputWorkspace", "", Direction::Output),
44 "Name of the output workspace, can be the same as the input");
45
46 // Extract the current contents of the UnitFactory to be the allowed values of
47 // the Target property
48 declareProperty("Target", "", std::make_shared<StringListValidator>(UnitFactory::Instance().getConvertibleUnits()),
49 "The name of the units to convert to (must be one of those "
50 "registered in\n"
51 "the Unit Factory)");
52 std::vector<std::string> propOptions{"Elastic", "Direct", "Indirect"};
53 declareProperty("EMode", "Elastic", std::make_shared<StringListValidator>(propOptions),
54 "The energy mode (default: elastic)");
55 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
56 mustBePositive->setLower(0.0);
57 declareProperty("EFixed", EMPTY_DBL(), mustBePositive,
58 "Value of fixed energy in meV : EI (EMode='Direct') or EF "
59 "(EMode='Indirect') . Must be\n"
60 "set if the target unit requires it (e.g. DeltaE)");
61
62 declareProperty("AlignBins", false,
63 "If true (default is false), rebins after conversion to "
64 "ensure that all spectra in the output workspace\n"
65 "have identical bin boundaries. This option is not "
66 "recommended (see "
67 "http://docs.mantidproject.org/algorithms/ConvertUnits).");
68
69 declareProperty("ConvertFromPointData", true,
70 "When checked, if the Input Workspace contains Points\n"
71 "the algorithm ConvertToHistogram will be run to convert\n"
72 "the Points to Bins. The Output Workspace will contains Bins.");
73}
74
86 // Get the workspaces
87 MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace");
88 const bool acceptPointData = getProperty("ConvertFromPointData");
89 bool workspaceWasConverted = false;
90
91 // we can do that before anything else, because it doesn't setup any blocksize, which is the one that changes with
92 // conversion
93 this->setupMemberVariables(inputWS);
94
95 // Check that the input workspace doesn't already have the desired unit.
96 if (m_inputUnit->unitID() == m_outputUnit->unitID()) {
97 const std::string outputWSName = getPropertyValue("OutputWorkspace");
98 const std::string inputWSName = getPropertyValue("InputWorkspace");
99 if (outputWSName == inputWSName) {
100 // If it does, just set the output workspace to point to the input one and be done
101 g_log.information() << "Input workspace already has target unit (" << m_outputUnit->unitID()
102 << "), so just pointing the output workspace property to the input workspace.\n";
103 setProperty("OutputWorkspace", std::const_pointer_cast<MatrixWorkspace>(inputWS));
104 return;
105 } else {
106 // Clone the workspace.
107 auto duplicate = createChildAlgorithm("CloneWorkspace", 0.0, 0.6);
108 duplicate->initialize();
109 duplicate->setProperty("InputWorkspace", inputWS);
110 duplicate->execute();
111 Workspace_sptr temp = duplicate->getProperty("OutputWorkspace");
112 auto outputWs = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
113 setProperty("OutputWorkspace", outputWs);
114 return;
115 }
116 }
117
118 // Holder for the correctWS, because if we're converting from
119 // PointData a new workspace is created
120 MatrixWorkspace_sptr correctWS;
121 if (!inputWS->isHistogramData()) {
122 if (acceptPointData) {
123 workspaceWasConverted = true;
124 g_log.information("ConvertFromPointData is checked. Running ConvertToHistogram\n");
125 // not histogram data
126 // ConvertToHistogram
127 auto convToHist = createChildAlgorithm("ConvertToHistogram");
128 convToHist->setProperty("InputWorkspace", inputWS);
129 convToHist->execute();
130 MatrixWorkspace_sptr temp = convToHist->getProperty("OutputWorkspace");
131 correctWS = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
132
133 if (!correctWS->isHistogramData()) {
134 throw std::runtime_error("Failed to convert workspace from Points to Bins");
135 }
136 } else {
137 throw std::runtime_error("Workspace contains points, you can either run ConvertToHistogram on it, or set "
138 "ConvertFromPointData to enabled");
139 }
140 } else {
141 correctWS = inputWS;
142 }
143
144 MatrixWorkspace_sptr outputWS = executeUnitConversion(correctWS);
145
146 // If InputWorkspace contained point data, convert back
147 if (workspaceWasConverted) {
148 g_log.information("ConvertUnits is completed. Running ConvertToPointData.\n");
149 auto convtoPoints = createChildAlgorithm("ConvertToPointData");
150 convtoPoints->setProperty("InputWorkspace", outputWS);
151 convtoPoints->execute();
152 MatrixWorkspace_sptr temp = convtoPoints->getProperty("OutputWorkspace");
153 outputWS = std::dynamic_pointer_cast<MatrixWorkspace>(temp);
154
155 if (outputWS->isHistogramData()) {
156 throw std::runtime_error("Failed to convert workspace from Bins to Points");
157 }
158 }
159
160 // Point the output property to the right place.
161 // Do right at end (workspace could could change in removeUnphysicalBins or alignBins methods)
162 setProperty("OutputWorkspace", outputWS);
163}
164
172
173 // A WS holding BinEdges cannot have less than 2 values, as a bin has
174 // 2 edges, having less than 2 values would mean that the WS contains Points
175 if (inputWS->x(0).size() < 2) {
176 std::stringstream msg;
177 msg << "Input workspace has invalid X axis binning parameters. Should have at least 2 values. Found "
178 << inputWS->x(0).size() << ".";
179 throw std::runtime_error(msg.str());
180 }
181 if (inputWS->x(0).front() > inputWS->x(0).back() ||
182 inputWS->x(m_numberOfSpectra / 2).front() > inputWS->x(m_numberOfSpectra / 2).back())
183 throw std::runtime_error("Input workspace has invalid X axis binning "
184 "parameters. X values should be increasing.");
185
186 MatrixWorkspace_sptr outputWS;
187 // Check whether there is a quick conversion available
188 double factor, power;
189 if (m_inputUnit->quickConversion(*m_outputUnit, factor, power))
190 // If test fails, could also check whether a quick conversion in the opposite direction has been entered
191 {
192 outputWS = this->convertQuickly(inputWS, factor, power);
193 } else {
194 outputWS = this->convertViaTOF(m_inputUnit, inputWS);
195 }
196
197 // If the units conversion has flipped the ascending direction of X, reverse all the vectors
198 if (!outputWS->x(0).empty() &&
199 (outputWS->x(0).front() > outputWS->x(0).back() ||
200 outputWS->x(m_numberOfSpectra / 2).front() > outputWS->x(m_numberOfSpectra / 2).back())) {
201 this->reverse(outputWS);
202 }
203
204 // Need to lop bins off if converting to energy transfer.
205 // Don't do for EventWorkspaces, where you can easily rebin to recover the situation without losing information
206 /* This is an ugly test - could be made more general by testing for DBL_MAX
207 values at the ends of all spectra, but that would be less efficient */
208 if (m_outputUnit->unitID().find("Delta") == 0 && !m_inputEvents)
209 outputWS = this->removeUnphysicalBins(outputWS);
210
211 // Rebin the data to common bins if requested, and if necessary
212 const bool doAlignBins = getProperty("AlignBins");
213 if (doAlignBins && !outputWS->isCommonBins())
214 outputWS = this->alignBins(outputWS);
215
216 // If appropriate, put back the bin width division into Y/E.
217 if (m_distribution && !m_inputEvents) { // Never do this for event workspaces
218 this->putBackBinWidth(outputWS);
219 }
220
221 return outputWS;
222}
227 m_numberOfSpectra = inputWS->getNumberHistograms();
228 // In the context of this algorithm, we treat things as a distribution if
229 // the flag is set AND the data are not dimensionless
230 m_distribution = inputWS->isDistribution() && !inputWS->YUnit().empty();
231 // Check if its an event workspace
232 m_inputEvents = (std::dynamic_pointer_cast<const EventWorkspace>(inputWS) != nullptr);
233
234 m_inputUnit = inputWS->getAxis(0)->unit();
235 const std::string targetUnit = getPropertyValue("Target");
236 m_outputUnit = UnitFactory::Instance().create(targetUnit);
237}
238
245 MatrixWorkspace_sptr outputWS = getProperty("OutputWorkspace");
246
247 // If input and output workspaces are NOT the same, create a new workspace for the output
248 if (outputWS != inputWS) {
249 outputWS = inputWS->clone();
250 }
251
253 // Loop over the histograms (detector spectra)
254 Progress prog(this, 0.0, 0.2, m_numberOfSpectra);
256 for (int64_t i = 0; i < static_cast<int64_t>(m_numberOfSpectra); ++i) {
258 // Take the bin width dependency out of the Y & E data
259 const auto &X = outputWS->x(i);
260 auto &Y = outputWS->mutableY(i);
261 auto &E = outputWS->mutableE(i);
262 for (size_t j = 0; j < Y.size(); ++j) {
263 const double width = std::abs(X[j + 1] - X[j]);
264 Y[j] *= width;
265 E[j] *= width;
266 }
267
268 prog.report("Convert to " + m_outputUnit->unitID());
270 }
272 }
273
274 // Set the final unit that our output workspace will have
275 outputWS->getAxis(0)->unit() = m_outputUnit;
276 storeEModeOnWorkspace(outputWS);
277
278 return outputWS;
279}
280
285 // Store the emode
286 const bool overwrite(true);
287 outputWS->mutableRun().addProperty("deltaE-mode", getPropertyValue("EMode"), overwrite);
288}
289
298 const double &power) {
299 Progress prog(this, 0.2, 1.0, m_numberOfSpectra);
300 auto numberOfSpectra_i = static_cast<int64_t>(m_numberOfSpectra); // cast to make openmp happy
301 // create the output workspace
302 MatrixWorkspace_sptr outputWS = this->setupOutputWorkspace(inputWS);
303 // See if the workspace has common bins - if so the X vector can be common
304 const bool commonBoundaries = inputWS->isCommonBins();
305 if (commonBoundaries) {
306 // Calculate the new (common) X values
307 std::transform(outputWS->mutableX(0).cbegin(), outputWS->mutableX(0).cend(), outputWS->mutableX(0).begin(),
308 [&](const auto &x) { return factor * std::pow(x, power); });
309
310 auto xVals = outputWS->sharedX(0);
311
313 for (int64_t j = 1; j < numberOfSpectra_i; ++j) {
315 outputWS->setX(j, xVals);
316 prog.report("Convert to " + m_outputUnit->unitID());
318 }
320 if (!m_inputEvents) // if in event mode the work is done
321 return outputWS;
322 }
323
324 EventWorkspace_sptr eventWS = std::dynamic_pointer_cast<EventWorkspace>(outputWS);
325 assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check
326
327 // If we get to here then the bins weren't aligned and each spectrum is
328 // unique
329 // Loop over the histograms (detector spectra)
331 for (int64_t k = 0; k < numberOfSpectra_i; ++k) {
333 if (!commonBoundaries) {
334 std::transform(outputWS->mutableX(k).cbegin(), outputWS->mutableX(k).cend(), outputWS->mutableX(k).begin(),
335 [&](const auto &x) { return factor * std::pow(x, power); });
336 }
337 // Convert the events themselves if necessary.
338 if (m_inputEvents) {
339 eventWS->getSpectrum(k).convertUnitsQuickly(factor, power);
340 }
341 prog.report("Convert to " + m_outputUnit->unitID());
343 }
345
346 if (m_inputEvents)
347 eventWS->clearMRU();
348
349 return outputWS;
350}
351
360 using namespace Geometry;
361
362 Progress prog(this, 0.2, 1.0, m_numberOfSpectra);
363 auto numberOfSpectra_i = static_cast<int64_t>(m_numberOfSpectra); // cast to make openmp happy
364
366
367 const auto &spectrumInfo = inputWS->spectrumInfo();
368 double l1 = spectrumInfo.l1();
369 g_log.debug() << "Source-sample distance: " << l1 << '\n';
370
371 int failedDetectorCount = 0;
372
375 const std::string emodeStr = getProperty("EMode");
377
378 // Not doing anything with the Y vector in to/fromTOF yet, so just pass
379 // empty
380 // vector
381 std::vector<double> emptyVec;
382 double efixedProp = getProperty("Efixed");
383 if (efixedProp == EMPTY_DBL() && emode == DeltaEMode::Type::Direct) {
384 try {
385 efixedProp = inputWS->getEFixedGivenEMode(nullptr, emode);
386 } catch (std::runtime_error &) {
387 }
388 }
389
390 std::vector<std::string> parameters = inputWS->getInstrument()->getStringParameter("show-signed-theta");
391 bool signedTheta = (!parameters.empty()) && find(parameters.begin(), parameters.end(), "Always") != parameters.end();
392
393 auto checkFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
394 auto checkOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
395
396 // Perform Sanity Validation before creating workspace
397 const double checkdelta = 0.0;
398 UnitParametersMap upmap = {{UnitParams::delta, checkdelta}};
399 if (efixedProp != EMPTY_DBL()) {
400 upmap[UnitParams::efixed] = efixedProp;
401 }
402 size_t checkIndex = 0;
403 spectrumInfo.getDetectorValues(*fromUnit, *outputUnit, emode, signedTheta, checkIndex, upmap);
404 // copy the X values for the check
405 auto checkXValues = inputWS->readX(checkIndex);
406 try {
407 // Convert the input unit to time-of-flight
408 checkFromUnit->toTOF(checkXValues, emptyVec, l1, emode, upmap);
409 // Convert from time-of-flight to the desired unit
410 checkOutputUnit->fromTOF(checkXValues, emptyVec, l1, emode, upmap);
411 } catch (std::runtime_error &) { // if it's a detector specific problem then ignore
412 }
413
414 // create the output workspace
415 MatrixWorkspace_sptr outputWS = this->setupOutputWorkspace(inputWS);
416 EventWorkspace_sptr eventWS = std::dynamic_pointer_cast<EventWorkspace>(outputWS);
417 assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check
418
419 auto &outSpectrumInfo = outputWS->mutableSpectrumInfo();
420 // Loop over the histograms (detector spectra)
422 for (int64_t i = 0; i < numberOfSpectra_i; ++i) {
424 double efixed = efixedProp;
425
426 // Now get the detector object for this histogram
428 const double delta = 0.0;
429
430 auto localFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
431 auto localOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
432
433 // TODO toTOF and fromTOF need to be reimplemented outside of kernel
434 UnitParametersMap pmap = {{UnitParams::delta, delta}};
435 if (efixedProp != EMPTY_DBL()) {
436 pmap[UnitParams::efixed] = efixed;
437 }
438 outSpectrumInfo.getDetectorValues(*fromUnit, *outputUnit, emode, signedTheta, i, pmap);
439 try {
440 localFromUnit->toTOF(outputWS->dataX(i), emptyVec, l1, emode, pmap);
441 // Convert from time-of-flight to the desired unit
442 localOutputUnit->fromTOF(outputWS->dataX(i), emptyVec, l1, emode, pmap);
443
444 // EventWorkspace part, modifying the EventLists.
445 if (m_inputEvents) {
446 eventWS->getSpectrum(i).convertUnitsViaTof(localFromUnit.get(), localOutputUnit.get());
447 }
448 } catch (std::runtime_error &) {
449 // Get to here if exception thrown in unit conversion eg when calculating
450 // distance to detector
451 failedDetectorCount++;
452 // Since you usually (always?) get to here when there's no attached
453 // detectors, this call is
454 // the same as just zeroing out the data (calling clearData on the
455 // spectrum)
456 outputWS->getSpectrum(i).clearData();
457 if (outSpectrumInfo.hasDetectors(i))
458 outSpectrumInfo.setMasked(i, true);
459 }
460
461 prog.report("Convert to " + m_outputUnit->unitID());
463 } // loop over spectra
465
466 if (failedDetectorCount != 0) {
467 g_log.warning() << "Unable to calculate sample-detector distance for " << failedDetectorCount
468 << " spectra. Masking spectrum.\n";
469 }
470 if (m_inputEvents)
471 eventWS->clearMRU();
472
473 if (emode == 1) {
474 //... direct efixed gather
475 if (efixedProp != EMPTY_DBL()) {
476 // set the Ei value in the run parameters
477 API::Run &run = outputWS->mutableRun();
478 run.addProperty<double>("Ei", efixedProp, true);
479 }
480 }
481
482 return outputWS;
483}
484
487 // Create a Rebin child algorithm
488 auto childAlg = createChildAlgorithm("Rebin");
489 childAlg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", workspace);
490 // Next line for EventWorkspaces - needed for as long as in/out set same
491 // keeps
492 // as events.
493 childAlg->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", workspace);
494 childAlg->setProperty<std::vector<double>>("Params", this->calculateRebinParams(workspace));
495 childAlg->executeAsChildAlg();
496 return childAlg->getProperty("OutputWorkspace");
497}
498
502 const auto &spectrumInfo = workspace->spectrumInfo();
503 // Need to loop round and find the full range
504 double XMin = DBL_MAX, XMax = DBL_MIN;
505 const size_t numSpec = workspace->getNumberHistograms();
506 for (size_t i = 0; i < numSpec; ++i) {
507 if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMasked(i)) {
508 auto &XData = workspace->x(i);
509 double xfront = XData.front();
510 double xback = XData.back();
511 if (std::isfinite(xfront) && std::isfinite(xback)) {
512 if (xfront < XMin)
513 XMin = xfront;
514 if (xback > XMax)
515 XMax = xback;
516 }
517 }
518 }
519 const double step = (XMax - XMin) / static_cast<double>(workspace->blocksize());
520
521 return {XMin, step, XMax};
522}
523
528 EventWorkspace_sptr eventWS = std::dynamic_pointer_cast<EventWorkspace>(WS);
529 auto isInputEvents = static_cast<bool>(eventWS);
530 size_t numberOfSpectra = WS->getNumberHistograms();
531 if (WS->isCommonBins() && !isInputEvents) {
532 auto reverseX = make_cow<HistogramData::HistogramX>(WS->x(0).crbegin(), WS->x(0).crend());
533 for (size_t j = 0; j < numberOfSpectra; ++j) {
534 WS->setSharedX(j, reverseX);
535 std::reverse(WS->dataY(j).begin(), WS->dataY(j).end());
536 std::reverse(WS->dataE(j).begin(), WS->dataE(j).end());
537 if (j % 100 == 0)
539 }
540 } else {
541 // either events or ragged boundaries
542 auto numberOfSpectra_i = static_cast<int>(numberOfSpectra);
544 for (int j = 0; j < numberOfSpectra_i; ++j) {
546 if (isInputEvents) {
547 eventWS->getSpectrum(j).reverse();
548 } else {
549 std::reverse(WS->mutableX(j).begin(), WS->mutableX(j).end());
550 std::reverse(WS->mutableY(j).begin(), WS->mutableY(j).end());
551 std::reverse(WS->mutableE(j).begin(), WS->mutableE(j).end());
552 }
554 }
556 }
557}
558
577
578 const auto &spectrumInfo = workspace->spectrumInfo();
579 const size_t numSpec = workspace->getNumberHistograms();
580 const std::string emode = getProperty("Emode");
581 if (emode == "Direct") {
582 // First the easy case of direct instruments, where all spectra will need
583 // the
584 // same number of bins removed
585 // Need to make sure we don't pick a monitor as the 'reference' X spectrum
586 // (X0)
587 size_t i = 0;
588 for (; i < numSpec; ++i) {
589 if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i))
590 break;
591 }
592 // Get an X spectrum to search (they're all the same, monitors excepted)
593 auto &X0 = workspace->x(i);
594 auto start = std::lower_bound(X0.cbegin(), X0.cend(), -1.0e-10 * DBL_MAX);
595 if (start == X0.end()) {
596 const std::string e("Check the input EFixed: the one given leads to all "
597 "bins being in the physically inaccessible region.");
598 g_log.error(e);
599 throw std::invalid_argument(e);
600 }
601 MantidVec::difference_type bins = X0.cend() - start;
602 MantidVec::difference_type first = start - X0.cbegin();
603
604 result = create<MatrixWorkspace>(*workspace, BinEdges(bins));
605
606 for (size_t wsIndex = 0; wsIndex < numSpec; ++wsIndex) {
607 auto &X = workspace->x(wsIndex);
608 auto &Y = workspace->y(wsIndex);
609 auto &E = workspace->e(wsIndex);
610 result->mutableX(wsIndex).assign(X.begin() + first, X.end());
611 result->mutableY(wsIndex).assign(Y.begin() + first, Y.end());
612 result->mutableE(wsIndex).assign(E.begin() + first, E.end());
613 }
614 } else if (emode == "Indirect") {
615 // Now the indirect instruments. In this case we could want to keep a
616 // different
617 // number of bins in each spectrum because, in general L2 is different for
618 // each
619 // one.
620 // Thus, we first need to loop to find largest 'good' range
621 std::vector<MantidVec::difference_type> lastBins(numSpec);
622 int maxBins = 0;
623 for (size_t i = 0; i < numSpec; ++i) {
624 const MantidVec &X = workspace->readX(i);
625 auto end = std::lower_bound(X.cbegin(), X.cend(), 1.0e-10 * DBL_MAX);
626 MantidVec::difference_type bins = end - X.cbegin();
627 lastBins[i] = bins;
628 if (bins > maxBins)
629 maxBins = static_cast<int>(bins);
630 }
631 g_log.debug() << maxBins << '\n';
632 // Now create an output workspace large enough for the longest 'good'
633 // range
634 result = create<MatrixWorkspace>(*workspace, numSpec, BinEdges(maxBins));
635 // Next, loop again copying in the correct range for each spectrum
636 for (int64_t j = 0; j < int64_t(numSpec); ++j) {
637 auto edges = workspace->binEdges(j);
638 auto k = lastBins[j];
639
640 auto &X = result->mutableX(j);
641 std::copy(edges.cbegin(), edges.cbegin() + k, X.begin());
642
643 // If the entire X range is not covered, generate fake values.
644 if (k < maxBins) {
645 std::iota(X.begin() + k, X.end(), workspace->x(j)[k] + 1);
646 }
647
648 std::copy(workspace->y(j).cbegin(), workspace->y(j).cbegin() + (k - 1), result->mutableY(j).begin());
649 std::copy(workspace->e(j).cbegin(), workspace->e(j).cbegin() + (k - 1), result->mutableE(j).begin());
650 }
651 }
652
653 return result;
654}
655
660 for (size_t i = 0; i < m_numberOfSpectra; ++i) {
661 const size_t outSize = outputWS->getNumberBins(i);
662 for (size_t j = 0; j < outSize; ++j) {
663 const double width = std::abs(outputWS->x(i)[j + 1] - outputWS->x(i)[j]);
664 outputWS->mutableY(i)[j] = outputWS->y(i)[j] / width;
665 outputWS->mutableE(i)[j] = outputWS->e(i)[j] / width;
666 }
667 }
668}
669
670} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
IPeaksWorkspace_sptr workspace
#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...
#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.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
void interruption_point()
This is called during long-running operations, and check if the algorithm has requested that it be ca...
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Definition LogManager.h:91
Helper class for reporting progress from algorithms.
Definition Progress.h:25
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
void reverse(const API::MatrixWorkspace_sptr &WS)
Reverses the workspace if X values are in descending order.
API::MatrixWorkspace_sptr convertQuickly(const API::MatrixWorkspace_const_sptr &inputWS, const double &factor, const double &power)
Convert the workspace units according to a simple output = a * (input^b) relationship.
virtual API::MatrixWorkspace_sptr convertViaTOF(Kernel::Unit_const_sptr fromUnit, API::MatrixWorkspace_const_sptr inputWS)
Convert the workspace units using TOF as an intermediate step in the conversion.
const std::vector< double > calculateRebinParams(const API::MatrixWorkspace_const_sptr &workspace) const
The Rebin parameters should cover the full range of the converted unit, with the same number of bins.
virtual void storeEModeOnWorkspace(API::MatrixWorkspace_sptr outputWS)
Stores the emode in the provided workspace.
Kernel::Unit_const_sptr m_inputUnit
The unit of the input workspace.
void putBackBinWidth(const API::MatrixWorkspace_sptr &outputWS)
Divide by the bin width if workspace is a distribution.
API::MatrixWorkspace_sptr alignBins(const API::MatrixWorkspace_sptr &workspace)
Calls Rebin as a Child Algorithm to align the bins.
API::MatrixWorkspace_sptr executeUnitConversion(const API::MatrixWorkspace_sptr &inputWS)
Executes the main part of the algorithm that handles the conversion of the units.
void init() override
Initialisation method.
void setupMemberVariables(const API::MatrixWorkspace_const_sptr &inputWS)
Initialise the member variables.
API::MatrixWorkspace_sptr removeUnphysicalBins(const API::MatrixWorkspace_const_sptr &workspace)
For conversions to energy transfer, removes bins corresponding to inaccessible values.
bool m_inputEvents
to histogram workspaces.
Kernel::Unit_sptr m_outputUnit
The unit we're going to.
bool m_distribution
Whether input is a distribution.
void exec() override
Executes the algorithm.
std::size_t m_numberOfSpectra
The number of spectra in the input workspace.
API::MatrixWorkspace_sptr setupOutputWorkspace(const API::MatrixWorkspace_const_sptr &inputWS)
Create an output workspace of the appropriate (histogram or event) type and copy over the data.
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:145
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::unordered_map< UnitParams, double > UnitParametersMap
Definition Unit.h:30
std::shared_ptr< const Unit > Unit_const_sptr
Shared pointer to the Unit base class (const version)
Definition Unit.h:196
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.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition cow_ptr.h:172
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
Generate a tableworkspace to store the calibration results.
static Type fromString(const std::string &modeStr)
Returns the emode from the given string.
Type
Define the available energy transfer modes It is important to assign enums proper numbers,...
Definition DeltaEMode.h:29
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54