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 if (spectrumInfo.hasDetectors(i)) {
101 g_log.
debug() <<
"Detector: " << spectrumInfo.firstDetectorID(i) <<
" Efixed: " << efixedProp <<
"\n";
105 spectrumInfo.getDetectorValues(*fromUnit, *toUnit, emode,
false, i,
pmap);
108 fromUnit->toTOF(xval, emptyVector, l1, emode,
pmap);
109 toUnit->fromTOF(xval, emptyVector, l1, emode,
pmap);
110 value = (xval.front() + xval.back()) / 2;
111 }
catch (std::runtime_error &) {
113 g_log.
warning() <<
"Unable to calculate new spectrum axis value for "
116 value = inputWS->getAxis(1)->getValue(i);
118 indexMap.emplace(
value, i);
120 if (nfailures == nHist) {
121 throw std::runtime_error(
"Unable to convert spectrum axis values on all spectra");
126 using namespace std::placeholders;
127 std::function<double(
const IDetector &)> thetaFunction;
128 if (unitTarget ==
"signed_theta") {
134 bool warningGiven =
false;
135 for (
size_t i = 0; i < nHist; ++i) {
139 indexMap.emplace(thetaFunction(*det) *
rad2deg, i);
142 g_log.
warning(
"The instrument definition is incomplete - spectra "
143 "dropped from output");
150 HistogramBuilder builder;
151 builder.setX(nxBins);
153 builder.setDistribution(inputWS->isDistribution());
154 MatrixWorkspace_sptr outputWS = create<MatrixWorkspace>(*inputWS, indexMap.size(), builder.build());
157 auto newAxis = std::make_unique<NumericAxis>(indexMap.size());
158 auto newAxisRaw = newAxis.get();
159 outputWS->replaceAxis(1, std::move(newAxis));
161 if (unitTarget ==
"theta" || unitTarget ==
"signed_theta") {
162 newAxisRaw->unit() = std::make_shared<Units::Degrees>();
164 newAxisRaw->unit() = UnitFactory::Instance().create(unitTarget);
166 std::multimap<double, size_t>::const_iterator it;
167 size_t currentIndex = 0;
168 for (it = indexMap.begin(); it != indexMap.end(); ++it) {
170 newAxisRaw->setValue(currentIndex, it->first);
172 outputWS->setHistogram(currentIndex, inputWS->histogram(it->second));
174 outputWS->getSpectrum(currentIndex).copyInfoFrom(inputWS->getSpectrum(it->second));