void BbyDetectorBankFactory::createAndAssign(size_t startIndex, const Kernel::V3D &pos, const Kernel::Quat &rot) const { // create a RectangularDetector which represents a rectangular array of pixels Geometry::RectangularDetector *bank = new Geometry::RectangularDetector( "bank", m_instrument.get()); // Bank gets registered with instrument component. // instrument acts as sink and manages lifetime. bank->initialize(m_pixelShape, // x static_cast<int>(m_xPixelCount), 0, m_pixelWidth, // y static_cast<int>(m_yPixelCount), 0, m_pixelHeight, // indices static_cast<int>(startIndex), true, static_cast<int>(m_yPixelCount)); for (size_t x = 0; x < m_xPixelCount; ++x) for (size_t y = 0; y < m_yPixelCount; ++y) m_instrument->markAsDetector( bank->getAtXY(static_cast<int>(x), static_cast<int>(y)).get()); Kernel::V3D center(m_center); rot.rotate(center); bank->rotate(rot); bank->translate(pos - center); }
/** * This function calculates the exponential contribution to the He3 tube * efficiency. * @param spectraIndex :: the current index to calculate * @param idet :: the current detector pointer * @throw out_of_range if twice tube thickness is greater than tube diameter * @return the exponential contribution for the given detector */ double He3TubeEfficiency::calculateExponential( std::size_t spectraIndex, boost::shared_ptr<const Geometry::IDetector> idet) { // Get the parameters for the current associated tube double pressure = this->getParameter("TubePressure", spectraIndex, "tube_pressure", idet); double tubethickness = this->getParameter("TubeThickness", spectraIndex, "tube_thickness", idet); double temperature = this->getParameter("TubeTemperature", spectraIndex, "tube_temperature", idet); double detRadius(0.0); Kernel::V3D detAxis; this->getDetectorGeometry(idet, detRadius, detAxis); double detDiameter = 2.0 * detRadius; double twiceTubeThickness = 2.0 * tubethickness; // now get the sin of the angle, it's the magnitude of the cross product of // unit vector along the detector tube axis and a unit vector directed from // the sample to the detector center Kernel::V3D vectorFromSample = idet->getPos() - this->samplePos; vectorFromSample.normalize(); Kernel::Quat rot = idet->getRotation(); // rotate the original cylinder object axis to get the detector axis in the // actual instrument rot.rotate(detAxis); detAxis.normalize(); // Scalar product is quicker than cross product double cosTheta = detAxis.scalar_prod(vectorFromSample); double sinTheta = std::sqrt(1.0 - cosTheta * cosTheta); const double straight_path = detDiameter - twiceTubeThickness; if (std::fabs(straight_path - 0.0) < TOL) { throw std::out_of_range("Twice tube thickness cannot be greater than " "or equal to the tube diameter"); } const double pathlength = straight_path / sinTheta; return EXP_SCALAR_CONST * (pressure / temperature) * pathlength; }