24#include "MantidTypes/Core/DateAndTime.h"
33using namespace Kernel;
42static const std::string
PXD{
"PXD"};
43static const std::string
PXD_ERROR{
"PXDError"};
51static const std::string COLUMN_STAMPS =
"midtime_stamp";
52static const std::string COLUMN_HOURS =
"hours";
53static const std::string COLUMN_HOURS_ERROR =
"hours_error";
57MatrixWorkspace_sptr createWorkspaceFromVectors(
const HistogramData::HistogramX &
x,
const std::vector<double> &
y,
58 const std::vector<double> &e) {
61 ws->mutableY(0) = HistogramData::HistogramY(
y);
62 ws->mutableE(0) = HistogramData::HistogramE(e);
63 ws->setDistribution(
true);
64 ws->getAxis(0)->unit() = Mantid::Kernel::UnitFactory::Instance().create(
"Wavelength");
69 if (ws->axes() == 0) {
72 const auto unit = ws->getAxis(0)->unit();
73 return (unit && unit->unitID() == unitToCompareWith);
77 const Run &run = ws->run();
78 const bool hasStart = run.hasProperty(
"start_time") || run.hasProperty(
"run_start");
79 const bool hasEnd = run.hasProperty(
"end_time") || run.hasProperty(
"run_end");
80 return hasStart && hasEnd;
84 const auto &ws_input = std::dynamic_pointer_cast<MatrixWorkspace>(ws);
85 return (ws_input && hasUnit(
"Wavelength", ws_input) && hasTimeLogs(ws_input));
88std::string validateWorkspaceWithProperties(
const Workspace_sptr &ws) {
90 return "Workspace has to be a valid workspace";
94 const auto &groupItems = std::dynamic_pointer_cast<WorkspaceGroup>(ws)->getAllItems();
95 if (std::any_of(groupItems.cbegin(), groupItems.cend(),
96 [](
const auto &childWs) { return !checkValidMatrixWorkspace(childWs); })) {
97 return "Workspace must have time logs and Wavelength units";
102 if (!checkValidMatrixWorkspace(ws)) {
103 return "Workspace must have time logs and Wavelength units";
110 auto wkpsValidator = std::make_shared<LambdaValidator<Workspace_sptr>>(validateWorkspaceWithProperties);
113 "Scattering Workspace from which to extract the experiment timestamp");
116 "Reference workspace for which to extract the reference timestamp and wavelength range");
118 "An ISO formatted date/time string specifying reference timestamp with respect to the scattering "
119 "workspace start time, e.g 2010-09-14T04:20:12",
122 const auto mustBePositive = std::make_shared<BoundedValidator<double>>();
123 mustBePositive->setLower(0);
129 "Lifetime of polarization decay of He gas in cell (in hours)");
132 "Helium analyzer efficiency as a function of wavelength");
135 "Unpolarized beam transmission as a function of wavelength");
144 std::map<std::string, std::string> errorList;
147 "Both ReferenceWorkspace and ReferenceTimeStamp properties are empty, at least one of the two has to be "
148 "supplied to execute the Algorithm";
157 if (outWs.size() > 1) {
166 if (inputWs->isGroup()) {
169 const auto ws = std::dynamic_pointer_cast<WorkspaceGroup>(inputWs);
170 return std::dynamic_pointer_cast<MatrixWorkspace>(ws->getItem(0));
172 return std::dynamic_pointer_cast<MatrixWorkspace>(inputWs);
187 const auto &pointData = inputWs->histogram(0).points();
188 const auto &lambdas = pointData.rawData();
189 const auto &binBoundaries = inputWs->x(0);
191 auto efficiency = std::vector<double>(lambdas.size());
192 auto efficiencyErrors = std::vector<double>(lambdas.size());
194 std::vector<double> unpolTransmission, unpolTransmissionErrors;
195 if (doUnpolTransmission) {
196 unpolTransmission = std::vector<double>(lambdas.size());
197 unpolTransmissionErrors = std::vector<double>(lambdas.size());
201 const auto lambdaError = binBoundaries[
index + 1] - binBoundaries[
index];
205 const auto expTerm = std::exp(-time / lifetime);
206 const auto polHe = polIni * expTerm;
208 efficiency.at(
index) = (1 + std::tanh(
mu * polHe)) / 2;
211 const auto muError = pxd * lambdaError +
lambda * pxdError;
212 const auto polError = std::sqrt(std::pow(2, expTerm * polIniError) + std::pow(2, polHe * timeError / lifetime) +
213 std::pow(2, polHe * time * lifetimeError / (std::pow(2, lifetime))));
215 const auto commonTerm = 0.5 / std::pow(std::cosh(
mu * polHe), 2);
216 efficiencyErrors.at(
index) =
217 std::sqrt(std::pow(2, commonTerm) * (std::pow(2,
mu * polError) + std::pow(2, polHe * muError)));
219 if (doUnpolTransmission) {
220 const auto expFactor = std::exp(-
mu);
221 const auto coshFactor = std::cosh(
mu * polHe);
222 const auto sinhFactor = std::sinh(
mu * polHe);
223 unpolTransmission.at(
index) = expFactor * coshFactor;
224 unpolTransmissionErrors.at(
index) =
225 std::sqrt(std::pow(2, (expFactor * (polHe * sinhFactor - coshFactor) * muError)) +
226 std::pow(2, expFactor * sinhFactor * polError));
230 const auto outputVec = std::vector({std::move(efficiency), std::move(efficiencyErrors), std::move(unpolTransmission),
231 std::move(unpolTransmissionErrors)});
232 std::vector<MatrixWorkspace_sptr> wsOut;
234 if (outputVec.at(
index).size() > 0) {
235 wsOut.push_back(createWorkspaceFromVectors(binBoundaries, outputVec.at(
index), outputVec.at(
index + 1)));
244 timeDiff->initialize();
247 std::string refTimeStamp;
258 const auto indexRow = table->rowCount() - 1;
259 const auto coltHoursErr = table->getColumn(COLUMN_HOURS_ERROR);
260 const auto tHoursErr =
static_cast<double>(coltHoursErr->cell<
float>(indexRow));
263 if (refTimeStamp.empty()) {
264 const auto coltHours = table->getColumn(COLUMN_HOURS);
265 tHours =
static_cast<double>(coltHours->cell<
float>(indexRow));
268 const auto colTimeStamps = table->getColumn(COLUMN_STAMPS);
269 const auto &expTimeStamp = colTimeStamps->cell<std::string>(indexRow);
270 const auto duration = Types::Core::DateAndTime(expTimeStamp) - Types::Core::DateAndTime(refTimeStamp);
271 tHours =
static_cast<double>(duration.total_seconds() / 3600);
273 return std::make_pair(std::abs(tHours), tHoursErr);
#define DECLARE_ALGORITHM(classname)
const std::vector< double > * lambda
std::map< DeltaEMode::Type, std::string > index
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.
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.
bool isDefault(const std::string &name) const
A property class for workspaces.
std::map< std::string, std::string > validateInputs() override
Check that input params are valid.
void exec() override
Virtual method - must be overridden by concrete algorithm.
void init() override
Virtual method - must be overridden by concrete algorithm.
std::vector< MatrixWorkspace_sptr > calculateOutputs()
MatrixWorkspace_sptr retrieveWorkspaceForWavelength() const
std::pair< double, double > getTimeDifference()
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
static const std::string INITIAL_POL_ERROR
static const std::string OUTPUT_WORKSPACE
static const std::string UNPOLARIZED_TRANSMISSION
static const std::string INPUT_WORKSPACE
static const std::string LIFETIME
static const std::string LIFETIME_ERROR
static const std::string REFERENCE_TIMESTAMP
static const std::string REFERENCE_WORKSPACE
static const std::string INITIAL_POL
constexpr double LAMBDA_CONVERSION_FACTOR
@ Input
An input workspace.
@ Output
An output workspace.