Skip to content
Snippets Groups Projects
CompareWorkspaces.cpp 42.2 KiB
Newer Older
    sortPeaks->setProperty("ColumnNameToSortBy", "DSpacing");
    sortPeaks->setProperty("SortAscending", true);
    sortPeaks->executeAsChildAlg();
    tws2 = sortPeaks->getProperty("OutputWorkspace");
  }

  const double tolerance = getProperty("Tolerance");
  for (int i = 0; i < tws1->getNumberPeaks(); i++) {
    const IPeak &peak1 = tws1->getPeak(i);
    const IPeak &peak2 = tws2->getPeak(i);
    for (size_t j = 0; j < tws1->columnCount(); j++) {
      boost::shared_ptr<const API::Column> col = tws1->getColumn(j);
      std::string name = col->name();
      double s1 = 0.0;
      double s2 = 0.0;
      if (name == "runnumber") {
        s1 = double(peak1.getRunNumber());
        s2 = double(peak2.getRunNumber());
      } else if (name == "detid") {
        s1 = double(peak1.getDetectorID());
        s2 = double(peak2.getDetectorID());
      } else if (name == "h") {
        s1 = peak1.getH();
        s2 = peak2.getH();
      } else if (name == "k") {
        s1 = peak1.getK();
        s2 = peak2.getK();
      } else if (name == "l") {
        s1 = peak1.getL();
        s2 = peak2.getL();
      } else if (name == "wavelength") {
        s1 = peak1.getWavelength();
        s2 = peak2.getWavelength();
      } else if (name == "energy") {
        s1 = peak1.getInitialEnergy();
        s2 = peak2.getInitialEnergy();
      } else if (name == "tof") {
        s1 = peak1.getTOF();
        s2 = peak2.getTOF();
      } else if (name == "dspacing") {
        s1 = peak1.getDSpacing();
        s2 = peak2.getDSpacing();
      } else if (name == "intens") {
        s1 = peak1.getIntensity();
        s2 = peak2.getIntensity();
      } else if (name == "sigint") {
        s1 = peak1.getSigmaIntensity();
        s2 = peak2.getSigmaIntensity();
      } else if (name == "bincount") {
        s1 = peak1.getBinCount();
        s2 = peak2.getBinCount();
      } else if (name == "row") {
        s1 = peak1.getRow();
        s2 = peak2.getRow();
      } else if (name == "col") {
        s1 = peak1.getCol();
        s2 = peak2.getCol();
      }
      if (std::fabs(s1 - s2) > tolerance) {
        g_log.debug() << "Data mismatch at cell (row#,col#): (" << i << "," << j
                      << ")\n";
        recordMismatch("Data mismatch");
//------------------------------------------------------------------------------------------------
void CompareWorkspaces::doTableComparison(
    API::ITableWorkspace_const_sptr tws1,
    API::ITableWorkspace_const_sptr tws2) {
  // First the easy things
  const auto numCols = tws1->columnCount();
  if (numCols != tws2->columnCount()) {
    g_log.debug() << "Number of columns mismatch (" << numCols << " vs "
                  << tws2->columnCount() << ")\n";
    recordMismatch("Number of columns mismatch");
    return;
  }
  const auto numRows = tws1->rowCount();
  if (numRows != tws2->rowCount()) {
    g_log.debug() << "Number of rows mismatch (" << numRows << " vs "
                  << tws2->rowCount() << ")\n";
    recordMismatch("Number of rows mismatch");
    return;
  }

  for (size_t i = 0; i < numCols; ++i) {
    auto c1 = tws1->getColumn(i);
    auto c2 = tws2->getColumn(i);

    if (c1->name() != c2->name()) {
      g_log.debug() << "Column name mismatch at column " << i << " ("
                    << c1->name() << " vs " << c2->name() << ")\n";
      recordMismatch("Column name mismatch");
      return;
    }
    if (c1->type() != c2->type()) {
      g_log.debug() << "Column type mismatch at column " << i << " ("
                    << c1->type() << " vs " << c2->type() << ")\n";
      recordMismatch("Column type mismatch");
      return;
    }
  }

  const bool checkAllData = getProperty("CheckAllData");

  for (size_t i = 0; i < numRows; ++i) {
    const TableRow r1 =
        boost::const_pointer_cast<ITableWorkspace>(tws1)->getRow(i);
    const TableRow r2 =
        boost::const_pointer_cast<ITableWorkspace>(tws2)->getRow(i);
    // Easiest, if not the fastest, way to compare is via strings
    std::stringstream r1s, r2s;
    r1s << r1;
    r2s << r2;
    if (r1s.str() != r2s.str()) {
      g_log.debug() << "Table data mismatch at row " << i << " (" << r1s.str()
                    << " vs " << r2s.str() << ")\n";
      recordMismatch("Table data mismatch");
      if (!checkAllData)
        return;
    }
  } // loop over columns
}

//------------------------------------------------------------------------------------------------
void CompareWorkspaces::doMDComparison(Workspace_sptr w1, Workspace_sptr w2) {
  IMDWorkspace_sptr mdws1, mdws2;
  mdws1 = boost::dynamic_pointer_cast<IMDWorkspace>(w1);
  mdws2 = boost::dynamic_pointer_cast<IMDWorkspace>(w2);

  IAlgorithm_sptr alg = this->createChildAlgorithm("CompareMDWorkspaces");
  alg->setProperty<IMDWorkspace_sptr>("Workspace1", mdws1);
  alg->setProperty<IMDWorkspace_sptr>("Workspace2", mdws2);
  const double tolerance = getProperty("Tolerance");
  alg->setProperty("Tolerance", tolerance);
  alg->executeAsChildAlg();
  bool doesMatch = alg->getProperty("Equals");
  std::string algResult = alg->getProperty("Result");
  if (!doesMatch) {
//------------------------------------------------------------------------------------------------
/**
 * Records a mismatch that has occurred in the output workspace and sets the
 * Result to indicate that the input workspaces did not match.
 *
 * @param msg Mismatch message to be logged in output workspace
void CompareWorkspaces::recordMismatch(std::string msg) {
  TableRow row = m_Messages->appendRow();
//------------------------------------------------------------------------------------------------
/** Function which calculates relative error between two values and analyses if
this error is within the limits
* requested. When the absolute value of the difference is smaller then the value
of the error requested,
* absolute error is used instead of relative error.

@param x1       -- first value to check difference
@param x2       -- second value to check difference
@param errorVal -- the value of the error, to check against. Should  be large
then 0

@returns true if error or false if the value is within the limits requested
*/
bool CompareWorkspaces::relErr(double x1, double x2, double errorVal) const {
  double num = std::fabs(x1 - x2);
  // how to treat x1<0 and x2 > 0 ?  probably this way
  double den = 0.5 * (std::fabs(x1) + std::fabs(x2));
  if (den < errorVal)
    return (num > errorVal);

  return (num / den > errorVal);
}

} // namespace Algorithms
} // namespace Mantid