Mantid
Loading...
Searching...
No Matches
SaveLauenorm.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 +
9#include "MantidAPI/Sample.h"
18#include "MantidKernel/Utils.h"
19#include "boost/math/special_functions/round.hpp"
20
21#include <cmath>
22#include <filesystem>
23#include <fstream>
24#include <iomanip>
25
26using namespace Mantid::Geometry;
27using namespace Mantid::DataObjects;
28using namespace Mantid::Kernel;
29using namespace Mantid::API;
30using namespace Mantid::PhysicalConstants;
31
32namespace Mantid::Crystal {
33
34// Register the algorithm into the AlgorithmFactory
35DECLARE_ALGORITHM(SaveLauenorm)
36
37//----------------------------------------------------------------------------------------------
40void SaveLauenorm::init() {
41 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("InputWorkspace", "", Direction::Input),
42 "An input PeaksWorkspace.");
43 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Save),
44 "Select the directory and base name for the output files.");
45 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
46 mustBePositive->setLower(0.0);
47 declareProperty("ScalePeaks", 1.0, mustBePositive, "Multiply FSQ and sig(FSQ) by scaleFactor");
48 declareProperty("MinDSpacing", 0.0, "Minimum d-spacing (Angstroms)");
49 declareProperty("MinWavelength", 0.0, "Minimum wavelength (Angstroms)");
50 declareProperty("MaxWavelength", EMPTY_DBL(), "Maximum wavelength (Angstroms)");
51 std::vector<std::string> histoTypes{"Bank", "RunNumber", "Both Bank and RunNumber"};
52 declareProperty("SortFilesBy", histoTypes[0], std::make_shared<StringListValidator>(histoTypes),
53 "Sort into files by bank(default), run number or both.");
54 declareProperty("MinIsigI", EMPTY_DBL(), mustBePositive, "The minimum I/sig(I) ratio");
55 declareProperty("WidthBorder", EMPTY_INT(), "Width of border of detectors");
56 declareProperty("MinIntensity", EMPTY_DBL(), mustBePositive, "The minimum Intensity");
57 declareProperty("UseDetScale", false,
58 "Scale intensity and sigI by scale "
59 "factor of detector if set in "
60 "SetDetScale.\n"
61 "If false, no change (default).");
62 declareProperty(std::make_unique<ArrayProperty<std::string>>("EliminateBankNumbers", Direction::Input),
63 "Comma deliminated string of bank numbers to exclude for example 1,2,5");
64 declareProperty("LaueScaleFormat", false, "New format for Lauescale");
65
66 declareProperty("CrystalSystem", m_typeList[0], std::make_shared<Kernel::StringListValidator>(m_typeList),
67 "The conventional cell type to use");
68
69 declareProperty("Centering", m_centeringList[0], std::make_shared<Kernel::StringListValidator>(m_centeringList),
70 "The centering for the conventional cell");
71}
72
73//----------------------------------------------------------------------------------------------
77
78 std::string filename = getProperty("Filename");
79 std::filesystem::path path(filename);
80 std::string basename = path.stem().string(); // Filename minus extension
81 ws = getProperty("InputWorkspace");
82 double scaleFactor = getProperty("ScalePeaks");
83 double dMin = getProperty("MinDSpacing");
84 double wlMin = getProperty("MinWavelength");
85 double wlMax = getProperty("MaxWavelength");
86 std::string type = getProperty("SortFilesBy");
87 double minIsigI = getProperty("MinIsigI");
88 double minIntensity = getProperty("MinIntensity");
89 int widthBorder = getProperty("WidthBorder");
90 bool newFormat = getProperty("LaueScaleFormat");
91 std::string cellType = getProperty("CrystalSystem");
92 auto iter = std::find(m_typeList.begin(), m_typeList.end(), cellType);
93 auto cellNo = 1 + std::distance(m_typeList.begin(), iter);
94 std::string cent = getProperty("Centering");
95 auto iter2 = std::find(m_centeringList.begin(), m_centeringList.end(), cent);
96 auto centerNo = 1 + std::distance(m_centeringList.begin(), iter2);
97 // sequenceNo and run number
98 int sequenceNo = 0;
99 int oldSequence = -1;
100
101 std::fstream out;
102 std::ostringstream ss;
103
104 // We must sort the peaks
105 std::vector<std::pair<std::string, bool>> criteria;
106 if (type.compare(0, 2, "Ba") == 0)
107 criteria.emplace_back("BankName", true);
108 else if (type.compare(0, 2, "Ru") == 0)
109 criteria.emplace_back("RunNumber", true);
110 else {
111 criteria.emplace_back("RunNumber", true);
112 criteria.emplace_back("BankName", true);
113 }
114 criteria.emplace_back("h", true);
115 criteria.emplace_back("k", true);
116 criteria.emplace_back("l", true);
117 ws->sort(criteria);
118
119 std::vector<Peak> peaks = ws->getPeaks();
120
121 // ============================== Save all Peaks
122 // =========================================
123 // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
124 // Default for kf-ki has -q
125 double qSign = -1.0;
126 std::string convention = ConfigService::Instance().getString("Q.convention");
127 if (convention == "Crystallography")
128 qSign = 1.0;
129 // scaleDet scales intensity and sigI for detector banks
130 bool scaleDet = getProperty("UseDetScale");
131 auto inst = ws->getInstrument();
132 OrientedLattice lattice;
133 if (newFormat) {
134 type = "Both Bank and RunNumber";
135 if (!ws->sample().hasOrientedLattice()) {
136
137 const std::string fft("FindUBUsingIndexedPeaks");
138 auto findUB = createChildAlgorithm(fft);
139 findUB->initialize();
140 findUB->setProperty<PeaksWorkspace_sptr>("PeaksWorkspace", ws);
141 findUB->executeAsChildAlg();
142
143 if (!ws->sample().hasOrientedLattice()) {
144 g_log.notice(std::string("Could not find UB for ") + std::string(ws->getName()));
145 throw std::invalid_argument(std::string("Could not find UB for ") + std::string(ws->getName()));
146 }
147 }
148 lattice = ws->sample().getOrientedLattice();
149 }
150 // Count peaks
151 std::vector<int> numPeaks;
152 int count = 0;
153 std::vector<double> maxLamVec;
154 std::vector<double> minLamVec;
155 std::vector<double> sumLamVec;
156 std::vector<double> minDVec;
157 double maxLam = 0;
158 double minLam = EMPTY_DBL();
159 double sumLam = 0;
160 double minD = EMPTY_DBL();
161 for (int wi = 0; wi < ws->getNumberPeaks(); wi++) {
162
163 const Peak &p = peaks[wi];
164 double intensity = p.getIntensity();
165 double sigI = p.getSigmaIntensity();
166 if (intensity == 0.0 || !(std::isfinite(sigI)))
167 continue;
168 if (minIsigI != EMPTY_DBL() && intensity < std::abs(minIsigI * sigI))
169 continue;
170 int sequence = p.getRunNumber();
171 std::string bankName = p.getBankName();
172 int nCols, nRows;
173 sizeBanks(bankName, nCols, nRows);
174 if (widthBorder != EMPTY_INT() && (p.getCol() < widthBorder || p.getRow() < widthBorder ||
175 p.getCol() > (nCols - widthBorder) || p.getRow() > (nRows - widthBorder)))
176 continue;
177 // Take out the "bank" part of the bank name and convert to an int
178 bankName.erase(remove_if(bankName.begin(), bankName.end(), std::not_fn(::isdigit)), bankName.end());
179 if (type.compare(0, 2, "Ba") == 0) {
180 Strings::convert(bankName, sequence);
181 }
182 // Do not use peaks from these banks
183 std::vector<std::string> notBanks = getProperty("EliminateBankNumbers");
184 if (std::find(notBanks.begin(), notBanks.end(), bankName) != notBanks.end())
185 continue;
186 if (scaleDet) {
187 if (inst->hasParameter("detScale" + bankName)) {
188 double correc = static_cast<double>(inst->getNumberParameter("detScale" + bankName)[0]);
189 intensity *= correc;
190 sigI *= correc;
191 }
192 }
193 if (minIntensity != EMPTY_DBL() && intensity < minIntensity)
194 continue;
195 double lambda = p.getWavelength();
196 double dsp = p.getDSpacing();
197 if (dsp < dMin || lambda < wlMin || (wlMax != EMPTY_DBL() && lambda > wlMax))
198 continue;
199 if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0)
200 continue;
201
202 if (sequence != oldSequence) {
203 oldSequence = sequence;
204 numPeaks.emplace_back(count);
205 maxLamVec.emplace_back(maxLam);
206 minLamVec.emplace_back(minLam);
207 sumLamVec.emplace_back(sumLam);
208 minDVec.emplace_back(minD);
209 count = 0;
210 maxLam = 0;
211 minLam = EMPTY_DBL();
212 sumLam = 0;
213 minD = EMPTY_DBL();
214 }
215 count++;
216 if (lambda < minLam)
217 minLam = lambda;
218 if (lambda > maxLam)
219 maxLam = lambda;
220 if (dsp < minD)
221 minD = dsp;
222 sumLam += lambda;
223 }
224 numPeaks.emplace_back(count);
225 maxLamVec.emplace_back(maxLam);
226 minLamVec.emplace_back(minLam);
227 sumLamVec.emplace_back(sumLam);
228 minDVec.emplace_back(minD);
229 oldSequence = -1;
230 // Go through each peak at this run / bank
231 for (int wi = 0; wi < ws->getNumberPeaks(); wi++) {
232
233 const Peak &p = peaks[wi];
234 double intensity = p.getIntensity();
235 double sigI = p.getSigmaIntensity();
236 if (intensity == 0.0 || !(std::isfinite(sigI)))
237 continue;
238 if (minIsigI != EMPTY_DBL() && intensity < std::abs(minIsigI * sigI))
239 continue;
240 int sequence = p.getRunNumber();
241 std::string bankName = p.getBankName();
242 int nCols, nRows;
243 sizeBanks(bankName, nCols, nRows);
244 if (widthBorder != EMPTY_INT() && (p.getCol() < widthBorder || p.getRow() < widthBorder ||
245 p.getCol() > (nCols - widthBorder) || p.getRow() > (nRows - widthBorder)))
246 continue;
247 // Take out the "bank" part of the bank name and convert to an int
248 bankName.erase(remove_if(bankName.begin(), bankName.end(), std::not_fn(::isdigit)), bankName.end());
249 if (type.compare(0, 2, "Ba") == 0) {
250 Strings::convert(bankName, sequence);
251 }
252 // Do not use peaks from these banks
253 std::vector<std::string> notBanks = getProperty("EliminateBankNumbers");
254 if (std::find(notBanks.begin(), notBanks.end(), bankName) != notBanks.end())
255 continue;
256 if (scaleDet) {
257 if (inst->hasParameter("detScale" + bankName)) {
258 double correc = static_cast<double>(inst->getNumberParameter("detScale" + bankName)[0]);
259 intensity *= correc;
260 sigI *= correc;
261 }
262 }
263 if (minIntensity != EMPTY_DBL() && intensity < minIntensity)
264 continue;
265 // Two-theta = polar angle = scattering angle = between +Z vector and the
266 // scattered beam
267 double scattering = p.getScattering();
268 double lambda = p.getWavelength();
269 double dsp = p.getDSpacing();
270 if (dsp < dMin || lambda < wlMin || (wlMax != EMPTY_DBL() && lambda > wlMax))
271 continue;
272 // This can be bank number of run number depending on
273 if (sequence != oldSequence) {
274 oldSequence = sequence;
275 if (newFormat) {
276 out << "END-OF-REFLECTION-DATA\n";
277 out << "HARMONICS DATA 0 REFLECTIONS\n";
278 out << "END-OF-FILE\n";
279 }
280 out.flush();
281 out.close();
282 sequenceNo++;
283 ss.str("");
284 ss.clear();
285 ss << std::setw(3) << std::setfill('0') << sequenceNo;
286
287 // Chop off filename
288 path = path.parent_path();
289 path /= basename + ss.str();
290 if (newFormat)
291 path.replace_extension("geasc");
292 out.open(path.string(), std::ios::out);
293 if (newFormat) {
294 out << "TITL\n";
295 out << basename << "\n";
296 out << "CRYS " << basename.substr(0, 6) << "\n";
297 out << "FIDX 1.00000 1.00000 1.00000 1.00000 "
298 "1.00000 1.00000\n";
299 out << "FIDY 1.00000 1.00000 1.00000 1.00000 "
300 "1.00000 1.00000\n";
301 out << "OMEG 1.00000 1.00000 1.00000 1.00000 "
302 "1.00000 1.00000\n";
303 out << "CELL " << std::setw(11) << std::setprecision(4) << 1.0 / lattice.a() << std::setw(12)
304 << std::setprecision(4) << 1.0 / lattice.b() << std::setw(12) << std::setprecision(4) << 1.0 / lattice.c()
305 << std::setw(9) << boost::math::iround(lattice.alpha()) << std::setw(9)
306 << boost::math::iround(lattice.beta()) << std::setw(9) << boost::math::iround(lattice.gamma()) << '\n';
307
308 out << "SYST " << cellNo << " " << centerNo << " 1 3"
309 << "\n";
310 out << "RAST 0.050"
311 << "\n";
312 out << "IBOX 1 1 1 1 1"
313 << "\n";
315 std::vector<double> angles = gon.getEulerAngles("yzy");
316
317 double phi = angles[2];
318 double chi = angles[1];
319 double omega = angles[0];
320
321 out << "PHIS " << std::setw(11) << std::setprecision(4) << phi << std::setw(12) << std::setprecision(4) << chi
322 << std::setw(12) << std::setprecision(4) << omega << "\n";
323 out << "LAMS ";
324
325 out << std::setprecision(1) << std::fixed << sumLamVec[sequenceNo] / numPeaks[sequenceNo] << " "
326 << minLamVec[sequenceNo] << " " << maxLamVec[sequenceNo] << "\n";
327
328 out << "DMIN ";
329 out << std::setprecision(2) << std::fixed << minDVec[sequenceNo] << "\n";
330
331 // distance from sample to detector (use first pixel) in mm
332 double L2 = 500.0;
333 out << "RADI " << std::setprecision(0) << std::fixed << L2 << "\n";
334 out << "SPIN 0.000"
335 << "\n";
336 out << "XC_S 0.00000 0.00000 0.00000 0.00000 "
337 "0.00000 0.00000\n";
338 out << "YC_S 0.00000 0.00000 0.00000 0.00000 "
339 "0.00000 0.00000\n";
340 out << "WC_S 0.00000 0.00000 0.00000 0.00000 "
341 "0.00000 0.00000\n";
342 out << "DELT 0.0000"
343 << "\n";
344 out << "TWIS 0.00000 0.00000 0.00000 0.00000 "
345 "0.00000 0.00000 \n";
346 out << "TILT 0.00000 0.00000 0.00000 0.00000 "
347 "0.00000 0.00000 \n";
348 out << "BULG 0.00000 0.00000 0.00000 0.00000 "
349 "0.00000 0.00000 \n";
350 out << "CTOF " << L2 << "\n";
351 out << "YSCA 1.00000 1.00000 1.00000 1.00000 "
352 "1.00000 1.00000\n";
353 out << "CRAT 1.00000 1.00000 1.00000 1.00000 "
354 "1.00000 1.00000\n";
355 out << "MINI ";
356 if (minIntensity != EMPTY_DBL()) {
357 out << minIntensity << "\n";
358 } else {
359 out << "0.0\n";
360 }
361 out << "MULT ";
362 out << numPeaks[sequenceNo]
363 << " 0 0 0 0 0 0 0 "
364 "0 0\n";
365 out << " 0 0 0 0 0 0 0 0 "
366 "0 0\n";
367 out << " 0 \n";
368 out << "LAMH " << numPeaks[sequenceNo]
369 << " 0 0 0 0 0 0 0 0 "
370 "0\n";
371 out << " 0 0 0 0 0 0\n";
372 out << "VERS 1"
373 << "\n";
374 out << "PACK 0"
375 << "\n";
376 out << "NSPT " << numPeaks[sequenceNo] << " 0 0 0 0"
377 << "\n";
378 out << "NODH " << numPeaks[sequenceNo] << " 0 0 0 0 0 0 0 0 0\n"
379 << " 0 0\n";
380 out << "INTF 0"
381 << "\n";
382 out << "REFLECTION DATA " << numPeaks[sequenceNo] << " REFLECTIONS"
383 << "\n";
384 }
385 }
386 // h k l lambda theta intensity and sig(intensity) in format
387 // (3I5,2F10.5,2I10)
388 // HKL is flipped by -1 due to different q convention in ISAW vs mantid.
389 // unless Crystallography convention
390 if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0)
391 continue;
392 out << std::setw(5) << Utils::round(qSign * p.getH()) << std::setw(5) << Utils::round(qSign * p.getK())
393 << std::setw(5) << Utils::round(qSign * p.getL());
394 if (newFormat) {
395 // Convert to mm from centre
396 out << std::setw(10) << std::fixed << std::setprecision(5) << (p.getCol() - 127.5) * 150.0 / 256.0;
397 out << std::setw(10) << std::fixed << std::setprecision(5) << (p.getRow() - 127.5) * 150.0 / 256.0 << "\n";
398 }
399 out << std::setw(10) << std::fixed << std::setprecision(5) << lambda;
400 if (newFormat) {
401 // mult nodal ovlp close h2 k2 l2 nidx lambda2 ipoint
402 out << " 1 0 0 0 0 0 0 0 0.0 0 ";
403 // Dmin threshold squared for next harmonic
404 out << std::setw(10) << std::fixed << std::setprecision(5) << dsp * dsp * 0.25 << "\n";
405 } else {
406 // Assume that want theta not two-theta
407 out << std::setw(10) << std::fixed << std::setprecision(5) << 0.5 * scattering;
408 }
409
410 // SHELX can read data without the space between the l and intensity
411 if (p.getDetectorID() != -1) {
412 double ckIntensity = scaleFactor * intensity;
413 if (ckIntensity > 999999999.985)
414 g_log.warning() << "Scaled intensity, " << ckIntensity << " is too large for format. Decrease ScalePeaks.\n";
415 out << std::setw(10) << Utils::round(ckIntensity);
416 if (newFormat) {
417 // mult nodal ovlp close h2 k2 l2 nidx lambda2 ipoint
418 out << " -9999 -9999 -9999 -9999 -9999 \n";
419 }
420
421 out << std::setw(10) << Utils::round(scaleFactor * sigI);
422 if (newFormat) {
423 // mult nodal ovlp close h2 k2 l2 nidx lambda2 ipoint
424 out << " -9999 -9999 -9999 -9999 -9999 \n";
425 out << std::setw(10) << Utils::round(ckIntensity);
426 out << " -9999 -9999 -9999 -9999 -9999 \n";
427 out << std::setw(10) << Utils::round(scaleFactor * sigI);
428 out << " -9999 -9999 -9999 -9999 -9999 * ";
429 }
430 } else {
431 // This is data from LoadLauenorm which is already corrected
432 out << std::setw(10) << Utils::round(intensity);
433 if (newFormat) {
434 // 5 more films (dummy)
435 out << " -9999 -9999 -9999 -9999 -9999 \n";
436 }
437 out << std::setw(10) << Utils::round(sigI);
438 if (newFormat) {
439 // 5 more films (dummy)
440 out << " -9999 -9999 -9999 -9999 -9999 \n";
441 out << std::setw(10) << Utils::round(intensity);
442 out << " -9999 -9999 -9999 -9999 -9999 \n";
443 out << std::setw(10) << Utils::round(sigI);
444 out << " -9999 -9999 -9999 -9999 -9999 * ";
445 }
446 }
447
448 out << '\n';
449 }
450 if (newFormat) {
451 out << "END-OF-REFLECTION-DATA\n";
452 out << "HARMONICS DATA 0 REFLECTIONS\n";
453 out << "END-OF-FILE\n";
454 }
455 out.flush();
456 out.close();
457}
458void SaveLauenorm::sizeBanks(const std::string &bankName, int &nCols, int &nRows) {
459 if (bankName == "None")
460 return;
461 std::shared_ptr<const IComponent> parent = ws->getInstrument()->getComponentByName(bankName);
462 if (!parent)
463 return;
464 if (parent->type() == "RectangularDetector") {
465 std::shared_ptr<const RectangularDetector> RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
466
467 nCols = RDet->xpixels();
468 nRows = RDet->ypixels();
469 } else {
470 std::vector<Geometry::IComponent_const_sptr> children;
471 std::shared_ptr<const Geometry::ICompAssembly> asmb =
472 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
473 asmb->getChildren(children, false);
474 std::shared_ptr<const Geometry::ICompAssembly> asmb2 =
475 std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
476 std::vector<Geometry::IComponent_const_sptr> grandchildren;
477 asmb2->getChildren(grandchildren, false);
478 nRows = static_cast<int>(grandchildren.size());
479 nCols = static_cast<int>(children.size());
480 }
481}
482
483} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
const std::vector< double > * lambda
int count
counter
Definition Matrix.cpp:37
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ Save
to specify a file to write to, the file may or may not exist
A property class for workspaces.
Save a PeaksWorkspace to a lauenorm format http://www.ccp4.ac.uk/cvs/viewvc.cgi/laue/doc/lauenorm....
void sizeBanks(const std::string &bankName, int &nCols, int &nRows)
const std::vector< std::string > m_centeringList
const std::vector< std::string > m_typeList
DataObjects::PeaksWorkspace_sptr ws
void exec() override
Run the algorithm.
double getL() const override
Get the L index of the peak.
Definition BasePeak.cpp:99
double getIntensity() const override
Return the integrated peak intensity.
Definition BasePeak.cpp:184
double getSigmaIntensity() const override
Return the error on the integrated peak intensity.
Definition BasePeak.cpp:187
double getK() const override
Get the K index of the peak.
Definition BasePeak.cpp:96
int getRunNumber() const override
Return the run number this peak was measured at.
Definition BasePeak.cpp:77
double getH() const override
Get the H index of the peak.
Definition BasePeak.cpp:93
Mantid::Kernel::Matrix< double > getGoniometerMatrix() const override
Get the goniometer rotation matrix at which this peak was measured.
Definition BasePeak.cpp:209
Structure describing a single-crystal peak.
Definition Peak.h:34
int getCol() const override
For RectangularDetectors only, returns the column (x) of the pixel of the detector or -1 if not found...
Definition Peak.cpp:335
double getDSpacing() const override
Calculate the d-spacing of the peak, in 1/Angstroms
Definition Peak.cpp:426
int getRow() const override
For RectangularDetectors only, returns the row (y) of the pixel of the detector or -1 if not found.
Definition Peak.cpp:326
int getDetectorID() const override
Get the ID of the detector at the center of the peak
Definition Peak.cpp:265
double getWavelength() const override
Calculate the neutron wavelength (in angstroms) at the peak (Note for inelastic scattering - it is th...
Definition Peak.cpp:358
const std::string & getBankName() const
Find the name of the bank that is the parent of the detector.
Definition Peak.cpp:347
double getScattering() const override
Calculate the scattering angle of the peak
Definition Peak.cpp:391
Class to represent a particular goniometer setting, which is described by the rotation matrix.
Definition Goniometer.h:55
std::vector< double > getEulerAngles(const std::string &convention="YZX")
Return Euler angles acording to a convention.
Class to implement UB matrix.
double alpha() const
Get lattice parameter.
Definition UnitCell.cpp:133
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
Definition UnitCell.cpp:94
double c() const
Get lattice parameter.
Definition UnitCell.cpp:128
double beta() const
Get lattice parameter.
Definition UnitCell.cpp:138
double b() const
Get lattice parameter.
Definition UnitCell.cpp:123
double gamma() const
Get lattice parameter.
Definition UnitCell.cpp:143
Support for a property that holds an array of values.
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition Strings.cpp:696
long round(double x)
Custom rounding method for a double->long because none is portable in C++ (!)
Definition Utils.h:37
A namespace containing physical constants that are required by algorithms and unit routines.
Definition Atom.h:14
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53