Skip to content
Snippets Groups Projects
AlgorithmHistory.cpp 11.2 KiB
Newer Older
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
//     NScD Oak Ridge National Laboratory, European Spallation Source
//     & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/AlgorithmHistory.h"

#if BOOST_VERSION == 106900
#ifndef BOOST_PENDING_INTEGER_LOG2_HPP
#define BOOST_PENDING_INTEGER_LOG2_HPP
#include <boost/integer/integer_log2.hpp>
#endif /* BOOST_PENDING_INTEGER_LOG2_HPP */
#endif /* BOOST_VERSION */

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
namespace Mantid {
namespace API {
using Kernel::PropertyHistories;
using Kernel::PropertyHistory;
using Kernel::PropertyHistory_const_sptr;
using Kernel::PropertyHistory_sptr;
using Types::Core::DateAndTime;
namespace {
/// The generator for algorithm history UUIDs
static boost::uuids::random_generator uuidGen;
} // namespace
 *  @param alg ::      A pointer to the algorithm for which the history should
 * be constructed
 *  @param start ::    The start time of the algorithm execution (optional)
 *  @param duration :: The time (in seconds) that it took to run this algorithm
 * (optional)
 *  @param uexeccount :: an  unsigned int for algorithm execution order
AlgorithmHistory::AlgorithmHistory(const Algorithm *const alg,
                                   const Types::Core::DateAndTime &start,
                                   const double &duration,
                                   std::size_t uexeccount)
    : m_name(alg->name()), m_version(alg->version()), m_executionDate(start),
      m_executionDuration(duration), m_execCount(uexeccount),
      m_childHistories() {
  // Now go through the algorithm's properties and create the PropertyHistory
  // objects.
  m_uuid = boost::uuids::to_string(uuidGen());
/// Default constructor
AlgorithmHistory::AlgorithmHistory() {
  m_uuid = boost::uuids::to_string(uuidGen());
Hahn, Steven's avatar
Hahn, Steven committed
AlgorithmHistory::~AlgorithmHistory() = default;
    Construct AlgorithmHistory by name. Can be used for rstoring the history
   from saved records.
    @param name :: The algorithm name.
    @param vers :: The algorithm version.
    @param uuid :: The universally unique id assigned to this alghistory on
   creation during assignment to history.
    @param start :: The start time of the algorithm execution (optional).
    @param duration :: The time (in seconds) that it took to run this algorithm
   (optional).
   @param uexeccount ::  an  unsigned int for algorithm execution order
AlgorithmHistory::AlgorithmHistory(const std::string &name, int vers,
                                   std::string uuid,
                                   const Types::Core::DateAndTime &start,
                                   const double &duration,
                                   std::size_t uexeccount)
    : m_name(name), m_version(vers), m_executionDate(start),
      m_executionDuration(duration), m_execCount(uexeccount),
      m_childHistories(), m_uuid(uuid) {}
/**
 *  Set the history properties for an algorithm pointer
 *  @param alg :: A pointer to the algorithm for which the history should be
 * constructed
void AlgorithmHistory::setProperties(const Algorithm *const alg) {
  // overwrite any existing properties
  // Now go through the algorithm's properties and create the PropertyHistory
  // objects.
  const std::vector<Property *> &properties = alg->getProperties();
Hahn, Steven's avatar
Hahn, Steven committed
  for (const auto &property : properties) {
    m_properties.emplace_back(
Hahn, Steven's avatar
Hahn, Steven committed
        boost::make_shared<PropertyHistory>(property->createHistory()));
  }
}

/**
 *  Fill the algoirthm history object after it has been created.
 *  @param alg ::      A pointer to the algorithm for which the history should
 * be constructed
 *  @param start ::    The start time of the algorithm execution (optional)
 *  @param duration :: The time (in seconds) that it took to run this algorithm
 * (optional)
 *  @param uexeccount :: an  unsigned int for algorithm execution order
 */
LamarMoore's avatar
LamarMoore committed
void AlgorithmHistory::fillAlgorithmHistory(
    const Algorithm *const alg, const Types::Core::DateAndTime &start,
    const double &duration, std::size_t uexeccount) {
  m_name = alg->name();
  m_version = alg->version();
  m_executionDate = start;
  m_executionDuration = duration;
  m_execCount = uexeccount;
Dickon Champion's avatar
Dickon Champion committed
    Standard Copy Constructor
AlgorithmHistory::AlgorithmHistory(const AlgorithmHistory &A)
    : m_name(A.m_name), m_version(A.m_version),
      m_executionDate(A.m_executionDate),
      m_executionDuration(A.m_executionDuration), m_properties(A.m_properties),
      m_execCount(A.m_execCount), m_uuid(A.m_uuid) {
  m_childHistories = A.m_childHistories;
}

/** Add details of an algorithm's execution to an existing history object
 *  @param start ::    The start time of the algorithm execution
 *  @param duration :: The time (in seconds) that it took to run this algorithm
void AlgorithmHistory::addExecutionInfo(const DateAndTime &start,
                                        const double &duration) {
  m_executionDate = start;
  m_executionDuration = duration;
}

    @param name :: The name of the property
    @param value :: The value of the property
    @param isdefault :: True if the property is default
    @param direction :: The direction of the property
void AlgorithmHistory::addProperty(const std::string &name,
                                   const std::string &value, bool isdefault,
                                   const unsigned int &direction) {
  m_properties.emplace_back(boost::make_shared<PropertyHistory>(
Hahn, Steven's avatar
Hahn, Steven committed
      name, value, "", isdefault, direction));
/** Add a child algorithm history to history
 *  @param childHist :: The child history
 */
void AlgorithmHistory::addChildHistory(AlgorithmHistory_sptr childHist) {
  // Don't copy one's own history onto oneself
  if (this == &(*childHist)) {
  m_childHistories.emplace_back(childHist);
/*
 Return the child history length
 */
size_t AlgorithmHistory::childHistorySize() const {
 * Retrieve a child algorithm history by index
 * @param index ::  An index within the child algorithm history set
 * @returns A pointer to an AlgorithmHistory object
 * @throws std::out_of_range error if the index is invalid
 */
AlgorithmHistory_sptr
AlgorithmHistory::getChildAlgorithmHistory(const size_t index) const {
  if (index >= this->getChildHistories().size()) {
    throw std::out_of_range(
        "AlgorithmHistory::getAlgorithmHistory() - Index out of range");
Hahn, Steven's avatar
Hahn, Steven committed
  return *std::next(m_childHistories.cbegin(), index);
/**
 * Index operator[] access to a child algorithm history
 * @param index ::  An index within the algorithm history
 * @returns A pointer to an AlgorithmHistory object
 * @throws std::out_of_range error if the index is invalid
AlgorithmHistory_sptr AlgorithmHistory::operator[](const size_t index) const {
  return getChildAlgorithmHistory(index);
 * Gets the value of a specified algorithm property
 * @param name ::  The property to find
 * @returns The string value of the property
 * @throw Exception::NotFoundError if the named property is unknown
 */
Nick Draper's avatar
Nick Draper committed
const std::string &
AlgorithmHistory::getPropertyValue(const std::string &name) const {
  const auto found = std::find_if(
      m_properties.cbegin(), m_properties.cend(),
      [&name](const auto &history) { return history->name() == name; });
  if (found == m_properties.cend()) {
    throw Kernel::Exception::NotFoundError(
        "Could not find the specified property", name);
  return (*found)->value();
/**
 *  Create an algorithm from a history record at a given index
 * @param index :: An index within the workspace history
 * @returns A shared pointer to an algorithm object
 */
boost::shared_ptr<IAlgorithm>
AlgorithmHistory::getChildAlgorithm(const size_t index) const {
  return Algorithm::fromHistory(*(this->getChildAlgorithmHistory(index)));
/** Prints a text representation of itself
 *  @param os :: The output stream to write to
 *  @param indent :: an indentation value to make pretty printing of object and
 * sub-objects
Nick Draper's avatar
Nick Draper committed
 *  @param maxPropertyLength :: the max length for any property value string (0
 * = full length)
void AlgorithmHistory::printSelf(std::ostream &os, const int indent,
Nick Draper's avatar
Nick Draper committed
                                 const size_t maxPropertyLength) const {
  auto execDate = m_executionDate.toISO8601String();
  execDate.replace(execDate.find("T"), 1, " ");
  os << std::string(indent, ' ') << "Algorithm: " << m_name;
  os << std::string(indent, ' ') << " v" << m_version << '\n';
  os << std::string(indent, ' ') << "Execution Date: " << execDate << '\n';
  os << std::string(indent, ' ')
Hahn, Steven's avatar
Hahn, Steven committed
     << "Execution Duration: " << m_executionDuration << " seconds\n";
  os << std::string(indent, ' ') << "UUID: " << m_uuid << '\n';
  os << std::string(indent, ' ') << "Parameters:\n";
Dickon Champion's avatar
Dickon Champion committed

Hahn, Steven's avatar
Hahn, Steven committed
  for (const auto &property : m_properties) {
    property->printSelf(os, indent + 2, maxPropertyLength);
Dickon Champion's avatar
Dickon Champion committed

/**
 * Create a concrete algorithm based on a history record
 * @returns An algorithm object constructed from this history record
 */
boost::shared_ptr<IAlgorithm> AlgorithmHistory::createAlgorithm() const {
Dickon Champion's avatar
Dickon Champion committed
    Standard Assignment operator
    @param A :: AlgorithmHistory Item to assign to 'this'
AlgorithmHistory &AlgorithmHistory::operator=(const AlgorithmHistory &A) {
  if (this != &A) {
    m_name = A.m_name;
    m_version = A.m_version;
    m_executionDate = A.m_executionDate;
    m_executionDuration = A.m_executionDuration;
    m_properties = A.m_properties;
    // required to prevent destruction of descendant if assigning a descendant
    // to an ancestor
    auto temp = A.m_childHistories;
    m_childHistories = temp;
    m_uuid = A.m_uuid;
 * @param os :: The ouput stream to write to
 * @param AH :: The AlgorithmHistory to output
std::ostream &operator<<(std::ostream &os, const AlgorithmHistory &AH) {
/** Write out this history record to file.
 * @param file :: The handle to the nexus file to save to
 * @param algCount :: Counter of the number of algorithms written to file.
 */
void AlgorithmHistory::saveNexus(::NeXus::File *file, int &algCount) const {
  std::stringstream algNumber;
  ++algCount;
  algNumber << "MantidAlgorithm_"
            << algCount; // history entry names start at 1 not 0

  std::stringstream algData;
  printSelf(algData);

  file->makeGroup(algNumber.str(), "NXnote", true);
  file->writeData("author", std::string("mantid"));
  file->writeData("description", std::string("Mantid Algorithm data"));
  file->writeData("data", algData.str());

  // child algorithms
  for (auto &history : m_childHistories) {
    history->saveNexus(file, algCount);