109 double primaryflightpath = -1;
110 std::vector<double> twothetas;
111 std::vector<double> difcs;
112 std::vector<double> totalflightpaths;
113 std::vector<int> detectorIDs;
116 std::vector<HistogramData::BinEdges> gsasDataX;
117 std::vector<HistogramData::Counts> gsasDataY;
118 std::vector<HistogramData::CountStandardDeviations> gsasDataE;
120 std::vector<double> vecX, vecY, vecE;
123 std::unique_ptr<Progress> prog =
nullptr;
126 char currentLine[256];
128 std::string slogTitle;
129 std::string instrumentname =
"Generic";
133 std::ifstream input(filename.c_str(), std::ios_base::in);
134 if (!input.is_open()) {
136 std::stringstream errss;
137 errss <<
"Unable to open GSAS file " << filename;
138 throw std::runtime_error(errss.str());
144 input.getline(currentLine, 256);
145 wsTitle = currentLine;
147 throw std::runtime_error(
"File is empty");
151 bool isOutOfHead =
false;
152 bool slogtitleset =
false;
153 bool multiplybybinwidth =
false;
155 bool calslogx0 =
true;
159 while (!input.eof() && input.getline(currentLine, 256)) {
161 if (nSpec != 0 && !prog) {
162 prog = std::make_unique<Progress>(
this, 0.0, 1.0, nSpec);
167 slogTitle = currentLine;
171 if (currentLine[0] ==
'\n' || currentLine[0] ==
'#') {
173 std::string key1, key2;
174 std::istringstream inputLine(currentLine, std::ios::in);
175 inputLine.ignore(256,
' ');
176 inputLine >> key1 >> key2;
178 if (key2 ==
"Histograms") {
180 nSpec = std::stoi(key1);
181 g_log.
information() <<
"Histogram Line: " << key1 <<
" nSpec = " << nSpec <<
"\n";
182 }
else if (key1 ==
"Instrument:") {
184 instrumentname = key2;
186 }
else if (key1 ==
"with") {
190 if (s1 ==
"multiplied") {
191 multiplybybinwidth =
true;
194 g_log.
warning() <<
"In line '" << currentLine <<
"', key word " << s1 <<
" is not allowed!\n";
196 }
else if (key1 ==
"Primary") {
198 boost::smatch result;
202 const std::string line = inputLine.str();
203 if (boost::regex_search(line, result, L1_REG_EXP) && result.size() == 2) {
204 primaryflightpath = std::stod(std::string(result[1]));
207 std::stringstream msg;
208 msg <<
"Failed to parse primary flight path from line \"" << inputLine.str() <<
"\"";
212 std::stringstream msg;
213 msg <<
"L1 = " << primaryflightpath;
215 }
else if (key1 ==
"Total") {
219 double totalpath(0.f);
223 boost::smatch result;
224 const std::string line = inputLine.str();
225 if (boost::regex_search(line, result, DET_POS_REG_EXP) && result.size() == 4) {
226 totalpath = std::stod(std::string(result[1]));
227 tth = std::stod(std::string(result[2]));
228 difc = std::stod(std::string(result[3]));
230 std::stringstream msg;
231 msg <<
"Failed to parse position from line \"" << inputLine.str() <<
"\"";
235 totalflightpaths.emplace_back(totalpath);
236 twothetas.emplace_back(tth);
237 difcs.emplace_back(
difc);
239 std::stringstream msg;
240 msg <<
"Bank " << difcs.size() - 1 <<
": Total flight path = " << totalpath <<
" 2Theta = " << tth
241 <<
" DIFC = " <<
difc;
246 else if (currentLine[0] ==
'B') {
253 gsasDataX.emplace_back(std::move(vecX));
254 gsasDataY.emplace_back(std::move(vecY));
255 gsasDataE.emplace_back(std::move(vecE));
272 int specno, nbin1, nbin2;
273 std::istringstream inputLine(currentLine, std::ios::in);
278 inputLine.ignore(256,
'K');
279 std::string filetypestring;
281 inputLine >> specno >> nbin1 >> nbin2 >> filetypestring;
282 g_log.
debug() <<
"Bank: " << specno <<
" filetypestring = " << filetypestring <<
'\n';
284 detectorIDs.emplace_back(specno);
286 if (filetypestring[0] ==
'S') {
289 inputLine >> bc1 >> bc2 >> bc3 >> bc4;
290 }
else if (filetypestring[0] ==
'R') {
293 inputLine >> bc1 >> bc2 >> bc1 >> bc4;
295 g_log.
error() <<
"Unsupported GSAS File Type: " << filetypestring <<
"\n";
300 if (filetype ==
'r') {
301 double x0 = bc1 / 32;
302 g_log.
debug() <<
"RALF: x0 = " << x0 <<
" bc4 = " << bc4 <<
'\n';
303 vecX.emplace_back(x0);
309 else if (isOutOfHead) {
320 }
else if (filetype ==
'r') {
328 if (filetype ==
'r') {
335 std::string str(currentLine, 15);
336 std::istringstream istr(str);
340 std::string str(currentLine + 15, 18);
341 std::istringstream istr(str);
345 std::string str(currentLine + 15 + 18, 18);
346 std::istringstream istr(str);
350 xValue = (2 * xValue) - xPrev;
352 }
else if (filetype ==
's') {
354 std::istringstream inputLine(currentLine, std::ios::in);
355 inputLine >> xValue >> yValue >> eValue;
358 g_log.
debug() <<
"x'_0 = " << xValue <<
" bc3 = " << bc3 <<
'\n';
360 double x0 = 2 * xValue / (bc3 + 2.0);
361 vecX.emplace_back(x0);
367 xValue = (2 * xValue) - xPrev;
369 g_log.
error() <<
"Unsupported GSAS File Type: " << filetype <<
"\n";
373 if (multiplybybinwidth) {
374 yValue = yValue / (xValue - xPrev);
375 eValue = eValue / (xValue - xPrev);
379 vecX.emplace_back(xValue);
380 vecY.emplace_back(yValue);
381 vecE.emplace_back(eValue);
384 g_log.
warning() <<
"Line not defined: " << currentLine <<
'\n';
389 auto nHist(
static_cast<int>(gsasDataX.size()));
390 auto xWidth(
static_cast<int>(vecX.size()));
391 auto yWidth(
static_cast<int>(vecY.size()));
395 gsasDataX.emplace_back(std::move(vecX));
396 gsasDataY.emplace_back(std::move(vecY));
397 gsasDataE.emplace_back(std::move(vecE));
410 outputWorkspace->getAxis(0)->unit() = UnitFactory::Instance().create(
"TOF");
414 outputWorkspace->setTitle(wsTitle);
416 outputWorkspace->setTitle(slogTitle);
419 if (detectorIDs.size() !=
static_cast<size_t>(nHist)) {
421 std::ostringstream mess(
"");
422 mess <<
"Number of spectra (" << detectorIDs.size() <<
") is not equal to number of histograms (" << nHist <<
").";
423 throw std::runtime_error(mess.str());
426 for (
int i = 0; i < nHist; ++i) {
428 outputWorkspace->setHistogram(i, BinEdges(std::move(gsasDataX[i])), Counts(std::move(gsasDataY[i])),
429 CountStandardDeviations(std::move(gsasDataE[i])));
432 if (useBankAsSpectrum) {
433 auto specno =
static_cast<specnum_t>(detectorIDs[i]);
434 outputWorkspace->getSpectrum(i).setSpectrumNo(specno);
439 createInstrumentGeometry(outputWorkspace, instrumentname, primaryflightpath, detectorIDs, totalflightpaths, twothetas,
442 return outputWorkspace;
469 const double &primaryflightpath,
const std::vector<int> &detectorids,
470 const std::vector<double> &totalflightpaths,
471 const std::vector<double> &twothetas,
const std::vector<double> &difcs) {
473 if (detectorids.size() != totalflightpaths.size() || totalflightpaths.size() != twothetas.size()) {
474 g_log.
warning(
"Cannot create geometry, because the numbers of L2 and Polar "
480 std::stringstream dbss;
481 dbss <<
"L1 = " << primaryflightpath <<
"\n";
482 for (
size_t i = 0; i < detectorids.size(); i++) {
483 dbss <<
"Detector " << detectorids[i] <<
" L1+L2 = " << totalflightpaths[i] <<
" 2Theta = " << twothetas[i]
493 instrument->add(samplepos);
494 instrument->markAsSamplePos(samplepos);
495 samplepos->
setPos(0.0, 0.0, 0.0);
498 instrument->add(source);
499 instrument->markAsSource(source);
501 double l1 = primaryflightpath;
502 source->
setPos(0.0, 0.0, -1.0 * l1);
507 const auto numDetector =
static_cast<int>(detectorids.size());
513 for (
int i = 0; i < numDetector; ++i) {
520 double r = totalflightpaths[i] - l1;
527 spec.clearDetectorIDs();
528 spec.addDetectorID(detectorids[i]);
529 instrument->add(detector);
530 instrument->markAsDetector(detector);
535 auto ¶mMap =
workspace->instrumentParameters();
536 for (
size_t i = 0; i <
workspace->getNumberHistograms(); i++) {
537 auto detector =
workspace->getDetector(i);
538 paramMap.addDouble(detector->getComponentID(),
"DIFC", difcs[i]);