-
Notifications
You must be signed in to change notification settings - Fork 122
/
SaveReflTBL.cpp
191 lines (167 loc) · 5.98 KB
/
SaveReflTBL.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*WIKI*
Saves a TableWorkspace at least 8 colunms wide into an ascii file in 17-column Reflectometry TBL format compatible with the old ISIS reflectometry Interface.
The 8 columns are grouped into rows of 17 according to stitch index, so up to 3 rows int he table would become a single row in the TBL file like so:
(Where Z is an identical stitch group index, and - is ignored as only the first instance of P and Q are used in the file)
A, B, C, D, E, P, Q, Z
F, G, H, I, J, -, -, Z
K, L, M, N, O, -, -, Z
becomes
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q
==== Limitations ====
The Algorithm will fail if any stitch index appears more than 3 times, as the old interface does not support more than 3 runs per row.
Stitch groups of index 0 are treated as non-grouped, and will not be grouped with one another (and by extension can be larger than 3 members). They will however be moved to the end of the file
*WIKI*/
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidDataHandling/SaveReflTBL.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/TableRow.h"
#include "MantidDataObjects/TableWorkspace.h"
#include <fstream>
#include <boost/tokenizer.hpp>
namespace Mantid
{
namespace DataHandling
{
// Register the algorithm into the algorithm factory
DECLARE_ALGORITHM(SaveReflTBL)
/// Sets documentation strings for this algorithm
void SaveReflTBL::initDocs()
{
this->setWikiSummary("Saves a table [[workspace]] to a reflectometry tbl format ascii file. ");
this->setOptionalMessage("Saves a table workspace to a reflectometry tbl format ascii file.");
}
using namespace Kernel;
using namespace API;
/// Empty constructor
SaveReflTBL::SaveReflTBL() : m_sep(','), m_stichgroups(), m_nogroup()
{
}
/// Initialisation method.
void SaveReflTBL::init()
{
std::vector<std::string> exts;
exts.push_back(".tbl");
declareProperty(new FileProperty("Filename", "", FileProperty::Save, exts),
"The filename of the output TBL file.");
declareProperty(new WorkspaceProperty<ITableWorkspace>("InputWorkspace", "", Direction::Input),
"The name of the workspace containing the data you want to save to a TBL file.");
}
/**
* Finds the stitch groups that need to be on the same line
* @param ws : a pointer to a tableworkspace
*/
void SaveReflTBL::findGroups(ITableWorkspace_sptr ws)
{
size_t rowCount = ws->rowCount();
for (size_t i = 0; i < rowCount; ++i)
{
TableRow row = ws->getRow(i);
if (row.cell<int>(7) != 0)
{
//it was part of a group
m_stichgroups[row.cell<int>(7)].push_back(i);
if (m_stichgroups[row.cell<int>(7)].size() > 3)
{
std::string message = "Cannot save a table with stitch groups that are larger than three runs to Reflectometry .tbl format.";
throw std::length_error(message);
}
}
else
{
//it wasn't part of a group
m_nogroup.push_back(i);
}
}
}
/**
* Executes the algorithm.
*/
void SaveReflTBL::exec()
{
// Get the workspace
ITableWorkspace_sptr ws = getProperty("InputWorkspace");
findGroups(ws);
std::string filename = getProperty("Filename");
std::ofstream file(filename.c_str());
if (!file)
{
throw Exception::FileError("Unable to create file: " , filename);
}
typedef std::map<int, std::vector<size_t>>::iterator map_it_type;
for(map_it_type iterator = m_stichgroups.begin(); iterator != m_stichgroups.end(); ++iterator)
{
std::vector<size_t> & rowNos = iterator->second;
size_t i = 0;
for (; i < rowNos.size(); ++i)
{
//for each row in the group print the first 5 columns to file
TableRow row = ws->getRow(rowNos[i]);
for (int j = 0; j < 5; ++j)
{
writeVal(row.cell<std::string>(j),file);
}
}
//if i comes out of that loop as less than 3, then we need to add the blank runs
for (; i < 3; ++i)
{
for (int j = 0; j < 5; ++j)
{
file << m_sep;
}
}
//now add dq/q and scale from the first row in the group
TableRow row = ws->getRow(rowNos[0]);
writeVal(row.cell<std::string>(5),file);
writeVal(row.cell<std::string>(6),file, false, true);
}
//now do the same for the ungrouped
typedef std::vector<size_t>::iterator vec_it_type;
for(vec_it_type iterator = m_nogroup.begin(); iterator != m_nogroup.end(); ++iterator)
{
TableRow row = ws->getRow(*iterator);
for (int j = 0; j < 5; ++j)
{
writeVal(row.cell<std::string>(j),file);
}
for (int k = 0; k < 10; ++k)
{
file << m_sep;
}
//now add dq/q and scale
writeVal(row.cell<std::string>(5),file);
writeVal(row.cell<std::string>(6),file, false, true);
}
file.close();
}
/**
* Writes the given value to file, checking if it needs to be surrounded in quotes due to a comma being included
* @param val : the string to be written
* @param file : the ouput file stream
* @param endsep : boolean true to include a comma after the data
* @param endline : boolean true to put an EOL at the end of this data value
*/
void SaveReflTBL::writeVal(std::string & val,std::ofstream & file, bool endsep, bool endline)
{
size_t comPos = val.find(',');
if (comPos != std::string::npos)
{
file << '"' << val << '"';
}
else
{
file << val;
}
if (endsep)
{
file << m_sep;
}
if (endline)
{
file << std::endl;
}
}
} // namespace DataHandling
} // namespace Mantid