16#include <boost/tokenizer.hpp>
21using namespace Kernel;
29 useAlgorithm(
"EnggSaveSinglePeakFitResultsToHDF5", 1);
36 "The name of the workspace containing the data you want to "
37 "save to a TBL file");
41 const std::vector<std::string> exts{
".txt",
".csv",
""};
43 "The filename to use for the saved data");
46 "Run number list of the focused files, which is used to generate the "
47 "parameters table workspace");
50 "Bank number list of the focused files, which is used to generate "
51 "the parameters table workspace");
53 std::vector<std::string> formats;
55 formats.emplace_back(
"AppendToExistingFile");
56 formats.emplace_back(
"OverwriteFile");
57 declareProperty(
"OutMode",
"AppendToExistingFile", std::make_shared<Kernel::StringListValidator>(formats),
58 "Over write the file or append data to existing file");
70 throw std::runtime_error(
"Please provide an input table workspace to be saved.");
72 std::vector<API::ITableWorkspace_sptr> input_ws;
73 input_ws.emplace_back(std::dynamic_pointer_cast<DataObjects::TableWorkspace>(tbl_ws));
86 std::vector<API::ITableWorkspace_sptr> input_ws;
87 input_ws.reserve(inputGroup->getNumberOfEntries());
88 for (
int i = 0; i < inputGroup->getNumberOfEntries(); ++i) {
89 input_ws.emplace_back(std::dynamic_pointer_cast<ITableWorkspace>(inputGroup->getItem(i)));
93 }
catch (std::runtime_error &rexc) {
94 g_log.
error(std::string(
"Error while processing a group of workspaces. Details: ") + rexc.what() +
'\n');
102 const std::string filename =
getProperty(
"Filename");
103 const std::string outMode =
getProperty(
"OutMode");
107 Poco::File pFile = (filename);
108 bool exist = pFile.exists();
110 bool appendToFile =
false;
111 if (outMode ==
"AppendToExistingFile")
115 std::ofstream file(filename.c_str(), (appendToFile ? std::ios::app : std::ios::out));
121 if (exist && !appendToFile) {
122 g_log.
warning() <<
"File " << filename <<
" exists and will be overwritten."
126 if (exist && appendToFile) {
133 std::vector<std::string> splitRunNum =
splitList(runNumList);
134 std::vector<std::string> splitBank =
splitList(bankList);
139 size_t breaker = input_ws.size();
140 if (outMode ==
"AppendToExistingFile" && input_ws.size() == 1)
143 for (
size_t i = 0; i < breaker; ++i) {
145 std::string runNum = splitRunNum[
m_counter];
148 if (!runNum.empty() || !bank.empty())
152 std::vector<std::string> columnHeadings = input_ws[i]->getColumnNames();
156 size_t columnSize = columnHeadings.size();
157 writeData(input_ws[i], file, columnSize);
159 if (input_ws.size() > 1 && (i + 1) != input_ws.size()) {
168 strList.erase(std::remove(strList.begin(), strList.end(),
' '), strList.end());
169 boost::split(
splitList, strList, boost::is_any_of(
","));
176 file <<
"run number: " << runNumber <<
'\n';
177 file <<
"bank: " << bank <<
'\n';
182 for (
const auto &heading : columnHeadings) {
184 if (&heading == &columnHeadings.back()) {
193 const size_t columnSize) {
195 for (
size_t rowIndex = 0; rowIndex <
workspace->rowCount(); ++rowIndex) {
197 for (
size_t columnIndex = 0; columnIndex < columnSize; columnIndex++) {
199 const auto row_str = boost::lexical_cast<std::string>(row.
Double(columnIndex));
202 if (columnIndex == columnSize - 1)
211 std::string valStr = boost::lexical_cast<std::string>(val);
215 size_t comPos = valStr.find(
',');
216 if (comPos != std::string::npos) {
217 file <<
'"' << val <<
'"';
219 file << boost::lexical_cast<std::string>(val);
230 std::map<std::string, std::string> errors;
235 const std::string inputWS =
getProperty(
"InputWorkspace");
245 if (!inGrp && !tbl_ws) {
246 std::string message =
"The current version of this algorithm only "
247 "supports input workspaces of type TableWorkspace and WorkspaceGroup";
248 errors[
"InputWorkspace"] = message;
253 errors[
"Filename"] =
"File name directory cannot be empty";
257 std::vector<std::string> splitRunNum =
splitList(runNumber);
260 std::vector<std::string> splitBank =
splitList(bankNumber);
262 if (bankNumber.empty()) {
263 if (!runNumber.empty())
264 errors[
"Bank"] =
"Please provide a valid bank list";
265 }
else if (runNumber.empty()) {
266 errors[
"RunNumber"] =
"Please provide a valid run number list";
267 }
else if (!is_grp) {
268 if (splitRunNum.size() > 1) {
269 errors[
"RunNumber"] =
"One run number should be provided when a Table"
270 "workspace is selected";
272 if (splitBank.size() > 1) {
273 errors[
"Bank"] =
"One bank should be provided when a Table"
274 "Workspace is selected";
277 if (splitRunNum.size() != inGrp->size()) {
278 errors[
"RunNumber"] =
"Run number list size should match the number of "
279 "TableWorkspaces in the GroupWorkspace selected";
281 if (splitBank.size() != inGrp->size()) {
282 errors[
"Bank"] =
"Bank list size should match the number of "
283 "TableWorkspaces in the GroupWorkspace selected";
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
Base class from which all concrete algorithm classes should be derived.
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.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
@ Save
to specify a file to write to, the file may or may not exist
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
double & Double(size_t col)
Returns a reference to the element in position col if its type is double.
Class to hold a set of workspaces.
A property class for workspaces.
void init() override
Initialisation code.
void writeHeader(const std::vector< std::string > &columnHeadings, std::ofstream &file)
std::vector< std::string > splitList(std::string strList)
void writeData(const API::ITableWorkspace_sptr &workspace, std::ofstream &file, const size_t columnSize)
std::map< std::string, std::string > validateInputs() override
Cross-check properties with each other.
void exec() override
Execution code.
int m_counter
table_counter
void writeInfo(const std::string &runNumber, const std::string &bank, std::ofstream &file)
const char m_sep
the separator
void writeVal(const std::string &val, std::ofstream &file, const bool endline)
bool processGroups() override
Process two groups and ensure the Result string is set properly on the final algorithm.
void processAll(const std::vector< API::ITableWorkspace_sptr > &input_ws)
Main exec routine, called for group or individual workspace processing.
const std::string name() const override
Algorithm's name.
Records the filename and the description of failure.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning 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< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< const WorkspaceGroup > WorkspaceGroup_const_sptr
shared pointer to Mantid::API::WorkspaceGroup, pointer to const version
Helper class which provides the Collimation Length for SANS instruments.
@ Input
An input workspace.