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