dataload_parquet.cpp
Go to the documentation of this file.
1 #include "dataload_parquet.h"
2 #include <QTextStream>
3 #include <QFile>
4 #include <QMessageBox>
5 #include <QDebug>
6 #include <QSettings>
7 #include <QProgressDialog>
8 #include <QDateTime>
9 #include <QInputDialog>
10 #include <QListWidget>
11 
13 {
14  ui = new Ui::DialogParquet();
15  _dialog = new QDialog();
16 
17  ui->setupUi(_dialog);
18 
19  connect(ui->checkBoxDateFormat, &QCheckBox::toggled, this,
20  [=](bool checked) { ui->lineEditDateFormat->setEnabled(checked); });
21 
22  connect(ui->listWidgetSeries, &QListWidget::currentTextChanged, this,
23  [=](QString text) { ui->buttonBox->setEnabled(!text.isEmpty()); });
24 
25  connect(ui->listWidgetSeries, &QListWidget::doubleClicked, this,
26  [=](const QModelIndex&) { _dialog->accept(); });
27 
28  connect(ui->radioButtonIndex, &QRadioButton::toggled, this, [=](bool checked) {
29  ui->buttonBox->setEnabled(checked);
30  ui->listWidgetSeries->setEnabled(!checked);
31  });
32 
33  QSettings settings;
34 
35  bool radio_index_checked =
36  settings.value("DataLoadParquet::radioIndexChecked", false).toBool();
37  ui->radioButtonIndex->setChecked(radio_index_checked);
38 
39  bool parse_date_time = settings.value("DataLoadParquet::parseDateTime", false).toBool();
40  ui->checkBoxDateFormat->setChecked(parse_date_time);
41 
42  QString date_format = settings.value("DataLoadParquet::dateFromat", false).toString();
43  if (date_format.isEmpty() == false)
44  {
45  ui->lineEditDateFormat->setText(date_format);
46  }
47 }
48 
50 {
51  delete ui;
52 }
53 
54 const std::vector<const char*>& DataLoadParquet::compatibleFileExtensions() const
55 {
56  static std::vector<const char*> extensions = { "parquet" };
57  return extensions;
58 }
59 
61 {
62  using parquet::ConvertedType;
63  using parquet::Type;
64 
65  parquet_reader_ = parquet::ParquetFileReader::OpenFile(info->filename.toStdString());
66 
67  if (!parquet_reader_)
68  {
69  return false;
70  }
71 
72  std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader_->metadata();
73  const auto schema = file_metadata->schema();
74  const size_t num_columns = file_metadata->num_columns();
75 
76  std::vector<parquet::Type::type> column_type;
77  std::vector<parquet::ConvertedType::type> converted_column_type;
78  std::vector<bool> valid_column(num_columns, true);
79 
80  for (size_t col = 0; col < num_columns; col++)
81  {
82  auto column = schema->Column(col);
83  auto type = column->physical_type();
84  auto converted_type = column->converted_type();
85 
86  column_type.push_back(type);
87  converted_column_type.push_back(converted_type);
88 
89  valid_column[col] =
90  (type == Type::BOOLEAN || type == Type::INT32 || type == Type::INT64 ||
91  type == Type::FLOAT || type == Type::DOUBLE);
92 
93  ui->listWidgetSeries->addItem(QString::fromStdString(column->name()));
94  }
95 
96  {
97  QSettings settings;
98  if (_default_time_axis.isEmpty())
99  {
101  settings.value("DataLoadParquet::prevTimestamp", {}).toString();
102  }
103 
104  if (_default_time_axis.isEmpty() == false)
105  {
106  auto items = ui->listWidgetSeries->findItems(_default_time_axis, Qt::MatchExactly);
107  if (items.size() > 0)
108  {
109  ui->listWidgetSeries->setCurrentItem(items.front());
110  }
111  }
112  }
113 
114  int ret = _dialog->exec();
115  if (ret != QDialog::Accepted)
116  {
117  return false;
118  }
119 
120  QString selected_stamp;
121 
122  if (ui->radioButtonSelect->isChecked())
123  {
124  auto selected = ui->listWidgetSeries->selectedItems();
125  if (selected.size() == 1)
126  {
127  selected_stamp = selected.front()->text();
128  }
129  }
130 
131  QSettings settings;
132  settings.setValue("DataLoadParquet::prevTimestamp", selected_stamp);
133  settings.setValue("DataLoadParquet::radioIndexChecked",
134  ui->radioButtonIndex->isChecked());
135  settings.setValue("DataLoadParquet::parseDateTime",
136  ui->checkBoxDateFormat->isChecked());
137  settings.setValue("DataLoadParquet::dateFromat", ui->lineEditDateFormat->text());
138 
139  //-----------------------------
140  // Time to parse
141  int timestamp_column = -1;
142 
143  std::vector<PlotData*> series(num_columns, nullptr);
144 
145  for (size_t col = 0; col < num_columns; col++)
146  {
147  auto column = schema->Column(col);
148  const std::string& name = column->name();
149  if (name == selected_stamp.toStdString())
150  {
151  timestamp_column = col;
152  }
153  if (valid_column[col])
154  {
155  series[col] = &(plot_data.addNumeric(name)->second);
156  }
157  }
158 
159  parquet::StreamReader os{ std::move(parquet_reader_) };
160 
161  std::vector<double> row_values(num_columns, 0.0);
162 
163  int row = 0;
164  while (!os.eof())
165  {
166  // extract an entire row
167  for (size_t col = 0; col < num_columns; col++)
168  {
169  if (!valid_column[col])
170  {
171  continue;
172  }
173  auto type = column_type[col];
174  auto converted_type = converted_column_type[col];
175 
176  switch (type)
177  {
178  case Type::BOOLEAN: {
179  bool tmp;
180  os >> tmp;
181  row_values[col] = static_cast<double>(tmp);
182  break;
183  }
184  case Type::INT32:
185  case Type::INT64: {
186  switch (converted_type)
187  {
188  case ConvertedType::INT_8: {
189  int8_t tmp;
190  os >> tmp;
191  row_values[col] = static_cast<double>(tmp);
192  break;
193  }
194  case ConvertedType::INT_16: {
195  int16_t tmp;
196  os >> tmp;
197  row_values[col] = static_cast<double>(tmp);
198  break;
199  }
200  case ConvertedType::INT_32: {
201  int32_t tmp;
202  os >> tmp;
203  row_values[col] = static_cast<double>(tmp);
204  break;
205  }
206  case ConvertedType::INT_64: {
207  int64_t tmp;
208  os >> tmp;
209  row_values[col] = static_cast<double>(tmp);
210  break;
211  }
212  case ConvertedType::UINT_8: {
213  uint8_t tmp;
214  os >> tmp;
215  row_values[col] = static_cast<double>(tmp);
216  break;
217  }
218  case ConvertedType::UINT_16: {
219  uint16_t tmp;
220  os >> tmp;
221  row_values[col] = static_cast<double>(tmp);
222  break;
223  }
224  case ConvertedType::UINT_32: {
225  uint32_t tmp;
226  os >> tmp;
227  row_values[col] = static_cast<double>(tmp);
228  break;
229  }
230  case ConvertedType::UINT_64: {
231  uint64_t tmp;
232  os >> tmp;
233  row_values[col] = static_cast<double>(tmp);
234  break;
235  }
236  default: {
237  // Fallback in case no converted type is provided
238  switch (type)
239  {
240  case Type::INT32: {
241  int32_t tmp;
242  os >> tmp;
243  row_values[col] = static_cast<double>(tmp);
244  break;
245  }
246  case Type::INT64: {
247  int64_t tmp;
248  os >> tmp;
249  row_values[col] = static_cast<double>(tmp);
250  break;
251  }
252  }
253  }
254  }
255  break;
256  }
257  case Type::FLOAT: {
258  float tmp;
259  os >> tmp;
260  row_values[col] = static_cast<double>(tmp);
261  break;
262  }
263  case Type::DOUBLE: {
264  os >> row_values[col];
265  break;
266  }
267  default: {
268  }
269  } // end switch
270  } // end for column
271 
272  os >> parquet::EndRow;
273 
274  double timestamp = timestamp_column >= 0 ? row_values[timestamp_column] : row;
275  row++;
276 
277  for (size_t col = 0; col < num_columns; col++)
278  {
279  if (!valid_column[col])
280  {
281  continue;
282  }
283 
284  if (valid_column[col])
285  {
286  series[col]->pushBack({ timestamp, row_values[col] });
287  }
288  }
289  }
290  return true;
291 }
292 
293 bool DataLoadParquet::xmlSaveState(QDomDocument& doc, QDomElement& parent_element) const
294 {
295  QDomElement elem = doc.createElement("default");
296  elem.setAttribute("prevTimestamp", _default_time_axis);
297  elem.setAttribute("radioIndexChecked", ui->radioButtonIndex->isChecked());
298  elem.setAttribute("parseDateTime", ui->checkBoxDateFormat->isChecked());
299  elem.setAttribute("dateFromat", ui->lineEditDateFormat->text());
300 
301  parent_element.appendChild(elem);
302  return true;
303 }
304 
305 bool DataLoadParquet::xmlLoadState(const QDomElement& parent_element)
306 {
307  QDomElement elem = parent_element.firstChildElement("default");
308  if (!elem.isNull())
309  {
310  if (elem.hasAttribute("prevTimestamp"))
311  {
312  _default_time_axis = elem.attribute("prevTimestamp");
313  }
314  if (elem.hasAttribute("radioIndexChecked"))
315  {
316  bool checked = elem.attribute("radioIndexChecked").toInt();
317  ui->radioButtonIndex->setChecked(checked);
318  }
319  if (elem.hasAttribute("parseDateTime"))
320  {
321  bool checked = elem.attribute("parseDateTime").toInt();
322  ui->checkBoxDateFormat->setChecked(checked);
323  }
324  if (elem.hasAttribute("dateFromat"))
325  {
326  ui->lineEditDateFormat->setText(elem.attribute("dateFromat"));
327  }
328  }
329 
330  return true;
331 }
DataLoadParquet::parquet_reader_
std::unique_ptr< parquet::ParquetFileReader > parquet_reader_
Definition: dataload_parquet.h:48
DataLoadParquet::name
virtual const char * name() const override
Name of the plugin type, NOT the particular instance.
Definition: dataload_parquet.h:29
DataLoadParquet::xmlSaveState
virtual bool xmlSaveState(QDomDocument &doc, QDomElement &parent_element) const override
Override this method to save the status of the plugin to XML.
Definition: dataload_parquet.cpp:293
PJ::FileLoadInfo
Definition: dataloader_base.h:18
DataLoadParquet::xmlLoadState
virtual bool xmlLoadState(const QDomElement &parent_element) override
Override this method to load the status of the plugin from XML.
Definition: dataload_parquet.cpp:305
backward::ColorMode::type
type
Definition: backward.hpp:3600
PJ::PlotDataMapRef::addNumeric
TimeseriesMap::iterator addNumeric(const std::string &name, PlotGroup::Ptr group={})
Definition: plotdata.cpp:51
DataLoadParquet::_default_time_axis
QString _default_time_axis
Definition: dataload_parquet.h:46
DataLoadParquet::DataLoadParquet
DataLoadParquet()
Definition: dataload_parquet.cpp:12
QwtTriangle::Type
Type
Definition: qwt_symbol.cpp:32
DataLoadParquet::compatibleFileExtensions
virtual const std::vector< const char * > & compatibleFileExtensions() const override
Provide a list of file extensions that this plugin can open.
Definition: dataload_parquet.cpp:54
backward::details::move
const T & move(const T &v)
Definition: backward.hpp:394
DataLoadParquet::readDataFromFile
virtual bool readDataFromFile(PJ::FileLoadInfo *fileload_info, PlotDataMapRef &destination) override
Definition: dataload_parquet.cpp:60
dataload_parquet.h
DataLoadParquet::~DataLoadParquet
~DataLoadParquet() override
Definition: dataload_parquet.cpp:49
DataLoadParquet::ui
Ui::DialogParquet * ui
Definition: dataload_parquet.h:42
DataLoadParquet::_dialog
QDialog * _dialog
Definition: dataload_parquet.h:50
PJ::PlotDataMapRef
Definition: plotdata.h:34
mqtt_test.ret
ret
Definition: mqtt_test.py:30
RosMsgParser::INT32
@ INT32
Definition: builtin_types.hpp:54
PJ::FileLoadInfo::filename
QString filename
name of the file to open
Definition: dataloader_base.h:21
RosMsgParser::INT64
@ INT64
Definition: builtin_types.hpp:55


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Nov 11 2024 03:23:44