39 auto wsVal = std::make_shared<CompositeValidator>();
44 "The name of the input workspace.");
46 "The name to use for the output workspace.");
47 std::vector<std::string> targetOptions = Mantid::Kernel::UnitFactory::Instance().getKeys();
48 targetOptions.emplace_back(
"theta");
49 targetOptions.emplace_back(
"signed_theta");
50 declareProperty(
"Target",
"", std::make_shared<StringListValidator>(targetOptions),
51 "The unit to which the spectrum axis should be converted. "
52 "This can be either \"theta\" (for <math>\\theta</math> "
53 "degrees), or any of the IDs known to the [[Unit Factory]].");
54 std::vector<std::string> eModeOptions;
55 eModeOptions.emplace_back(
"Direct");
56 eModeOptions.emplace_back(
"Indirect");
57 declareProperty(
"EMode",
"Direct", std::make_shared<StringListValidator>(eModeOptions),
58 "Some unit conversions require this value to be set "
59 "(\"Direct\" or \"Indirect\")");
60 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
61 mustBePositive->setLower(0.0);
63 "Value of fixed energy in meV : EI (EMode=Direct) or EF "
74 std::multimap<double, size_t> indexMap;
75 const size_t nHist = inputWS->getNumberHistograms();
76 const size_t nBins = inputWS->blocksize();
77 const bool isHist = inputWS->isHistogramData();
78 auto &spectrumInfo = inputWS->spectrumInfo();
85 if (unitTarget !=
"theta" && unitTarget !=
"signed_theta") {
88 std::vector<double> emptyVector;
89 const double l1 = spectrumInfo.l1();
93 for (
size_t i = 0; i < nHist; i++) {
94 std::vector<double> xval{inputWS->x(i).front(), inputWS->x(i).back()};
99 pmap[UnitParams::efixed] = efixedProp;
100 g_log.
debug() <<
"Detector: " << spectrumInfo.detector(i).getID() <<
" Efixed: " << efixedProp <<
"\n";
103 spectrumInfo.getDetectorValues(*fromUnit, *toUnit, emode,
false, i,
pmap);
106 fromUnit->toTOF(xval, emptyVector, l1, emode,
pmap);
107 toUnit->fromTOF(xval, emptyVector, l1, emode,
pmap);
108 value = (xval.front() + xval.back()) / 2;
109 }
catch (std::runtime_error &) {
111 g_log.
warning() <<
"Unable to calculate new spectrum axis value for "
114 value = inputWS->getAxis(1)->getValue(i);
116 indexMap.emplace(
value, i);
118 if (nfailures == nHist) {
119 throw std::runtime_error(
"Unable to convert spectrum axis values on all spectra");
124 using namespace std::placeholders;
125 std::function<double(
const IDetector &)> thetaFunction;
126 if (unitTarget ==
"signed_theta") {
132 bool warningGiven =
false;
133 for (
size_t i = 0; i < nHist; ++i) {
137 indexMap.emplace(thetaFunction(*det) *
rad2deg, i);
140 g_log.
warning(
"The instrument definition is incomplete - spectra "
141 "dropped from output");
148 HistogramBuilder builder;
149 builder.setX(nxBins);
151 builder.setDistribution(inputWS->isDistribution());
152 MatrixWorkspace_sptr outputWS = create<MatrixWorkspace>(*inputWS, indexMap.size(), builder.build());
155 auto newAxis = std::make_unique<NumericAxis>(indexMap.size());
156 auto newAxisRaw = newAxis.get();
157 outputWS->replaceAxis(1, std::move(newAxis));
159 if (unitTarget ==
"theta" || unitTarget ==
"signed_theta") {
160 newAxisRaw->unit() = std::make_shared<Units::Degrees>();
162 newAxisRaw->unit() = UnitFactory::Instance().create(unitTarget);
164 std::multimap<double, size_t>::const_iterator it;
165 size_t currentIndex = 0;
166 for (it = indexMap.begin(); it != indexMap.end(); ++it) {
168 newAxisRaw->setValue(currentIndex, it->first);
170 outputWS->setHistogram(currentIndex, inputWS->histogram(it->second));
172 outputWS->getSpectrum(currentIndex).copyInfoFrom(inputWS->getSpectrum(it->second));