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