Skip to content
Snippets Groups Projects
Commit b3924af2 authored by Matthias Puchner's avatar Matthias Puchner
Browse files

add reader for NICOS 2D files

parent 4e8d0324
No related branches found
No related tags found
1 merge request!18Feature read nicos and crash fix
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/InputOutput/OutputDataReadWriteNicos.cpp
//! @brief Implements class OutputDataReadWriteNicos
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2021
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Device/InputOutput/OutputDataReadWriteNicos.h"
#include "Base/Utils/StringUtils.h"
OutputData<double>* OutputDataReadWriteNicos::readOutputData(std::istream& input_stream)
{
OutputData<double>* result = new OutputData<double>;
std::string line;
m_currentLineNr = 0;
int m_width = 0;
int m_height = 0;
// -- read dimensions
bool inFileSection = false;
bool fileSectionFound = false;
while (std::getline(input_stream, line)) {
m_currentLineNr++;
line = StringUtils::trimFront(line, " ");
if (!inFileSection && StringUtils::startsWith(line, "%File")) {
inFileSection = true;
fileSectionFound = true;
continue;
}
if (!inFileSection)
continue;
if (StringUtils::startsWith(line, "%")) {
inFileSection = false;
break;
}
if (StringUtils::startsWith(line, "DataSizeX") && inFileSection) {
m_width = readAssignedIntValue(line);
} else if (StringUtils::startsWith(line, "DataSizeY") && inFileSection) {
m_height = readAssignedIntValue(line);
}
if (m_width != 0 && m_height != 0)
break;
}
if (!fileSectionFound)
throw std::runtime_error("Could not find 'File' section.");
if (m_width == 0)
throw std::runtime_error("Could not find DataSizeX value.");
if (m_height == 0)
throw std::runtime_error("Could not find DataSizeY value.");
result->addAxis("x", m_width, 0.0, m_width);
result->addAxis("y", m_height, 0.0, m_height);
// -- read data
bool inCountSection = false;
bool countSectionFound = false;
int dataRow = 0;
std::vector<unsigned> axes_indices(2);
while (std::getline(input_stream, line)) {
m_currentLineNr++;
line = StringUtils::trimFront(line, " ");
if (!inCountSection && StringUtils::startsWith(line, "%Counts")) {
inCountSection = true;
countSectionFound = true;
continue;
}
if (!inCountSection)
continue;
if (StringUtils::startsWith(line, "%")) {
inCountSection = false;
break;
}
// line is a data line
line = StringUtils::trim(line, " ");
if (line.empty())
continue;
const auto valuesAsString = StringUtils::split(line, ",");
if (valuesAsString.size() != m_width)
throw std::runtime_error(lineRelatedError(
"Number of found values (" + std::to_string(valuesAsString.size())
+ ") does not match DataSizeX (" + std::to_string(m_width) + ")."));
for (unsigned col = 0; col < m_width; ++col) {
axes_indices[0] = col;
axes_indices[1] = static_cast<unsigned>(m_height) - 1
- dataRow; // #baNicos check this (taken from TIFF)
const size_t global_index = result->toGlobalIndex(axes_indices);
int value = 0;
if (!StringUtils::to_int(valuesAsString[col], &value))
throw std::runtime_error(lineRelatedError(
"Value '" + valuesAsString[col] + "' could not be converted to integer."));
(*result)[global_index] = value;
}
dataRow++;
if (dataRow == m_height)
break;
}
if (!countSectionFound)
throw std::runtime_error("Could not find 'Counts' section.");
if (dataRow != m_height)
throw std::runtime_error("Number of found data rows (" + std::to_string(dataRow)
+ ") does not match DataSizeY (" + std::to_string(m_height)
+ ").");
return result;
}
int OutputDataReadWriteNicos::readAssignedIntValue(const std::string& line) const
{
auto parts = StringUtils::split(line, "=");
if (parts.size() != 2)
throw std::runtime_error(lineRelatedError("Missing assigned value."));
int value = 0;
if (!StringUtils::to_int(parts[1], &value))
throw std::runtime_error(
lineRelatedError("Can't parse assigned value '" + parts[1] + "'."));
return value;
}
std::string OutputDataReadWriteNicos::lineRelatedError(const std::string& errorText) const
{
return "Line " + std::to_string(m_currentLineNr) + ": " + errorText;
}
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Device/InputOutput/OutputDataReadWriteNicos.h
//! @brief Defines class OutputDataReadWriteNicos
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2021
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENICOS_H
#define BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENICOS_H
#include "Device/Data/OutputData.h"
//! Read/write Nicos files (*.001).
//! @ingroup input_output_internal
class OutputDataReadWriteNicos {
public:
OutputData<double>* readOutputData(std::istream& input_stream);
private:
//! Reads the assigned integer value from a line content like "DataSizeX = 100"
//! Throws if not successful
int readAssignedIntValue(const std::string& line) const;
//! Returns errorText with prepended line number (suitable for throwing errors)
std::string lineRelatedError(const std::string& errorText) const;
int m_currentLineNr = 0; //!< "1" means "first line" (human readable counting)
};
#endif // BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENICOS_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment