Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 25 additions & 26 deletions Framework/Algorithms/src/AddSampleLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "MantidAPI/Run.h"
#include "MantidAPI/Workspace.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/EnumeratedString.h"
#include "MantidKernel/EnumeratedStringProperty.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/MandatoryValidator.h"
Expand All @@ -22,13 +24,15 @@

namespace {

static const std::string intTypeOption = "Int";
static const std::string doubleTypeOption = "Double";
static const std::string autoTypeOption = "AutoDetect";
const std::string NumberType("NumberType");
const std::vector<std::string> typeOptions{"Int", "Double", "AutoDetect"};
enum class TypeMode { INT, DOUBLE, AUTO_DETECT, enum_count };
typedef Mantid::Kernel::EnumeratedString<TypeMode, &typeOptions> TYPEMODE;

static const std::string stringLogOption = "String";
static const std::string numberLogOption = "Number";
static const std::string numberSeriesLogOption = "Number Series";
const std::string LogType("LogType");
const std::vector<std::string> propOptions{"String", "Number", "Number Series"};
enum class LogMode { STRING_LOG, NUMBER_LOG, NUMBER_SERIES_LOG, enum_count };
typedef Mantid::Kernel::EnumeratedString<LogMode, &propOptions> LOGMODE;
} // namespace

namespace Mantid::Algorithms {
Expand All @@ -48,21 +52,14 @@ void AddSampleLog::init() {

declareProperty("LogText", "", "The content of the log");

std::vector<std::string> propOptions;
propOptions.emplace_back(stringLogOption);
propOptions.emplace_back(numberLogOption);
propOptions.emplace_back(numberSeriesLogOption);
declareProperty("LogType", stringLogOption, std::make_shared<StringListValidator>(propOptions),
declareProperty(std::make_unique<EnumeratedStringProperty<LogMode, &propOptions>>(LogType),
"The type that the log data will be.");
declareProperty("LogUnit", "", "The units of the log");

std::vector<std::string> typeOptions;
typeOptions.emplace_back(intTypeOption);
typeOptions.emplace_back(doubleTypeOption);
typeOptions.emplace_back(autoTypeOption);
declareProperty("NumberType", autoTypeOption, std::make_shared<StringListValidator>(typeOptions),
declareProperty(std::make_unique<EnumeratedStringProperty<TypeMode, &typeOptions>>(NumberType),
"Force LogText to be interpreted as a number of type 'int' "
"or 'double'.");
setPropertyValue(NumberType, typeOptions[2]);

// add optional workspace which contains the data of the TimeSeriesProperty
declareProperty(std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("TimeSeriesWorkspace", "", Direction::Input,
Expand Down Expand Up @@ -112,11 +109,11 @@ void AddSampleLog::exec() {
std::string propName = getProperty("LogName");
std::string propValue = getProperty("LogText");
std::string propUnit = getProperty("LogUnit");
std::string propType = getPropertyValue("LogType");
std::string propNumberType = getPropertyValue("NumberType");
LOGMODE propType = getPropertyValue(LogType);
TYPEMODE propNumberType = getPropertyValue("NumberType");

// check inputs
if ((propNumberType != autoTypeOption) && ((propType != numberLogOption) && (propType != numberSeriesLogOption))) {
if ((propNumberType != TypeMode::AUTO_DETECT) && (propType == LogMode::STRING_LOG)) {
throw std::invalid_argument("You may only use NumberType 'Int' or 'Double' options if "
"LogType is 'Number' or 'Number Series'");
}
Expand All @@ -127,10 +124,10 @@ void AddSampleLog::exec() {
}

// add sample log!
if (propType == stringLogOption) {
if (propType == LogMode::STRING_LOG) {
// add string log value and return
addStringLog(theRun, propName, propValue, propUnit);
} else if (propType == numberSeriesLogOption) {
} else if (propType == LogMode::NUMBER_SERIES_LOG) {
// add a TimeSeriesProperty
// TODO: Need to re-define the behavior on the default propNumberType for
// Series.
Expand Down Expand Up @@ -161,8 +158,9 @@ void AddSampleLog::addSingleValueProperty(Run &theRun, const std::string &propNa
const std::string &propUnit, const std::string &propNumberType) {
// add a single value property, integer or double
bool value_is_int(false);
if (propNumberType != autoTypeOption) {
value_is_int = (propNumberType == intTypeOption);
TYPEMODE propType = propNumberType;
if (propType != TypeMode::AUTO_DETECT) {
value_is_int = (propType == TypeMode::INT);
} else {
int intVal;
if (Strings::convert(propValue, intVal)) {
Expand Down Expand Up @@ -225,10 +223,11 @@ void AddSampleLog::addTimeSeriesProperty(Run &run_obj, const std::string &prop_n
const std::string &prop_unit, const std::string &prop_number_type) {
// set up the number type right
bool is_int_series(false);
if (prop_number_type == intTypeOption) {
TYPEMODE propType = prop_number_type;
if (propType == TypeMode::INT) {
// integer type
is_int_series = true;
} else if (prop_number_type == autoTypeOption) {
} else if (propType == TypeMode::AUTO_DETECT) {
// auto type. by default
if (prop_value.empty())
g_log.warning("For sample log in TimeSeriesProperty and values are given "
Expand All @@ -241,7 +240,7 @@ void AddSampleLog::addTimeSeriesProperty(Run &run_obj, const std::string &prop_n
is_int_series = true;
}
}
} else if (prop_number_type != doubleTypeOption) {
} else if (propType != TypeMode::DOUBLE) {
// unsupported type: anything but double, integer or auto
g_log.error() << "TimeSeriesProperty with data type " << prop_number_type << " is not supported.\n";
throw std::runtime_error("Unsupported TimeSeriesProperty type.");
Expand Down
23 changes: 11 additions & 12 deletions Framework/Algorithms/src/CalculateDIFC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@
#include "MantidDataObjects/SpecialWorkspace2D.h"
#include "MantidGeometry/IDetector.h"
#include "MantidKernel/EnumeratedString.h"
#include "MantidKernel/EnumeratedStringProperty.h"
#include "MantidKernel/ListValidator.h"

namespace Mantid {

namespace PropertyNames {
const std::string INPUT_WKSP("InputWorkspace");
const std::string OUTPUT_WKSP("OutputWorkspace");
const std::string CALIB_WKSP("CalibrationWorkspace");
const std::string OFFSTS_WKSP("OffsetsWorkspace");
const std::string OFFSET_MODE("OffsetMode");
const std::string BINWIDTH("BinWidth");
} // namespace PropertyNames
namespace {

enum class OffsetMode { RELATIVE_OFFSET, ABSOLUTE_OFFSET, SIGNED_OFFSET, enum_count };
Expand Down Expand Up @@ -58,15 +66,6 @@ void calculateFromOffset(API::Progress &progress, DataObjects::SpecialWorkspace2
}
}

namespace PropertyNames {
const std::string INPUT_WKSP("InputWorkspace");
const std::string OUTPUT_WKSP("OutputWorkspace");
const std::string CALIB_WKSP("CalibrationWorkspace");
const std::string OFFSTS_WKSP("OffsetsWorkspace");
const std::string OFFSET_MODE("OffsetMode");
const std::string BINWIDTH("BinWidth");
} // namespace PropertyNames

// look through the columns of detid and difc and copy them into the
// SpecialWorkspace2D
void calculateFromTable(API::Progress &progress, DataObjects::SpecialWorkspace2D &outputWs,
Expand Down Expand Up @@ -125,8 +124,8 @@ void CalculateDIFC::init() {
"which will be copied. This property cannot be set in "
"conjunction with property OffsetsWorkspace.");

declareProperty(PropertyNames::OFFSET_MODE, offsetModeNames[size_t(OffsetMode::RELATIVE_OFFSET)],
std::make_shared<Mantid::Kernel::StringListValidator>(offsetModeNames),
declareProperty(std::make_unique<Mantid::Kernel::EnumeratedStringProperty<OffsetMode, &offsetModeNames>>(
PropertyNames::OFFSET_MODE),
"Optional: Whether to calculate a relative, absolute, or signed offset. Default relative");

declareProperty(PropertyNames::BINWIDTH, EMPTY_DBL(),
Expand Down
4 changes: 2 additions & 2 deletions Framework/Algorithms/src/Rebin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/EnumeratedString.h"
#include "MantidKernel/EnumeratedStringProperty.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/RebinParamsValidator.h"
#include "MantidKernel/VectorHelper.h"
Expand Down Expand Up @@ -263,8 +264,7 @@ void Rebin::init() {
"is linear. Power must be between 0 and 1.");

declareProperty(
PropertyNames::BINMODE, binningModeNames[size_t(BinningMode::DEFAULT)],
std::make_shared<Mantid::Kernel::StringListValidator>(binningModeNames),
std::make_unique<EnumeratedStringProperty<BinningMode, &binningModeNames>>(PropertyNames::BINMODE),
"Optional. "
"Binning behavior can be specified in the usual way through sign of binwidth and other properties ('Default'); "
"or can be set to one of the allowed binning modes. "
Expand Down
1 change: 1 addition & 0 deletions Framework/Kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ set(TEST_FILES
DynamicPointerCastHelperTest.h
EigenConversionHelpersTest.h
EnabledWhenPropertyTest.h
EnumeratedStringPropertyTest.h
EnumeratedStringTest.h
EnvironmentHistoryTest.h
EqualBinsCheckerTest.h
Expand Down
3 changes: 2 additions & 1 deletion Framework/Kernel/inc/MantidKernel/EnumeratedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class EnumeratedString {
// treat the object as either the enum, or a string
operator E() const { return value; }
operator std::string() const { return name; }

// explicitly define copy assignment operator to avoid deprecation warnings
EnumeratedString &operator=(const EnumeratedString &other) = default;
// assign the object either by the enum, or by string
EnumeratedString &operator=(E e) {
if (int(e) >= 0 && size_t(e) < names->size()) {
Expand Down
106 changes: 106 additions & 0 deletions Framework/Kernel/inc/MantidKernel/EnumeratedStringProperty.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2007 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include "MantidKernel/EnumeratedString.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/NullValidator.h"
#include "MantidKernel/Property.h"
#include <vector>

namespace NeXus {
class File;
}

namespace Mantid {

namespace Kernel {
/** A concrete property based on user options of a finite list of strings.
* Allows for easy comparison by binding the string list to an enum.
@class Mantid::Kernel::EnumeratedStringProperty
@author Reece Boston, ORNL
@date October 1, in this the two-thousand-and-twenty-fourth year of our Lord
*/
template <class E, std::vector<std::string> const *const names> class EnumeratedStringProperty : public Property {

using ENUMSTRING = EnumeratedString<E, names>;

public:
// CONSTRUCTORS
EnumeratedStringProperty(std::string const &name, ENUMSTRING const &defaultValue = static_cast<E>(0),
Direction::Type const direction = Direction::Input);
EnumeratedStringProperty(EnumeratedStringProperty const &right);
EnumeratedStringProperty *clone() const override;
EnumeratedStringProperty &operator=(EnumeratedStringProperty const &right);

// GETTERS
std::string value() const override;
std::string valueAsPrettyStr(size_t const maxLength = 0, bool const collapseLists = true) const override;
Json::Value valueAsJson() const override;

bool operator==(EnumeratedStringProperty const &rhs) const;
bool operator!=(EnumeratedStringProperty const &rhs) const;
int size() const override;
std::string getDefault() const override;

/** Allows you to get the value of the property simply by typing its name.
* Means you can use an expression like: int i = myProperty;
* @return the value
*/
operator ENUMSTRING() const { return this->m_value; };
operator E() const { return static_cast<E>(m_value); };
operator std::string() const { return static_cast<std::string>(m_value); };

ENUMSTRING operator()() const;
std::string isValid() const override;
bool isDefault() const override;
std::vector<std::string> allowedValues() const override;
bool isMultipleSelectionAllowed() override;

// SETTERS
std::string setValue(E const value);
std::string setValue(std::string const &value) override;
std::string setValue(ENUMSTRING const &value);
std::string setValueFromJson(const Json::Value &value) override;
std::string setDataItem(const std::shared_ptr<DataItem> &data) override;
EnumeratedStringProperty const &operator=(E const value);
EnumeratedStringProperty const &operator=(std::string const &value);
EnumeratedStringProperty const &operator=(ENUMSTRING const &value);

// MUTATORS AND SUNDRY
EnumeratedStringProperty &operator+=(Property const *right) override;
void saveProperty(::NeXus::File *file) override;

protected:
/// The value of the property
ENUMSTRING m_value;
/// the property's default value which is also its initial value
// const TYPE m_initialValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this line

Copy link
Collaborator Author

@dmitry-ganyushin dmitry-ganyushin Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remove it, I have the following compilation error:

/home/yvg/mantid/Framework/Kernel/inc/MantidKernel/EnumeratedStringProperty.hxx:279:9: error: 'class Mantid::Kernel::EnumeratedStringProperty<{anonymous}::TypeMode, (& {anonymous}::typeOptions)>' has no member named 'm_value'; did you mean 'value'?
  279 |   this->m_value = static_cast<EnumeratedString<E, names>>(value);
      |   ~~~~~~^~~~~~~
      |   value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think he means the commented out line of code

ENUMSTRING m_initialValue;

private:
std::string setValueFromProperty(Property const &right) override;

template <typename U> std::string setTypedValue(U const &value, std::true_type const &);

template <typename U> std::string setTypedValue(U const &value, std::false_type const &);

/// Static reference to the logger class
static Logger g_logger;

/// Private default constructor
EnumeratedStringProperty() = default;
};

// template <typename TYPE> Logger PropertyWithValue<TYPE>::g_logger("PropertyWithValue");

} // namespace Kernel
} // namespace Mantid

#include "EnumeratedStringProperty.hxx"
Loading
Loading