void vtkDataSetToNonOrthogonalDataSet::execute() {
  // Downcast to a vtkUnstructuredGrid
  vtkUnstructuredGrid *data = vtkUnstructuredGrid::SafeDownCast(m_dataSet);
  if (NULL == data)
  {
    throw std::runtime_error("VTK dataset does not inherit from vtkPointSet");
  }

  // Get the workspace from the ADS
  ADSWorkspaceProvider<API::IMDWorkspace> workspaceProvider;
  API::Workspace_sptr ws = workspaceProvider.fetchWorkspace(m_wsName);
  std::string wsType = ws->id();

  Geometry::OrientedLattice oLatt;
  std::vector<double> wMatArr;
  Kernel::Matrix<coord_t> affMat;

  // Have to cast since inherited class doesn't provide access to all info
  if (boost::algorithm::find_first(wsType, "MDHistoWorkspace")) {
    API::IMDHistoWorkspace_const_sptr infoWs =
        boost::dynamic_pointer_cast<const API::IMDHistoWorkspace>(ws);

    m_boundingBox[0] = infoWs->getDimension(0)->getMinimum();
    m_boundingBox[1] = infoWs->getDimension(0)->getMaximum();
    m_boundingBox[2] = infoWs->getDimension(1)->getMinimum();
    m_boundingBox[3] = infoWs->getDimension(1)->getMaximum();
    m_boundingBox[4] = infoWs->getDimension(2)->getMinimum();
    m_boundingBox[5] = infoWs->getDimension(2)->getMaximum();

    m_numDims = infoWs->getNumDims();
    m_coordType = infoWs->getSpecialCoordinateSystem();
    if (Kernel::HKL != m_coordType) {
      throw std::invalid_argument(
          "Cannot create non-orthogonal view for non-HKL coordinates");
    }
    const API::Sample sample = infoWs->getExperimentInfo(0)->sample();
    if (!sample.hasOrientedLattice()) {
      throw std::invalid_argument(
          "OrientedLattice is not present on workspace");
    }
    oLatt = sample.getOrientedLattice();
    const API::Run run = infoWs->getExperimentInfo(0)->run();
    if (!run.hasProperty("W_MATRIX")) {
      throw std::invalid_argument("W_MATRIX is not present on workspace");
    }
    wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX");
    try {
      API::CoordTransform const * transform = infoWs->getTransformToOriginal();
      affMat = transform->makeAffineMatrix();
    } catch (std::runtime_error &) {
      // Create identity matrix of dimension+1
      std::size_t nDims = infoWs->getNumDims() + 1;
      Kernel::Matrix<coord_t> temp(nDims, nDims, true);
      affMat = temp;
    }
  }
  // This is only here to make the unit test run.
  if (boost::algorithm::find_first(wsType, "MDEventWorkspace")) {
    API::IMDEventWorkspace_const_sptr infoWs =
        boost::dynamic_pointer_cast<const API::IMDEventWorkspace>(ws);
    m_numDims = infoWs->getNumDims();
    m_coordType = infoWs->getSpecialCoordinateSystem();
    if (Kernel::HKL != m_coordType) {
      throw std::invalid_argument(
          "Cannot create non-orthogonal view for non-HKL coordinates");
    }
    const API::Sample sample = infoWs->getExperimentInfo(0)->sample();
    if (!sample.hasOrientedLattice()) {
      throw std::invalid_argument(
          "OrientedLattice is not present on workspace");
    }
    oLatt = sample.getOrientedLattice();
    const API::Run run = infoWs->getExperimentInfo(0)->run();
    if (!run.hasProperty("W_MATRIX")) {
      throw std::invalid_argument("W_MATRIX is not present on workspace");
    }
    wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX");
    try {
      API::CoordTransform const *transform = infoWs->getTransformToOriginal();
      affMat = transform->makeAffineMatrix();
    } catch (std::runtime_error &) {
      // Create identity matrix of dimension+1
      std::size_t nDims = infoWs->getNumDims() + 1;
      Kernel::Matrix<coord_t> temp(nDims, nDims, true);
      affMat = temp;
    }
  }
  Kernel::DblMatrix wTrans(wMatArr);
  this->createSkewInformation(oLatt, wTrans, affMat);

  // Get the original points
  vtkPoints *points = data->GetPoints();
  double outPoint[3];
  vtkPoints *newPoints = vtkPoints::New();
  newPoints->Allocate(points->GetNumberOfPoints());

  /// Put together the skew matrix for use
  double skew[9];

  // Create from the internal skew matrix
  std::size_t index = 0;
  for (std::size_t i = 0; i < m_skewMat.numRows(); i++) {
    for (std::size_t j = 0; j < m_skewMat.numCols(); j++) {
      skew[index] = m_skewMat[i][j];
      index++;
    }
  }

  for (int i = 0; i < points->GetNumberOfPoints(); i++) {
    double *inPoint = points->GetPoint(i);
    vtkMatrix3x3::MultiplyPoint(skew, inPoint, outPoint);
    newPoints->InsertNextPoint(outPoint);
  }
  data->SetPoints(newPoints);
  this->updateMetaData(data);
}
void vtkDataSetToNonOrthogonalDataSet::execute() {
  // Downcast to a vtkPointSet
  vtkPointSet *data = vtkPointSet::SafeDownCast(m_dataSet);
  if (NULL == data) {
    throw std::runtime_error("VTK dataset does not inherit from vtkPointSet");
  }

  // Get the workspace from the ADS
  ADSWorkspaceProvider<API::IMDWorkspace> workspaceProvider;
  API::Workspace_sptr ws = workspaceProvider.fetchWorkspace(m_wsName);
  std::string wsType = ws->id();

  Geometry::OrientedLattice oLatt;
  std::vector<double> wMatArr;
  Kernel::Matrix<coord_t> affMat;

  // Have to cast since inherited class doesn't provide access to all info
  if (boost::algorithm::find_first(wsType, "MDHistoWorkspace")) {
    API::IMDHistoWorkspace_const_sptr infoWs =
        boost::dynamic_pointer_cast<const API::IMDHistoWorkspace>(ws);

    m_boundingBox[0] = infoWs->getXDimension()->getMinimum();
    m_boundingBox[1] = infoWs->getXDimension()->getMaximum();
    m_boundingBox[2] = infoWs->getYDimension()->getMinimum();
    m_boundingBox[3] = infoWs->getYDimension()->getMaximum();
    m_boundingBox[4] = infoWs->getZDimension()->getMinimum();
    m_boundingBox[5] = infoWs->getZDimension()->getMaximum();

    m_numDims = infoWs->getNumDims();
    m_coordType = infoWs->getSpecialCoordinateSystem();
    if (Kernel::HKL != m_coordType) {
      throw std::invalid_argument(
          "Cannot create non-orthogonal view for non-HKL coordinates");
    }
    const API::Sample sample = infoWs->getExperimentInfo(0)->sample();
    if (!sample.hasOrientedLattice()) {
      throw std::invalid_argument(
          "OrientedLattice is not present on workspace");
    }
    oLatt = sample.getOrientedLattice();
    const API::Run run = infoWs->getExperimentInfo(0)->run();
    if (!run.hasProperty("W_MATRIX")) {
      throw std::invalid_argument("W_MATRIX is not present on workspace");
    }
    wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX");
    try {
      API::CoordTransform const *transform = infoWs->getTransformToOriginal();
      affMat = transform->makeAffineMatrix();
    } catch (std::runtime_error &) {
      // Create identity matrix of dimension+1
      std::size_t nDims = infoWs->getNumDims() + 1;
      Kernel::Matrix<coord_t> temp(nDims, nDims, true);
      affMat = temp;
    }
  }
  // This is only here to make the unit test run.
  if (boost::algorithm::find_first(wsType, "MDEventWorkspace")) {
    API::IMDEventWorkspace_const_sptr infoWs =
        boost::dynamic_pointer_cast<const API::IMDEventWorkspace>(ws);

    m_boundingBox[0] = infoWs->getXDimension()->getMinimum();
    m_boundingBox[1] = infoWs->getXDimension()->getMaximum();
    m_boundingBox[2] = infoWs->getYDimension()->getMinimum();
    m_boundingBox[3] = infoWs->getYDimension()->getMaximum();
    m_boundingBox[4] = infoWs->getZDimension()->getMinimum();
    m_boundingBox[5] = infoWs->getZDimension()->getMaximum();

    m_numDims = infoWs->getNumDims();
    m_coordType = infoWs->getSpecialCoordinateSystem();
    if (Kernel::HKL != m_coordType) {
      throw std::invalid_argument(
          "Cannot create non-orthogonal view for non-HKL coordinates");
    }
    const API::Sample sample = infoWs->getExperimentInfo(0)->sample();
    if (!sample.hasOrientedLattice()) {
      throw std::invalid_argument(
          "OrientedLattice is not present on workspace");
    }
    oLatt = sample.getOrientedLattice();
    const API::Run run = infoWs->getExperimentInfo(0)->run();
    if (!run.hasProperty("W_MATRIX")) {
      throw std::invalid_argument("W_MATRIX is not present on workspace");
    }
    wMatArr = run.getPropertyValueAsType<std::vector<double>>("W_MATRIX");
    try {
      API::CoordTransform const *transform = infoWs->getTransformToOriginal();
      affMat = transform->makeAffineMatrix();
    } catch (std::runtime_error &) {
      // Create identity matrix of dimension+1
      std::size_t nDims = infoWs->getNumDims() + 1;
      Kernel::Matrix<coord_t> temp(nDims, nDims, true);
      affMat = temp;
    }
  }
  Kernel::DblMatrix wTrans(wMatArr);
  this->createSkewInformation(oLatt, wTrans, affMat);

  /// Put together the skew matrix for use
  Mantid::coord_t skew[9];

  // Create from the internal skew matrix
  std::size_t index = 0;
  for (std::size_t i = 0; i < m_skewMat.numRows(); i++) {
    for (std::size_t j = 0; j < m_skewMat.numCols(); j++) {
      skew[index] = static_cast<Mantid::coord_t>(m_skewMat[i][j]);
      index++;
    }
  }

  // Get the original points
  vtkFloatArray *points =
      vtkFloatArray::SafeDownCast(data->GetPoints()->GetData());
  if (points == NULL) {
    throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray.");
  } else if (points->GetNumberOfComponents() != 3) {
    throw std::runtime_error("points array must have 3 components.");
  }

  float *end = points->GetPointer(points->GetNumberOfTuples() * 3);
  for (float *it = points->GetPointer(0); it < end; std::advance(it, 3)) {
    float v1 = it[0];
    float v2 = it[1];
    float v3 = it[2];
    it[0] = v1 * skew[0] + v2 * skew[1] + v3 * skew[2];
    it[1] = v1 * skew[3] + v2 * skew[4] + v3 * skew[5];
    it[2] = v1 * skew[6] + v2 * skew[7] + v3 * skew[8];
  }
  this->updateMetaData(data);
}