/** Get instrument geometry setup including L2 for each detector and L1 */ void CreateLogTimeCorrection::getInstrumentSetup() { // 1. Get sample position and source position IComponent_const_sptr sample = m_instrument->getSample(); if (!sample) { throw runtime_error("No sample has been set."); } V3D samplepos = sample->getPos(); IComponent_const_sptr source = m_instrument->getSource(); if (!source) { throw runtime_error("No source has been set."); } V3D sourcepos = source->getPos(); m_L1 = sourcepos.distance(samplepos); // 2. Get detector IDs std::vector<detid_t> detids = m_instrument->getDetectorIDs(true); for (auto &detid : detids) { IDetector_const_sptr detector = m_instrument->getDetector(detid); V3D detpos = detector->getPos(); double l2 = detpos.distance(samplepos); m_l2map.emplace(detid, l2); } // 3. Output information g_log.information() << "Sample position = " << samplepos << "; " << "Source position = " << sourcepos << ", L1 = " << m_L1 << "; " << "Number of detector/pixels = " << detids.size() << ".\n"; }
double RadiusSum::getMaxDistance(const V3D ¢re, const std::vector<double> &boundary_limits) { std::array<double, 2> Xs = {{boundary_limits[0], boundary_limits[1]}}; std::array<double, 2> Ys = {{boundary_limits[2], boundary_limits[3]}}; std::array<double, 2> Zs = {{0., 0.}}; if (boundary_limits.size() == 6) { Zs[0] = boundary_limits[4]; Zs[1] = boundary_limits[5]; } double max_distance = 0; for (auto &x : Xs) for (auto &y : Ys) for (auto &z : Zs) { // define all the possible combinations for the limits double curr_distance = centre.distance(V3D(x, y, z)); if (curr_distance > max_distance) max_distance = curr_distance; // keep the maximum distance. } return max_distance; }
/** Checks whether the track given will pass through this Component. * @param track :: The Track object to test (N.B. Will be modified if hits are * found) * @returns The number of track segments added (i.e. 1 if the track enters and * exits the object once each) * @throw NullPointerException if the underlying geometrical Object has not been * set */ int ObjComponent::interceptSurface(Track &track) const { // If the form of this component is not defined, throw NullPointerException if (!shape()) throw Kernel::Exception::NullPointerException( "ObjComponent::interceptSurface", "shape"); // TODO: If scaling parameters are ever enabled, would they need need to be // used here? V3D trkStart = factorOutComponentPosition(track.startPoint()); V3D trkDirection = takeOutRotation(track.direction()); Track probeTrack(trkStart, trkDirection); int intercepts = shape()->interceptSurface(probeTrack); Track::LType::const_iterator it; for (it = probeTrack.cbegin(); it != probeTrack.cend(); ++it) { V3D in = it->entryPoint; this->getRotation().rotate(in); // use the scale factor in *= getScaleFactor(); in += this->getPos(); V3D out = it->exitPoint; this->getRotation().rotate(out); // use the scale factor out *= getScaleFactor(); out += this->getPos(); track.addLink(in, out, out.distance(track.startPoint()), *(this->shape()), this->getComponentID()); } return intercepts; }
void EstimatePDDetectorResolution::retrieveInstrumentParameters() { #if 0 // Call SolidAngle to get solid angles for all detectors Algorithm_sptr calsolidangle = createChildAlgorithm("SolidAngle", -1, -1, true); calsolidangle->initialize(); calsolidangle->setProperty("InputWorkspace", m_inputWS); calsolidangle->execute(); if (!calsolidangle->isExecuted()) throw runtime_error("Unable to run solid angle. "); m_solidangleWS = calsolidangle->getProperty("OutputWorkspace"); if (!m_solidangleWS) throw runtime_error("Unable to get solid angle workspace from SolidAngle(). "); size_t numspec = m_solidangleWS->getNumberHistograms(); for (size_t i = 0; i < numspec; ++i) g_log.debug() << "[DB]: " << m_solidangleWS->readY(i)[0] << "\n"; #endif // Calculate centre neutron velocity Property* cwlproperty = m_inputWS->run().getProperty("LambdaRequest"); if (!cwlproperty) throw runtime_error("Unable to locate property LambdaRequest as central wavelength. "); TimeSeriesProperty<double>* cwltimeseries = dynamic_cast<TimeSeriesProperty<double>* >(cwlproperty); if (!cwltimeseries) throw runtime_error("LambdaReqeust is not a TimeSeriesProperty in double. "); if (cwltimeseries->size() != 1) throw runtime_error("LambdaRequest should contain 1 and only 1 entry. "); double centrewavelength = cwltimeseries->nthValue(0); string unit = cwltimeseries->units(); if (unit.compare("Angstrom") == 0) centrewavelength *= 1.0E-10; else throw runtime_error("Unit is not recognized"); m_centreVelocity = PhysicalConstants::h/PhysicalConstants::NeutronMass/centrewavelength; g_log.notice() << "Centre wavelength = " << centrewavelength << ", Centre neutron velocity = " << m_centreVelocity << "\n"; // Calcualte L1 sample to source Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); V3D sourcepos = instrument->getSource()->getPos(); m_L1 = samplepos.distance(sourcepos); g_log.notice() << "L1 = " << m_L1 << "\n"; return; }
bool PeakBackground::isBackground(Mantid::API::IMDIterator *iterator) const { if (!HardThresholdBackground::isBackground(iterator)) { const VMD ¢er = iterator->getCenter(); V3D temp(center[0], center[1], center[2]); // This assumes dims 1, 2, and 3 // in the workspace correspond to // positions. for (int i = 0; i < m_peaksWS->getNumberPeaks(); ++i) { const IPeak &peak = m_peaksWS->getPeak(i); V3D coords = m_coordFunction(&peak); if (coords.distance(temp) < m_radiusEstimate) { return false; } } } return true; }
void EstimateResolutionDiffraction::retrieveInstrumentParameters() { double centrewavelength = getWavelength(); g_log.notice() << "Centre wavelength = " << centrewavelength << " Angstrom\n"; if (centrewavelength > WAVELENGTH_MAX) { throw runtime_error("unphysical wavelength used"); } // Calculate centre neutron velocity m_centreVelocity = WAVELENGTH_TO_VELOCITY / centrewavelength; g_log.notice() << "Centre neutron velocity = " << m_centreVelocity << "\n"; // Calculate L1 sample to source Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); V3D sourcepos = instrument->getSource()->getPos(); m_L1 = samplepos.distance(sourcepos); g_log.notice() << "L1 = " << m_L1 << "\n"; return; }
void EstimateResolutionDiffraction::estimateDetectorResolution() { Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); size_t numspec = m_inputWS->getNumberHistograms(); double mintwotheta = 10000; double maxtwotheta = 0; double mint3 = 1; double maxt3 = 0; size_t count_nodetsize = 0; for (size_t i = 0; i < numspec; ++i) { // Get detector IDetector_const_sptr det = m_inputWS->getDetector(i); double detdim; boost::shared_ptr<const Detector> realdet = boost::dynamic_pointer_cast<const Detector>(det); if (realdet) { double dy = realdet->getHeight(); double dx = realdet->getWidth(); detdim = sqrt(dx * dx + dy * dy) * 0.5; } else { // Use detector dimension as 0 as no-information detdim = 0; ++count_nodetsize; } // Get the distance from detector to source V3D detpos = det->getPos(); double l2 = detpos.distance(samplepos); if (l2 < 0) throw runtime_error("L2 is negative"); // Calculate T double centraltof = (m_L1 + l2) / m_centreVelocity; // Angle double twotheta = m_inputWS->detectorTwoTheta(det); double theta = 0.5 * twotheta; // double solidangle = m_solidangleWS->readY(i)[0]; double solidangle = det->solidAngle(samplepos); double deltatheta = sqrt(solidangle); // Resolution double t1 = m_deltaT / centraltof; double t2 = detdim / (m_L1 + l2); double t3 = deltatheta * (cos(theta) / sin(theta)); double resolution = sqrt(t1 * t1 + t2 * t2 + t3 * t3); m_outputWS->dataX(i)[0] = static_cast<double>(i); m_outputWS->dataY(i)[0] = resolution; if (twotheta > maxtwotheta) maxtwotheta = twotheta; else if (twotheta < mintwotheta) mintwotheta = twotheta; if (fabs(t3) < mint3) mint3 = fabs(t3); else if (fabs(t3) > maxt3) maxt3 = fabs(t3); g_log.debug() << det->type() << " " << i << "\t\t" << twotheta << "\t\tdT/T = " << t1 * t1 << "\t\tdL/L = " << t2 << "\t\tdTheta*cotTheta = " << t3 << "\n"; } g_log.notice() << "2theta range: " << mintwotheta << ", " << maxtwotheta << "\n"; g_log.notice() << "t3 range: " << mint3 << ", " << maxt3 << "\n"; g_log.notice() << "Number of detector having NO size information = " << count_nodetsize << "\n"; return; }