Mantid
Loading...
Searching...
No Matches
SaveIsawPeaks.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"
21#include "MantidKernel/Utils.h"
22#include <Poco/File.h>
23#include <boost/algorithm/string/trim.hpp>
24#include <fstream>
25
26using namespace Mantid::Geometry;
27using namespace Mantid::DataObjects;
28using namespace Mantid::Kernel;
29using namespace Mantid::API;
30
31namespace Mantid::Crystal {
32
33// Register the algorithm into the AlgorithmFactory
34DECLARE_ALGORITHM(SaveIsawPeaks)
35
36
38void SaveIsawPeaks::init() {
39 declareProperty(std::make_unique<WorkspaceProperty<PeaksWorkspace>>("InputWorkspace", "", Direction::Input,
40 std::make_shared<InstrumentValidator>()),
41 "An input PeaksWorkspace with an instrument.");
42
43 declareProperty("AppendFile", false,
44 "Append to file if true.\n"
45 "If false, new file (default).");
46
47 const std::vector<std::string> exts{".peaks", ".integrate"};
48 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save, exts),
49 "Path to an ISAW-style peaks or integrate file to save.");
50
51 declareProperty(std::make_unique<WorkspaceProperty<Workspace2D>>("ProfileWorkspace", "", Direction::Input,
53 "An optional Workspace2D of profiles from integrating cylinder.");
54
55 declareProperty("RenumberPeaks", false,
56 "If true, sequential peak numbers\n"
57 "If false, keep original numbering (default).");
58}
59
63 // Section header
64 std::string header = "2 SEQN H K L COL ROW CHAN "
65 " L2 2_THETA AZ WL D IPK "
66 " INTI SIGI RFLG";
67
68 const std::string filename = getPropertyValue("Filename");
69 PeaksWorkspace_sptr ws = getProperty("InputWorkspace");
70 const auto &peaks = ws->getPeaks();
71 inst = ws->getInstrument();
72 if (!inst)
73 throw std::runtime_error("No instrument in the Workspace. Cannot save DetCal file.");
74 const auto &detectorInfo = ws->detectorInfo();
75
76 // We must sort the peaks first by run, then bank #, and save the list of
77 // workspace indices of it
78 using bankMap_t = std::map<int, std::vector<size_t>>;
79 using runMap_t = std::map<int, bankMap_t>;
80 std::set<int, std::less<int>> uniqueBanks;
81 // We cannot assume the peaks have bank type detector modules, so we have a
82 // string to check this
83 std::string bankPart = "bank";
84 if (inst->getName() == "WISH")
85 bankPart = "WISHpanel";
86
87 // Get all children
88 std::vector<IComponent_const_sptr> comps;
89 inst->getChildren(comps, true);
90
91 for (auto &comp : comps) {
92 std::string bankName = comp->getName();
93 boost::trim(bankName);
94 boost::erase_all(bankName, bankPart);
95 int bank = 0;
96 Strings::convert(bankName, bank);
97 if (bank == 0)
98 continue;
99 if (bankMasked(comp, detectorInfo))
100 continue;
101 // Track unique bank numbers
102 uniqueBanks.insert(bank);
103 }
104 runMap_t runMap;
105 for (size_t i = 0; i < peaks.size(); ++i) {
106 const Peak &p = peaks[i];
107 if (p.getIntMNP() != V3D(0, 0, 0))
109 int run = p.getRunNumber();
110 int bank = 0;
111 std::string bankName = p.getBankName();
112 if (bankName.size() <= 4) {
113 g_log.information() << "Could not interpret bank number of peak " << i << "(" << bankName << ")\n";
114 continue;
115 }
116 // Save the "bank" part once to check whether it really is a bank
117 if (bankPart == "?")
118 bankPart = bankName.substr(0, 4);
119 // Take out the "bank" part of the bank name and convert to an int
120 if (bankPart == "bank")
121 bankName = bankName.substr(4, bankName.size() - 4);
122 else if (bankPart == "WISHpanel")
123 bankName = bankName.substr(9, bankName.size() - 9);
124 Strings::convert(bankName, bank);
125
126 // Save in the map
127 runMap[run][bank].emplace_back(i);
128 }
130 header = "2 SEQN H K L M N P COL ROW CHAN "
131 " L2 2_THETA AZ WL D IPK "
132 " INTI SIGI RFLG";
133
134 if (!inst)
135 throw std::runtime_error("No instrument in PeaksWorkspace. Cannot save peaks file.");
136
137 if (bankPart != "bank" && bankPart != "WISHpanel" && bankPart != "?") {
138 std::ostringstream mess;
139 mess << "Detector module of type " << bankPart << " not supported in ISAWPeaks. Cannot save peaks file";
140 throw std::runtime_error(mess.str());
141 }
142
143 double l1;
144 V3D beamline;
145 double beamline_norm;
146 V3D samplePos;
147 inst->getInstrumentParameters(l1, beamline, beamline_norm, samplePos);
148
149 std::ofstream out;
150 bool append = getProperty("AppendFile");
151 const bool renumber = getProperty("RenumberPeaks");
152
153 // do not append if file does not exist
154 if (!Poco::File(filename.c_str()).exists())
155 append = false;
156
157 int appendPeakNumb = 0;
158 if (append) {
159 std::ifstream infile(filename.c_str());
160 std::string line;
161 while (!infile.eof()) // To get you all the lines.
162 {
163 getline(infile, line); // Saves the line in STRING.
164 if (infile.eof())
165 break;
166 std::stringstream ss(line);
167 double three;
168 ss >> three;
169 if (three == 3) {
170 int peakNumber;
171 ss >> peakNumber;
172 appendPeakNumb = std::max(peakNumber, appendPeakNumb);
173 }
174 }
175
176 infile.close();
177 out.open(filename.c_str(), std::ios::app);
178 appendPeakNumb = appendPeakNumb + 1;
179 } else {
180 out.open(filename.c_str());
181
182 const auto instrumentName = inst->getName();
183 std::string facilityName;
184 try {
185 facilityName = ConfigService::Instance().getInstrument(instrumentName).facility().name();
186 } catch (Exception::NotFoundError &) {
187 g_log.warning() << "Instrument " << instrumentName
188 << " not found at any defined facility. Setting facility "
189 "name to Unknown\n";
190 facilityName = "Unknown";
191 }
192 out << "Version: 2.0 Facility: " << facilityName;
193 out << " Instrument: " << instrumentName << " Date: ";
194
195 // TODO: The experiment date might be more useful than the instrument date.
196 // For now, this allows the proper instrument to be loaded back after
197 // saving.
198 Types::Core::DateAndTime expDate = inst->getValidFromDate() + 1.0;
199 out << expDate.toISO8601String();
201 out << " MOD";
202 out << '\n';
203
204 out << "6 L1 T0_SHIFT\n";
205 out << "7 " << std::setw(10);
206 out << std::setprecision(4) << std::fixed << (l1 * 100);
207 out << std::setw(12) << std::setprecision(3) << std::fixed;
208 // Time offset from property
209 const API::Run &run = ws->run();
210 double T0 = 0.0;
211 if (run.hasProperty("T0")) {
212 T0 = run.getPropertyValueAsType<double>("T0");
213 if (T0 != 0) {
214 g_log.notice() << "T0 = " << T0 << '\n';
215 }
216 }
217 out << T0 << '\n';
218
219 // Save .detcal info
220 out << "4 DETNUM NROWS NCOLS WIDTH HEIGHT DEPTH DETD CenterX "
221 " CenterY CenterZ BaseX BaseY BaseZ UpX UpY "
222 " UpZ\n";
223 // Here would save each detector...
224 for (const auto bank : uniqueBanks) {
225 // Build up the bank name
226 std::ostringstream mess;
227 if (bankPart == "bank")
228 mess << "bank" << bank;
229 else if (bankPart == "WISHpanel") {
230 mess << "WISHpanel" << std::setfill('0') << std::setw(2) << bank;
231 }
232
233 std::string bankName = mess.str();
234 // Retrieve it
235 std::shared_ptr<const IComponent> det = inst->getComponentByName(bankName);
236 if (inst->getName() == "CORELLI") // for Corelli with sixteenpack under bank
237 {
238 std::vector<Geometry::IComponent_const_sptr> children;
239 auto asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(inst->getComponentByName(bankName));
240 asmb->getChildren(children, false);
241 det = children[0];
242 }
243 if (det) {
244 // Center of the detector
245 V3D center = det->getPos();
246
247 // Distance to center of detector
248 double detd = (center - inst->getSample()->getPos()).norm();
249 int NCOLS, NROWS;
250 double xsize, ysize;
251 sizeBanks(bankName, NCOLS, NROWS, xsize, ysize);
252 // Base unit vector (along the horizontal, X axis)
253 int midX = NCOLS / 2;
254 int midY = NROWS / 2;
255 V3D base = findPixelPos(bankName, midX + 1, midY) - findPixelPos(bankName, midX, midY);
256 base.normalize();
257
258 // Up unit vector (along the vertical, Y axis)
259 V3D up = findPixelPos(bankName, midX, midY + 1) - findPixelPos(bankName, midX, midY);
260 up.normalize();
261
262 // Write the line
263 out << "5 " << std::setw(6) << std::right << bank << " " << std::setw(6) << std::right << NROWS << " "
264 << std::setw(6) << std::right << NCOLS << " " << std::setw(7) << std::right << std::fixed
265 << std::setprecision(4) << 100.0 * xsize << " " << std::setw(7) << std::right << std::fixed
266 << std::setprecision(4) << 100.0 * ysize << " "
267 << " 0.2000 " << std::setw(6) << std::right << std::fixed << std::setprecision(2) << 100.0 * detd << " "
268 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.X() << " "
269 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.Y() << " "
270 << std::setw(9) << std::right << std::fixed << std::setprecision(4) << 100.0 * center.Z() << " "
271 << std::setw(8) << std::right << std::fixed << std::setprecision(5) << base.X() << " " << std::setw(8)
272 << std::right << std::fixed << std::setprecision(5) << base.Y() << " " << std::setw(8) << std::right
273 << std::fixed << std::setprecision(5) << base.Z() << " " << std::setw(8) << std::right << std::fixed
274 << std::setprecision(5) << up.X() << " " << std::setw(8) << std::right << std::fixed << std::setprecision(5)
275 << up.Y() << " " << std::setw(8) << std::right << std::fixed << std::setprecision(5) << up.Z() << " \n";
276
277 } else
278 g_log.warning() << "Information about detector module " << bankName << " not found and recognised\n";
279 }
280 }
281 // HKL's are flipped by -1 because of the internal Q convention
282 // unless Crystallography convention
283 double qSign = -1.0;
284 if (ws->getConvention() == "Crystallography")
285 qSign = 1.0;
286
287 // Save all Peaks
288 // Go in order of run numbers
289 int sequenceNumber = appendPeakNumb;
290 for (const auto &runBankMap : runMap) {
291 // Start of a new run
292 const int run = runBankMap.first;
293 const auto &bankMap = runBankMap.second;
294
295 for (const auto &bankIDs : bankMap) {
296 // Start of a new bank.
297 const int bank = bankIDs.first;
298 const auto &ids = bankIDs.second;
299
300 if (!ids.empty()) {
301 // Write the bank header
302 out << "0 NRUN DETNUM CHI PHI OMEGA MONCNT\n";
303 out << "1 " << std::setw(5) << run << std::setw(7) << std::right << bank;
304
305 // Determine goniometer angles by calculating from the goniometer matrix
306 // of a peak in the list
307 Goniometer gon(peaks[ids[0]].getGoniometerMatrix());
308 std::vector<double> angles = gon.getEulerAngles("yzy");
309
310 double phi = angles[2];
311 double chi = angles[1];
312 double omega = angles[0];
313
314 out << std::setw(8) << std::fixed << std::setprecision(2) << chi << " ";
315 out << std::setw(8) << std::fixed << std::setprecision(2) << phi << " ";
316 out << std::setw(8) << std::fixed << std::setprecision(2) << omega << " ";
317
318 // Get the monitor count from the first peak (should all be the same for
319 // one run)
320 const size_t first_peak_index = ids[0];
321 const auto &first_peak = peaks[first_peak_index];
322 const double monct = first_peak.getMonitorCount();
323 out << std::setw(12) << static_cast<int>(monct) << '\n';
324 out << header << '\n';
325
326 // Go through each peak at this run / bank
327 for (auto wi : ids) {
328 const auto &peak = peaks[wi];
329
330 // Sequence (run) number
331 std::string firstNumber = "3";
333 firstNumber = "9";
334 }
335 if (renumber) {
336 out << firstNumber << std::setw(7) << sequenceNumber;
337 sequenceNumber++;
338 } else {
339 out << firstNumber << std::setw(7) << peak.getPeakNumber() + appendPeakNumb;
340 }
341
342 // HKL's are flipped by -1 because of the internal Q convention
343 // unless Crystallography convention
345 const V3D mod = peak.getIntMNP();
346 const auto intHKL = peak.getIntHKL();
347 out << std::setw(5) << Utils::round(qSign * intHKL.X()) << std::setw(5) << Utils::round(qSign * intHKL.Y())
348 << std::setw(5) << Utils::round(qSign * intHKL.Z());
349
350 out << std::setw(5) << Utils::round(qSign * mod[0]) << std::setw(5) << Utils::round(qSign * mod[1])
351 << std::setw(5) << Utils::round(qSign * mod[2]);
352 } else {
353 out << std::setw(5) << Utils::round(qSign * peak.getH()) << std::setw(5)
354 << Utils::round(qSign * peak.getK()) << std::setw(5) << Utils::round(qSign * peak.getL());
355 }
356
357 // Row/column
358 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getCol()) << " ";
359
360 out << std::setw(8) << std::fixed << std::setprecision(2) << static_cast<double>(peak.getRow()) << " ";
361
362 out << std::setw(8) << std::fixed << std::setprecision(0) << peak.getTOF() << " ";
363
364 out << std::setw(9) << std::fixed << std::setprecision(3) << (peak.getL2() * 100.0) << " ";
365
366 // This is the scattered beam direction
367 const V3D dir = peak.getDetPos() - inst->getSample()->getPos();
368 double scattering, azimuth;
369
370 // Two-theta = polar angle = scattering angle = between +Z vector and
371 // the scattered beam
372 scattering = dir.angle(V3D(0.0, 0.0, 1.0));
373
374 // "Azimuthal" angle: project the scattered beam direction onto the XY
375 // plane,
376 // and calculate the angle between that and the +X axis (right-handed)
377 azimuth = atan2(dir.Y(), dir.X());
378
379 out << std::setw(9) << std::fixed << std::setprecision(5) << scattering << " "; // two-theta scattering
380
381 out << std::setw(9) << std::fixed << std::setprecision(5) << azimuth << " ";
382
383 out << std::setw(10) << std::fixed << std::setprecision(6) << peak.getWavelength() << " ";
384
385 out << std::setw(9) << std::fixed << std::setprecision(4) << peak.getDSpacing() << " ";
386
387 out << std::setw(8) << std::fixed << std::setprecision(0) << int(peak.getBinCount()) << " ";
388
389 out << std::setw(10) << std::fixed << std::setprecision(2) << peak.getIntensity() << " ";
390
391 out << std::setw(7) << std::fixed << std::setprecision(2) << peak.getSigmaIntensity() << " ";
392
393 int thisReflag = 310;
394 out << std::setw(5) << thisReflag;
395
396 out << '\n';
397
398 Workspace2D_sptr wsProfile2D = getProperty("ProfileWorkspace");
399 if (wsProfile2D) {
400 out << "8";
401 const auto &yValues = wsProfile2D->y(wi);
402 for (size_t j = 0; j < yValues.size(); j++) {
403 out << std::setw(8) << static_cast<int>(yValues[j]);
404 if ((j + 1) % 10 == 0) {
405 out << '\n';
406 if (j + 1 != yValues.size())
407 out << "8";
408 }
409 }
410 }
411 }
412 }
413 }
414 }
415
416 out.flush();
417 out.close();
418}
419
421 std::vector<Geometry::IComponent_const_sptr> children;
422 auto asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
423 asmb->getChildren(children, false);
424 if (children[0]->getName() == "sixteenpack") {
425 asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
426 children.clear();
427 asmb->getChildren(children, false);
428 }
429
430 for (const auto &col : children) {
431 auto asmb2 = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(col);
432 std::vector<Geometry::IComponent_const_sptr> grandchildren;
433 asmb2->getChildren(grandchildren, false);
434 for (const auto &row : grandchildren) {
435 auto *d = dynamic_cast<Detector *>(const_cast<IComponent *>(row.get()));
436 if (d) {
437 auto detID = d->getID();
438 if (detID < 0)
439 continue;
440 const auto index = detectorInfo.indexOf(detID);
441 if (!detectorInfo.isMasked(index))
442 return false;
443 }
444 }
445 }
446 return true;
447}
448
449V3D SaveIsawPeaks::findPixelPos(const std::string &bankName, int col, int row) {
450 auto parent = inst->getComponentByName(bankName);
451 if (parent->type() == "RectangularDetector") {
452 const auto RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
453 const auto pixel = RDet->getAtXY(col, row);
454 return pixel->getPos();
455 } else {
456 std::vector<Geometry::IComponent_const_sptr> children;
457 auto asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
458 asmb->getChildren(children, false);
459 if (children[0]->getName() == "sixteenpack") {
460 asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
461 children.clear();
462 asmb->getChildren(children, false);
463 }
464 int col0 = col - 1;
465 // WISH detectors are in bank in this order in instrument
466 if (inst->getName() == "WISH")
467 col0 = (col % 2 == 0 ? col / 2 + 75 : (col - 1) / 2);
468 auto asmb2 = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[col0]);
469 std::vector<Geometry::IComponent_const_sptr> grandchildren;
470 asmb2->getChildren(grandchildren, false);
471 auto first = grandchildren[row - 1];
472 return first->getPos();
473 }
474}
475void SaveIsawPeaks::sizeBanks(const std::string &bankName, int &NCOLS, int &NROWS, double &xsize, double &ysize) {
476 if (bankName == "None")
477 return;
478 const auto parent = inst->getComponentByName(bankName);
479 if (parent->type() == "RectangularDetector") {
480 const auto RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
481
482 NCOLS = RDet->xpixels();
483 NROWS = RDet->ypixels();
484 xsize = RDet->xsize();
485 ysize = RDet->ysize();
486 } else {
487 std::vector<Geometry::IComponent_const_sptr> children;
488 auto asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(parent);
489 asmb->getChildren(children, false);
490 if (children[0]->getName() == "sixteenpack") {
491 asmb = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
492 children.clear();
493 asmb->getChildren(children, false);
494 }
495 const auto asmb2 = std::dynamic_pointer_cast<const Geometry::ICompAssembly>(children[0]);
496 std::vector<Geometry::IComponent_const_sptr> grandchildren;
497 asmb2->getChildren(grandchildren, false);
498 NROWS = static_cast<int>(grandchildren.size());
499 NCOLS = static_cast<int>(children.size());
500 auto first = children[0];
501 auto last = children[NCOLS - 1];
502 xsize = first->getDistance(*last);
503 first = grandchildren[0];
504 last = grandchildren[NROWS - 1];
505 ysize = first->getDistance(*last);
506 }
507}
508void SaveIsawPeaks::writeOffsets(std::ofstream &out, double qSign, std::vector<double> offset) {
509 for (size_t i = 0; i < 3; i++) {
510 out << std::setw(12) << std::fixed << std::setprecision(6) << qSign * offset[i] << " ";
511 }
512}
513} // namespace Mantid::Crystal
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::string getName(const IMDDimension &self)
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
@ Save
to specify a file to write to, the file may or may not exist
Definition: FileProperty.h:49
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Definition: LogManager.cpp:265
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
Definition: LogManager.cpp:332
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
A property class for workspaces.
Save a PeaksWorkspace to a ISAW-style ASCII .peaks file.
Definition: SaveIsawPeaks.h:23
bool m_isModulatedStructure
Flag for writing modulated structures.
Definition: SaveIsawPeaks.h:38
bool bankMasked(const Geometry::IComponent_const_sptr &parent, const Geometry::DetectorInfo &detectorInfo)
void writeOffsets(std::ofstream &out, double qSign, std::vector< double > offset)
void exec() override
Run the algorithm.
Kernel::V3D findPixelPos(const std::string &bankName, int col, int row)
find position for rectangular and non-rectangular
Geometry::Instrument_const_sptr inst
Definition: SaveIsawPeaks.h:49
void sizeBanks(const std::string &bankName, int &NCOLS, int &NROWS, double &xsize, double &ysize)
Mantid::Kernel::V3D getIntMNP() const override
Return the int MNP vector.
Definition: BasePeak.cpp:116
int getRunNumber() const override
Return the run number this peak was measured at.
Definition: BasePeak.cpp:78
Structure describing a single-crystal peak.
Definition: Peak.h:34
std::string getBankName() const
Find the name of the bank that is the parent of the detector.
Definition: Peak.cpp:353
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
Definition: DetectorInfo.h:49
bool isMasked(const size_t index) const
Returns true if the detector is masked.
size_t indexOf(const detid_t id) const
Returns the index of the detector with the given detector ID.
This class represents a detector - i.e.
Definition: Detector.h:30
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.
Definition: Goniometer.cpp:282
base class for Geometric IComponent
Definition: IComponent.h:51
Exception for when an item is not found in a collection.
Definition: Exception.h:145
void notice(const std::string &msg)
Logs at notice level.
Definition: Logger.cpp:95
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition: V3D.h:34
constexpr double X() const noexcept
Get x.
Definition: V3D.h:232
double normalize()
Make a normalized vector (return norm value)
Definition: V3D.cpp:130
constexpr double Y() const noexcept
Get y.
Definition: V3D.h:233
constexpr double Z() const noexcept
Get z.
Definition: V3D.h:234
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition: IComponent.h:161
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition: Strings.cpp:665
long round(double x)
Custom rounding method for a double->long because none is portable in C++ (!)
Definition: Utils.h:37
Peak indexing algorithm, which works by assigning multiple possible HKL values to each peak and then ...
Definition: IndexSXPeaks.h:29
@ Input
An input workspace.
Definition: Property.h:53