25#include <boost/algorithm/string/trim.hpp>
49 const std::string &extn = descriptor.
extension();
51 if (extn !=
".peaks" && extn !=
".integrate")
56 auto &in = descriptor.
data();
59 std::string r = getWord(in,
false);
62 throw std::logic_error(std::string(
"No first line of Peaks file"));
65 throw std::logic_error(std::string(
"No Version: on first line of Peaks file"));
67 std::string C_version = getWord(in,
false);
68 if (C_version.length() < 1)
69 throw std::logic_error(std::string(
"No Version for Peaks file"));
75 std::string C_Instrument = getWord(in,
false);
77 if (C_Instrument.length() < 1)
78 throw std::logic_error(std::string(
"No Instrument for Peaks file"));
81 Types::Core::DateAndTime C_experimentDate;
82 tag = getWord(in,
false);
85 readToEndOfLine(in,
true);
87 }
catch (std::exception &) {
97 const std::vector<std::string> exts{
".peaks",
".integrate"};
99 "Path to an ISAW-style .peaks filename.");
101 "Name of the output workspace.");
115 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<Workspace>(ws));
129 std::string r = getWord(in,
false);
132 throw std::logic_error(std::string(
"No first line of Peaks file"));
135 throw std::logic_error(std::string(
"No Version: on first line of Peaks file"));
137 std::string C_version = getWord(in,
false);
138 if (C_version.length() < 1)
139 throw std::logic_error(std::string(
"No Version for Peaks file"));
145 std::string C_Instrument = getWord(in,
false);
147 if (C_Instrument.length() < 1)
148 throw std::logic_error(std::string(
"No Instrument for Peaks file"));
151 Types::Core::DateAndTime C_experimentDate;
153 tag = getWord(in,
false);
155 date = Types::Core::DateAndTime::getCurrentTime().toISO8601String();
156 else if (tag ==
"Date:")
157 date = getWord(in,
false);
158 tag = getWord(in,
false);
160 readToEndOfLine(in,
true);
164 tempWS->mutableRun().addProperty<std::string>(
"run_start", date);
167 loadInst->setPropertyValue(
"InstrumentName", C_Instrument);
170 loadInst->executeAsChildAlg();
174 tempWS->populateInstrumentParameters();
176 outWS->setInstrument(instr);
179 applyCal->initialize();
180 applyCal->setProperty(
"InputWorkspace", outWS);
182 applyCal->executeAsChildAlg();
183 T0 = applyCal->getProperty(
"TimeOffset");
188 std::vector<int> det;
189 while (s !=
"0" && in.good()) {
190 readToEndOfLine(in,
true);
191 s = getWord(in,
false);
196 det.emplace_back(bank);
199 std::string maskBanks;
201 throw std::runtime_error(
"No instrument in the Workspace. Cannot save DetCal file.");
204 std::string bankPart =
"bank";
205 if (instr->getName() ==
"WISH")
206 bankPart =
"WISHpanel";
208 const auto &componentInfo = outWS->componentInfo();
210 size_t const rootIndex = componentInfo.root();
211 auto const topChildren = componentInfo.children(rootIndex);
212 for (
size_t const i : topChildren) {
214 size_t bankParent = componentInfo.findBankParent(i, bankPart);
215 auto const children = componentInfo.children(bankParent);
216 for (
size_t const child : children) {
217 std::string bankName = componentInfo.name(child);
218 boost::trim(bankName);
219 boost::erase_all(bankName, bankPart);
222 maskBanks += bankName +
",";
227 if (!maskBanks.empty()) {
229 maskBanks.resize(maskBanks.size() - 1);
234 alg->setProperty(
"Bank", maskBanks);
235 alg->setProperty(
"Instrument", instr->getName());
237 throw std::runtime_error(
"MaskDetectors Child Algorithm has not executed successfully");
239 g_log.
error(
"Can't execute MaskBTP algorithm");
257 int &seqNum,
const std::string &bankName,
double qSign) {
268 std::string s = lastStr;
270 if (s.length() < 1 && in.good())
272 readToEndOfLine(in,
true);
273 s = getWord(in,
false);
277 throw std::runtime_error(
"Empty peak line encountered.");
280 readToEndOfLine(in,
true);
281 for (s = getWord(in,
false); s.length() < 1 && in.good(); s = getWord(in,
true)) {
282 s = getWord(in,
false);
287 throw std::runtime_error(
"Empty peak line encountered.");
292 if (s !=
"3" && s !=
"9")
293 throw std::runtime_error(
"Empty peak line encountered.");
295 seqNum = std::stoi(getWord(in,
false));
297 h = qSign * std::stod(getWord(in,
false),
nullptr);
298 k = qSign * std::stod(getWord(in,
false),
nullptr);
299 l = qSign * std::stod(getWord(in,
false),
nullptr);
303 mod[0] = qSign * std::stoi(getWord(in,
false),
nullptr);
304 mod[1] = qSign * std::stoi(getWord(in,
false),
nullptr);
305 mod[2] = qSign * std::stoi(getWord(in,
false),
nullptr);
308 col = std::stod(getWord(in,
false),
nullptr);
309 row = std::stod(getWord(in,
false),
nullptr);
310 UNUSED_ARG(std::stod(getWord(in,
false),
nullptr));
311 UNUSED_ARG(std::stod(getWord(in,
false),
nullptr));
312 UNUSED_ARG(std::stod(getWord(in,
false),
nullptr));
314 UNUSED_ARG(std::stod(getWord(in,
false),
nullptr));
315 wl = std::stod(getWord(in,
false),
nullptr);
316 UNUSED_ARG(std::stod(getWord(in,
false),
nullptr));
317 IPK = std::stod(getWord(in,
false),
nullptr);
319 Inti = std::stod(getWord(in,
false),
nullptr);
320 SigI = std::stod(getWord(in,
false),
nullptr);
324 readToEndOfLine(in,
true);
325 lastStr = getWord(in,
false);
330 throw std::runtime_error(
"No instrument in PeaksWorkspace!");
332 int pixelID =
findPixelID(outWS, bankName,
static_cast<int>(col),
static_cast<int>(row));
335 Peak peak(outWS->getInstrument(), pixelID, wl);
355 if (parent->type() ==
"RectangularDetector") {
356 std::shared_ptr<const RectangularDetector> RDet = std::dynamic_pointer_cast<const RectangularDetector>(parent);
358 std::shared_ptr<Detector> pixel = RDet->getAtXY(col, row);
359 return pixel->getID();
361 const auto &componentInfo = ws->componentInfo();
362 const size_t parentIndex = componentInfo.indexOfAny(bankName);
363 auto children = componentInfo.children(parentIndex);
365 if (!children.empty() && componentInfo.name(children[0]) ==
"sixteenpack") {
366 children = componentInfo.children(children[0]);
370 if (inst->getName() ==
"WISH")
371 col0 = (col % 2 == 0 ? col / 2 + 75 : (col - 1) / 2);
373 auto grandchildren = componentInfo.children(children[col0]);
374 const auto *first = componentInfo.componentID(grandchildren[row - 1]);
386 double &chi,
double &phi,
double &omega,
double &monCount) {
387 std::string s = std::move(lastStr);
389 if (s.length() < 1 && in.good())
391 readToEndOfLine(in,
true);
392 s = getWord(in,
false);
396 return std::string();
399 readToEndOfLine(in,
true);
400 s = getWord(in,
false);
401 while (s.length() < 1) {
402 readToEndOfLine(in,
true);
403 s = getWord(in,
false);
410 run = std::stoi(getWord(in,
false));
411 detName = std::stoi(getWord(in,
false));
412 chi = std::stod(getWord(in,
false),
nullptr);
413 phi = std::stod(getWord(in,
false),
nullptr);
415 omega = std::stod(getWord(in,
false),
nullptr);
416 monCount = std::stod(getWord(in,
false),
nullptr);
417 readToEndOfLine(in,
true);
419 return getWord(in,
false);
432 std::string convention = ConfigService::Instance().getString(
"Q.convention");
433 if (convention ==
"Crystallography")
436 std::ifstream in(filename.c_str());
440 auto filelen = in.tellg();
447 API::Run &m_run = outWS->mutableRun();
450 if (!in.good() || s.length() < 1)
451 throw std::runtime_error(
"End of Peaks file before peaks");
454 throw std::logic_error(
"No header for Peak segments");
456 readToEndOfLine(in,
true);
457 s = getWord(in,
false);
460 double chi, phi, omega, monCount;
467 Progress prog(
this, 0.0, 1.0, filelen);
477 outWS->mutableRun().setGoniometer(uniGonio,
false);
479 std::ostringstream oss;
480 std::string bankString =
"bank";
481 if (outWS->getInstrument()->getName() ==
"WISH") {
483 bankString =
"WISHpanel0";
485 bankString =
"WISHpanel";
487 oss << bankString << bankNum;
488 std::string bankName = oss.str();
494 Peak peak =
readPeak(outWS, s, in, seqNum, bankName, qSign);
503 double tof = peak.
getTOF();
506 wl.
initialize(peak.
getL1(), 0, {{UnitParams::l2, peak.getL2()}, {UnitParams::twoTheta, peak.getScattering()}});
508 peak.setWavelength(wl.singleFromTOF(tof));
510 outWS->addPeak(peak);
511 }
catch (std::runtime_error &e) {
512 g_log.
error() <<
"Error reading peak SEQN " << seqNum <<
" : " << e.what() <<
'\n';
513 throw std::runtime_error(
"Corrupted input file. ");
519 if (m_isModulatedStructure) {
520 auto findUB = createChildAlgorithm(
"FindUBUsingIndexedPeaks");
521 findUB->setPropertyValue(
"ToleranceForSatellite",
"0.05");
523 findUB->executeAsChildAlg();
525 if (outWS->mutableSample().hasOrientedLattice()) {
526 OrientedLattice o_lattice = outWS->mutableSample().getOrientedLattice();
527 auto &peaks = outWS->getPeaks();
528 for (
auto &peak : peaks) {
530 V3D hkl = peak.getHKL();
531 V3D mnp = peak.getIntMNP();
532 for (
int i = 0; i <= 2; i++)
538 }
catch (std::runtime_error &e) {
539 g_log.
warning() <<
"Could not recalculate modulated UB\n";
540 g_log.
warning() <<
"Load a modulated UB workspace on this workspace to recover the modulation vectors\n";
541 g_log.
warning() <<
"Error calculating UB : " << e.what() <<
'\n';
553 std::ifstream in(filename.c_str());
556 while (getline(in, first)) {
557 if (first[0] ==
'3' || first[0] ==
'9')
560 if (NumberPeaks != outWS->getNumberPeaks()) {
561 g_log.
error() <<
"Number of peaks in file is " << NumberPeaks <<
" but only read " << outWS->getNumberPeaks()
563 throw std::length_error(
"Wrong number of peaks read");
585std::shared_ptr<const IComponent>
586LoadIsawPeaks::getCachedBankByName(
const std::string &bankname,
587 const std::shared_ptr<const Geometry::Instrument> &inst) {
588 m_banks.try_emplace(bankname, inst->getComponentByName(bankname));
589 return m_banks[bankname];
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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.
@ Load
allowed here which will be passed to the algorithm
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Helper class for reporting progress from algorithms.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
void checkNumberPeaks(const Mantid::DataObjects::PeaksWorkspace_sptr &outWS, const std::string &filename)
Compare number of peaks in given file to given workspace Throws std::length_error on mismatch.
void exec() override
Run the algorithm.
std::shared_ptr< const Geometry::IComponent > getCachedBankByName(const std::string &bankname, const std::shared_ptr< const Geometry::Instrument > &inst)
Retrieve cached bank (or load and cache for next time)
std::string readHeader(const Mantid::DataObjects::PeaksWorkspace_sptr &outWS, std::ifstream &in, double &T0)
Reads first line of peaks file and returns first word of next line.
void appendFile(const Mantid::DataObjects::PeaksWorkspace_sptr &outWS, const std::string &filename)
Append peaks from given file to given workspace.
void init() override
Initialise the properties.
int findPixelID(const DataObjects::PeaksWorkspace_sptr &ws, const std::string &bankName, int col, int row)
DataObjects::Peak readPeak(const DataObjects::PeaksWorkspace_sptr &outWS, std::string &lastStr, std::ifstream &in, int &seqNum, const std::string &bankName, double qSign)
Read a single peak from peaks file.
std::string readPeakBlockHeader(std::string lastStr, std::ifstream &in, int &run, int &detName, double &chi, double &phi, double &omega, double &monCount)
Read the header of a peak block section, returns first word of next line.
bool m_isModulatedStructure
Flag for reading modulated structures.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
void setSigmaIntensity(double m_sigmaIntensity) override
Set the error on the integrated peak intensity.
void setIntMNP(const Mantid::Kernel::V3D &MNP) override
Sets the modulated peak structure number.
void setRunNumber(int m_runNumber) override
Set the run number that measured this peak.
void setPeakNumber(int m_peakNumber) override
Sets the unique peak number.
void setMonitorCount(double m_monitorCount) override
Set the monitor count for this peak.
void setIntensity(double m_intensity) override
Set the integrated peak intensity.
void setHKL(double H, double K, double L) override
Set all three H,K,L indices of the peak.
void setIntHKL(const Kernel::V3D &HKL) override
Set int HKL.
void setGoniometerMatrix(const Mantid::Kernel::Matrix< double > &goniometerMatrix) override
Set the goniometer rotation matrix at which this peak was measured.
void setBinCount(double m_binCount) override
Set the # of counts in the bin at its peak.
Structure describing a single-crystal peak.
Geometry::Instrument_const_sptr getInstrument() const
Return a shared ptr to the instrument for this peak.
double getL1() const override
Return the L1 flight path length (source to sample), in meters.
double getTOF() const override
Calculate the time of flight (in microseconds) of the neutrons for this peak, using the geometry of t...
The class PeaksWorkspace stores information about a set of SCD peaks.
Class to represent a particular goniometer setting, which is described by the rotation matrix.
void setRotationAngle(const std::string &name, double value)
Set rotation angle for an axis using motor name.
void makeUniversalGoniometer()
Make a default universal goniometer with phi,chi,omega angles according to SNS convention.
const Kernel::DblMatrix & getR() const
Return global rotation matrix.
Interface class for detector objects.
virtual detid_t getID() const =0
Get the detector ID.
Class to implement UB matrix.
const Kernel::V3D getModVec(int j) const
Get modulation vectors for satellites.
Defines a wrapper around an open file.
std::istream & data()
Access the open file stream.
const std::string & extension() const
Access the file extension.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
OptionalBool : Tri-state bool.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void initialize(const double &_l1, const int &_emode, const UnitParametersMap ¶ms)
Initialize the unit to perform conversion using singleToTof() and singleFromTof()
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
MANTID_KERNEL_DLL void readToEndOfLine(std::istream &in, bool ConsumeEOL)
Eat everything from the stream until the next EOL.
int convert(const std::string &A, T &out)
Convert a string into a number.
MANTID_KERNEL_DLL std::string getWord(std::istream &in, bool consumeEOL)
Returns the next word in the stream.
static constexpr double h
Planck constant in J*s.
@ Output
An output workspace.