-
Federico Montesino Pouzols authored
Apply changes from clang-tidy: modernize-use-default. (Part 1)
Federico Montesino Pouzols authoredApply changes from clang-tidy: modernize-use-default. (Part 1)
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
AddLogDerivative.cpp 5.27 KiB
#include "MantidAlgorithms/AddLogDerivative.h"
#include "MantidKernel/System.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidKernel/MandatoryValidator.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidAPI/Run.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
namespace Mantid {
namespace Algorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(AddLogDerivative)
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void AddLogDerivative::init() {
declareProperty(
make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::InOut),
"An input/output workspace. The new log will be added to it.");
declareProperty(
"LogName", "", boost::make_shared<MandatoryValidator<std::string>>(),
"The name that will identify the log entry to perform a derivative.\n"
"This log must be a numerical series (double).");
declareProperty("Derivative", 1,
boost::make_shared<BoundedValidator<int>>(1, 10),
"How many derivatives to perform. Default 1.");
declareProperty("NewLogName", "", "Name of the newly created log. If not "
"specified, the string '_derivativeN' will "
"be appended to the original name");
}
//----------------------------------------------------------------------------------------------
/** Perform the N^th derivative of a log
*
* @param progress :: Progress indicator
* @param input :: input TSP. Must have N+1 log entries
* @param name :: name of the resulting log
* @param numDerivatives :: number of times to perform derivative.
* @return
*/
Mantid::Kernel::TimeSeriesProperty<double> *AddLogDerivative::makeDerivative(
API::Progress &progress, Mantid::Kernel::TimeSeriesProperty<double> *input,
const std::string &name, int numDerivatives) {
if (input->size() < numDerivatives + 1)
throw std::runtime_error(
"Log " + input->name() + " only has " +
Strings::toString(input->size()) + " values. Need at least " +
Strings::toString(numDerivatives + 1) + " to make this derivative.");
std::vector<double> values, dVal;
std::vector<double> times, dTime;
values = input->valuesAsVector();
times = input->timesAsVectorSeconds();
for (int deriv = 0; deriv < numDerivatives; deriv++) {
dVal.clear();
dTime.clear();
double t0 = times[0];
double y0 = values[0];
for (size_t i = 0; i < times.size() - 1; i++) {
double y1 = values[i + 1];
double t1 = times[i + 1];
if (t1 != t0) {
// Avoid repeated time values giving infinite derivatives
double dy = (y1 - y0) / (t1 - t0);
double t = (t0 + t1) / 2.0;
dVal.push_back(dy);
dTime.push_back(t);
// For the next time interval
t0 = t1;
y0 = y1;
}
}
times = dTime;
values = dVal;
progress.report("Add Log Derivative");
}
if (times.empty())
throw std::runtime_error("Log " + input->name() +
" did not have enough non-repeated time values to "
"make this derivative.");
// Convert time in sec to DateAndTime
DateAndTime start = input->nthTime(0);
std::vector<DateAndTime> timeFull;
timeFull.reserve(times.size());
for (double time : times)
timeFull.push_back(start + time);
// Create the TSP out of it
auto out = new TimeSeriesProperty<double>(name);
out->addValues(timeFull, values);
return out;
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void AddLogDerivative::exec() {
MatrixWorkspace_sptr ws = getProperty("InputWorkspace");
std::string LogName = getPropertyValue("LogName");
std::string NewLogName = getPropertyValue("NewLogName");
int Derivative = getProperty("Derivative");
if (!ws)
return;
if (NewLogName.empty())
NewLogName = LogName + "_derivative" + Strings::toString(Derivative);
Run &run = ws->mutableRun();
if (!run.hasProperty(LogName))
throw std::invalid_argument("Log " + LogName +
" not found in the workspace sample logs.");
Property *prop = run.getProperty(LogName);
if (!prop)
throw std::invalid_argument("Log " + LogName +
" not found in the workspace sample logs.");
TimeSeriesProperty<double> *tsp =
dynamic_cast<TimeSeriesProperty<double> *>(prop);
if (!tsp)
throw std::invalid_argument("Log " + LogName + " is not a numerical series "
"(TimeSeriesProperty<double>"
") so we can't perform its "
"derivative.");
Progress progress(this, 0, 1, Derivative);
// Perform derivative
TimeSeriesProperty<double> *output =
makeDerivative(progress, tsp, NewLogName, Derivative);
// Add the log
run.addProperty(output, true);
g_log.notice() << "Added log named " << NewLogName << '\n';
}
} // namespace Mantid
} // namespace Algorithms