Mantid
Loading...
Searching...
No Matches
LoadIsawUB.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidAPI/Sample.h"
13#include <fstream>
14
15using namespace Mantid::Kernel::Strings;
18
19namespace Mantid::Crystal {
20
21// Register the algorithm into the AlgorithmFactory
22DECLARE_ALGORITHM(LoadIsawUB)
23
24using namespace Mantid::Kernel;
25using namespace Mantid::API;
26
30 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::InOut),
31 "An input workspace to which to add the lattice information.");
32
33 const std::vector<std::string> exts{".mat", ".ub", ".txt"};
34 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, exts),
35 "Path to an ISAW-style UB matrix text file.");
36
37 declareProperty("CheckUMatrix", true,
38 "If True (default) then a check is "
39 "performed to ensure the U matrix is a "
40 "proper rotation matrix");
41}
42
46 std::string Filename = getProperty("Filename");
47
48 // Open the file
49 std::ifstream in(Filename.c_str());
50
51 Kernel::DblMatrix ub(3, 3);
52 std::string s;
53 double val;
54
55 // Read the ISAW UB matrix
56 for (size_t row = 0; row < 3; row++) {
57 for (size_t col = 0; col < 3; col++) {
58 s = getWord(in, true);
59 if (!convert(s, val))
60 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
61 ub[row][col] = val;
62 }
63 readToEndOfLine(in, true);
64 }
65
66 readModulatedUB(in, ub);
67}
68void LoadIsawUB::readModulatedUB(std::ifstream &in, DblMatrix &ub) {
69 int ModDim = 0;
70 Kernel::DblMatrix modub(3, 3);
71 Kernel::DblMatrix ModVecErr(3, 3);
72 int maxorder = 0;
73 bool crossterm = false;
74 std::string s;
75 double val;
76 s = getWord(in, true);
77 if (!convert(s, val)) {
78 readToEndOfLine(in, true);
79 for (size_t row = 0; row < 3; row++) {
80 for (size_t col = 0; col < 3; col++) {
81 s = getWord(in, true);
82 if (!convert(s, val))
83 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
84 modub[row][col] = val;
85 }
86 readToEndOfLine(in, true);
87 if (modub[row][0] != 0.0 || modub[row][1] != 0.0 || modub[row][2] != 0.0)
88 ModDim++;
89 }
90 }
91
92 readToEndOfLine(in, true);
93
94 double latVals[6];
95 for (double &latVal : latVals) {
96 s = getWord(in, true);
97 if (!convert(s, val))
98 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
99 latVal = val;
100 }
101
102 if (ModDim > 0) {
103 readToEndOfLine(in, true);
104 readToEndOfLine(in, true);
105 for (int i = 0; i < ModDim; i++) {
106 readToEndOfLine(in, true);
107 for (int j = 0; j < 4; j++)
108 s = getWord(in, true);
109 for (int j = 0; j < 3; j++) {
110 s = getWord(in, true);
111 if (!convert(s, val))
112 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
113 ModVecErr[i][j] = val;
114 }
115 readToEndOfLine(in, true);
116 }
117
118 readToEndOfLine(in, true);
119 for (int j = 0; j < 3; j++)
120 s = getWord(in, true);
121 if (!convert(s, val))
122 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
123 maxorder = static_cast<int>(val);
124 readToEndOfLine(in, true);
125 for (int j = 0; j < 3; j++)
126 s = getWord(in, true);
127 bool valBool;
128 if (!convert(s, valBool))
129 throw std::runtime_error("The string '" + s + "' in the file was not understood as a number.");
130 crossterm = valBool;
131 }
132 // Adjust the UB by transposing
133 ub = ub.Transpose();
134 modub = modub.Transpose();
135
136 /* The method in OrientedLattice gets both the lattice parameters and the U
137 * matrix from the UB matrix.
138 * This is compatible (same results) with the ISAW lattice parameters */
139 auto latt = std::make_unique<OrientedLattice>();
140 latt->setUB(ub);
141 latt->setError(latVals[0], latVals[1], latVals[2], latVals[3], latVals[4], latVals[5]);
142 latt->setModUB(modub);
143
144 for (int i = 0; i < ModDim; i++)
145 latt->setModerr(i, ModVecErr[i][0], ModVecErr[i][1], ModVecErr[i][2]);
146
147 latt->setMaxOrder(maxorder);
148 latt->setCrossTerm(crossterm);
149
150 DblMatrix U = latt->getU();
151
152 // Swap rows around to accound for IPNS convention
153 DblMatrix U2 = U;
154 // Swap rows around
155 for (size_t r = 0; r < 3; r++) {
156 U2[2][r] = U[0][r];
157 U2[1][r] = U[2][r];
158 U2[0][r] = U[1][r];
159 }
160 U = U2;
161 const bool checkU = getProperty("CheckUMatrix");
162 latt->setU(U, !checkU);
163
164 // In and Out workspace.
165 Workspace_sptr ws1 = getProperty("InputWorkspace");
166
168 MultipleExperimentInfos_sptr MDWS = std::dynamic_pointer_cast<MultipleExperimentInfos>(ws1);
169 if (MDWS != nullptr) {
170 ws = MDWS->getExperimentInfo(0);
171 } else {
172 ws = std::dynamic_pointer_cast<ExperimentInfo>(ws1);
173 }
174 if (!ws)
175 throw std::invalid_argument("Must specify either a MatrixWorkspace or a "
176 "PeaksWorkspace or a MDWorkspace.");
177
178 // Save a copy of it to every experiment info in MD workspaces
179 if ((MDWS != nullptr) && (MDWS->getNumExperimentInfo() > 1)) {
180 for (uint16_t i = 1; i < MDWS->getNumExperimentInfo(); i++) {
181 ws = MDWS->getExperimentInfo(i);
182 ws->mutableSample().setOrientedLattice(std::make_unique<OrientedLattice>(*latt));
183 }
184 }
185 // Save it into the main workspace
186 ws->mutableSample().setOrientedLattice(std::move(latt));
187
188 this->setProperty("InputWorkspace", ws1);
189}
190
191} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
@ Load
allowed here which will be passed to the algorithm
Definition: FileProperty.h:52
A property class for workspaces.
void init() override
Initialise the properties.
Definition: LoadIsawUB.cpp:29
void readModulatedUB(std::ifstream &in, Kernel::DblMatrix &ub)
load the modulation UB
Definition: LoadIsawUB.cpp:68
void exec() override
Run the algorithm.
Definition: LoadIsawUB.cpp:45
Class to implement UB matrix.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Matrix< T > & Transpose()
Transpose the matrix.
Definition: Matrix.cpp:793
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Definition: Workspace_fwd.h:20
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< MultipleExperimentInfos > MultipleExperimentInfos_sptr
Holds support functions for strings.
Definition: RegexStrings.h:16
MANTID_KERNEL_DLL void readToEndOfLine(std::istream &in, bool ConsumeEOL)
Eat everything from the stream until the next EOL.
Definition: Strings.cpp:951
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition: Strings.cpp:665
MANTID_KERNEL_DLL std::string getWord(std::istream &in, bool consumeEOL)
Returns the next word in the stream.
Definition: Strings.cpp:900
@ InOut
Both an input & output workspace.
Definition: Property.h:55