Exemple #1
0
/**
 * Construct the volume encompassing the sample + any environment kit. The
 * beam profile defines a bounding region for the sampling of the scattering
 * position.
 * @param sample A reference to a sample object that defines a valid shape
 * & material
 * @param activeRegion Restrict scattering point sampling to this region
 */
MCInteractionVolume::MCInteractionVolume(
    const API::Sample &sample, const Geometry::BoundingBox &activeRegion)
    : m_sample(sample.getShape()), m_env(nullptr),
      m_activeRegion(activeRegion) {
  if (!m_sample.hasValidShape()) {
    throw std::invalid_argument(
        "MCInteractionVolume() - Sample shape does not have a valid shape.");
  }
  try {
    m_env = &sample.getEnvironment();
    if (m_env->nelements() == 0) {
      throw std::invalid_argument(
          "MCInteractionVolume() - Sample enviroment has zero components.");
    }
  } catch (std::runtime_error &) {
    // swallow this as no defined environment from getEnvironment
  }
}
/// Create the sample object using the Geometry classes, or use the existing one
void AbsorptionCorrection::constructSample(API::Sample &sample) {
  const std::string xmlstring = sampleXML();
  if (xmlstring.empty()) {
    // This means that we should use the shape already defined on the sample.
    m_sampleObject = &sample.getShape();
    // Check there is one, and fail if not
    if (!m_sampleObject->hasValidShape()) {
      const std::string mess(
          "No shape has been defined for the sample in the input workspace");
      g_log.error(mess);
      throw std::invalid_argument(mess);
    }
  } else {
    boost::shared_ptr<IObject> shape = ShapeFactory().createShape(xmlstring);
    sample.setShape(shape);
    m_sampleObject = &sample.getShape();

    g_log.information("Successfully constructed the sample object");
  }
}
Exemple #3
0
/**
 * Compute a region that defines how the beam illuminates the given sample/can
 * @param sample A reference to a sample object holding its shape
 * @return A BoundingBox defining the active region
 */
Geometry::BoundingBox
RectangularBeamProfile::defineActiveRegion(const API::Sample &sample) const {
  auto sampleBox = sample.getShape().getBoundingBox();
  try {
    const auto &envBox = sample.getEnvironment().boundingBox();
    sampleBox.grow(envBox);
  } catch (std::runtime_error &) {
  }
  // In the beam direction use the maximum sample extent other wise restrict
  // the active region to the width/height of beam
  const auto &sampleMin(sampleBox.minPoint());
  const auto &sampleMax(sampleBox.maxPoint());
  V3D minPoint, maxPoint;
  minPoint[m_horIdx] = m_min[m_horIdx];
  maxPoint[m_horIdx] = m_min[m_horIdx] + m_width;
  minPoint[m_upIdx] = m_min[m_upIdx];
  maxPoint[m_upIdx] = m_min[m_upIdx] + m_height;
  minPoint[m_beamIdx] = sampleMin[m_beamIdx];
  maxPoint[m_beamIdx] = sampleMax[m_beamIdx];

  return Geometry::BoundingBox(maxPoint.X(), maxPoint.Y(), maxPoint.Z(),
                               minPoint.X(), minPoint.Y(), minPoint.Z());
}
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);
}