/
FindUBUsingMinMaxD.cpp
146 lines (117 loc) · 4.95 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "MantidCrystal/FindUBUsingMinMaxD.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/Crystal/IndexingUtils.h"
#include "MantidGeometry/Crystal/OrientedLattice.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");
}
//--------------------------------------------------------------------------
/** Destructor
*/
FindUBUsingMinMaxD::~FindUBUsingMinMaxD() {}
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(make_unique<WorkspaceProperty<PeaksWorkspace>>(
"PeaksWorkspace", "", Direction::InOut),
"Input Peaks Workspace");
auto mustBePositive = boost::make_shared<BoundedValidator<double>>();
mustBePositive->setLower(0.0);
auto atLeast3Int = boost::make_shared<BoundedValidator<int>>();
atLeast3Int->setLower(3);
// use negative values, force user to input all parameters
this->declareProperty(make_unique<PropertyWithValue<double>>(
"MinD", -1.0, mustBePositive, Direction::Input),
"Lower Bound on Lattice Parameters a, b, c");
this->declareProperty(make_unique<PropertyWithValue<double>>(
"MaxD", -1.0, mustBePositive, Direction::Input),
"Upper Bound on Lattice Parameters a, b, c");
this->declareProperty(make_unique<PropertyWithValue<int>>(
"NumInitial", 20, atLeast3Int, Direction::Input),
"Number of Peaks to Use on First Pass(20)");
this->declareProperty(
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;
PeaksWorkspace_sptr ws = this->getProperty("PeaksWorkspace");
if (!ws)
throw std::runtime_error("Could not read the peaks workspace");
std::vector<Peak> &peaks = ws->getPeaks();
size_t n_peaks = ws->getNumberPeaks();
std::vector<V3D> q_vectors;
q_vectors.reserve(n_peaks);
for (size_t i = 0; i < n_peaks; i++)
q_vectors.push_back(peaks[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 << std::endl;
std::cout << "UB = " << UB << std::endl;
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));
OrientedLattice o_lattice;
o_lattice.setUB(UB);
o_lattice.setError(sigabc[0], sigabc[1], sigabc[2], sigabc[3], sigabc[4],
sigabc[5]);
// Show the modified lattice parameters
g_log.notice() << o_lattice << "\n";
ws->mutableSample().setOrientedLattice(&o_lattice);
}
}
} // namespace Mantid
} // namespace Crystal