14#include "MantidTypes/Core/DateAndTime.h"
16#include <boost/algorithm/string/classification.hpp>
17#include <boost/algorithm/string/split.hpp>
18#include <boost/functional/hash.hpp>
19#if BOOST_VERSION == 106900
20#ifndef BOOST_PENDING_INTEGER_LOG2_HPP
21#define BOOST_PENDING_INTEGER_LOG2_HPP
22#include <boost/integer/integer_log2.hpp>
25#include <boost/uuid/uuid.hpp>
26#include <boost/uuid/uuid_generators.hpp>
27#include <boost/uuid/uuid_io.hpp>
29#include "Poco/DateTime.h"
30#include <Poco/DateTimeParser.h>
32using boost::algorithm::split;
38Kernel::Logger
g_log(
"WorkspaceHistory");
39struct AlgorithmHistorySearch {
42struct AlgorithmHistoryHasher {
44 std::size_t nameAsSeed = std::hash<std::string>{}(
x->name());
45 boost::hash_combine(nameAsSeed,
x->executionDate().totalNanoseconds());
49struct AlgorithmHistoryComparator {
51 return a->uuid() == b->uuid();
67 if (
this == &otherHistory) {
74 for (
const auto &algHistory : otherAlgorithms) {
78 using UniqueAlgorithmHistories =
79 std::unordered_set<AlgorithmHistory_sptr, AlgorithmHistoryHasher, AlgorithmHistoryComparator>;
85 UniqueAlgorithmHistories uniqueHistories;
87 uniqueHistories.insert(algorithmHistory);
89 m_algorithms.assign(std::begin(uniqueHistories), std::end(uniqueHistories));
124 throw std::out_of_range(
"WorkspaceHistory::getAlgorithmHistory() - Index out of range");
154 throw std::out_of_range(
"WorkspaceHistory::lastAlgorithm() - History contains no algorithms.");
166 os << std::string(indent,
' ') <<
"Histories:\n";
181 file->makeGroup(
"process",
"NXprocess",
true);
182 std::stringstream output;
190 strftime(buffer, 25,
"%Y-%b-%d %H:%M:%S", localtime(&now));
191 file->makeGroup(
"MantidEnvironment",
"NXnote",
true);
192 file->writeData(
"author",
"mantid");
193 file->openData(
"author");
194 file->putAttr(
"date", std::string(buffer));
196 file->writeData(
"description",
"Mantid Environment data");
197 file->writeData(
"data", output.str());
203 algorithm->saveNexus(file, algCount);
220void getWordsInString(
const std::string &words3, std::string &w1, std::string &w2, std::string &w3) {
222 if (data.
count() != 3)
223 throw std::out_of_range(
"Algorithm list line " + words3 +
" is not of the correct format\n");
241void getWordsInString(
const std::string &words4, std::string &w1, std::string &w2, std::string &w3, std::string &w4) {
243 if (data.
count() != 4)
244 throw std::out_of_range(
"Algorithm list line " + words4 +
" is not of the correct format\n");
261 file->openGroup(
"process",
"NXprocess");
262 }
catch (std::exception &) {
263 g_log.
warning() <<
"Error opening the algorithm history field 'process'. "
264 "Workspace will have no history."
285 for (
auto historyNumber : historyNumbers) {
288 file->openGroup(entryName,
"NXnote");
289 file->readData(
"data", rawData);
295 parent->addChildHistory(
history);
301 }
catch (std::runtime_error &e) {
315 std::set<int> historyNumbers;
316 std::map<std::string, std::string> entries;
317 file->getEntries(entries);
321 for (
auto &entry : entries) {
322 std::string entryName = entry.first;
323 if (entryName.find(
"MantidAlgorithm_") != std::string::npos) {
325 entryName = entryName.substr(16, entryName.size() - 16);
328 historyNumbers.insert(num);
332 return historyNumbers;
350 std::vector<std::string> info;
351 boost::split(info, rawData, boost::is_any_of(
"\n"));
353 const size_t nlines = info.size();
356 throw std::runtime_error(
"Malformed history record: Incorrect record size.");
359 std::string algName, dummy, temp;
364 size_t numStart = temp.find(
'v');
366 numStart = numStart != 1 ? 1 : 0;
367 temp = std::string(temp.begin() + numStart, temp.end());
368 const auto version = boost::lexical_cast<int>(temp);
371 std::string date, time;
373 Mantid::Types::Core::DateAndTime utc_start;
375 if (std::isdigit(date[6])) {
376 Mantid::Types::Core::DateAndTime timeConstruction(date +
"T" + time);
377 utc_start = timeConstruction;
379 Poco::DateTime start_timedate;
382 if (!Poco::DateTimeParser::tryParse(
"%Y-%b-%d %H:%M:%S", date +
" " + time, start_timedate, tzdiff)) {
383 g_log.
warning() <<
"Error parsing start time in algorithm history entry."
385 utc_start = Types::Core::DateAndTime::defaultTime();
387 utc_start.set_from_time_t(start_timedate.timestamp().epochTime());
392 auto dur = boost::lexical_cast<double>(temp);
394 g_log.
warning() <<
"Error parsing duration in algorithm history entry."
403 if (info[3] !=
"Parameters:") {
405 uuid.erase(uuid.find(
"UUID: "), 6);
408 uuid = boost::uuids::to_string(boost::uuids::random_generator()());
418 for (
size_t index =
static_cast<size_t>(paramNum) + 1;
index < nlines; ++
index) {
419 const std::string line = info[
index];
420 std::string::size_type colon = line.find(
':');
421 std::string::size_type comma = line.find(
',');
423 std::string prop_name = line.substr(colon + 2, comma - colon - 2);
424 colon = line.find(
':', comma);
425 comma = line.find(
", Default?", colon);
426 std::string prop_value = line.substr(colon + 2, comma - colon - 2);
427 colon = line.find(
':', comma);
428 comma = line.find(
", Direction", colon);
429 std::string is_def = line.substr(colon + 2, comma - colon - 2);
430 colon = line.find(
':', comma);
431 comma = line.find(
',', colon);
432 std::string direction = line.substr(colon + 2, comma - colon - 2);
434 alg_hist.
addProperty(prop_name, prop_value, (is_def[0] ==
'Y'), direc);
const std::vector< double > & rhs
std::map< DeltaEMode::Type, std::string > index
std::vector< history_type > history
history information
This class stores information about the Command History used by algorithms on a workspace.
void addProperty(const std::string &name, const std::string &value, bool isdefault, const unsigned int &direction=99)
Add a property to the history.
static size_t g_execCount
Counter to keep track of algorithm execution order.
static IAlgorithm_sptr fromHistory(const AlgorithmHistory &history)
Construct an object from a history entry.
This class stores information about the Workspace History used by algorithms on a workspace and the e...
std::set< int > findHistoryEntries(::NeXus::File *file)
Find the history entries at this level in the file.
void loadNestedHistory(::NeXus::File *file, const AlgorithmHistory_sptr &parent=std::shared_ptr< AlgorithmHistory >())
Recursive function to load the algorithm history tree from file.
std::shared_ptr< IAlgorithm > getAlgorithm(const size_t index) const
Create an algorithm from a history record at a given index.
AlgorithmHistory_const_sptr getAlgorithmHistory(const size_t index) const
Retrieve an algorithm history by index.
AlgorithmHistory_const_sptr operator[](const size_t index) const
Add operator[] access.
Mantid::API::AlgorithmHistories m_algorithms
The algorithms which have been called on the workspace.
bool operator==(const WorkspaceHistory &otherHistory) const
Add an operator== that compares algorithm historys.
WorkspaceHistory()
Default constructor.
std::shared_ptr< HistoryView > createView() const
Create a flat view of the workspaces algorithm history.
void printSelf(std::ostream &, const int indent=0) const
Pretty print the entire history.
void saveNexus(::NeXus::File *file) const
Save the workspace history to a nexus file.
void addHistory(const WorkspaceHistory &otherHistory)
Append an workspace history to this one.
std::shared_ptr< IAlgorithm > lastAlgorithm() const
Convenience function for retrieving the last algorithm.
const Kernel::EnvironmentHistory & getEnvironmentHistory() const
Retrieve the environment history.
bool empty() const
Is the history empty.
const AlgorithmHistories & getAlgorithmHistories() const
Retrieve the algorithm history list.
AlgorithmHistory_sptr parseAlgorithmHistory(const std::string &rawData)
Parse an algorithm history string loaded from file.
size_t size() const
How many entries are there.
void clearHistory()
remove all algorithm history objects from the workspace history
const Kernel::EnvironmentHistory m_environment
The environment of the workspace.
void loadNexus(::NeXus::File *file)
Load the workspace history from a nexus file.
This class stores information about the Environment of the computer used by the framework.
void printSelf(std::ostream &, const int indent=0) const
print contents of object
void warning(const std::string &msg)
Logs at warning level.
@ TOK_TRIM
remove leading and trailing whitespace from tokens
std::size_t count() const
Get the total number of tokens.
std::vector< AlgorithmHistory_sptr > AlgorithmHistories
void getWordsInString(const std::string &words3, std::string &w1, std::string &w2, std::string &w3)
If the first string contains exactly three words separated by spaces these words will be copied into ...
MANTID_API_DLL std::ostream & operator<<(std::ostream &, const AlgorithmHistory &)
Prints a text representation.
std::shared_ptr< const AlgorithmHistory > AlgorithmHistory_const_sptr
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< AlgorithmHistory > AlgorithmHistory_sptr
int convert(const std::string &A, T &out)
Convert a string into a number.
std::string toString(const T &value)
Convert a number to a string.
static int asEnum(const std::string &direction)
Returns an enum representation of the input Direction string.