Commit 2ffc98b4 authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

Merge branch 'simplifyLoader' into 'main'

Session::loadRawData(): split off function askRawFileNames

See merge request !513
parents b3f8daae ed2a90ab
Pipeline #72293 passed with stage
in 1 minute and 10 seconds
......@@ -58,7 +58,7 @@ DataSet::DataSet(const std::string& dataset_name, Diffractometer* diffractometer
_metadata.add<int>(ohkl::at_nMasks, 0);
}
void DataSet::_setReader(const DataFormat dataformat, const std::string& filename)
void DataSet::setReader(const DataFormat dataformat, const std::string& filename)
{
ohklLog(Level::Debug, "Initializing a DataReader for the format ", static_cast<int>(dataformat));
......@@ -111,7 +111,7 @@ void DataSet::addDataFile(const std::string& filename, const std::string& extens
throw std::runtime_error("DataSet '" + _name + "': DataReader is already set.");
}
_setReader(datafmt, filename);
setReader(datafmt, filename);
}
void DataSet::setRawReaderParameters(const RawDataReaderParameters& params)
......@@ -126,7 +126,7 @@ void DataSet::setRawReaderParameters(const RawDataReaderParameters& params)
"DataSet '" + _name + "': Cannot set raw parameters since data format is not raw.");
if (!_reader)
_setReader(DataFormat::RAW);
setReader(DataFormat::RAW);
RawDataReader& rawreader = *static_cast<RawDataReader*>(_reader.get());
rawreader.setParameters(params);
......@@ -139,7 +139,7 @@ void DataSet::setRawReaderParameters(const RawDataReaderParameters& params)
void DataSet::addRawFrame(const std::string& rawfilename)
{
if (!_reader)
_setReader(DataFormat::RAW);
setReader(DataFormat::RAW);
// prevent mixing data formats
if (_dataformat != DataFormat::RAW)
......
......@@ -161,7 +161,7 @@ class DataSet {
gsl_histogram* getTotalHistogram();
private:
void _setReader(const DataFormat dataformat, const std::string& filename = "");
void setReader(const DataFormat dataformat, const std::string& filename = "");
private:
std::string _name = ohkl::kw_datasetDefaultName;
......
......@@ -29,6 +29,7 @@ class DataSet;
class Diffractometer;
class InstrumentStateHandler;
//! Holds named DataSet%s, experiment name, and info on the instrument.
class DataHandler {
public:
......@@ -40,32 +41,32 @@ class DataHandler {
const std::string& experiment_name, const std::string& diffractometerName,
InstrumentStateHandler* instrument_state_handler);
public: // Handling data sets
//! Get the diffractometer
public:
//! Returns pointer to the diffractometer
Diffractometer* getDiffractometer();
//! Set the diffractometer
//! Sets the diffractometer
void setDiffractometer(const std::string& diffractometerName);
//! Gets a reference to the data
//! Returns pointer to the DataMap
const DataMap* getDataMap() const;
//! Gets the pointer to a given data stored in the experiment
//! Returns pointer to the DataSet of given name
sptrDataSet getData(std::string name) const;
//! Return all data sets as a DataList
//! Returns all data sets as a DataList
DataList getAllData() const;
//! Get number of data
//! Returns number of DataSet%s
int numData() const;
//! Add some data to the experiment
//! Adds a DataSet to the experiment
bool addData(sptrDataSet data, std::string name, bool default_states = true);
//! Returns true if the experiment has a data
//! Returns true if the experiment has a DataSet of given name
bool hasData(const std::string& name) const;
//! Remove a data from the experiment
//! Removes a DataSet from the experiment
void removeData(const std::string& name);
private:
std::string _experiment_name;
std::unique_ptr<Diffractometer> _diffractometer;
//! A map of the data related to the experiment.
//! Map name -> DataSet, holding all data sets pertaining to the experiment.
DataMap _data_map;
//! pointer to handler for instrument states
//! Pointer to handler for instrument states
InstrumentStateHandler* _instrument_state_handler;
};
......
......@@ -14,6 +14,7 @@
#include <cmath>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <map>
#include <set>
......@@ -132,9 +133,6 @@ void RawDataReader::setParameters(const RawDataReaderParameters& parameters)
void RawDataReader::swapEndian()
{
if (!_parameters.swap_endian)
return;
const std::size_t nrows = _dataset_out->nRows(), ncols = _dataset_out->nCols();
for (std::size_t i = 0; i < nrows * ncols; ++i) {
......@@ -148,37 +146,32 @@ void RawDataReader::swapEndian()
Eigen::MatrixXi RawDataReader::data(size_t frame)
{
checkInit();
std::string filename = _filenames.at(frame);
const size_t fsize = std::filesystem::file_size(filename);
if (fsize != _length) {
std::string err_msg = "data file " + filename + " is not of the expected size: "
+ "expected " + std::to_string(_length) + " bytes but found "
+ std::to_string(fsize);
throw std::runtime_error(err_msg);
}
std::ifstream file;
file.open(filename, std::ios_base::binary | std::ios_base::in);
if (!file.is_open())
throw std::runtime_error("could not open data file " + filename);
file.seekg(0, std::ios_base::end);
if (_length != size_t(file.tellg())) {
std::string err_msg = "data file " + filename + " is not of the expected size: ";
err_msg += "expected " + std::to_string(_length) + " bytes but found "
+ std::to_string(file.tellg());
throw std::runtime_error(err_msg);
}
file.seekg(0, std::ios_base::beg);
file.read(&_data[0], long(_length));
if (_length != size_t(file.gcount())) {
std::string err_msg = "LOL did not read " + filename + " successfully: ";
err_msg += "expected " + std::to_string(_length) + " bytes but read "
if (size_t(file.gcount()) != _length) {
std::string err_msg = "cannot load file " + filename + ": "
+ "expected " + std::to_string(_length) + " bytes but found "
+ std::to_string(file.gcount());
throw std::runtime_error(err_msg);
}
swapEndian();
if (_parameters.swap_endian)
swapEndian();
switch (_parameters.bpp) {
case 1: return matrixFromData<uint8_t>().cast<int>();
......
......@@ -18,6 +18,7 @@
#include "core/data/DataSet.h"
#include "core/loader/IDataReader.h" // inherits from
#include "core/raw/DataKeys.h"
#include "base/utils/Path.h" // fileBasename
#include <fstream>
#include <stdexcept>
......@@ -26,7 +27,7 @@ namespace ohkl {
//! Minimal meta data set, to supplement binary raw data in RawDataReader.
struct RawDataReaderParameters {
std::string dataset_name = ohkl::kw_datasetDefaultName;
std::string dataset_name = kw_datasetDefaultName;
double wavelength = 0.0;
double delta_omega = 0.0;
double delta_chi = 0.0;
......@@ -39,6 +40,8 @@ struct RawDataReaderParameters {
void LoadDataFromFile(std::string file)
{
dataset_name = fileBasename(file);
std::size_t pos1 = file.find_last_of("/");
std::size_t pos0 = (file.substr(0, pos1 - 1)).find_last_of("/");
std::size_t pos2 = file.find_last_of(".");
......
......@@ -111,7 +111,7 @@ RawDataDialog::RawDataDialog(
_gain->setValue(detector->gain());
connect(_buttons, &QDialogButtonBox::accepted, this, &RawDataDialog::verify);
connect(_buttons, &QDialogButtonBox::rejected, this, &RawDataDialog::reject);
connect(_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
......@@ -141,7 +141,7 @@ int RawDataDialog::bpp()
void RawDataDialog::verify()
{
// confirm overwrite if the name already exists
const QString& dname = dataset_name();
const QString& dname = _datasetName->text();
const bool name_exists = _dataset_names.contains(dname);
bool dialog_accepted = true;
......@@ -154,7 +154,7 @@ void RawDataDialog::verify()
// check wavelength
const double eps = 1e-8;
const double waveln = wavelength();
const double waveln = _wavelength->value();
if (waveln < eps) {
const QString msg{
QString::fromStdString("Wavelength, " + std::to_string(waveln) + ", must be > 0")};
......
......@@ -36,25 +36,15 @@ class RawDataDialog : public QDialog {
const ohkl::RawDataReaderParameters& parameters0,
const QStringList& datanames_cur = QStringList());
QString dataset_name() { return _datasetName->text(); }
double wavelength() { return _wavelength->value(); }
double deltaChi() { return _chi->value(); }
double deltaOmega() { return _omega->value(); }
double deltaPhi() { return _phi->value(); }
bool swapEndian() { return _swapEndianness->isChecked(); }
double baseline() { return _baseline->value(); }
double gain() { return _gain->value(); }
bool rowMajor();
int bpp();
void setWavelength(double newWavelength) { _wavelength->setValue(newWavelength); }
//! Return a copy of the parameters acquired from the dialog
ohkl::RawDataReaderParameters parameters();
private:
//! Verify user-provided parameters
void verify();
bool rowMajor();
int bpp();
private:
QComboBox* _dataArrangement;
QComboBox* _dataFormat;
QCheckBox* _swapEndianness;
......
......@@ -40,6 +40,7 @@ class Project {
const ohkl::Experiment* experiment() const;
ohkl::Experiment* experiment();
//! Returns list of DataSet names.
QStringList getDataNames() const;
std::shared_ptr<ohkl::DataSet> getData(int index = -1) const;
std::vector<std::shared_ptr<ohkl::DataSet>> allData() const;
......
......@@ -15,7 +15,6 @@
#include "gui/models/Session.h"
#include "base/utils/Logger.h"
#include "base/utils/Path.h" // fileBasename
#include "core/data/DataSet.h"
#include "core/data/DataTypes.h"
#include "core/detector/Detector.h"
......@@ -52,12 +51,11 @@
#include <QSettings>
#include <QStringList>
Session* gSession;
namespace {
// open a dialog to choose a name for a dataset; warn against name clashes with previous names
//! Opens a dialog to choose a name for a dataset; warn against name clashes with previous names
std::string askDataName(const std::string dataname0, const QStringList* const datanames_pre)
{
DataNameDialog dataname_dialog(QString::fromStdString(dataname0), datanames_pre);
......@@ -68,6 +66,40 @@ std::string askDataName(const std::string dataname0, const QStringList* const da
return dataname0;
}
//! Opens a dialog to choose a list of raw files
std::vector<std::string> askRawFileNames()
{
QSettings qset = gGui->qSettings();
qset.beginGroup("RecentDirectories");
QString loadDirectory = qset.value("data_raw", QDir::homePath()).toString();
QStringList qfilenames =
QFileDialog::getOpenFileNames(gGui, "import raw data", loadDirectory,
"Image files (*.raw *.tiff);; All files (*.* *)");
if (qfilenames.empty())
return {};
// Don't leave sorting the files to the OS. Use QCollator + std::sort to sort naturally
// (numerically)
QCollator collator;
collator.setNumericMode(true);
std::sort(
qfilenames.begin(), qfilenames.end(),
[&collator](const QString& file1, const QString& file2) {
return collator.compare(file1, file2) < 0;
});
QFileInfo info(qfilenames.at(0));
loadDirectory = info.absolutePath();
qset.setValue("data_raw", loadDirectory);
std::vector<std::string> result;
for (const QString& filename : qfilenames)
result.push_back(filename.toStdString());
return result;
}
} // namespace
Session::Session()
......@@ -274,69 +306,43 @@ void Session::removeData()
bool Session::loadRawData()
{
// Loading data requires an existing Experiment
if (_currentProject < 0) {
return false;
}
if (_currentProject < 0)
return false; // loading data requires an existing Experiment
try {
QSettings qset = gGui->qSettings();
qset.beginGroup("RecentDirectories");
QString loadDirectory = qset.value("data_raw", QDir::homePath()).toString();
QStringList qfilenames =
QFileDialog::getOpenFileNames(gGui, "import raw data",
loadDirectory, "Image files (*.raw *.tiff);; All files (*.* *)");
if (qfilenames.empty())
// Get input filenames from dialog.
std::vector<std::string> filenames = askRawFileNames();
if (filenames.empty())
return false;
// Don't leave sorting the files to the OS. Use QCollator + std::sort to sort naturally
// (numerically)
QCollator collator;
collator.setNumericMode(true);
std::sort(
qfilenames.begin(), qfilenames.end(),
[&collator](const QString& file1, const QString& file2) {
return collator.compare(file1, file2) < 0;
});
QFileInfo info(qfilenames.at(0));
loadDirectory = info.absolutePath();
qset.setValue("data_raw", loadDirectory);
std::vector<std::string> filenames;
for (const QString& filename : qfilenames)
filenames.push_back(filename.toStdString());
// Get metadata from readme file, then edit them in dialog.
const QStringList& extant_dataset_names = currentProject()->getDataNames();
ohkl::RawDataReaderParameters parameters;
parameters.dataset_name = ohkl::fileBasename(filenames[0]);
parameters.LoadDataFromFile(filenames.at(0));
const QStringList& datanames_pre{currentProject()->getDataNames()};
RawDataDialog dialog(parameters, datanames_pre);
if (!dialog.exec()) {
RawDataDialog dialog(parameters, extant_dataset_names);
if (!dialog.exec())
return false;
}
ohkl::Experiment* exp = currentProject()->experiment();
// update the parameters by those from the dialog
parameters = dialog.parameters();
// Transfer metadata to diffractometer.
ohkl::Detector* detector = exp->getDiffractometer()->detector();
detector->setBaseline(parameters.baseline);
detector->setGain(parameters.gain);
ohkl::Diffractometer* diff = exp->getDiffractometer();
const std::shared_ptr<ohkl::DataSet> dataset_ptr{
std::make_shared<ohkl::DataSet>(parameters.dataset_name, diff)};
dataset_ptr->setRawReaderParameters(parameters);
for (const auto& filenm : filenames)
dataset_ptr->addRawFrame(filenm);
// Transfer metadata to dataset, and load the raw data.
const std::shared_ptr<ohkl::DataSet> dataset{
std::make_shared<ohkl::DataSet>(parameters.dataset_name, exp->getDiffractometer())};
dataset->setRawReaderParameters(parameters);
for (const auto& filename : filenames)
dataset->addRawFrame(filename);
dataset->finishRead();
exp->addData(dataset);
dataset_ptr->finishRead();
if (!exp->addData(dataset_ptr)) { }
onDataChanged();
auto data_list = currentProject()->getDataNames();
gGui->sentinel->setLinkedComboList(ComboType::DataSet, data_list);
gGui->sentinel->setLinkedComboList(ComboType::DataSet,
currentProject()->getDataNames());
} catch (std::exception& e) {
QMessageBox::critical(nullptr, "Error", QString(e.what()));
} catch (...) {
......@@ -348,7 +354,6 @@ bool Session::loadRawData()
void Session::onDataChanged()
{
DataList data = currentProject()->experiment()->getAllData();
// gGui->onDataChanged();
_data_combo->clearAll();
_data_combo->addDataSets(data);
_data_combo->refreshAll();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment