/** Opens a group called "process" and loads the workspace history from
 * it.
 *
 * @param file :: previously opened NXS file.
 */
void WorkspaceHistory::loadNexus(::NeXus::File * file)
{
    /// specifies the order that algorithm data is listed in workspaces' histories
    enum AlgorithmHist
    {
        NAME = 0,                          //< algorithms name
        EXEC_TIME = 1,                     //< when the algorithm was run
        EXEC_DUR = 2,                      //< execution time for the algorithm
        PARAMS = 3                         //< the algorithm's parameters
    };


    // Warn but continue if the group does not exist.
    try
    {
        file->openGroup("process", "NXprocess");
    }
    catch (std::exception & )
    {
        g_log.warning() << "Error opening the algorithm history field 'process'. Workspace will have no history." << "\n";
        return;
    }
    std::map<std::string, std::string> entries;
    file->getEntries(entries);


    // Histories are numberd MantidAlgorithm_0, ..., MantidAlgorithm_10, etc.
    // Find all the unique numbers
    std::set<int> historyNumbers;
    for (auto it = entries.begin(); it != entries.end(); ++it)
    {
        std::string entryName = it->first;
        if( entryName.find("MantidAlgorithm_") != std::string::npos )
        {
            // Just get the number
            entryName = entryName.substr(16, entryName.size()-16);
            int num=-1;
            if (Kernel::Strings::convert(entryName, num))
                historyNumbers.insert(num);
        }
    }

    // historyNumbers should be sorted by number
    for (auto it = historyNumbers.begin(); it != historyNumbers.end(); ++it)
    {
        std::string entryName = "MantidAlgorithm_" + Kernel::Strings::toString(*it);
        file->openGroup(entryName, "NXnote");
        std::string rawData;
        file->readData("data", rawData);
        file->closeGroup();

        // Split into separate lines
        std::vector<std::string> info;
        boost::split(info, rawData, boost::is_any_of("\n"));

        const size_t nlines = info.size();
        if( nlines < 4 )
        {   // ignore badly formed history entries
            continue;
        }

        std::string algName, dummy, temp;
        // get the name and version of the algorithm
        getWordsInString(info[NAME], dummy, algName, temp);

        //Chop of the v from the version string
        size_t numStart = temp.find('v');
        // this doesn't abort if the version string doesn't contain a v
        numStart = numStart != 1 ? 1 : 0;
        temp = std::string(temp.begin() + numStart, temp.end());
        const int version = boost::lexical_cast<int>(temp);

        //Get the execution date/time
        std::string date, time;
        getWordsInString(info[EXEC_TIME], dummy, dummy, date, time);
        Poco::DateTime start_timedate;
        //This is needed by the Poco parsing function
        int tzdiff(-1);
        if( !Poco::DateTimeParser::tryParse("%Y-%b-%d %H:%M:%S", date + " " + time, start_timedate, tzdiff))
        {
            g_log.warning() << "Error parsing start time in algorithm history entry." << "\n";
            file->closeGroup();
            return;
        }
        //Get the duration
        getWordsInString(info[EXEC_DUR], dummy, dummy, temp, dummy);
        double dur = boost::lexical_cast<double>(temp);
        if ( dur < 0.0 )
        {
            g_log.warning() << "Error parsing start time in algorithm history entry." << "\n";
            file->closeGroup();
            return;
        }
        //Convert the timestamp to time_t to DateAndTime
        Mantid::Kernel::DateAndTime utc_start;
        utc_start.set_from_time_t( start_timedate.timestamp().epochTime() );
        //Create the algorithm history
        API::AlgorithmHistory alg_hist(algName, version, utc_start, dur,Algorithm::g_execCount);
        // Simulate running an algorithm
        ++Algorithm::g_execCount;

        //Add property information
        for( size_t index = static_cast<size_t>(PARAMS)+1; index < nlines; ++index )
        {
            const std::string line = info[index];
            std::string::size_type colon = line.find(":");
            std::string::size_type comma = line.find(",");
            //Each colon has a space after it
            std::string prop_name = line.substr(colon + 2, comma - colon - 2);
            colon = line.find(":", comma);
            comma = line.find(", Default?", colon);
            std::string prop_value = line.substr(colon + 2, comma - colon - 2);
            colon = line.find(":", comma);
            comma = line.find(", Direction", colon);
            std::string is_def = line.substr(colon + 2, comma - colon - 2);
            colon = line.find(":", comma);
            comma = line.find(",", colon);
            std::string direction = line.substr(colon + 2, comma - colon - 2);
            unsigned int direc(Mantid::Kernel::Direction::asEnum(direction));
            alg_hist.addProperty(prop_name, prop_value, (is_def[0] == 'Y'), direc);
        }
        this->addHistory(alg_hist);
    }

    file->closeGroup();
}
Exemple #2
0
/**
 * Read the algorithm history from the "mantid_workspace_i/process" group
 * @param mtd_entry :: The node for the current workspace
 * @param local_workspace :: The workspace to attach the history to
 *  @throw out_of_range an algorithm history entry doesn't have the excepted number of entries
 */
void LoadNexusProcessed::readAlgorithmHistory(NXEntry & mtd_entry, API::MatrixWorkspace_sptr local_workspace)
{
  int exeCount=0;
  NXMainClass history = mtd_entry.openNXClass<NXMainClass>("process");
  //Group will contain a class for each algorithm, called MantidAlgorithm_i and then an
  //environment class
  //const std::vector<NXClassInfo> & classes = history.groups();
  std::vector<NXClassInfo>&  classes = history.groups();
  //sort by execution order - to execute the script generated by algorithmhistory in proper order
  sort(classes.begin(),classes.end(),UDlesserExecCount);
  std::vector<NXClassInfo>::const_iterator iend = classes.end();
  for( std::vector<NXClassInfo>::const_iterator itr = classes.begin(); itr != iend; ++itr )
  {
    if( itr->nxname.find("MantidAlgorithm") != std::string::npos )
    {
      NXNote entry(history,itr->nxname);
      entry.openLocal();
      const std::vector<std::string> & info = entry.data();
      const size_t nlines = info.size();
      if( nlines < 4 )
      {// ignore badly formed history entries
        continue;
      }

      std::string algName, dummy, temp;
      // get the name and version of the algorithm
      getWordsInString(info[NAME], dummy, algName, temp);

      //Chop of the v from the version string
      size_t numStart = temp.find('v');
      // this doesn't abort if the version string doesn't contain a v
      numStart = numStart != 1 ? 1 : 0;
      temp = std::string(temp.begin() + numStart, temp.end());
      const int version = boost::lexical_cast<int>(temp);

      //Get the execution date/time
      std::string date, time;
      getWordsInString(info[EXEC_TIME], dummy, dummy, date, time);
      Poco::DateTime start_timedate;
      //This is needed by the Poco parsing function
      int tzdiff(-1);
      if( !Poco::DateTimeParser::tryParse(Mantid::NeXus::g_processed_datetime, date + " " + time, start_timedate, tzdiff))
      {
        g_log.warning() << "Error parsing start time in algorithm history entry." << "\n";
        return;
      }
      //Get the duration
      getWordsInString(info[EXEC_DUR], dummy, dummy, temp, dummy);
      double dur = boost::lexical_cast<double>(temp);
      if ( dur < 0.0 )
      {
        g_log.warning() << "Error parsing start time in algorithm history entry." << "\n";
        return;
      }
      //API::AlgorithmHistory alg_hist(algname, version, start_timedate.timestamp().epochTime(), dur);

      ++exeCount;
      //Convert the timestamp to time_t to DateAndTime
      Mantid::Kernel::DateAndTime utc_start;
      utc_start.set_from_time_t( start_timedate.timestamp().epochTime() );
      //Create the algorithm history
      API::AlgorithmHistory alg_hist(algName, version, utc_start, dur,exeCount);

      //Add property information
      for( size_t index = static_cast<size_t>(PARAMS)+1;index < nlines;++index )
      {
        const std::string line = info[index];
        std::string::size_type colon = line.find(":");
        std::string::size_type comma = line.find(",");
        //Each colon has a space after it
        std::string prop_name = line.substr(colon + 2, comma - colon - 2);
        colon = line.find(":", comma);
        comma = line.find(",", colon);
        std::string prop_value = line.substr(colon + 2, comma - colon - 2);
        colon = line.find(":", comma);
        comma = line.find(",", colon);
        std::string is_def = line.substr(colon + 2, comma - colon - 2);
        colon = line.find(":", comma);
        comma = line.find(",", colon);
        std::string direction = line.substr(colon + 2, comma - colon - 2);
        unsigned int direc(Mantid::Kernel::Direction::asEnum(direction));
        alg_hist.addProperty(prop_name, prop_value, (is_def[0] == 'Y'), direc);
      }
      local_workspace->history().addHistory(alg_hist);
      entry.close();
    }
  }

}
Exemple #3
0
/** Parse an algorithm history entry loaded from file.
 * @param rawData :: The string containing the history entry loaded from file
 * @returns a pointer to the loaded algorithm history object
 * @throws std::runtime_error if the loaded data could not be parsed
 */
AlgorithmHistory_sptr
WorkspaceHistory::parseAlgorithmHistory(const std::string &rawData) {
  /// specifies the order that algorithm data is listed in workspaces' histories
  enum AlgorithmHist {
    NAME = 0,      //< algorithms name
    EXEC_TIME = 1, //< when the algorithm was run
    EXEC_DUR = 2,  //< execution time for the algorithm
    PARAMS = 3     //< the algorithm's parameters
  };

  std::vector<std::string> info;
  boost::split(info, rawData, boost::is_any_of("\n"));

  const size_t nlines = info.size();
  if (nlines < 4) { // ignore badly formed history entries
    throw std::runtime_error(
        "Malformed history record: Incorrect record size.");
  }

  std::string algName, dummy, temp;
  // get the name and version of the algorithm
  getWordsInString(info[NAME], dummy, algName, temp);

  // Chop of the v from the version string
  size_t numStart = temp.find('v');
  // this doesn't abort if the version string doesn't contain a v
  numStart = numStart != 1 ? 1 : 0;
  temp = std::string(temp.begin() + numStart, temp.end());
  const int version = boost::lexical_cast<int>(temp);

  // Get the execution date/time
  std::string date, time;
  getWordsInString(info[EXEC_TIME], dummy, dummy, date, time);
  Poco::DateTime start_timedate;
  // This is needed by the Poco parsing function
  int tzdiff(-1);
  Mantid::Types::Core::DateAndTime utc_start;
  if (!Poco::DateTimeParser::tryParse("%Y-%b-%d %H:%M:%S", date + " " + time,
                                      start_timedate, tzdiff)) {
    g_log.warning() << "Error parsing start time in algorithm history entry."
                    << "\n";
    utc_start = Types::Core::DateAndTime::defaultTime();
  }
  // Get the duration
  getWordsInString(info[EXEC_DUR], dummy, dummy, temp, dummy);
  double dur = boost::lexical_cast<double>(temp);
  if (dur < -1.0) {
    g_log.warning() << "Error parsing duration in algorithm history entry."
                    << "\n";
    dur = -1.0;
  }
  // Convert the timestamp to time_t to DateAndTime
  utc_start.set_from_time_t(start_timedate.timestamp().epochTime());
  // Create the algorithm history
  API::AlgorithmHistory alg_hist(algName, version, utc_start, dur,
                                 Algorithm::g_execCount);
  // Simulate running an algorithm
  ++Algorithm::g_execCount;

  // Add property information
  for (size_t index = static_cast<size_t>(PARAMS) + 1; index < nlines;
       ++index) {
    const std::string line = info[index];
    std::string::size_type colon = line.find(':');
    std::string::size_type comma = line.find(',');
    // Each colon has a space after it
    std::string prop_name = line.substr(colon + 2, comma - colon - 2);
    colon = line.find(':', comma);
    comma = line.find(", Default?", colon);
    std::string prop_value = line.substr(colon + 2, comma - colon - 2);
    colon = line.find(':', comma);
    comma = line.find(", Direction", colon);
    std::string is_def = line.substr(colon + 2, comma - colon - 2);
    colon = line.find(':', comma);
    comma = line.find(',', colon);
    std::string direction = line.substr(colon + 2, comma - colon - 2);
    unsigned int direc(Mantid::Kernel::Direction::asEnum(direction));
    alg_hist.addProperty(prop_name, prop_value, (is_def[0] == 'Y'), direc);
  }

  AlgorithmHistory_sptr history =
      boost::make_shared<AlgorithmHistory>(alg_hist);
  return history;
}