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