/** * Fire the test ray at the instrument and perform a bread-first search of the * object tree to find the objects that were intersected. * @param testRay :: An input/output parameter that defines the track and accumulates the * intersection results */ void InstrumentRayTracer::fireRay(Track & testRay) const { // Go through the instrument tree and see if we get any hits by // (a) first testing the bounding box and if we're inside that then // (b) test the lower components. std::deque<IComponent_const_sptr> nodeQueue; //Start at the root of the tree nodeQueue.push_back(m_instrument); IComponent_const_sptr node; while( !nodeQueue.empty() ) { node = nodeQueue.front(); nodeQueue.pop_front(); BoundingBox bbox; node->getBoundingBox(bbox); // Quick test. If this suceeds moved on to test the children if( bbox.doesLineIntersect(testRay) ) { if( ICompAssembly_const_sptr assembly = boost::dynamic_pointer_cast<const ICompAssembly>(node) ) { assembly->testIntersectionWithChildren(testRay, nodeQueue); } else { throw Kernel::Exception::NotImplementedError("Implement non-comp assembly interactions"); } } } }
/** * Cache frequently accessed values * @param instrument : The instrument for this run * @param detID : The det ID for this observation */ void CachedExperimentInfo::initCaches( const Geometry::Instrument_const_sptr &instrument, const detid_t detID) { // Throws if detector does not exist // Takes into account possible detector mapping IDetector_const_sptr det = m_exptInfo.getDetectorByID(detID); // Instrument distances boost::shared_ptr<const ReferenceFrame> refFrame = instrument->getReferenceFrame(); m_beam = refFrame->pointingAlongBeam(); m_up = refFrame->pointingUp(); m_horiz = refFrame->pointingHorizontal(); IComponent_const_sptr source = instrument->getSource(); IComponent_const_sptr sample = instrument->getSample(); IComponent_const_sptr aperture = instrument->getComponentByName("aperture", 1); if (!aperture) { throw std::invalid_argument( "No component named \"aperture\" found in instrument."); } IObjComponent_const_sptr firstChopper = instrument->getChopperPoint(0); const Kernel::V3D samplePos = sample->getPos(); const Kernel::V3D beamDir = samplePos - source->getPos(); // Cache m_twoTheta = det->getTwoTheta(samplePos, beamDir); m_phi = det->getPhi(); m_modToChop = firstChopper->getDistance(*source); m_apertureToChop = firstChopper->getDistance(*aperture); m_chopToSample = sample->getDistance(*firstChopper); m_sampleToDet = det->getDistance(*sample); // Aperture Geometry::BoundingBox apertureBox; aperture->getBoundingBox(apertureBox); if (apertureBox.isNull()) { throw std::invalid_argument("CachedExperimentInfo::initCaches - Aperture " "has no bounding box, cannot sample from it"); } m_apertureSize.first = apertureBox.maxPoint()[0] - apertureBox.minPoint()[0]; m_apertureSize.second = apertureBox.maxPoint()[1] - apertureBox.minPoint()[1]; // Sample volume const API::Sample &sampleDescription = m_exptInfo.sample(); const Geometry::Object &shape = sampleDescription.getShape(); m_sampleWidths = shape.getBoundingBox().width(); // Detector volume // Make sure it encompasses all possible detectors det->getBoundingBox(m_detBox); if (m_detBox.isNull()) { throw std::invalid_argument("CachedExperimentInfo::initCaches - Detector " "has no bounding box, cannot sample from it. " "ID:" + boost::lexical_cast<std::string>(det->getID())); } const double rad2deg = 180. / M_PI; const double thetaInDegs = twoTheta() * rad2deg; const double phiInDegs = phi() * rad2deg; m_gonimeter = new Goniometer; m_gonimeter->makeUniversalGoniometer(); m_gonimeter->setRotationAngle("phi", thetaInDegs); m_gonimeter->setRotationAngle("chi", phiInDegs); m_sampleToDetMatrix = m_exptInfo.sample().getOrientedLattice().getU() * m_gonimeter->getR(); // EFixed m_efixed = m_exptInfo.getEFixed(det); }