30 "Input Peaks Workspace");
31 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
32 mustBePositive->setLower(0.0);
33 declareProperty(
"Tolerance", 0.1, mustBePositive,
"Indexing Tolerance (0.1)");
34 declareProperty(
"ToleranceForSatellite", 0.1, mustBePositive,
"Indexing Tolerance for satellite (0.1)");
35 declareProperty(
"CommonUBForAll",
false,
"Used when evaluating the uncertainty of modHKL");
42 const int n_peaks = ws->getNumberPeaks();
44 std::vector<V3D> q_vectors;
45 std::vector<V3D> hkl_vectors;
46 std::vector<V3D> mnp_vectors;
53 bool CrossTerm =
false;
56 q_vectors.reserve(n_peaks);
57 hkl_vectors.reserve(n_peaks);
58 mnp_vectors.reserve(n_peaks);
60 size_t indexed_count = 0;
61 std::unordered_set<int> run_numbers;
62 for (
int i = 0; i < n_peaks; i++) {
63 const IPeak &peak = ws->getPeak(i);
71 if (mnp[0] != 0 && ModDim == 0)
73 if (mnp[1] != 0 && ModDim == 1)
75 if (mnp[2] != 0 && ModDim == 2)
77 if (mnp[0] * mnp[1] != 0 || mnp[1] * mnp[2] != 0 || mnp[2] * mnp[0] != 0)
82 hkl_vectors.emplace_back(hkl);
83 mnp_vectors.emplace_back(mnp);
90 throw std::runtime_error(
"At least three linearly independent indexed peaks are needed.");
95 std::vector<double> sigabc(7);
96 std::vector<double> sigq(3);
102 g_log.
notice(std::string(
"Found Invalid UB...peaks used might not be linearly independent"));
107 q_vectors.reserve(n_peaks);
109 for (
int i = 0; i < n_peaks; i++) {
110 q_vectors.emplace_back(ws->getPeak(i).getQSampleFrame());
114 int sate_indexed = 0;
115 double satetolerance =
getProperty(
"ToleranceForSatellite");
118 for (
int run : run_numbers) {
119 std::vector<V3D> run_q_vectors;
120 std::vector<V3D> run_fhkl_vectors;
121 std::vector<V3D> run_hkl_vectors;
122 std::vector<V3D> run_mnp_vectors;
123 size_t run_indexed = 0;
125 for (
int i = 0; i < n_peaks; i++) {
126 const IPeak &peak = ws->getPeak(i);
133 g_log.
notice() <<
"Number of Indexed Peaks in Run " << run <<
" is " << run_indexed <<
"\n";
135 run_q_vectors.reserve(run_indexed);
136 run_hkl_vectors.reserve(run_indexed);
137 run_mnp_vectors.reserve(run_indexed);
138 run_fhkl_vectors.reserve(run_indexed);
140 for (
int i = 0; i < n_peaks; i++) {
141 const IPeak &peak = ws->getPeak(i);
147 run_hkl_vectors.emplace_back(hkl);
148 run_mnp_vectors.emplace_back(mnp);
159 run_lattice.
setUB(UB);
161 run_lattice.
setError(sigabc[0], sigabc[1], sigabc[2], sigabc[3], sigabc[4], sigabc[5]);
165 std::vector<double> run_sigabc(7);
166 std::vector<double> run_sigq(3);
168 run_sigabc, run_sigq);
169 run_lattice.
setUB(run_UB);
171 run_lattice.
setError(run_sigabc[0], run_sigabc[1], run_sigabc[2], run_sigabc[3], run_sigabc[4],
176 double average_error = 0.;
178 for (
size_t i = 0; i < run_indexed; i++) {
182 V3D fhkl(run_fhkl_vectors[i]);
183 for (
int j = 0; j < 3; j++) {
184 if (run_mnp_vectors[i][j] != 0) {
185 fhkl -= run_lattice.
getModVec(j) * run_mnp_vectors[i][j];
188 V3D errhkl = fhkl - run_hkl_vectors[i];
190 for (
int k = 0; k < 3; k++)
191 errorHKL[k][j] += errhkl[k];
199 std::stringstream stream;
200 stream <<
"New UB will index " << num_indexed <<
" main Peaks with tolerance " <<
tolerance <<
" and "
201 << sate_indexed <<
" Satellite Peaks with tolerance " << satetolerance <<
" ,out of " << n_peaks
205 auto o_lattice = std::make_unique<OrientedLattice>();
206 o_lattice->setUB(UB);
207 o_lattice->setModUB(modUB);
208 o_lattice->setError(sigabc[0], sigabc[1], sigabc[2], sigabc[3], sigabc[4], sigabc[5]);
209 double ind_count_inv = 1. /
static_cast<double>(indexed_count);
210 errorHKL *= ind_count_inv;
211 o_lattice->setErrorModHKL(errorHKL);
213 o_lattice->setMaxOrder(MaxOrder);
214 o_lattice->setCrossTerm(CrossTerm);
219 ws->mutableSample().setOrientedLattice(std::move(o_lattice));
225 g_log.
notice() <<
"Modulation Dimension is: " << ModDim <<
"\n";
226 for (
int i = 0; i < ModDim; i++) {
228 g_log.
notice() <<
"Modulation Vector " << i + 1 <<
" error: " << o_lattice.
getVecErr(i) <<
"\n";
#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.
A property class for workspaces.
void logLattice(const Geometry::OrientedLattice &o_lattice, const int &ModDim)
void exec() override
Run the algorithm.
bool isPeakIndexed(const Geometry::IPeak &peak)
void init() override
Initialise the properties.
Structure describing a single-crystal peak.
virtual Mantid::Kernel::V3D getIntHKL() const =0
virtual int getRunNumber() const =0
virtual Mantid::Kernel::V3D getQSampleFrame() const =0
virtual Mantid::Kernel::V3D getIntMNP() const =0
static double Optimize_6dUB(Kernel::DblMatrix &UB, Kernel::DblMatrix &ModUB, const std::vector< Kernel::V3D > &hkl_vectors, const std::vector< Kernel::V3D > &mnp_vectors, const int &ModDim, const std::vector< Kernel::V3D > &q_vectors, std::vector< double > &sigabc, std::vector< double > &sigq)
STATIC method Optimize_UB: Calculates the matrix that most nearly maps the specified hkl_vectors to t...
static bool CheckUB(const Kernel::DblMatrix &UB)
Check that the specified UB is reasonable for an orientation matrix.
static int NumberIndexed(const Kernel::DblMatrix &UB, const std::vector< Kernel::V3D > &q_vectors, double tolerance)
Calculate the number of Q vectors that are mapped to integer indices by UB.
static bool ValidIndex(const Kernel::V3D &hkl, double tolerance)
Check is hkl is within tolerance of integer (h,k,l) non-zero values.
static int CalculateMillerIndices(const Kernel::DblMatrix &UB, const std::vector< Kernel::V3D > &q_vectors, double tolerance, std::vector< Kernel::V3D > &miller_indices, double &ave_error)
Given a UB, get list of Miller indices for specifed Qs and tolerance.
Class to implement UB matrix.
void setModUB(const Kernel::DblMatrix &newModUB)
Sets the Modulation UB matrix.
void setUB(const Kernel::DblMatrix &newUB)
Sets the UB matrix and recalculates lattice parameters.
const Kernel::DblMatrix & getUB() const
Get the UB matrix.
const Kernel::V3D getVecErr(int j) const
Get errors for modulation vectors for satellites.
void setError(double _aerr, double _berr, double _cerr, double _alphaerr, double _betaerr, double _gammaerr, const int angleunit=angDegrees)
Set lattice parameter errors.
const Kernel::V3D getModVec(int j) const
Get modulation vectors for satellites.
void notice(const std::string &msg)
Logs at notice level.
V3D absoluteValue() const
Absolute value.
int maxCoeff()
Maximum absolute integer value.
std::shared_ptr< IPeaksWorkspace > IPeaksWorkspace_sptr
shared pointer to Mantid::API::IPeaksWorkspace
const int MIN_INDEXED_PEAKS
@ InOut
Both an input & output workspace.