19using Mantid::HistogramData::HistogramE;
20using Mantid::HistogramData::HistogramX;
21using Mantid::HistogramData::HistogramY;
25using namespace Kernel;
32 :
API::
Algorithm(), m_inputWorkspace(), m_spectrumInfo(
nullptr), m_startX(DBL_MAX), m_endX(-DBL_MAX), m_rangeUnit(),
33 m_interpolate(false) {}
39 auto wsValidator = std::make_shared<HistogramValidator>();
41 "The name of the input workspace.");
43 "The name of the output workspace.");
45 auto mustHaveValue = std::make_shared<MandatoryValidator<double>>();
52 units.erase(std::remove(units.begin(), units.end(),
"Empty"), units.end());
53 units.erase(std::remove(units.begin(), units.end(),
"Label"), units.end());
54 units.erase(std::remove(units.begin(), units.end(),
"Time"), units.end());
55 units.erase(std::remove(units.begin(), units.end(),
"Degrees"), units.end());
58 units.insert(units.begin(),
"AsInput");
59 declareProperty(
"RangeUnit",
"AsInput", std::make_shared<StringListValidator>(units),
60 "The unit in which XMin/XMax are being given. If not given, "
61 "it will peak the unit from the Input workspace X unit.");
63 std::vector<std::string> propOptions{
"None",
"Linear"};
64 declareProperty(
"Interpolation",
"None", std::make_shared<StringListValidator>(propOptions),
65 "Whether mid-axis bins should be interpolated linearly "
66 "(\"Linear\") or set to zero (\"None\"). Note: Used when the "
67 "region to be removed is within a bin. Linear scales the "
68 "value in that bin by the proportion of it that is outside "
69 "the region to be removed and none sets it to zero");
71 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
72 mustBePositive->setLower(0);
74 "If set, will remove data only in the given spectrum of the "
75 "workspace. Otherwise, all spectra will be acted upon.");
82 std::map<std::string, std::string> result;
83 const std::string rangeUnit =
getProperty(
"RangeUnit");
93 const std::string failure(
"XMax must be greater than XMin.");
95 result[
"XMax"] = failure;
101 std::stringstream failureMsg;
102 failureMsg <<
"The value of WorkspaceIndex provided (" <<
index <<
") is larger than the size of this workspace ("
105 result[
"WorkspaceIndex"] = failureMsg.str();
108 const std::string interpolation =
getProperty(
"Interpolation");
111 const bool unitChange = (rangeUnit !=
"AsInput");
113 std::string errorString =
"";
115 errorString =
"A single valued workspace has no unit, which is required for "
121 if (unit && (!std::dynamic_pointer_cast<const Kernel::Unit>(unit))) {
122 errorString =
"The workspace must have units if the RangeUnit is not \"AsInput\"";
124 if (!errorString.empty()) {
125 g_log.
error() <<
"InputWorkspace: " << errorString <<
"\n";
126 result[
"InputWorkspace"] = errorString;
139 const std::string rangeUnit =
getProperty(
"RangeUnit");
140 const bool unitChange = (rangeUnit !=
"AsInput" && rangeUnit !=
m_inputWorkspace->getAxis(0)->unit()->unitID());
146 const bool recalcRange = (unitChange || !commonBins);
152 if (!singleSpectrum && !recalcRange && (
m_startX <= X0.front() ||
m_endX >= X0.back())) {
163 this->
crop(start, end);
179 int start = 0, end = 0;
181 const auto numHists =
static_cast<int>(
m_inputWorkspace->getNumberHistograms());
182 Progress prog(
this, 0.0, 1.0, numHists);
183 for (
int i = 0; i < numHists; ++i) {
188 if (singleSpectrum && (i !=
index))
198 auto &outY = outputWS->mutableY(i);
199 auto &outE = outputWS->mutableE(i);
201 if (recalcRange || singleSpectrum || !i) {
206 if (start == 0 || end == blockSize) {
211 const double startFrac = (
X[start] - startX) / (
X[start] -
X[start - 1]);
212 const double endFrac = (endX -
X[end - 1]) / (
X[end] -
X[end - 1]);
229 childAlg->setProperty<
double>(
"XMin", start);
230 childAlg->setProperty<
double>(
"XMax", end);
231 childAlg->executeAsChildAlg();
247 double factor, power;
248 if (
m_rangeUnit->quickConversion(*inputUnit, factor, power)) {
249 startX = factor * std::pow(
m_startX, power);
250 endX = factor * std::pow(
m_endX, power);
257 if (
pmap.find(UnitParams::l2) !=
pmap.end()) {
258 l2 =
pmap[UnitParams::l2];
261 if (
pmap.find(UnitParams::twoTheta) !=
pmap.end()) {
262 l2 =
pmap[UnitParams::twoTheta];
264 g_log.
debug() <<
"Detector for index " <<
index <<
" has L1+L2=" << l1 +
l2 <<
" & 2theta= " << theta <<
'\n';
265 std::vector<double> endPoints;
266 endPoints.emplace_back(startX);
267 endPoints.emplace_back(endX);
269 std::vector<double> emptyVec;
272 inputUnit->fromTOF(endPoints, emptyVec, l1, 0,
pmap);
273 startX = endPoints.front();
274 endX = endPoints.back();
275 }
catch (std::exception &) {
276 throw std::runtime_error(
"Unable to retrieve detector properties "
277 "required for unit conversion");
282 const double temp = startX;
287 g_log.
debug() <<
"For index " <<
index <<
", X range given corresponds to " << startX <<
"-" << endX
288 <<
" in workspace's unit\n";
298 auto pos = std::lower_bound(vec.cbegin(), vec.cend(),
value);
299 return static_cast<int>(std::distance(vec.cbegin(), pos));
311 auto size =
static_cast<int>(
Y.size());
314 for (
int j = start; j < end; ++j) {
335 HistogramY &
Y, HistogramE &E) {
344 valPrev =
Y[start - 1];
346 errPrev = E[start - 1];
350 const double m = (valNext - valPrev) / (1.0 * (end - start) + 2.0);
351 const double c = valPrev;
353 double aveE = (errPrev + errNext) / 2;
355 for (
int j = start; j < end; ++j) {
363 Y[j] =
m * (j - start + 1) + c;
#define DECLARE_ALGORITHM(classname)
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
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.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
Helper class for reporting progress from algorithms.
double l1() const
Returns L1 (distance from source to sample).
void getDetectorValues(const Kernel::Unit &inputUnit, const Kernel::Unit &outputUnit, const Kernel::DeltaEMode::Type emode, const bool signedTheta, int64_t wsIndex, Kernel::UnitParametersMap &pmap) const
Get the detector values relevant to unit conversion for a workspace index.
A property class for workspaces.
Removes bins from a workspace.
void RemoveFromEnds(int start, int end, HistogramData::HistogramY &Y, HistogramData::HistogramE &E)
Zeroes data (Y/E) at the end of a spectrum.
void init() override
Initialisation method.
double m_endX
The range end point.
void transformRangeUnit(const int index, double &startX, double &endX)
Convert the X range given into the unit of the input workspace.
double m_startX
The range start point.
void exec() override
Executes the algorithm.
Kernel::Unit_sptr m_rangeUnit
The unit in which the above range is given.
void crop(const double &start, const double &end)
Calls CropWorkspace as a Child Algorithm to remove bins from the start or end of a square workspace.
void RemoveFromMiddle(const int &start, const int &end, const double &startFrac, const double &endFrac, HistogramData::HistogramY &Y, HistogramData::HistogramE &E)
Removes bins in the middle of the data (Y/E).
API::MatrixWorkspace_const_sptr m_inputWorkspace
The input workspace.
int findIndex(const double &value, const HistogramData::HistogramX &vec)
Finds the index in an ordered vector which follows the given value.
bool m_interpolate
Whether removed bins should be interpolated.
std::map< std::string, std::string > validateInputs() override
Checks cross property validation.
const API::SpectrumInfo * m_spectrumInfo
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.
void error(const std::string &msg)
Logs at error level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unordered_map< UnitParams, double > UnitParametersMap
std::shared_ptr< const Unit > Unit_const_sptr
Shared pointer to the Unit base class (const version)
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Generate a tableworkspace to store the calibration results.
@ Input
An input workspace.
@ Output
An output workspace.