Newer
Older
#include "MantidAlgorithms/ExportTimeSeriesLog.h"
#include "MantidKernel/System.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidAPI/IEventList.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/EventList.h"
#include "MantidDataObjects/Events.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include <algorithm>
#include <fstream>
#include "MantidKernel/ListValidator.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace std;
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
namespace Mantid {
namespace Algorithms {
DECLARE_ALGORITHM(ExportTimeSeriesLog)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
ExportTimeSeriesLog::ExportTimeSeriesLog() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
ExportTimeSeriesLog::~ExportTimeSeriesLog() {}
//----------------------------------------------------------------------------------------------
/** Definition of all input arguments
*/
void ExportTimeSeriesLog::init() {
declareProperty(
new API::WorkspaceProperty<MatrixWorkspace>("InputWorkspace", "Anonymous",
Direction::InOut),
"Name of input Matrix workspace containing the log to export. ");
declareProperty(
new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "Dummy",
Direction::Output),
"Name of the workspace containing the log events in Export. ");
declareProperty("LogName", "", "Log's name to filter events.");
declareProperty(
"NumberEntriesExport", EMPTY_INT(),
"Number of entries of the log to be exported. Default is all entries.");
declareProperty("IsEventWorkspace", true, "If set to true, output workspace "
"is EventWorkspace. Otherwise, it "
"is Workspace2D.");
return;
}
//----------------------------------------------------------------------------------------------
/** Main execution
*/
void ExportTimeSeriesLog::exec() {
// 1. Get property
m_dataWS = this->getProperty("InputWorkspace");
string logname = getProperty("LogName");
int numberoutputentries = getProperty("NumberEntriesExport");
bool outputeventworkspace = getProperty("IsEventWorkspace");
// 2. Call the main
exportLog(logname, numberoutputentries, outputeventworkspace);
// 3. Output
setProperty("OutputWorkspace", m_outWS);
return;
}
//----------------------------------------------------------------------------------------------
/** Export part of designated log to an file in column format and a output file
* @param logname :: name of log to export
* @param numentries :: number of log entries to export
* @param outputeventws :: boolean. output workspace is event workspace if
* true.
*/
void ExportTimeSeriesLog::exportLog(string logname, int numentries,
bool outputeventws) {
// 1. Get log, time, and etc.
std::vector<Kernel::DateAndTime> times;
std::vector<double> values;
if (logname.size() > 0) {
// Log
Kernel::TimeSeriesProperty<double> *tlog =
dynamic_cast<Kernel::TimeSeriesProperty<double> *>(
m_dataWS->run().getProperty(logname));
if (!tlog) {
std::stringstream errmsg;
errmsg << "TimeSeriesProperty Log " << logname
<< " does not exist in workspace " << m_dataWS->getName();
g_log.error(errmsg.str());
throw std::invalid_argument(errmsg.str());
times = tlog->timesAsVector();
values = tlog->valuesAsVector();
} else {
throw std::runtime_error("Log name cannot be left empty.");
// 2. Determine number of export log
if (numentries == EMPTY_INT()) {
numentries = static_cast<int>(times.size());
} else if (numentries <= 0) {
stringstream errmsg;
errmsg << "For Export Log, NumberEntriesExport must be greater than 0. "
"Input = " << numentries;
g_log.error(errmsg.str());
throw std::runtime_error(errmsg.str());
} else if (static_cast<size_t>(numentries) > times.size()) {
numentries = static_cast<int>(times.size());
}
// 3. Create otuput workspace
if (outputeventws) {
setupEventWorkspace(numentries, times, values);
} else {
setupWorkspace2D(numentries, times, values);
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
return;
}
/** Set up the output workspace in a Workspace2D
* @param numentries :: number of log entries to output
* @param times :: vector of Kernel::DateAndTime
* @param values :: vector of log value in double
*/
void ExportTimeSeriesLog::setupWorkspace2D(int numentries,
vector<DateAndTime> ×,
vector<double> values) {
Kernel::DateAndTime runstart(
m_dataWS->run().getProperty("run_start")->value());
size_t size = static_cast<size_t>(numentries);
m_outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(
WorkspaceFactory::Instance().create("Workspace2D", 1, size, size));
if (!m_outWS)
throw runtime_error(
"Unable to create a Workspace2D casted to MatrixWorkspace.");
MantidVec &vecX = m_outWS->dataX(0);
MantidVec &vecY = m_outWS->dataY(0);
MantidVec &vecE = m_outWS->dataE(0);
for (size_t i = 0; i < size; ++i) {
int64_t dtns = times[i].totalNanoseconds() - runstart.totalNanoseconds();
vecX[i] = static_cast<double>(dtns) * 1.0E-9;
vecY[i] = values[i];
vecE[i] = 0.0;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
Axis *xaxis = m_outWS->getAxis(0);
xaxis->setUnit("Time");
return;
}
//----------------------------------------------------------------------------------------------
/** Set up an Event workspace
* @param numentries :: number of log entries to output
* @param times :: vector of Kernel::DateAndTime
* @param values :: vector of log value in double
*/
void ExportTimeSeriesLog::setupEventWorkspace(int numentries,
vector<DateAndTime> ×,
vector<double> values) {
Kernel::DateAndTime runstart(
m_dataWS->run().getProperty("run_start")->value());
// Get some stuff from the input workspace
const size_t numberOfSpectra = 1;
const int YLength = static_cast<int>(m_dataWS->blocksize());
// Make a brand new EventWorkspace
EventWorkspace_sptr outEventWS = boost::dynamic_pointer_cast<EventWorkspace>(
API::WorkspaceFactory::Instance().create(
"EventWorkspace", numberOfSpectra, YLength + 1, YLength));
// Copy geometry over.
API::WorkspaceFactory::Instance().initializeFromParent(m_dataWS, outEventWS,
false);
m_outWS = boost::dynamic_pointer_cast<MatrixWorkspace>(outEventWS);
if (!m_outWS)
throw runtime_error(
"Output workspace cannot be casted to a MatrixWorkspace.");
g_log.debug("[DBx336] An output workspace is generated.!");
// Create the output event list (empty)
EventList &outEL = outEventWS->getOrAddEventList(0);
outEL.switchTo(WEIGHTED_NOTIME);
// Allocate all the required memory
outEL.reserve(numentries);
outEL.clearDetectorIDs();
for (size_t i = 0; i < static_cast<size_t>(numentries); i++) {
Kernel::DateAndTime tnow = times[i];
int64_t dt = tnow.totalNanoseconds() - runstart.totalNanoseconds();
// convert to microseconds
double dtmsec = static_cast<double>(dt) / 1000.0;
outEL.addEventQuickly(WeightedEventNoTime(dtmsec, values[i], values[i]));
}
// Ensure thread-safety
outEventWS->sortAll(TOF_SORT, NULL);
// Now, create a default X-vector for histogramming, with just 2 bins.
Kernel::cow_ptr<MantidVec> axis;
MantidVec &xRef = axis.access();
xRef.resize(2);
std::vector<WeightedEventNoTime> &events = outEL.getWeightedEventsNoTime();
xRef[0] = events.begin()->tof();
xRef[1] = events.rbegin()->tof();
// Set the binning axis using this.
outEventWS->setX(0, axis);
return;
}
} // namespace Mantid
} // namespace Algorithms