34DblMatrix createRotationMatrix(
const double phi,
const double chi,
const double omega) {
36 g.pushAxis(
"omega", 0., 1., 0., omega);
37 g.pushAxis(
"chi", 0., 0., 1., chi);
38 g.pushAxis(
"phi", 0., 1., 0., phi);
43 const double phi,
const double chi,
const double omega) {
47 auto Rinv = createRotationMatrix(phi, chi, omega);
53 for (
int i{0}; i < peakWS->getNumberPeaks(); i++) {
54 const auto &peak = peakWS->getPeak(i);
55 const auto q_lab = peak.getQLabFrame();
56 const auto q_sample = Rinv * q_lab;
57 const auto hkl = UBinv * q_sample / (2 * M_PI);
63 V3D q_error = UB *
HKL;
66 sum_sq_err += q_error.norm2();
70 return std::make_pair(n_indexed, sum_sq_err);
87 return "Do a brute force search for the goniometer rotation angles that maximize the number of peaks indexed by the "
96 "Workspace of Peaks with UB loaded");
99 "The maximum change in angle to try for any of the goniometer angles, phi, chi and omega, in degrees.",
101 declareProperty(
"Tolerance", 0.15,
"The tolerance on Miller indices for a peak to be considered indexed",
103 declareProperty(
"Apply",
false,
"Update goniometer in peaks workspace");
118 const auto UB = peakWS->sample().getOrientedLattice().getUB();
120 auto g = peakWS->run().getGoniometer();
121 const std::vector<double> YZY =
g.getEulerAngles(
"YZY");
123 double omega = YZY[0];
127 auto results = NumIndexed(UB, peakWS,
tolerance, phi, chi, omega);
128 g_log.
information() <<
"Starting Max Indexed = " << results.first <<
" Err = " << results.second
129 <<
" Phi: " << phi <<
" Chi: " << chi <<
" Omega: " << omega <<
"\n";
131 const int N_TRIES = 5;
133 double phi_offset{phi};
134 double chi_offset{chi};
135 double omega_offset{omega};
138 double best_omega{0};
140 auto progress = std::make_unique<API::Progress>(
this, 0.0, 1.0, N_TRIES);
142 for (
int range{1}; range <= N_TRIES; range++) {
143 double max_quality{0};
147 double step = max_angle / range;
149 while (step > sqrt(1e-5)) {
150 for (
int i{-range}; i <= range; i++)
151 for (
int j{-range}; j <= range; j++)
152 for (
int k{-range}; k <= range; k++) {
153 phi = phi_offset + i * step;
154 chi = chi_offset + j * step;
155 omega = omega_offset + k * step;
156 results = NumIndexed(UB, peakWS,
tolerance, phi, chi, omega);
157 const double quality = results.first - 0.1 * results.second / results.first;
159 if (quality > max_quality) {
160 max_quality = quality;
161 max_indexed = results.first;
162 max_error = results.second;
170 phi_offset = best_phi;
171 chi_offset = best_chi;
172 omega_offset = best_omega;
178 <<
"Max Indexed = " << max_indexed <<
" Err = " << max_error <<
" Phi: " << best_phi
179 <<
" Chi: " << best_chi <<
" Omega: " << best_omega <<
"\n";
188 const auto R = createRotationMatrix(best_phi, best_chi, best_omega);
190 peakWS->mutableRun().setGoniometer(R,
false);
193 for (
int i{0}; i < peakWS->getNumberPeaks(); i++) {
194 auto &peak = peakWS->getPeak(i);
195 const auto q_lab = peak.getQLabFrame();
196 peak.setGoniometerMatrix(R);
197 peak.setQLabFrame(q_lab, std::nullopt);
#define DECLARE_ALGORITHM(classname)
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Interface to the class Mantid::DataObjects::PeaksWorkspace.
A property class for workspaces.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
void init() override
Initialize the algorithm's properties.
void exec() override
Execute the algorithm.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
const std::string name() const override
Algorithms name for identification.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
This class contains static utility methods for indexing peaks and finding the UB matrix.
static bool ValidIndex(const Kernel::V3D &hkl, double tolerance)
Check is hkl is within tolerance of integer (h,k,l) non-zero values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void information(const std::string &msg)
Logs at information level.
T Invert()
LU inversion routine.
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
Mantid::Kernel::Matrix< double > DblMatrix
static constexpr double g
Standard acceleration due to gravity.
Helper class which provides the Collimation Length for SANS instruments.
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.