-
Notifications
You must be signed in to change notification settings - Fork 122
/
FindUBUsingMinMaxD.cpp
129 lines (103 loc) · 4.79 KB
/
FindUBUsingMinMaxD.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidCrystal/FindUBUsingMinMaxD.h"
#include "MantidAPI/IPeaksWorkspace.h"
#include "MantidAPI/Sample.h"
#include "MantidDataObjects/LeanElasticPeaksWorkspace.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/IndexingUtils.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidKernel/BoundedValidator.h"
namespace Mantid {
namespace Crystal {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(FindUBUsingMinMaxD)
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
/** Constructor
*/
FindUBUsingMinMaxD::FindUBUsingMinMaxD() {
useAlgorithm("FindUBUsingFFT");
deprecatedDate("2013-06-03");
}
const std::string FindUBUsingMinMaxD::name() const { return "FindUBUsingMinMaxD"; }
int FindUBUsingMinMaxD::version() const { return 1; }
const std::string FindUBUsingMinMaxD::category() const { return "Crystal\\UBMatrix"; }
/** Initialize the algorithm's properties.
*/
void FindUBUsingMinMaxD::init() {
this->declareProperty(std::make_unique<WorkspaceProperty<IPeaksWorkspace>>("PeaksWorkspace", "", Direction::InOut),
"Input Peaks Workspace");
auto mustBePositive = std::make_shared<BoundedValidator<double>>();
mustBePositive->setLower(0.0);
auto atLeast3Int = std::make_shared<BoundedValidator<int>>();
atLeast3Int->setLower(3);
// use negative values, force user to input all parameters
this->declareProperty(std::make_unique<PropertyWithValue<double>>("MinD", -1.0, mustBePositive, Direction::Input),
"Lower Bound on Lattice Parameters a, b, c");
this->declareProperty(std::make_unique<PropertyWithValue<double>>("MaxD", -1.0, mustBePositive, Direction::Input),
"Upper Bound on Lattice Parameters a, b, c");
this->declareProperty(std::make_unique<PropertyWithValue<int>>("NumInitial", 20, atLeast3Int, Direction::Input),
"Number of Peaks to Use on First Pass(20)");
this->declareProperty(
std::make_unique<PropertyWithValue<double>>("Tolerance", 0.15, mustBePositive, Direction::Input),
"Indexing Tolerance (0.15)");
}
//--------------------------------------------------------------------------
/** Execute the algorithm.
*/
void FindUBUsingMinMaxD::exec() {
double min_d = this->getProperty("MinD");
double max_d = this->getProperty("MaxD");
int num_initial = this->getProperty("NumInitial");
double tolerance = this->getProperty("Tolerance");
int base_index = -1; // these "could" be properties if need be
double degrees_per_step = 1;
IPeaksWorkspace_sptr ws = this->getProperty("PeaksWorkspace");
if (!ws)
throw std::runtime_error("Could not read the peaks workspace");
int n_peaks = ws->getNumberPeaks();
std::vector<V3D> q_vectors;
q_vectors.reserve(n_peaks);
for (int i = 0; i < n_peaks; i++)
q_vectors.emplace_back(ws->getPeak(i).getQSampleFrame());
Matrix<double> UB(3, 3, false);
double error =
IndexingUtils::Find_UB(UB, q_vectors, min_d, max_d, tolerance, base_index, num_initial, degrees_per_step);
std::cout << "Error = " << error << '\n';
std::cout << "UB = " << UB << '\n';
if (!IndexingUtils::CheckUB(UB)) // UB not found correctly
{
g_log.notice(std::string("Found Invalid UB...peaks used might not be linearly independent"));
g_log.notice(std::string("UB NOT SAVED."));
} else // tell user how many would be indexed
{ // and save the UB in the sample
std::vector<double> sigabc(7);
std::vector<V3D> miller_ind;
std::vector<V3D> indexed_qs;
double fit_error;
miller_ind.reserve(q_vectors.size());
indexed_qs.reserve(q_vectors.size());
IndexingUtils::GetIndexedPeaks(UB, q_vectors, tolerance, miller_ind, indexed_qs, fit_error);
IndexingUtils::Optimize_UB(UB, miller_ind, indexed_qs, sigabc);
char logInfo[200];
int num_indexed = IndexingUtils::NumberIndexed(UB, q_vectors, tolerance);
sprintf(logInfo, std::string("New UB will index %1d Peaks out of %1d with tolerance %5.3f").c_str(), num_indexed,
n_peaks, tolerance);
g_log.notice(std::string(logInfo));
auto lattice = std::make_unique<OrientedLattice>();
lattice->setUB(UB);
lattice->setError(sigabc[0], sigabc[1], sigabc[2], sigabc[3], sigabc[4], sigabc[5]);
// Show the modified lattice parameters
g_log.notice() << *lattice << "\n";
ws->mutableSample().setOrientedLattice(std::move(lattice));
}
}
} // namespace Crystal
} // namespace Mantid