/** Parse profile table workspace to a map (the new ...
  */
void SaveGSASInstrumentFile::parseProfileTableWorkspace(
    ITableWorkspace_sptr ws,
    map<unsigned int, map<string, double>> &profilemap) {
  size_t numbanks = ws->columnCount() - 1;
  size_t numparams = ws->rowCount();
  vector<map<string, double>> vec_maptemp(numbanks);
  vector<unsigned int> vecbankindex(numbanks);

  // Check
  vector<string> colnames = ws->getColumnNames();
  if (colnames[0].compare("Name"))
    throw runtime_error("The first column must be Name");

  // Parse
  for (size_t irow = 0; irow < numparams; ++irow) {
    TableRow tmprow = ws->getRow(irow);
    string parname;
    tmprow >> parname;
    if (parname.compare("BANK")) {
      for (size_t icol = 0; icol < numbanks; ++icol) {
        double tmpdbl;
        tmprow >> tmpdbl;
        vec_maptemp[icol].insert(make_pair(parname, tmpdbl));
      }
    } else {
      for (size_t icol = 0; icol < numbanks; ++icol) {
        double tmpint;
        tmprow >> tmpint;
        vecbankindex[icol] = static_cast<unsigned int>(tmpint);
      }
    }
  }
/** Constructor
@param tableWorkspace : The table workspace to wrap
@param whitelist : A DataProcessorWhiteList containing the columns
*/
QDataProcessorOneLevelTreeModel::QDataProcessorOneLevelTreeModel(
    ITableWorkspace_sptr tableWorkspace,
    const DataProcessorWhiteList &whitelist)
    : m_tWS(tableWorkspace), m_whitelist(whitelist) {

  if (tableWorkspace->columnCount() != m_whitelist.size())
    throw std::invalid_argument(
        "Invalid table workspace. Table workspace must "
        "have the same number of columns as the white list");
}
/** Constructor
@param tableWorkspace : The table workspace to wrap
@param whitelist : A DataProcessorWhiteList containing information about the
columns, their indices and descriptions
*/
QDataProcessorTreeModel::QDataProcessorTreeModel(
    ITableWorkspace_sptr tableWorkspace,
    const DataProcessorWhiteList &whitelist)
    : m_tWS(tableWorkspace), m_whitelist(whitelist) {

  if (tableWorkspace->columnCount() != m_whitelist.size() + 1)
    throw std::invalid_argument("Invalid table workspace. Table workspace must "
                                "have one extra column accounting for groups");

  setupModelData(tableWorkspace);
}
Example #4
0
/**
*   Executes the algorithm.
*/
void LoadTBL::exec() {
  std::string filename = getProperty("Filename");
  std::ifstream file(filename.c_str());
  if (!file) {
    throw Exception::FileError("Unable to open file: ", filename);
  }
  std::string line;

  ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable();

  std::vector<std::string> columnHeadings;

  Kernel::Strings::extractToEOL(file, line);
  // We want to check if the first line contains an empty string or series of
  // ",,,,,"
  // to see if we are loading a TBL file that actually contains data or not.
  boost::split(columnHeadings, line, boost::is_any_of(","),
               boost::token_compress_off);
  for (auto entry = columnHeadings.begin(); entry != columnHeadings.end();) {
    if (entry->empty()) {
      // erase the empty values
      entry = columnHeadings.erase(entry);
    } else {
      // keep any non-empty values
      ++entry;
    }
  }
  if (columnHeadings.empty()) {
    // we have an empty string or series of ",,,,,"
    throw std::runtime_error("The file you are trying to load is Empty. \n "
                             "Please load a non-empty TBL file");
  } else {
    // set columns back to empty ready to populated with columnHeadings.
    columnHeadings.clear();
  }
  // this will tell us if we need to just fill in the cell values
  // or whether we will have to create the column headings as well.
  bool isOld = getColumnHeadings(line, columnHeadings);

  std::vector<std::string> rowVec;
  if (isOld) {
    /**THIS IS ESSENTIALLY THE OLD LoadReflTBL CODE**/
    // create the column headings
    auto colStitch = ws->addColumn("str", "StitchGroup");
    auto colRuns = ws->addColumn("str", "Run(s)");
    auto colTheta = ws->addColumn("str", "ThetaIn");
    auto colTrans = ws->addColumn("str", "TransRun(s)");
    auto colQmin = ws->addColumn("str", "Qmin");
    auto colQmax = ws->addColumn("str", "Qmax");
    auto colDqq = ws->addColumn("str", "dq/q");
    auto colScale = ws->addColumn("str", "Scale");
    auto colOptions = ws->addColumn("str", "Options");
    auto colHiddenOptions = ws->addColumn("str", "HiddenOptions");

    for (size_t i = 0; i < ws->columnCount(); i++) {
      auto col = ws->getColumn(i);
      col->setPlotType(0);
    }

    // we are using the old ReflTBL format
    // where all of the entries are on one line
    // so we must reset the stream to reread the first line.
    std::ifstream file(filename.c_str());
    if (!file) {
      throw Exception::FileError("Unable to open file: ", filename);
    }
    std::string line;
    int stitchID = 1;
    while (Kernel::Strings::extractToEOL(file, line)) {
      if (line.empty() || line == ",,,,,,,,,,,,,,,,") {
        continue;
      }
      getCells(line, rowVec, 16, isOld);
      const std::string scaleStr = rowVec.at(16);
      const std::string stitchStr = boost::lexical_cast<std::string>(stitchID);

      // check if the first run in the row has any data associated with it
      // 0 = runs, 1 = theta, 2 = trans, 3 = qmin, 4 = qmax
      if (!rowVec[0].empty() || !rowVec[1].empty() || !rowVec[2].empty() ||
          !rowVec[3].empty() || !rowVec[4].empty()) {
        TableRow row = ws->appendRow();
        row << stitchStr;
        for (int i = 0; i < 5; ++i) {
          row << rowVec.at(i);
        }
        row << rowVec.at(15);
        row << scaleStr;
      }

      // check if the second run in the row has any data associated with it
      // 5 = runs, 6 = theta, 7 = trans, 8 = qmin, 9 = qmax
      if (!rowVec[5].empty() || !rowVec[6].empty() || !rowVec[7].empty() ||
          !rowVec[8].empty() || !rowVec[9].empty()) {
        TableRow row = ws->appendRow();
        row << stitchStr;
        for (int i = 5; i < 10; ++i) {
          row << rowVec.at(i);
        }
        row << rowVec.at(15);
        row << scaleStr;
      }

      // check if the third run in the row has any data associated with it
      // 10 = runs, 11 = theta, 12 = trans, 13 = qmin, 14 = qmax
      if (!rowVec[10].empty() || !rowVec[11].empty() || !rowVec[12].empty() ||
          !rowVec[13].empty() || !rowVec[14].empty()) {
        TableRow row = ws->appendRow();
        row << stitchStr;
        for (int i = 10; i < 17; ++i) {
          if (i == 16)
            row << scaleStr;
          else
            row << rowVec.at(i);
        }
      }
      ++stitchID;
      setProperty("OutputWorkspace", ws);
    }

  } else {
    // we have a TBL format that contains column headings
    // on the first row. These are now entries in the columns vector
    if (!columnHeadings.empty()) {
      // now we need to add the custom column headings from
      // the columns vector to the TableWorkspace
      for (auto heading = columnHeadings.begin();
           heading != columnHeadings.end();) {
        if (heading->empty()) {
          // there is no need to have empty column headings.
          heading = columnHeadings.erase(heading);
        } else {
          Mantid::API::Column_sptr col;
          col = ws->addColumn("str", *heading);
          col->setPlotType(0);
          heading++;
        }
      }
    }
    size_t expectedCommas = columnHeadings.size() - 1;
    while (Kernel::Strings::extractToEOL(file, line)) {
      if (line.empty() || line == ",,,,,,,,,,,,,,,,") {
        // skip over any empty lines
        continue;
      }
      getCells(line, rowVec, columnHeadings.size() - 1, isOld);
      // populate the columns with their values for this row.
      TableRow row = ws->appendRow();
      for (size_t i = 0; i < expectedCommas + 1; ++i) {
        row << rowVec.at(i);
      }
    }
    setProperty("OutputWorkspace", ws);
  }
}
/**
 * Write log and parameter values to the table for the case of multiple fits.
 * @param table :: [input, output] Table to write to
 * @param paramsByLabel :: [input] Map of <label name, <workspace name,
 * <parameter, value>>>
 * @param paramsToDisplay :: [input] List of parameters to display in table
 */
void MuonAnalysisResultTableCreator::writeDataForMultipleFits(
    ITableWorkspace_sptr &table,
    const QMap<QString, WSParameterList> &paramsByLabel,
    const QStringList &paramsToDisplay) const {
  assert(m_multiple);
  assert(m_logValues);

  // Add data to table
  for (const auto &labelName : m_items) {
    Mantid::API::TableRow row = table->appendRow();
    size_t columnIndex(0); // Which column we are writing to

    row << labelName.toStdString();
    columnIndex++;

    // Get log values for this row and write in table
    for (const auto &log : m_logs) {
      QStringList valuesPerWorkspace;
      for (const auto &wsName : paramsByLabel[labelName].keys()) {
        const auto &logValues = m_logValues->value(wsName);
        const auto &val = logValues[log];

        auto dashIndex = val.toString().indexOf("-");
        // Special case: if log is time in sec, subtract the first start time
        if (log.endsWith(" (s)")) {
          auto seconds =
              val.toDouble() - static_cast<double>(m_firstStart_ns) * 1.e-9;
          valuesPerWorkspace.append(QString::number(seconds));
        } else if (dashIndex != 0 && dashIndex != -1) {
          valuesPerWorkspace.append(logValues[log].toString());
        } else if (MuonAnalysisHelper::isNumber(val.toString()) &&
                   !log.endsWith(" (text)")) {

          valuesPerWorkspace.append(QString::number(val.toDouble()));

        } else {
          valuesPerWorkspace.append(logValues[log].toString());
        }
      }

      // Range of values - use string comparison as works for numbers too
      // Why not use std::minmax_element? To avoid MSVC warning: QT bug 41092
      // (https://bugreports.qt.io/browse/QTBUG-41092)
      valuesPerWorkspace.sort();

      auto dashIndex =
          valuesPerWorkspace.front().toStdString().find_first_of("-");
      if (dashIndex != std::string::npos && dashIndex != 0) {
        std::ostringstream oss;
        auto dad = valuesPerWorkspace.front().toStdString();
        oss << valuesPerWorkspace.front().toStdString();
        row << oss.str();

      } else {
        if (MuonAnalysisHelper::isNumber(valuesPerWorkspace.front())) {
          const auto &min = valuesPerWorkspace.front().toDouble();
          const auto &max = valuesPerWorkspace.back().toDouble();
          if (min == max) {
            row << min;
          } else {
            std::ostringstream oss;
            oss << valuesPerWorkspace.front().toStdString() << "-"
                << valuesPerWorkspace.back().toStdString();
            row << oss.str();
          }
        } else {
          const auto &front = valuesPerWorkspace.front().toStdString();
          const auto &back = valuesPerWorkspace.back().toStdString();
          if (front == back) {
            row << front;
          } else {
            std::ostringstream oss;
            oss << valuesPerWorkspace[0].toStdString();

            for (int k = 1; k < valuesPerWorkspace.size(); k++) {
              oss << ", " << valuesPerWorkspace[k].toStdString();
              row << oss.str();
            }
          }
        }
      }
      columnIndex++;
    }

    // Parse column name - could be param name or f[n].param
    const auto parseColumnName =
        [&paramsToDisplay](
            const std::string &columnName) -> std::pair<int, std::string> {
      if (paramsToDisplay.contains(QString::fromStdString(columnName))) {
        return {0, columnName};
      } else {
        // column name is f[n].param
        size_t pos = columnName.find_first_of('.');
        if (pos != std::string::npos) {
          try {
            const auto &paramName = columnName.substr(pos + 1);
            const auto wsIndex = std::stoi(columnName.substr(1, pos));
            return {wsIndex, paramName};
          } catch (const std::exception &ex) {
            throw std::runtime_error("Failed to parse column name " +
                                     columnName + ": " + ex.what());
          }
        } else {
          throw std::runtime_error("Failed to parse column name " + columnName);
        }
      }
    };

    // Add param values
    const auto &params = paramsByLabel[labelName];
    while (columnIndex < table->columnCount()) {
      const auto &parsedColName =
          parseColumnName(table->getColumn(columnIndex)->name());
      const QString wsName = params.keys().at(parsedColName.first);
      const QString &paramName = QString::fromStdString(parsedColName.second);
      row << params[wsName].value(paramName);
      columnIndex++;
    }
  }
}