22#include <boost/lexical_cast.hpp>
32using namespace Kernel;
41 "The name of the workspace containing the data you want to save.");
42 declareProperty(std::make_unique<FileProperty>(
"Filename",
"",
FileProperty::Save),
"The output filename");
43 std::vector<std::string> extension = {
".mft",
".txt",
".dat",
".lam",
"custom"};
44 declareProperty(
"FileExtension",
".mft", std::make_shared<StringListValidator>(extension),
45 "Choose the file extension according to the file format.");
46 auto mft = std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
"mft");
47 auto cus = std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
"custom");
49 setPropertySettings(
"LogList", std::make_unique<VisibleWhenProperty>(std::move(mft), std::move(cus),
OR));
50 declareProperty(
"WriteHeader",
false,
"Whether to write header lines.");
51 setPropertySettings(
"WriteHeader", std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
"custom"));
52 std::vector<std::string> separator = {
"comma",
"space",
"tab"};
53 declareProperty(
"WriteResolution",
true,
54 "Whether to compute resolution values and write them as fourth "
56 setPropertySettings(
"WriteResolution", std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
"custom"));
57 declareProperty(
"Separator",
"tab", std::make_shared<StringListValidator>(separator),
58 "The separator used for splitting data columns.");
59 setPropertySettings(
"Separator", std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
"custom"));
60 declareProperty(
"Theta", 0.0,
"The angle (in deg) used to calculate wavelength from momentum exchange.");
61 setPropertySettings(
"Theta", std::make_unique<VisibleWhenProperty>(
"FileExtension",
IS_EQUAL_TO,
".lam"));
66 std::map<std::string, std::string> issues;
78 issues[
"InputWorkspace"] =
"Must be a MatrixWorkspace";
82 }
catch (std::range_error &) {
83 issues[
"InputWorkspace"] =
"Workspace does not contain data";
86 if (
m_ext ==
".lam") {
89 issues[
"Theta"] =
"The theta angle necessary to calculate wavelength is not defined.";
98 m_file << std::setprecision(std::numeric_limits<double>::digits10);
99 const auto points =
m_ws->points(0);
100 const auto &yData =
m_ws->y(0);
101 const auto &eData =
m_ws->e(0);
102 for (
size_t i = 0; i <
m_ws->y(0).size(); ++i) {
110 outputval(points[i] * ((points[1] + points[0]) / points[1]));
112 if (
m_ext ==
".lam") {
122 if (
m_ext ==
"custom") {
123 const std::string sepOption =
getProperty(
"Separator");
124 if (sepOption ==
"comma")
126 if (sepOption ==
"space")
152 if constexpr (std::is_floating_point<T>::value) {
164 m_file << std::setw(28) << val;
170 auto run =
m_ws->run();
172 return boost::lexical_cast<std::string>(run.getLogData(logName)->value());
174 return "Not defined";
180 auto run =
m_ws->run();
182 return " " + boost::lexical_cast<std::string>(run.getLogData(logName)->units());
195 if (!logNameFixed.empty()) {
202 m_file <<
" : " << logValue << logUnit <<
'\n';
207 m_file << std::setfill(
' ');
208 auto fileType =
"MFT\n";
212 std::vector<std::string> logs{
"instrument.name",
"user.namelocalcontact",
"title",
"start_time",
"end_time"};
213 writeInfo(
"instrument.name",
"Instrument");
214 writeInfo(
"user.namelocalcontact",
"User-local contact");
217 writeInfo(
"start_time",
"Start date + time");
218 writeInfo(
"end_time",
"End date + time");
219 writeInfo(
"",
"Theta 1 + dir + ref numbers");
220 writeInfo(
"",
"Theta 2 + dir + ref numbers");
221 writeInfo(
"",
"Theta 3 + dir + ref numbers");
222 const std::vector<std::string> logList =
getProperty(
"LogList");
224 for (
const auto &log : logList) {
225 if (find(logs.cbegin(), logs.cend(), log) == logs.end()) {
231 for (
auto i = nLogs; i < 9; ++i)
233 m_file <<
"Number of file format : "
235 m_file <<
"Number of data points : " <<
m_ws->y(0).size() <<
'\n';
249 if (Poco::File(filename).
exists()) {
250 g_log.
warning(
"File already exists and will be overwritten");
252 Poco::File(filename).remove();
254 g_log.
error(
"Error deleting file " + filename);
259 g_log.
error(
"Unable to create file: " + filename);
270 else if (
m_ext ==
".dat")
283 for (
auto i : group->getAllItems()) {
284 if (i->getName().empty())
287 const auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(i);
289 g_log.
warning(
"WorkspaceGroup must contain MatrixWorkspaces, skip");
293 }
catch (std::range_error &) {
294 throw(std::runtime_error(
"InputWorkspace does not contain data"));
297 m_wsName.emplace_back(i->getName());
301 if (group->isEmpty())
302 g_log.
warning(
"WorkspaceGroup does not contain MatrixWorkspaces");
304 if (filename.empty())
305 throw(std::runtime_error(
"Provide a file name"));
316 for (
auto i = 0u; i <
m_group.size(); ++i) {
318 std::string ending{
""};
320 ending = filename.substr(filename.find(
"."));
#define DECLARE_ALGORITHM(classname)
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.
@ Save
to specify a file to write to, the file may or may not exist
Class to hold a set of workspaces.
A property class for workspaces.
Saves a file of desired (mft, txt, dat or custom) Ascii format from a 2D workspace.
bool checkGroups() override
Check if input workspace is a group.
void header()
Write header.
std::string m_filename
Filename.
void checkFile(const std::string &filename)
Check file validity.
std::ofstream m_file
The output file stream.
std::string m_ext
File extension.
std::vector< std::string > m_wsName
Names of the workspaces in a group.
void data()
Write the data.
void separator()
Determine the separator.
std::vector< API::MatrixWorkspace_const_sptr > m_group
Input workspace group.
API::MatrixWorkspace_const_sptr m_ws
Input workspace.
double m_theta
The angle used to calculate wavelength from momentum exchange, in rad.
void writeInfo(const std::string &logName, const std::string &logNameFixed="")
Write one header line.
void exec() override
Algorithm execution for single MatrixWorkspaces.
std::string sampleLogValue(const std::string &logName)
Retrieve sample log value.
void outputval(const T &val, bool firstColumn=false)
Print a value to file.
std::string sampleLogUnit(const std::string &logName)
Retrieve sample log unit.
bool processGroups() override
Algorithm execution for WorkspaceGroups.
std::map< std::string, std::string > validateInputs() override
Cross-check properties with each other.
bool includeQResolution() const
Whether the Q resolution should be included in the output.
Support for a property that holds an array of values.
Exception for when an item is not found in a collection.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< const WorkspaceGroup > WorkspaceGroup_const_sptr
shared pointer to Mantid::API::WorkspaceGroup, pointer to const version
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
@ Input
An input workspace.