20#include <boost/algorithm/string.hpp>
21#include <boost/algorithm/string/finder.hpp>
22#include <boost/algorithm/string/iter_find.hpp>
23#include <boost/algorithm/string/predicate.hpp>
24#include <boost/algorithm/string/trim.hpp>
26#include <Poco/DOM/AutoPtr.h>
27#include <Poco/DOM/DOMWriter.h>
28#include <Poco/DOM/Element.h>
52 declareProperty(std::make_unique<FileProperty>(
"Filename",
"",
FileProperty::Load,
".prm"),
53 "Path to an GSAS file to load.");
56 auto wsprop = std::make_unique<WorkspaceProperty<API::ITableWorkspace>>(
"OutputTableWorkspace",
"",
Direction::Output,
58 declareProperty(std::move(wsprop),
"Name of the output TableWorkspace containing "
59 "instrument parameter information read from file. ");
63 "Use bank IDs as given in file rather than ordinal number of bank. "
64 "If the bank IDs in the file are not unique, it is advised to set this "
68 declareProperty(std::make_unique<
ArrayProperty<int>>(
"Banks"),
"ID(s) of specified bank(s) to load, "
69 "The IDs are as specified by UseBankIDsInFile. "
70 "Default is all banks contained in input .prm file.");
76 "A workspace group with the instrument to which we add the "
77 "parameters from the GSAS instrument file, with one "
78 "workspace for each bank of the .prm file");
83 " the ID of the corresponding workspace in same order as the "
84 "banks are specified. "
85 "ID=1 refers to the first workspace in the workspace group, "
86 "ID=2 refers to the second workspace and so on. "
87 "Default is all workspaces in numerical order. "
88 "If default banks are specified, they too are taken to be in "
100 vector<string> lines;
105 if (histType !=
"PNTR") {
106 throw std::runtime_error(
"Error on checking histogram type: " + histType +
"\n");
110 g_log.
debug() << numBanks <<
"banks in file \n";
113 vector<size_t> bankStartIndex;
116 if (bankStartIndex.empty()) {
117 throw std::runtime_error(
"No nanks found in file. \n");
120 if (numBanks != bankStartIndex.size()) {
123 g_log.
warning() <<
"The number of banks found" << bankStartIndex.size()
124 <<
"is not equal to the number of banks stated" << numBanks <<
".\n";
126 numBanks = bankStartIndex.size();
130 map<size_t, map<string, double>> bankparammap;
131 for (
size_t i = 0; i < numBanks; ++i) {
132 size_t bankid = i + 1;
133 g_log.
debug() <<
"Parse bank " << bankid <<
" of total " << numBanks <<
".\n";
134 map<string, double> parammap;
135 parseBank(parammap, lines, bankid, bankStartIndex[bankid - 1]);
136 bankparammap.emplace(bankid, parammap);
137 g_log.
debug() <<
"Bank starts at line" << bankStartIndex[i] + 1 <<
"\n";
150 vector<int> workspaceIds =
getProperty(
"WorkspacesForBanks");
151 map<int, size_t> workspaceOfBank;
154 if (!bankIds.empty()) {
157 for (
auto bankId : bankIds) {
158 if (!bankparammap.count(bankId)) {
159 std::stringstream errorString;
160 errorString <<
"Bank " << bankId <<
" not found in .prm file";
161 throw runtime_error(errorString.str());
166 bankIds.reserve(bankparammap.size());
167 std::transform(bankparammap.cbegin(), bankparammap.cend(), std::back_inserter(bankIds),
168 [](
const auto &bank) { return static_cast<int>(bank.first); });
175 for (
size_t i = 0; i < bankIds.size(); ++i) {
176 int bankId = bankIds[i];
177 size_t wsId = workspaceOfBank[bankId];
179 auto workspace = std::dynamic_pointer_cast<MatrixWorkspace>(wsi);
182 std::string parameterXMLString;
184 OutTabColumn,
workspace,
static_cast<int>(bankparammap[i][
"NPROF"]), parameterXMLString);
187 loadParamAlg->setProperty(
"ParameterXML", parameterXMLString);
188 loadParamAlg->setProperty(
"Workspace",
workspace);
189 loadParamAlg->execute();
203 ifstream myfile(filename.c_str());
206 if (myfile.is_open()) {
209 while (!myfile.eof()) {
212 getline(myfile, line);
215 boost::algorithm::trim(line);
217 lines.emplace_back(line);
224 errmsg <<
"Input .prm file " << filename <<
" cannot be open. ";
226 throw runtime_error(errmsg.str());
237 std::string lookFor =
"INS HTYPE";
238 for (
size_t i = 0; i < lines.size(); ++i) {
239 if (lines[i].substr(0, lookFor.size()) == lookFor) {
240 if (lines[i].size() < lookFor.size() + 7) {
242 return "HTYPE line too short";
244 return lines[i].substr(lookFor.size() + 3, 4);
247 return "HTYPE line not found";
257 std::string lookFor =
"INS BANK";
258 for (
size_t i = 0; i < lines.size(); ++i) {
259 if (lines[i].substr(0, lookFor.size()) == lookFor) {
260 if (lines[i].size() < lookFor.size() + 3) {
264 return boost::lexical_cast<size_t>(lines[i].substr(lookFor.size() + 2, 1));
280 for (
size_t i = 0; i < lines.size(); ++i) {
281 string line = lines[i];
282 if (line.substr(0, 3) ==
"INS") {
283 if (line.find(
"BNKPAR") != string::npos) {
284 bankStartIndex.emplace_back(i);
299 size_t bankid,
size_t startlineindex) {
300 double param1, param2, param3, param4;
305 size_t currentLineIndex =
findINSPRCFLine(lines, startlineindex, param1, param2, param3, param4);
307 parammap[
"NPROF"] = param2;
311 currentLineIndex =
findINSPRCFLine(lines, currentLineIndex + 1, param1, param2, param3, param4);
312 parammap[
"Alph0"] = param1;
313 parammap[
"Alph1"] = param2;
314 parammap[
"Beta0"] = param3;
315 parammap[
"Beta1"] = param4;
317 currentLineIndex =
findINSPRCFLine(lines, currentLineIndex + 1, param1, param2, param3, param4);
318 parammap[
"Sig0"] = param1;
319 parammap[
"Sig1"] = param2;
320 parammap[
"Sig2"] = param3;
321 parammap[
"Gam0"] = param4;
323 findINSPRCFLine(lines, currentLineIndex + 1, param1, param2, param3, param4);
324 parammap[
"Gam1"] = param1;
325 parammap[
"Gam2"] = param2;
327 g_log.
warning() <<
"Bank" << bankid <<
"stec not 0, but " << param3;
330 g_log.
warning() <<
"Bank" << bankid <<
"ptec not 0, but " << param4;
346 double ¶m2,
double ¶m3,
double ¶m4) {
347 for (
size_t i = lineIndex; i < lines.size(); ++i) {
348 string line = lines[i];
349 if ((line.substr(0, 3) ==
"INS") && (line.substr(6, 4) ==
"PRCF")) {
350 std::istringstream paramLine;
351 paramLine.str(lines[i].substr(15));
352 paramLine >> param1 >> param2 >> param3 >> param4;
356 throw std::runtime_error(
"Unexpected end of file reached while searching for INS line. \n");
366 g_log.
notice() <<
"Start to generate table workspace ...."
370 size_t numbanks = bankparammap.size();
372 throw runtime_error(
"Unable to generate a table from an empty map!");
374 auto bankmapiter = bankparammap.begin();
375 size_t numparams = bankmapiter->second.size();
378 vector<string> vec_parname;
379 vector<size_t> vec_bankids;
381 map<string, double>::iterator parmapiter;
382 for (parmapiter = bankmapiter->second.begin(); parmapiter != bankmapiter->second.end(); ++parmapiter) {
383 string parname = parmapiter->first;
384 vec_parname.emplace_back(parname);
387 for (bankmapiter = bankparammap.begin(); bankmapiter != bankparammap.end(); ++bankmapiter) {
388 size_t bankid = bankmapiter->first;
389 vec_bankids.emplace_back(bankid);
392 g_log.
debug() <<
"[DBx240] Number of imported parameters is " << numparams
393 <<
", Number of banks = " << vec_bankids.size() <<
"."
397 auto tablews = std::make_shared<TableWorkspace>();
401 tablews->addColumn(
"str",
"Name");
402 for (
size_t i = 0; i < numbanks; ++i) {
403 stringstream colnamess;
404 size_t bankid = vec_bankids[i];
405 colnamess <<
"Value_" << bankid;
406 tablews->addColumn(
"double", colnamess.str());
409 g_log.
debug() <<
"Number of column = " << tablews->columnCount() <<
".\n";
412 TableRow newrow = tablews->appendRow();
414 for (
size_t i = 0; i < numbanks; ++i)
415 newrow <<
static_cast<double>(vec_bankids[i]);
417 g_log.
debug() <<
"Number of row now = " << tablews->rowCount() <<
".\n";
420 for (
size_t i = 0; i < numparams; ++i) {
421 newrow = tablews->appendRow();
423 string parname = vec_parname[i];
426 for (
size_t j = 0; j < numbanks; ++j) {
427 size_t bankid = vec_bankids[j];
430 map<size_t, map<string, double>>::iterator bpmapiter;
431 bpmapiter = bankparammap.find(bankid);
432 if (bpmapiter == bankparammap.end()) {
433 throw runtime_error(
"Bank cannot be found in map.");
437 parmapiter = bpmapiter->second.find(parname);
438 if (parmapiter == bpmapiter->second.end()) {
439 throw runtime_error(
"Parameter cannot be found in a bank's map.");
441 double pvalue = parmapiter->second;
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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.
@ Load
allowed here which will be passed to the algorithm
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
static void getTableRowNumbers(const API::ITableWorkspace_sptr &tablews, std::map< std::string, size_t > ¶mmap)
Get row numbers of the parameters in the table workspace.
static void putParametersIntoWorkspace(const API::Column_const_sptr &, const API::MatrixWorkspace_sptr &ws, int nProf, std::string ¶meterXMLString)
Put parameters into a matrix workspace.
static void createBankToWorkspaceMap(const std::vector< int > &banks, const std::vector< int > &workspaces, std::map< int, size_t > &workspaceOfBank)
Create Bank to Workspace Correspondence.
static std::map< std::string, size_t > m_rowNumbers
Place to store the row numbers.
LoadGSASInstrumentFile : Load GSAS instrument file to TableWorkspace(s)
std::string getHistogramType(const std::vector< std::string > &lines)
Get Histogram type.
size_t findINSPRCFLine(const std::vector< std::string > &lines, size_t lineIndex, double ¶m1, double ¶m2, double ¶m3, double ¶m4)
Find first INS line at or after lineIndex.
size_t getNumberOfBanks(const std::vector< std::string > &lines)
Get Number of banks.
DataObjects::TableWorkspace_sptr genTableWorkspace(std::map< size_t, std::map< std::string, double > > bankparammap)
Generate output workspace.
void scanBanks(const std::vector< std::string > &lines, std::vector< size_t > &bankStartIndex)
Scan imported file for bank information.
void exec() override
Implement abstract Algorithm methods.
void loadFile(const std::string &filename, std::vector< std::string > &lines)
Load file to a vector of strings.
void parseBank(std::map< std::string, double > ¶mmap, const std::vector< std::string > &lines, size_t bankid, size_t startlineindex)
Parse bank in file to a map.
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
The concrete, templated class for properties.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const Column > Column_const_sptr
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
Helper class which provides the Collimation Length for SANS instruments.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.
@ Output
An output workspace.