Mantid
Loading...
Searching...
No Matches
SaveIsawUB.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/Run.h"
11#include "MantidAPI/Sample.h"
14
15#include <fstream>
16#include <iomanip>
17
20
21namespace Mantid::Crystal {
22
23// Register the algorithm into the AlgorithmFactory
24DECLARE_ALGORITHM(SaveIsawUB)
25
26using namespace Mantid::Kernel;
27using namespace Mantid::DataObjects;
28using namespace Mantid::API;
29using namespace std;
30
34 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input),
35 "An input workspace containing the orientation matrix.");
36
37 const std::vector<std::string> exts{".mat", ".ub", ".txt"};
38 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save, exts),
39 "Path to an ISAW-style UB matrix text file.");
40
42 std::make_unique<PropertyWithValue<bool>>("RotateByGoniometerMatrix", false, Direction::Input),
43 "If True this option will rotate the UB by the goniometer rotation, R - i.e. will save R*UB. "
44 "If the InputWorkspace is a PeaksWorkspace then the goniometer matrix will be taken from the first peak.");
45}
46
48 double Volume;
49 double const latticeParams[6] = {lattice.a(), lattice.b(), lattice.c(),
50 lattice.alpha(), lattice.beta(), lattice.gamma()};
51 double const lattice_errors[6] = {lattice.errora(), lattice.errorb(), lattice.errorc(),
52 lattice.erroralpha(), lattice.errorbeta(), lattice.errorgamma()};
53 if (lattice.volume() <= 0) {
54
55 double xA = cos(lattice.alpha() / 180. * M_PI);
56 double xB = cos(lattice.beta() / 180. * M_PI);
57 double xC = cos(lattice.gamma() / 180. * M_PI);
58 Volume = lattice.a() * lattice.b() * lattice.c() * sqrt(1 - xA * xA - xB * xB - xC * xC + 2 * xA * xB * xC);
59 } else
60 Volume = lattice.volume();
61
62 double dV = 0;
63 for (int i = 0; i < 3; i++) {
64 double U = (Volume / latticeParams[i] * lattice_errors[i]);
65 dV += U * U;
66 }
67
68 double U = (lattice_errors[3]) * (sin(2 * latticeParams[3] / 180. * M_PI) - sin(latticeParams[3] / 180. * M_PI) *
69 cos(latticeParams[4] / 180 * M_PI) *
70 cos(latticeParams[5] / 180 * M_PI));
71 dV += U * U;
72 U = (lattice_errors[4]) *
73 (sin(2 * latticeParams[4] / 180. * M_PI) -
74 sin(latticeParams[4] / 180. * M_PI) * cos(latticeParams[3] / 180 * M_PI) * cos(latticeParams[5] / 180 * M_PI));
75 dV += U * U;
76 U = (lattice_errors[5]) *
77 (sin(2 * latticeParams[5] / 180. * M_PI) -
78 sin(latticeParams[5] / 180. * M_PI) * cos(latticeParams[4] / 180 * M_PI) * cos(latticeParams[3] / 180 * M_PI));
79 dV += U * U;
80 dV = sqrt(dV);
81
82 return dV;
83}
84
88 try {
89 Workspace_sptr ws = getProperty("InputWorkspace");
90 ExperimentInfo_sptr expInfo;
91 MultipleExperimentInfos_sptr expInfoMD = std::dynamic_pointer_cast<MultipleExperimentInfos>(ws);
92 if (expInfoMD != nullptr && expInfoMD->getNumExperimentInfo() > 0) {
93 expInfo = expInfoMD->getExperimentInfo(0);
94 } else {
95 expInfo = std::dynamic_pointer_cast<ExperimentInfo>(ws);
96 }
97
98 if (!expInfo)
99 throw std::invalid_argument("Must specify either a MatrixWorkspace or a "
100 "PeaksWorkspace or a MDWorkspace.");
101
102 if (!expInfo->sample().hasOrientedLattice())
103 throw std::invalid_argument("Workspace must have an oriented lattice to save");
104
105 OrientedLattice lattice = expInfo->sample().getOrientedLattice();
106 Kernel::DblMatrix ub = lattice.getUB();
107 Kernel::DblMatrix modub = lattice.getModUB();
108
109 // rotate by gonio matrix if requested
110 if (getProperty("RotateByGoniometerMatrix")) {
111 DblMatrix gonioR(3, 3, true); // identity
112 auto peakWs = std::dynamic_pointer_cast<PeaksWorkspace>(ws);
113 if (peakWs != nullptr) {
114 gonioR = peakWs->getPeak(0).getGoniometerMatrix();
115 } else {
116 gonioR = expInfo->run().getGoniometer().getR();
117 }
118 ub = gonioR * ub;
119 modub = gonioR * modub;
120 }
121
122 // Write the ISAW UB matrix
123 std::string Filename = getProperty("Filename");
124 ofstream out;
125 out.open(Filename.c_str());
126
127 const int beam = 2;
128 const int up = 1;
129 const int back = 0;
130 out << fixed;
131
132 for (size_t basis = 0; basis < 3; basis++) {
133 out << setw(11) << setprecision(8) << ub[beam][basis] << setw(12) << setprecision(8) << ub[back][basis]
134 << setw(12) << setprecision(8) << ub[up][basis] << " \n";
135 }
136
137 int ModDim = 0;
138 for (int i = 0; i < 3; i++) {
139 if (lattice.getModVec(i) == V3D(0, 0, 0))
140 continue;
141 else
142 ModDim++;
143 }
144
145 if (ModDim > 0) {
146 out << "ModUB: \n";
147 for (size_t basis = 0; basis < 3; basis++) {
148 out << setw(11) << setprecision(8) << modub[beam][basis] << setw(12) << setprecision(8) << modub[back][basis]
149 << setw(12) << setprecision(8) << modub[up][basis] << " \n";
150 }
151 }
152
153 // out << "Lattice Parameters: \n";
154 out << setw(11) << setprecision(4) << lattice.a() << setw(12) << setprecision(4) << lattice.b() << setw(12)
155 << setprecision(4) << lattice.c() << setw(12) << setprecision(4) << lattice.alpha() << setw(12)
156 << setprecision(4) << lattice.beta() << setw(12) << setprecision(4) << lattice.gamma() << setw(12)
157 << setprecision(4) << lattice.volume() << " \n";
158 double ErrorVolume = getErrorVolume(lattice);
159 out << setw(11) << setprecision(4) << lattice.errora() << setw(12) << setprecision(4) << lattice.errorb()
160 << setw(12) << setprecision(4) << lattice.errorc() << setw(12) << setprecision(4) << lattice.erroralpha()
161 << setw(12) << setprecision(4) << lattice.errorbeta() << setw(12) << setprecision(4) << lattice.errorgamma()
162 << setw(12) << setprecision(4) << ErrorVolume << " \n";
163
164 out << "\n";
165 if (ModDim >= 1) {
166 out << "Modulation Vector 1: " << setw(12) << setprecision(4) << lattice.getdh(0) << setw(12) << setprecision(4)
167 << lattice.getdk(0) << setw(12) << setprecision(4) << lattice.getdl(0) << " \n";
168
169 out << "Modulation Vector 1 error: " << setw(6) << setprecision(4) << lattice.getdherr(0) << setw(12)
170 << setprecision(4) << lattice.getdkerr(0) << setw(12) << setprecision(4) << lattice.getdlerr(0) << " \n";
171 }
172 if (ModDim >= 2) {
173 out << "Modulation Vector 2: " << setw(12) << setprecision(4) << lattice.getdh(1) << setw(12) << setprecision(4)
174 << lattice.getdk(1) << setw(12) << setprecision(4) << lattice.getdl(1) << " \n";
175
176 out << "Modulation Vector 2 error: " << setw(6) << setprecision(4) << lattice.getdherr(1) << setw(12)
177 << setprecision(4) << lattice.getdkerr(1) << setw(12) << setprecision(4) << lattice.getdlerr(1) << " \n";
178 }
179 if (ModDim == 3) {
180 out << "Modulation Vector 3: " << setw(12) << setprecision(4) << lattice.getdh(2) << setw(12) << setprecision(4)
181 << lattice.getdk(2) << setw(12) << setprecision(4) << lattice.getdl(2) << " \n";
182
183 out << "Modulation Vector 3 error: " << setw(6) << setprecision(4) << lattice.getdherr(2) << setw(12)
184 << setprecision(4) << lattice.getdkerr(2) << setw(12) << setprecision(4) << lattice.getdlerr(2) << " \n";
185 }
186 if (ModDim >= 1) {
187 out << "\n";
188 out << "Max Order: " << lattice.getMaxOrder() << " \n";
189 out << "Cross Terms: " << lattice.getCrossTerm() << " \n";
190 }
191
192 out << "\n";
193
194 if (ModDim == 0) {
195 out << "The above matrix is the Transpose of the UB Matrix. ";
196 out << "The UB matrix maps the column\n";
197 out << "vector (h,k,l ) to the column vector ";
198 out << "(q'x,q'y,q'z).\n";
199 out << "|Q'|=1/dspacing and its coordinates are a ";
200 out << "right-hand coordinate system where\n";
201 out << " x is the beam direction and z is vertically ";
202 out << "upward.(IPNS convention)\n";
203 } else {
204 out << "The above matrix is the Transpose of the UB Matrix and the "
205 "Transpose of ModUB. ";
206 out << "The UB matrix together with ModUB maps the column vector "
207 "(h,k,l,m,n,p) \n";
208 out << "to the column vector (q'x,q'y,q'z).\n";
209 out << "The columns of ModUB are the coordinates of modulation vectors "
210 "in Qlab. \n";
211 out << "|Q'|=1/dspacing and its coordinates are a ";
212 out << "right-hand coordinate system where";
213 out << " x is the beam direction and z is vertically ";
214 out << "upward.(IPNS convention)\n";
215 }
216
217 out.close();
218
219 } catch (exception &s) {
220 throw std::invalid_argument(s.what());
221 }
222}
223
224} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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.
@ Save
to specify a file to write to, the file may or may not exist
A property class for workspaces.
void init() override
Initialise the properties.
void exec() override
Run the algorithm.
double getErrorVolume(const Geometry::OrientedLattice &lattice)
Class to implement UB matrix.
const Kernel::DblMatrix & getUB() const
Get the UB matrix.
const Kernel::DblMatrix & getModUB() const
double alpha() const
Get lattice parameter.
Definition UnitCell.cpp:133
double erroralpha(const int angleunit=angDegrees) const
Get lattice parameter error.
Definition UnitCell.cpp:225
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
Definition UnitCell.cpp:94
int getMaxOrder() const
Get max order.
Definition UnitCell.cpp:596
double c() const
Get lattice parameter.
Definition UnitCell.cpp:128
double getdh(int j) const
Get modulation vectors for satellites.
Definition UnitCell.cpp:555
double getdk(int j) const
Get modulation vectors for satellites.
Definition UnitCell.cpp:562
double volume() const
Volume of the direct unit-cell.
Definition UnitCell.cpp:737
bool getCrossTerm() const
Get cross term boolean.
Definition UnitCell.cpp:602
double getdl(int j) const
Get modulation vectors for satellites.
Definition UnitCell.cpp:569
double errorgamma(const int angleunit=angDegrees) const
Get lattice parameter error.
Definition UnitCell.cpp:252
double getdherr(int j) const
Get error of modulation vectors for satellites.
Definition UnitCell.cpp:576
double errorbeta(const int angleunit=angDegrees) const
Get lattice parameter error.
Definition UnitCell.cpp:239
double beta() const
Get lattice parameter.
Definition UnitCell.cpp:138
double getdlerr(int j) const
Get error of modulation vectors for satellites.
Definition UnitCell.cpp:590
double b() const
Get lattice parameter.
Definition UnitCell.cpp:123
double getdkerr(int j) const
Get error of modulation vectors for satellites.
Definition UnitCell.cpp:583
const Kernel::V3D getModVec(int j) const
Get modulation vectors for satellites.
Definition UnitCell.cpp:535
double errorc() const
Get lattice parameter error.
Definition UnitCell.cpp:218
double gamma() const
Get lattice parameter.
Definition UnitCell.cpp:143
double errora() const
Get lattice parameter error.
Definition UnitCell.cpp:208
double errorb() const
Get lattice parameter error.
Definition UnitCell.cpp:213
The concrete, templated class for properties.
Class for 3D vectors.
Definition V3D.h:34
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< MultipleExperimentInfos > MultipleExperimentInfos_sptr
STL namespace.
@ Input
An input workspace.
Definition Property.h:53