/** * 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"); } }
/** * 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); }