Commit 956ac276 authored by Elliot Oram's avatar Elliot Oram Committed by Gigg, Martyn Anthony
Browse files

Speed up findingDetectors for IPeaks in PredictFractionalPeaks

PredictFractionalPeaks was using a new raytracer for every peak it created and therefore throwing away the caching information about the bounding boxs of detectors / panels causing a huge slow down. Resolved by exposing the findDetector(raytracer) overload to IPeaks and using single raytracer for all calls.
Work also include small refactor for const autos

Refs #22060
parent e63a7a85
......@@ -9,6 +9,7 @@
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidGeometry/Objects/InstrumentRayTracer.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/ArrayLengthValidator.h"
#include "MantidKernel/EnabledWhenProperty.h"
......@@ -129,16 +130,16 @@ void PredictFractionalPeaks::exec() {
V3D hkl;
int peakNum = 0;
int NPeaks = Peaks->getNumberPeaks();
const auto NPeaks = Peaks->getNumberPeaks();
Kernel::Matrix<double> Gon;
Gon.identityMatrix();
double Hmin = getProperty("Hmin");
double Hmax = getProperty("Hmax");
double Kmin = getProperty("Kmin");
double Kmax = getProperty("Kmax");
double Lmin = getProperty("Lmin");
double Lmax = getProperty("Lmax");
const double Hmin = getProperty("Hmin");
const double Hmax = getProperty("Hmax");
const double Kmin = getProperty("Kmin");
const double Kmax = getProperty("Kmax");
const double Lmin = getProperty("Lmin");
const double Lmax = getProperty("Lmax");
int N = NPeaks;
if (includePeaksInRange) {
......@@ -147,7 +148,7 @@ void PredictFractionalPeaks::exec() {
N = max<int>(100, N);
}
IPeak &peak0 = Peaks->getPeak(0);
int RunNumber = peak0.getRunNumber();
auto RunNumber = peak0.getRunNumber();
Gon = peak0.getGoniometerMatrix();
Progress prog(this, 0.0, 1.0, N);
if (includePeaksInRange) {
......@@ -165,6 +166,7 @@ void PredictFractionalPeaks::exec() {
vector<vector<int>> AlreadyDonePeaks;
bool done = false;
int ErrPos = 1; // Used to determine position in code of a throw
Geometry::InstrumentRayTracer tracer(Peaks->getInstrument());
while (!done) {
for (double hOffset : hOffsets) {
for (double kOffset : kOffsets) {
......@@ -190,7 +192,7 @@ void PredictFractionalPeaks::exec() {
peak->setGoniometerMatrix(Gon);
if (Qs[2] > 0 && peak->findDetector()) {
if (Qs[2] > 0 && peak->findDetector(tracer)) {
ErrPos = 2;
vector<int> SavPk{RunNumber,
boost::math::iround(1000.0 * hkl1[0]),
......
......@@ -86,7 +86,7 @@ public:
Geometry::Instrument_const_sptr getInstrument() const override;
bool findDetector() override;
bool findDetector(const Geometry::InstrumentRayTracer &tracer);
bool findDetector(const Geometry::InstrumentRayTracer &tracer) override;
int getRunNumber() const override;
void setRunNumber(int m_runNumber) override;
......
......@@ -628,6 +628,14 @@ bool Peak::findDetector() {
return findDetector(tracer);
}
/**
* Performs the same algorithm as findDetector() but uses a pre-existing
* InstrumentRayTracer object to be able to take adavtange of its caches.
* This method should be preferred if findDetector is to be called many times
* over the same instrument.
* @param tracer A reference to an existing InstrumentRayTracer object.
* @return true if the detector ID was found.
*/
bool Peak::findDetector(const InstrumentRayTracer &tracer) {
// Scattered beam direction
V3D beam = detPos - samplePos;
......
......@@ -11,6 +11,7 @@
namespace Mantid {
namespace Geometry {
class InstrumentRayTracer;
/** Structure describing a single-crystal peak
*
......@@ -49,6 +50,7 @@ public:
virtual Mantid::Kernel::V3D getQLabFrame() const = 0;
virtual Mantid::Kernel::V3D getQSampleFrame() const = 0;
virtual bool findDetector() = 0;
virtual bool findDetector(const InstrumentRayTracer &tracer) = 0;
virtual void setQSampleFrame(const Mantid::Kernel::V3D &QSampleFrame,
boost::optional<double> detectorDistance) = 0;
......
......@@ -11,6 +11,7 @@
#include "MantidGeometry/Crystal/IPeak.h"
#include "MantidGeometry/Crystal/PeakTransform.h"
#include "MantidGeometry/Crystal/PeakTransformFactory.h"
#include "MantidGeometry/Objects/InstrumentRayTracer.h"
#include "MantidKernel/SpecialCoordinateSystem.h"
#include "MantidKernel/WarningSuppressions.h"
#include <boost/regex.hpp>
......@@ -80,6 +81,8 @@ public:
MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
MOCK_METHOD0(findDetector, bool());
MOCK_METHOD1(findDetector,
bool(const Mantid::Geometry::InstrumentRayTracer &tracer));
MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame,
boost::optional<double> detectorDistance));
MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame,
......
......@@ -89,7 +89,8 @@ void export_IPeak() {
":class:`~mantid.geometry.Goniometer` rotation was NOT taken "
"out.\n"
"Note: There is no 2*pi factor used, so \\|Q| = 1/wavelength.")
.def("findDetector", &IPeak::findDetector, arg("self"),
.def("findDetector", (bool (IPeak::*)()) & IPeak::findDetector,
arg("self"),
"Using the :class:`~mantid.geometry.Instrument` set in the peak, "
"perform ray tracing to find "
"the exact :class:`~mantid.geometry.Detector`.")
......
......@@ -160,66 +160,6 @@ public:
void(boost::shared_ptr<Mantid::API::IPeaksWorkspace> &));
};
/*------------------------------------------------------------
Mock IPeak
------------------------------------------------------------*/
class MockIPeak : public Mantid::Geometry::IPeak {
public:
MOCK_METHOD1(setInstrument,
void(const Geometry::Instrument_const_sptr &inst));
MOCK_CONST_METHOD0(getDetectorID, int());
MOCK_METHOD1(setDetectorID, void(int m_DetectorID));
MOCK_CONST_METHOD0(getDetector, Geometry::IDetector_const_sptr());
MOCK_CONST_METHOD0(getInstrument, Geometry::Instrument_const_sptr());
MOCK_CONST_METHOD0(getRunNumber, int());
MOCK_METHOD1(setRunNumber, void(int m_RunNumber));
MOCK_CONST_METHOD0(getMonitorCount, double());
MOCK_METHOD1(setMonitorCount, void(double m_MonitorCount));
MOCK_CONST_METHOD0(getH, double());
MOCK_CONST_METHOD0(getK, double());
MOCK_CONST_METHOD0(getL, double());
MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D());
MOCK_METHOD1(setH, void(double m_H));
MOCK_METHOD1(setK, void(double m_K));
MOCK_METHOD1(setL, void(double m_L));
MOCK_METHOD3(setHKL, void(double H, double K, double L));
MOCK_METHOD1(setHKL, void(const Mantid::Kernel::V3D &HKL));
MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
MOCK_METHOD0(findDetector, bool());
MOCK_METHOD2(setQSampleFrame, void(const Mantid::Kernel::V3D &QSampleFrame,
boost::optional<double> detectorDistance));
MOCK_METHOD2(setQLabFrame, void(const Mantid::Kernel::V3D &QLabFrame,
boost::optional<double> detectorDistance));
MOCK_METHOD1(setWavelength, void(double wavelength));
MOCK_CONST_METHOD0(getWavelength, double());
MOCK_CONST_METHOD0(getScattering, double());
MOCK_CONST_METHOD0(getDSpacing, double());
MOCK_CONST_METHOD0(getTOF, double());
MOCK_CONST_METHOD0(getInitialEnergy, double());
MOCK_CONST_METHOD0(getFinalEnergy, double());
MOCK_METHOD1(setInitialEnergy, void(double m_InitialEnergy));
MOCK_METHOD1(setFinalEnergy, void(double m_FinalEnergy));
MOCK_CONST_METHOD0(getIntensity, double());
MOCK_CONST_METHOD0(getSigmaIntensity, double());
MOCK_METHOD1(setIntensity, void(double m_Intensity));
MOCK_METHOD1(setSigmaIntensity, void(double m_SigmaIntensity));
MOCK_CONST_METHOD0(getBinCount, double());
MOCK_METHOD1(setBinCount, void(double m_BinCount));
MOCK_CONST_METHOD0(getGoniometerMatrix, Mantid::Kernel::Matrix<double>());
MOCK_METHOD1(setGoniometerMatrix,
void(const Mantid::Kernel::Matrix<double> &m_GoniometerMatrix));
MOCK_CONST_METHOD0(getBankName, std::string());
MOCK_CONST_METHOD0(getRow, int());
MOCK_CONST_METHOD0(getCol, int());
MOCK_CONST_METHOD0(getDetPos, Mantid::Kernel::V3D());
MOCK_CONST_METHOD0(getL1, double());
MOCK_CONST_METHOD0(getL2, double());
MOCK_CONST_METHOD0(getDetectorPosition, Mantid::Kernel::V3D());
MOCK_CONST_METHOD0(getDetectorPositionNoCheck, Mantid::Kernel::V3D());
MOCK_CONST_METHOD0(getPeakShape, const Mantid::Geometry::PeakShape &());
};
/*------------------------------------------------------------
Mock MDGeometry
------------------------------------------------------------*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment