41 if (param_vector.empty()) {
42 param_vector.resize(grow_to_size, 0.0);
43 }
else if (param_vector.size() == 1) {
44 param_vector.resize(grow_to_size, param_vector[0]);
45 }
else if (param_vector.size() != grow_to_size) {
46 throw std::invalid_argument(
"Psi, Gl, Gs and EFix must have one value per run.");
56bool any_given(
const std::vector<std::vector<double>> ¶ms) {
57 std::vector<double> param;
58 for (
const auto &iter : params) {
73bool all_given(
const std::vector<std::vector<double>> ¶ms) {
74 std::vector<double> param;
75 for (
const auto &iter : params) {
90const
std::
string CreateMD::name()
const {
return "CreateMD"; }
99const std::string
CreateMD::summary()
const {
return "Creates an MDWorkspace in the Q3D, HKL frame"; }
107 "MDEventWorkspace with new data appended.");
112 "Input workspaces to process, or filenames to load and process");
116 std::vector<std::string> e_mode_options{
"Elastic",
"Direct",
"Indirect"};
118 declareProperty(
"Emode",
"Direct", std::make_shared<StringListValidator>(e_mode_options),
119 "Analysis mode ['Elastic', 'Direct', 'Indirect'].");
123 "Lattice parameters");
131 "Lattice vector parallel to neutron beam");
135 "Lattice vector perpendicular to neutron beam in the horizontal plane");
138 "Psi rotation in degrees. Optional or one entry per run.");
141 "gl rotation in degrees. Optional or one entry per run.");
144 "gs rotation in degrees. Optional or one entry per run.");
147 "Execute conversions to MD and Merge in one-step. Less "
151 "The name of the Nexus file to write, as a full or relative path.\n"
152 "Only used if FileBackEnd is true.");
153 setPropertySettings(
"Filename", std::make_unique<EnabledWhenProperty>(
"FileBackEnd",
IS_EQUAL_TO,
"1"));
155 declareProperty(
"FileBackEnd",
false,
156 "If true, Filename must also be specified. The algorithm "
157 "will create the specified file in addition to an output "
158 "workspace. The workspace will load data from the file on "
159 "demand in order to reduce memory use.");
167 const std::string emode = this->
getProperty(
"Emode");
168 const std::vector<double> alatt = this->
getProperty(
"Alatt");
169 const std::vector<double> angdeg = this->
getProperty(
"Angdeg");
170 const std::vector<double> u = this->
getProperty(
"u");
171 const std::vector<double> v = this->
getProperty(
"v");
172 std::vector<double> psi = this->
getProperty(
"Psi");
175 std::vector<double> efix = this->
getProperty(
"Efix");
177 const std::vector<std::string> data_sources = this->
getProperty(
"DataSources");
178 const std::string out_filename = this->
getProperty(
"Filename");
179 const bool fileBackEnd = this->
getProperty(
"FileBackEnd");
181 const size_t entries = data_sources.size();
187 efix.emplace_back(-1.0);
192 std::vector<std::string> to_merge_names;
193 std::string to_merge_name;
195 std::stringstream ws_name;
197 Progress progress(
this, 0.0, 1.0, entries + 1);
198 for (
unsigned long entry_number = 0; entry_number < entries; ++entry_number, ++counter) {
199 ws_name.str(std::string());
206 std::string filename_noext = Poco::Path(data_sources[entry_number]).getBaseName();
209 ws_name << filename_noext <<
"_md_" << counter;
210 to_merge_name = ws_name.str();
212 std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
loadWs(data_sources[entry_number], to_merge_name));
214 workspace = std::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
216 ws_name << data_sources[entry_number] <<
"_md";
217 to_merge_name = ws_name.str();
221 bool do_in_place = in_place && (counter > 0);
222 run_md =
single_run(
workspace, emode, efix[entry_number], psi[entry_number], gl[entry_number], gs[entry_number],
223 do_in_place, alatt, angdeg, u, v, out_filename, fileBackEnd, run_md);
225 to_merge_names.emplace_back(to_merge_name);
237 if (to_merge_names.size() > 1 && !in_place) {
238 progress.
doReport(
"Merging loaded data into single workspace");
239 output_workspace =
merge_runs(to_merge_names);
247 for (
const auto &
name : to_merge_names) {
251 this->setProperty(
"OutputWorkspace", output_workspace);
264 load_alg->setProperty(
"Filename", filename);
265 load_alg->setPropertyValue(
"OutputWorkspace", wsname);
266 load_alg->executeAsChildAlg();
268 return load_alg->getProperty(
"OutputWorkspace");
282 log_alg->setProperty(
"Workspace",
workspace);
283 log_alg->setProperty(
"LogName", log_name);
284 log_alg->setProperty(
"LogText", boost::lexical_cast<std::string>(log_number));
285 log_alg->setProperty(
"LogType",
"Number");
287 log_alg->setProperty(
"NumberType",
"Double");
289 log_alg->executeAsChildAlg();
299 if (!
workspace->run().getProperty(
"gl")) {
300 std::ostringstream temp_ss;
301 temp_ss <<
"Value of gl in log is: " <<
workspace->run().getPropertyAsSingleValue(
"gl");
302 throw std::invalid_argument(temp_ss.str());
304 log_alg->setProperty(
"Workspace",
workspace);
305 log_alg->setProperty(
"Axis0",
"gl,0,0,1,1");
306 log_alg->setProperty(
"Axis1",
"gs,1,0,0,1");
307 log_alg->setProperty(
"Axis2",
"psi,0,1,0,1");
309 log_alg->executeAsChildAlg();
326 double beta,
double gamma,
const std::vector<double> &u,
const std::vector<double> &v) {
329 set_ub_alg->setProperty(
"Workspace",
workspace);
330 set_ub_alg->setProperty(
"a", a);
331 set_ub_alg->setProperty(
"b", b);
332 set_ub_alg->setProperty(
"c", c);
333 set_ub_alg->setProperty(
"alpha", alpha);
334 set_ub_alg->setProperty(
"beta", beta);
335 set_ub_alg->setProperty(
"gamma", gamma);
336 set_ub_alg->setProperty(
"u", u);
337 set_ub_alg->setProperty(
"v", v);
338 set_ub_alg->executeAsChildAlg();
351 const std::string &analysis_mode,
bool in_place,
352 const std::string &filebackend_filename,
353 const bool filebackend,
356 min_max_alg->setProperty(
"InputWorkspace",
workspace);
357 min_max_alg->setProperty(
"QDimensions",
"Q3D");
358 min_max_alg->setProperty(
"dEAnalysisMode", analysis_mode);
359 min_max_alg->executeAsChildAlg();
360 std::string min_values = min_max_alg->getPropertyValue(
"MinValues");
361 std::string max_values = min_max_alg->getPropertyValue(
"MaxValues");
364 convert_alg->setProperty(
"InputWorkspace",
workspace);
365 convert_alg->setProperty(
"QDimensions",
"Q3D");
366 convert_alg->setProperty(
"QConversionScales",
"HKL");
367 convert_alg->setProperty(
"dEAnalysisMode", analysis_mode);
368 convert_alg->setPropertyValue(
"MinValues", min_values);
369 convert_alg->setPropertyValue(
"MaxValues", max_values);
372 convert_alg->setProperty(
"SplitInto",
SPLITINTO);
375 convert_alg->setProperty(
"Filename", filebackend_filename);
376 convert_alg->setProperty(
"FileBackEnd", filebackend);
379 convert_alg->setProperty(
"OverwriteExisting", !in_place);
381 convert_alg->setProperty(
"OutputWorkspace", out_mdws);
383 convert_alg->setProperty(
"OutputWorkspace",
"dummy");
385 convert_alg->executeAsChildAlg();
387 return convert_alg->getProperty(
"OutputWorkspace");
399 merge_alg->setProperty(
"InputWorkspaces", to_merge);
400 merge_alg->setPropertyValue(
"OutputWorkspace",
"dummy");
403 merge_alg->setProperty(
"SplitInto",
SPLITINTO);
406 merge_alg->executeAsChildAlg();
408 return merge_alg->getProperty(
"OutputWorkspace");
430 double psi,
double gl,
double gs,
bool in_place,
const std::vector<double> &alatt,
431 const std::vector<double> &angdeg,
const std::vector<double> &u,
const std::vector<double> &v,
432 const std::string &filebackend_filename,
const bool filebackend,
435 std::vector<std::vector<double>> ub_params{alatt, angdeg, u, v};
438 throw std::invalid_argument(
"Either specify all of alatt, angledeg, u, v or none of them");
440 if (input_workspace->sample().hasOrientedLattice()) {
441 g_log.
warning() <<
"Sample already has a UB. This will not be "
442 "overwritten. Use ClearUB and re-run.\n";
444 setUB(input_workspace, alatt[0], alatt[1], alatt[2], angdeg[0], angdeg[1], angdeg[2], u, v);
456 return convertToMD(input_workspace, emode, in_place, filebackend_filename, filebackend, out_mdws);
468 std::map<std::string, std::string> validation_output;
471 const std::vector<std::string> data_sources = this->
getProperty(
"DataSources");
472 const std::vector<double> u = this->
getProperty(
"u");
473 const std::vector<double> v = this->
getProperty(
"v");
474 const std::vector<double> alatt = this->
getProperty(
"Alatt");
475 const std::vector<double> angdeg = this->
getProperty(
"Angdeg");
476 const std::vector<double> psi = this->
getProperty(
"Psi");
477 const std::vector<double> gl = this->
getProperty(
"Gl");
478 const std::vector<double> gs = this->
getProperty(
"Gs");
479 const std::vector<double> efix = this->
getProperty(
"Efix");
480 const std::string filename = this->
getProperty(
"Filename");
481 const bool fileBackEnd = this->
getProperty(
"FileBackEnd");
483 if (fileBackEnd && filename.empty()) {
484 validation_output[
"Filename"] =
"Filename must be given if FileBackEnd is required.";
487 const size_t ws_entries = data_sources.size();
488 for (
const auto &source : data_sources) {
490 validation_output[
"DataSources"] =
"All given data sources must exist. "
491 "For files, ensure the path is added to "
492 "Mantid's 'Data Search Directories'";
497 validation_output[
"u"] =
"u must have 3 components";
500 validation_output[
"v"] =
"v must have 3 components";
502 if (alatt.size() != 3) {
503 validation_output[
"Alatt"] =
"Lattice parameters must have 3 components";
505 if (angdeg.size() != 3) {
506 validation_output[
"Angdeg"] =
"Angle must have 3 components";
508 if (!psi.empty() && psi.size() != ws_entries) {
509 validation_output[
"Psi"] =
"If Psi is given an entry "
510 "should be provided for "
511 "every input datasource";
513 if (!gl.empty() && gl.size() != ws_entries) {
514 validation_output[
"Gl"] =
"If Gl is given an entry "
515 "should be provided for "
516 "every input datasource";
518 if (!gs.empty() && gs.size() != ws_entries) {
519 validation_output[
"Gs"] =
"If Gs is given an entry "
520 "should be provided for "
521 "every input datasource";
523 if (efix.size() > 1 && efix.size() != ws_entries) {
524 validation_output[
"EFix"] =
"Either specify a single EFix value, or as many "
525 "as there are input datasources";
528 return validation_output;
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
@ OptionalSave
to specify a file to write to but an empty string is
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) override
Create a Child Algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
Helper class for reporting progress from algorithms.
void doReport(const std::string &msg="") override
Actually do the reporting, without changing the loop counter.
A property class for workspaces.
Support for a property that holds an array of values.
void warning(const std::string &msg)
Logs at warning level.
Validator to check that a property is not left empty.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
CreateMD : This workflow algorithm creates MDWorkspaces in the Q3D, HKL frame using ConvertToMD.
void setGoniometer(const Mantid::API::MatrixWorkspace_sptr &workspace)
Set the goniometer values in a workspace.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
const std::string name() const override
Algorithms name for identification.
Mantid::API::IMDEventWorkspace_sptr merge_runs(const std::vector< std::string > &to_merge)
Merge input workspaces.
std::map< std::string, std::string > validateInputs() override
Validate the algorithm's input properties.
void setUB(const Mantid::API::MatrixWorkspace_sptr &workspace, double a, double b, double c, double alpha, double beta, double gamma, const std::vector< double > &u, const std::vector< double > &v)
Set the UB matrix in a workspace.
Mantid::API::IMDEventWorkspace_sptr single_run(const Mantid::API::MatrixWorkspace_sptr &input_workspace, const std::string &emode, double efix, double psi, double gl, double gs, bool in_place, const std::vector< double > &alatt, const std::vector< double > &angdeg, const std::vector< double > &u, const std::vector< double > &v, const std::string &filebackend_filename, const bool filebackend, const Mantid::API::IMDEventWorkspace_sptr &out_mdws)
Add logs and convert to MDWorkspace for a single run.
void addSampleLog(const Mantid::API::MatrixWorkspace_sptr &workspace, const std::string &log_name, double log_number)
Add a sample log to a workspace.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
int version() const override
Algorithm's version for identification.
Mantid::API::IMDEventWorkspace_sptr convertToMD(const Mantid::API::Workspace_sptr &workspace, const std::string &analysis_mode, bool in_place, const std::string &filebackend_filename, const bool filebackend, const Mantid::API::IMDEventWorkspace_sptr &out_mdws)
Convert a workspace to MDWorkspace.
const std::string category() const override
Algorithm's category for identification.
Mantid::API::Workspace_sptr loadWs(const std::string &filename, const std::string &wsname)
Load data from file into a workspace.
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void MANTID_MDALGORITHMS_DLL padParameterVector(std::vector< double > ¶m_vector, const size_t grow_to_size)
Pad vector of parameters to given length.
bool MANTID_MDALGORITHMS_DLL dataExists(const std::string &data_name)
Check if the named data source is an existing workspace or file.
static const std::string MAXRECURSIONDEPTH("20")
bool any_given(const std::vector< std::vector< double > > ¶ms)
bool all_given(const std::vector< std::vector< double > > ¶ms)
static const std::string SPLITINTO("2")
static const std::string SPLITTHRESHOLD("500")
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.