24#include <boost/algorithm/string.hpp>
25#include <boost/regex.hpp>
41std::vector<std::string>
parseNames(
const std::string &names_string) {
49 regex expression(R
"(\[([^\[]*)\]|[^,]+)");
51 boost::sregex_token_iterator iter(names_string.begin(), names_string.end(), expression, 0);
52 boost::sregex_token_iterator end;
54 std::vector<std::string> names_result(iter, end);
67 "Number of dimensions that the workspace will have.");
69 std::vector<std::string> propOptions{
"MDEvent",
"MDLeanEvent"};
70 declareProperty(
"EventType",
"MDLeanEvent", std::make_shared<StringListValidator>(propOptions),
71 "Which underlying data type will event take.");
74 "A comma separated list of min, max for each dimension,\n"
75 "specifying the extents of each dimension.");
78 "A comma separated list of the name of each dimension.");
81 "A comma separated list of the units of each dimension.");
83 " A comma separated list of the frames of each dimension. "
85 " **General Frame**: Any frame which is not a Q-based frame."
86 " **QLab**: Wave-vector converted into the lab frame."
87 " **QSample**: Wave-vector converted into the frame of the sample."
88 " **HKL**: Wave-vector converted into the crystal's HKL indices."
89 " Note if nothing is specified then the **General Frame** is being "
90 "selected. Also note that if you select a frame then this might override "
91 "your unit selection if it is not compatible with the frame.");
93 this->initBoxControllerProps(
"5", 1000, 5);
96 "Optional. If specified, then all the boxes will be split to "
97 "this minimum recursion depth. 0 = no splitting, 1 = one "
98 "level of splitting, etc.\n"
99 "Be careful using this since it can quickly create a huge "
100 "number of boxes = (SplitInto ^ (MinRercursionDepth * "
102 setPropertyGroup(
"MinRecursionDepth", getBoxSettingsGroupName());
105 "Name of the output MDEventWorkspace.");
107 "Optional: to use a file as the back end, give the path to the file to "
111 "If Filename is specified to use a file back end:\n"
112 " The amount of memory (in MB) to allocate to the in-memory cache.\n"
113 " If not specified, a default of 40% of free physical memory is used.");
114 setPropertySettings(
"Memory", std::make_unique<EnabledWhenProperty>(
"Filename",
IS_NOT_DEFAULT));
130 int minDepth = this->
getProperty(
"MinRecursionDepth");
132 throw std::invalid_argument(
"MinRecursionDepth must be >= 0.");
144 throw std::invalid_argument(
"You must specify a number of dimensions >= 1.");
148 throw std::invalid_argument(
"MinRecursionDepth must be <= MaxRecursionDepth.");
149 if (mind < 0 || maxd < 0)
150 throw std::invalid_argument(
"MinRecursionDepth and MaxRecursionDepth must be positive.");
152 auto ndims =
static_cast<size_t>(ndims_prop);
154 std::vector<double> extents =
getProperty(
"Extents");
156 std::vector<std::string> names =
parseNames(dimensions_string);
158 std::vector<std::string> units =
getProperty(
"Units");
159 std::vector<std::string> frames =
getProperty(
"Frames");
161 if (extents.size() != ndims * 2)
162 throw std::invalid_argument(
"You must specify twice as many extents "
163 "(min,max) as there are dimensions.");
164 if (names.size() != ndims)
165 throw std::invalid_argument(
"You must specify as many names as there are dimensions.");
166 if (units.size() != ndims)
167 throw std::invalid_argument(
"You must specify as many units as there are dimensions.");
172 if (!frames.empty() && frames.size() != ndims) {
173 throw std::invalid_argument(
"You must specify as many frames as there are dimensions.");
176 if (frames.empty()) {
177 frames.resize(ndims);
185 for (
size_t d = 0;
d < ndims;
d++) {
188 static_cast<coord_t>(extents[
d * 2 + 1]), 1);
200 if (!filename.empty()) {
204 alg->setPropertyValue(
"Filename", filename);
205 alg->setProperty(
"InputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(out));
206 alg->executeAsChildAlg();
210 alg->setPropertyValue(
"Filename", filename);
211 alg->setProperty(
"FileBackEnd",
true);
213 alg->executeAsChildAlg();
216 temp = alg->getProperty(
"OutputWorkspace");
217 out = std::dynamic_pointer_cast<IMDEventWorkspace>(temp);
221 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<Workspace>(out));
227 return frameFactory->create(frameArg);
232 std::map<std::string, std::string> errors;
233 std::string framePropertyName =
"Frames";
234 std::vector<std::string> frames =
getProperty(framePropertyName);
236 auto ndims =
static_cast<size_t>(ndims_prop);
242 auto isValidFrame =
true;
243 for (
auto &frame : frames) {
246 isValidFrame = result;
250 if (!frames.empty() && frames.size() != ndims) {
251 isValidFrame =
false;
255 std::string message =
"The selected frames can be 'HKL', 'QSample', 'QLab' "
256 "or 'General Frame'. You must specify as many frames "
257 "as there are dimensions.";
258 errors.emplace(framePropertyName, message);
270 return std::any_of(targetFrames.cbegin(), targetFrames.cend(),
271 [&frame](
const auto &targetFrame) { return targetFrame == frame; });
#define DECLARE_ALGORITHM(classname)
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
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.
void setBoxController(const Mantid::API::BoxController_sptr &bc, const Mantid::Geometry::Instrument_const_sptr &instrument)
Set the settings in the given box controller.
@ OptionalSave
to specify a file to write to but an empty string is
A property class for workspaces.
static API::IMDEventWorkspace_sptr CreateMDWorkspace(size_t nd, const std::string &eventType="MDLeanEvent", const Mantid::API::MDNormalization &preferredNormalization=Mantid::API::MDNormalization::VolumeNormalization, const Mantid::API::MDNormalization &preferredNormalizationHisto=Mantid::API::MDNormalization::VolumeNormalization)
Create a MDEventWorkspace of the given type.
void splitBox() override
Split the top-level MDBox into a MDGridBox.
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
void setMinRecursionDepth(size_t minDepth) override
Recurse down to a minimum depth.
Mantid::API::BoxController_sptr getBoxController() override
Returns the BoxController used in this workspace.
static const std::string GeneralFrameName
static const std::string HKLName
Input argument type for MDFrameFactory chainable factory.
static const std::string QLabName
static const std::string QSampleName
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
The concrete, templated class for properties.
Mantid::Geometry::MDFrame_uptr createMDFrame(const std::string &frame, const std::string &unit)
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
void finish(typename DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
Finish initialisation.
void exec() override
Execute the algorithm.
bool checkIfFrameValid(const std::string &frame, const std::vector< std::string > &targetFrames)
Check if the specified frame matches a target frame.
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
std::unique_ptr< MDFrame > MDFrame_uptr
MDFrameFactory_uptr MANTID_GEOMETRY_DLL makeMDFrameFactoryChain()
Make a complete factory chain.
std::shared_ptr< MDHistoDimension > MDHistoDimension_sptr
Shared pointer to a MDHistoDimension.
std::vector< std::string > MANTID_MDALGORITHMS_DLL parseNames(const std::string &names_string)
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
@ Input
An input workspace.
@ Output
An output workspace.