Skip to content
Snippets Groups Projects
MDFramesToSpecialCoordinateSystem.cpp 3.66 KiB
Newer Older
#include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidKernel/WarningSuppressions.h"

namespace Mantid {
namespace DataObjects {

MDFramesToSpecialCoordinateSystem::MDFramesToSpecialCoordinateSystem() {}

MDFramesToSpecialCoordinateSystem::~MDFramesToSpecialCoordinateSystem() {}

// Need to turn off the warnings because of boost optional being used.
// clang-format off
GCC_DIAG_OFF(cast-qual)
// clang-format on
GCC_DIAG_OFF(maybe-uninitialized)
 * Get the Special Coordinate System based on the MDFrame information.
 * @param workspace: the workspace which is being queried
 * @returns either a special coordinate or an empty optional
boost::optional<Mantid::Kernel::SpecialCoordinateSystem>
    MDFramesToSpecialCoordinateSystem::
    operator()(const Mantid::API::IMDWorkspace *workspace) const {
  // Make sure that the workspaces are either an MDHisto or MDEvent workspaces
  if (!dynamic_cast<const Mantid::API::IMDEventWorkspace *>(workspace) &&
      !dynamic_cast<const Mantid::API::IMDHistoWorkspace *>(workspace)) {
    throw std::invalid_argument("Error in MDFrameFromWorkspace: Can only "
                                "extract MDFrame from MDEvent and MDHisto "
                                "workspaces");
  }

  // Requirements for the special coordinate are: If there are more than one
  // Q-compatible (QSample, QLab, HKL) dimension, then they have to be identical
  // This dimension will define the special coordinate system. Otherwise, we
  // don't have a special coordinate system

  boost::optional<Mantid::Kernel::SpecialCoordinateSystem> qFrameType;
  for (size_t dimIndex = 0; dimIndex < workspace->getNumDims(); ++dimIndex) {
    auto dimension = workspace->getDimension(dimIndex);
    auto &frame = dimension->getMDFrame();
    // Check for QCompatibility
    if (frame.getMDUnit().isQUnit()) {
      auto specialCoordinteSystem = frame.equivalientSpecialCoordinateSystem();
      checkQCompatibility(specialCoordinteSystem, qFrameType);
      qFrameType = specialCoordinteSystem;
    isUnknown = isUnknownFrame(dimension);
  }

  boost::optional<Mantid::Kernel::SpecialCoordinateSystem> output;
  if (qFrameType) {
    output = qFrameType;
  } else {
    // If the frame is unknown then keep the optional empty
    if (!isUnknown) {
      output = Mantid::Kernel::SpecialCoordinateSystem::None;
    }
GCC_DIAG_ON(maybe-uninitialized)
// clang-format off
GCC_DIAG_ON(cast-qual)
// clang-format on
 * Make sure that the QFrame types are the same.
 * @param specialCoordinateSystem: the q frame type to test.
 * @param qFrameType: the current q frame type
void MDFramesToSpecialCoordinateSystem::checkQCompatibility(
    Mantid::Kernel::SpecialCoordinateSystem specialCoordinateSystem,
    boost::optional<Mantid::Kernel::SpecialCoordinateSystem> qFrameType) const {
  if (qFrameType) {
    if (specialCoordinateSystem != qFrameType.get()) {
      throw std::invalid_argument("Error in MDFrameFromWorkspace: Coordinate "
                                  "system in the different dimensions don't "
                                  "match.");
    }
  }
/* Checks if an MDFrame is an UnknownFrame
* @param dimension: a dimension
* @returns true if the MDFrame is of UnknownFrame type.
*/
bool MDFramesToSpecialCoordinateSystem::isUnknownFrame(
    Mantid::Geometry::IMDDimension_const_sptr dimension) const {
  Mantid::Geometry::MDFrame_uptr replica(dimension->getMDFrame().clone());
  auto isUnknown = false;
  if (dynamic_cast<Mantid::Geometry::UnknownFrame *>(replica.get())) {
    isUnknown = true;
  }
  return isUnknown;
}