21using Mantid::Types::Core::DateAndTime;
33std::string
const LOG_NAME(
"LogName");
34std::string
const SMOOTHING_METHOD(
"SmoothingMethod");
35std::string
const PARAMS(
"Params");
36std::string
const NEW_LOG_NAME(
"NewLogName");
41enum class SmoothingMethod { BOXCAR, FFT_ZERO, FFT_BUTTERWORTH, enum_count };
42const std::vector<std::string> smoothingMethods{
"BoxCar",
"Zeroing",
"Butterworth"};
48std::vector<double> getUniformXValues(std::vector<double>
const &xVec) {
49 std::vector<double> newX;
50 newX.reserve(xVec.size());
51 if (xVec.size() < 2) {
54 double const xf = xVec.back(), xi = xVec.front();
55 double const dx = (xf - xi) /
static_cast<double>(xVec.size() - 1);
56 for (std::size_t i = 0; i < xVec.size(); i++) {
57 newX.push_back(xi +
static_cast<double>(i) * dx);
63std::vector<DateAndTime> relativeToAbsoluteTime(DateAndTime
const &startTime, std::vector<double>
const &relTimes) {
65 std::vector<DateAndTime> timeFull;
66 timeFull.reserve(relTimes.size());
67 std::transform(relTimes.begin(), relTimes.end(), std::back_inserter(timeFull),
68 [&startTime](
const double time) { return startTime + time; });
78 "An input/output workspace. The new log will be added to it.");
81 "The name that will identify the log entry to be smoothed.\nThis log must be a numerical series (double).");
83 PropertyNames::SMOOTHING_METHOD),
84 "The smoothing method to use");
86 "The parameters which will be passed to the smoothing function.");
88 PropertyNames::NEW_LOG_NAME,
"",
89 "Name of the newly created log. If not specified, the string '_smoothed' will be appended to the original name");
93 std::map<std::string, std::string> issues;
99 case SmoothingMethod::BOXCAR: {
100 if (params.empty()) {
102 }
else if (params[0] < 0) {
104 }
else if (params[0] % 2 == 0) {
106 "Boxcar smoothing requires an odd window size: " +
std::to_string(params[0]) +
" is even";
110 case SmoothingMethod::FFT_ZERO: {
111 if (params.empty()) {
113 }
else if (params[0] <= 1) {
115 "The cutoff in FFT zeroing must be larger than 1; passed " +
std::to_string(params[0]);
119 case SmoothingMethod::FFT_BUTTERWORTH: {
120 if (params.size() < 2) {
122 "Butterworth smoothing requires two parameters, passed " +
std::to_string(params.size());
123 }
else if (params[0] <= 1 || params[1] < 1) {
125 "In Butterworth smoothing, cutoff must be greater than 1 and order must be greater than 0";
130 issues[PropertyNames::SMOOTHING_METHOD] =
131 "Parameter validation for smoothing method " + std::string(type) +
" has not been implemented";
144 Run const &run = ws->run();
146 issues[PropertyNames::LOG_NAME] =
"Log " + logName +
" not found in the workspace sample logs.";
151 issues[PropertyNames::LOG_NAME] =
"Log " + logName +
" must be a numerical time series (TimeSeries<double>).";
153 std::size_t
const minBoxCarSize = (params.empty() ? 0 :
static_cast<std::size_t
>(params[0]));
154 std::size_t
const MIN_SPLINE_POINTS{5UL};
155 std::size_t minSize = (type == SmoothingMethod::BOXCAR ? minBoxCarSize : MIN_SPLINE_POINTS);
156 if (
static_cast<std::size_t
>(tsp->size()) < minSize) {
157 issues[PropertyNames::LOG_NAME] =
"Log " + logName +
158 " has insufficient number of points: " +
std::to_string(tsp->size()) +
" < " +
173 if (newLogName.empty())
174 newLogName = logName +
"_smoothed";
177 Run &run = ws->mutableRun();
180 std::vector<double> times = tsp->timesAsVectorSeconds();
183 auto output = std::make_unique<TimeSeriesProperty<double>>(newLogName);
185 switch (smoothingMethod) {
186 case SmoothingMethod::BOXCAR: {
188 output->addValues(tsp->timesAsVector(), newValues);
191 case SmoothingMethod::FFT_ZERO: {
192 std::vector<double> flatTimes = getUniformXValues(times);
195 output->addValues(relativeToAbsoluteTime(tsp->nthTime(0), flatTimes), smoothedValues);
198 case SmoothingMethod::FFT_BUTTERWORTH: {
199 std::vector<double> flatTimes = getUniformXValues(times);
202 output->addValues(relativeToAbsoluteTime(tsp->nthTime(0), flatTimes), smoothedValues);
207 " has not been implemented");
213 g_log.
notice() <<
"Added log named " << newLogName <<
" to " << ws->getName() <<
'\n';
#define DECLARE_ALGORITHM(classname)
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.
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Kernel::Property * getProperty(const std::string &name) const
Returns the named property as a pointer.
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
std::map< std::string, std::string > validateInputs() override
Validate input parameters.
void init() override
Initialise the properties.
void exec() override
Run the algorithm.
Support for a property that holds an array of values.
static std::vector< Y > getSplinedYValues(std::span< X const > newX, std::span< X const > x, std::span< Y const > y)
A concrete property based on user options of a finite list of strings.
Marks code as not implemented yet.
void notice(const std::string &msg)
Logs at notice level.
Validator to check that a property is not left empty.
A specialised Property class for holding a series of time-value pairs.
std::vector< TYPE > valuesAsVector() const
Return the time series's values (unfiltered) as a vector<TYPE>
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::string const INPUT_WKSP("InputWorkspace")
std::string const PARAMS("Params")
std::vector< T > boxcarSmooth(std::vector< T > const &input, unsigned int const numPoints)
Performs boxcar (moving average) smoothing on the input data.
std::vector< Y > fftButterworthSmooth(std::vector< Y > const &input, unsigned const cutoff, unsigned const order)
Performs FFT smoothing on the input data, using a Butterworth filter NOTE: the input data MUST be def...
std::vector< Y > fftSmooth(std::vector< Y > const &input, unsigned const cutoff)
Performs FFT smoothing on the input data, with high frequencies set to zero NOTE: the input data MUST...
const std::string PARAMS("Params")
const std::string INPUT_WKSP("InputWorkspace")
std::string to_string(const wide_integer< Bits, Signed > &n)
@ InOut
Both an input & output workspace.