BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
ImportDataUtils.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/View/Import/ImportDataUtils.cpp
6 //! @brief Implements ImportDataUtils namespace
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "Device/Data/Datafield.h"
17 #include "Device/IO/DataFormatUtils.h"
19 #include "GUI/Support/IO/IOUtils.h"
22 #include <QApplication>
23 #include <QMessageBox>
24 
25 namespace {
26 
27 const QString filter_string_ba = "Intensity File (*.int *.gz *.tif *.tiff *.txt *.csv);;"
28  "Other (*.*)";
29 const QString filter_string_ascii = "Intensity File (*.int *.int.gz *.txt *.csv *.dat *.ascii);;"
30  "Ascii column-wise data (*.*)";
31 
32 //! Imports for 2D or 1D data, using given loader.
33 //! Allocates Datafield, and returns owning pointer.
34 //! Currently used for all 2D, and some 1D data files.
35 
36 std::unique_ptr<Datafield> ImportKnownData(const QString& fileName,
37  IOFactory::LoaderSelector loader = IOFactory::automatic)
38 {
39  // Try to use the canonical tools for importing data
40  std::unique_ptr<Datafield> result;
41  try {
42  std::unique_ptr<Datafield> data(IOFactory::readDatafield(fileName.toStdString(), loader));
43  result = GUI::Util::IO::binifyAxes(*data);
44  } catch (std::exception& ex) {
45  QString message = QString("Error while trying to read file\n\n'%1'\n\n%2")
46  .arg(fileName)
47  .arg(QString::fromStdString(std::string(ex.what())));
48  QMessageBox::warning(nullptr, "IO Problem", message);
49  }
50  return result;
51 }
52 
53 } // namespace
54 
55 
56 std::unique_ptr<Datafield>
57 GUI::View::ImportDataUtils::Import2dData(const QString& fileName, IOFactory::LoaderSelector loader)
58 {
59  return ImportKnownData(fileName, loader);
60 }
61 
63  const AbstractDataLoader* selectedLoader)
64 {
65  const QString fileName = realDataItem->nativeFileName();
66  const std::string fileNameStdString = fileName.toStdString();
67 
68  if (selectedLoader == nullptr) {
69  if (DataUtils::Format::isCompressed(fileNameStdString)
70  || DataUtils::Format::isIntFile(fileNameStdString)
71  || DataUtils::Format::isTiffFile(fileNameStdString)) {
72  try {
73  ImportDataInfo info(ImportKnownData(fileName), Coords::QSPACE);
74  if (info) {
75  realDataItem->setImportData(std::move(info));
76  return QString();
77  }
78  } catch (std::exception& ex) {
79  // If it is not tiff but e.g. dat.gz, it could be tried with CSV import
80  const bool tryWithLoaders =
81  (DataUtils::Format::isIntFile(fileNameStdString)
82  && !DataUtils::Format::isCompressed(
83  fileNameStdString)); // #baimport support compressed
84 
85  if (!tryWithLoaders)
86  // import is not possible
87  return QString::fromLatin1(ex.what());
88  }
89  }
90  }
91 
92  // -- try with selected CSV loader. If none selected, try with QRE loader
93 
94  QFile file(fileName);
95  const bool ok = file.open(QFile::ReadOnly | QIODevice::Text);
96  if (!ok)
97  return "File could not be opened.";
98 
99  QByteArray fileContent = file.readAll();
100  file.close();
101 
102  if (fileContent.isEmpty())
103  return "The imported file is empty.";
104 
105  if (DataUtils::Format::isCompressed(fileNameStdString)) {
106  // #baimport implement decompress
107  }
108 
109  AbstractDataLoader* loader = nullptr;
110  if (selectedLoader == nullptr)
111  loader = new QREDataLoader();
112  else
113  loader = selectedLoader->clone();
115  loader->setRealDataItem(realDataItem);
116  realDataItem->setDataLoader(loader);
117  QApplication::setOverrideCursor(Qt::WaitCursor);
118  loader->setFileContents(fileContent);
119  loader->guessSettings();
120  loader->processContents();
121  QApplication::restoreOverrideCursor();
122 
123  return QString();
124 }
Defines namespace GUI::Util::IO.
Defines ImportDataInfo helper struct.
Defines ImportDataUtils namespace.
Defines class QREDataLoader.
Defines class RealDataItem.
Abstract base class for all data loaders (classes to import real data).
virtual void guessSettings()
Guess appropriate settings (for example the separator in a CSV file). Is called only once,...
virtual void setFileContents(const QByteArray &fileContent)=0
Sets the file contents to be imported. If the file was a compressed file, then the decompressed conte...
virtual void processContents()=0
Process the file contents. Can be called more than once, e.g. if the import settings have changed....
virtual void initWithDefaultImportSettings()
Set import settings to defaults.
virtual AbstractDataLoader * clone() const =0
Create a complete clone, including all internal states.
void setRealDataItem(RealDataItem *item)
Define the real data item on which the import shall work.
Carries information about loaded data.
Loader for experimental reflectometry CSV files that contain three columns with Q,...
Definition: QREDataLoader.h:29
Provides access to experimental data, for display and fitting. Owns an AbstractDataLoader.
Definition: RealDataItem.h:33
void setImportData(ImportDataInfo info)
Sets imported data to underlying item. Creates it if not existing. This is used for 1D import....
QString nativeFileName() const
void setDataLoader(AbstractDataLoader *loader)
Takes ownership of loader.
std::unique_ptr< Datafield > binifyAxes(const Datafield &data)
Creates Datafield with bin-valued axes.
Definition: IOUtils.cpp:22
void warning(QWidget *parent, const QString &title, const QString &text, const QString &detailedText)
Definition: MessageBox.cpp:37
QString Import1dData(RealDataItem *realDataItem, const AbstractDataLoader *selectedLoader)
Imports 1D data into the given item.
std::unique_ptr< Datafield > Import2dData(const QString &fileName, IOFactory::LoaderSelector loader)
Imports 2D data, stores them as Datafield, and returns owning pointer.