0.5.1
Loading...
Searching...
No Matches
CsvFile.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#include "CsvFile.hpp"
10#include <algorithm>
11#include <string>
12#include <vector>
13
14#include "util/Logger.hpp"
15#include "util/StringUtil.hpp"
16
19
21 : Node(typeStatic())
22{
23 LOG_TRACE("{}: called", name);
24
25 _hasConfig = true;
26 _guiConfigDefaultWindowSize = { 530, 271 };
27
29}
30
32{
33 LOG_TRACE("{}: called", nameId());
34}
35
37{
38 return "CsvFile";
39}
40
41std::string NAV::CsvFile::type() const
42{
43 return typeStatic();
44}
45
47{
48 return "Data Provider";
49}
50
52{
53 if (auto res = FileReader::guiConfig(".csv,.*", { ".csv" }, size_t(id), nameId()))
54 {
55 LOG_DEBUG("{}: Path changed to {}", nameId(), _path);
57 if (res == FileReader::PATH_CHANGED)
58 {
60 }
61 else
62 {
64 }
65 }
66
67 struct TextFilters
68 {
69 // Cuts off characters if the length exceeds 1
70 static int FilterSingleCharacter(ImGuiInputTextCallbackData* data)
71 {
72 while (data->BufTextLen > 1)
73 {
74 data->BufDirty = true;
75 data->DeleteChars(1, 1);
76 }
77 return 0;
78 }
79 };
80
81 std::string tmpStr(1, _delimiter);
82 if (ImGui::InputText(fmt::format("Delimiter character##{}", size_t(id)).c_str(), &tmpStr, ImGuiInputTextFlags_CallbackEdit, TextFilters::FilterSingleCharacter))
83 {
84 _delimiter = tmpStr.empty() ? '\0' : tmpStr.at(0);
85 LOG_DEBUG("{}: Delimiter character changed to {}", nameId(), _delimiter);
87 if (_delimiter)
88 {
90 }
91 }
92
93 tmpStr = std::string(1, _comment);
94 if (ImGui::InputText(fmt::format("Comment character##{}", size_t(id)).c_str(), &tmpStr, ImGuiInputTextFlags_CallbackEdit, TextFilters::FilterSingleCharacter))
95 {
96 _comment = tmpStr.empty() ? '\0' : tmpStr.at(0);
97 LOG_DEBUG("{}: Comment character changed to {}", nameId(), _comment);
100 }
101
102 if (ImGui::InputIntL(fmt::format("Skip lines##{}", size_t(id)).c_str(), &_skipLines, 0, std::numeric_limits<int>::max()))
103 {
104 LOG_DEBUG("{}: Skip lines changed to {}", nameId(), _skipLines);
106 doInitialize();
107 }
108
109 if (ImGui::Checkbox(fmt::format("Header line##{}", size_t(id)).c_str(), &_hasHeaderLine))
110 {
111 LOG_DEBUG("{}: HasHeaderLine changed to {}", nameId(), _hasHeaderLine);
113 doInitialize();
114 }
115
116 ImGui::Separator();
117
118 ImGui::Text("Amount of data lines in file: %zu", _data.lines.size());
119
120 // Header info
121 if (ImGui::BeginTable(fmt::format("##CSVHeaders ({})", size_t(id)).c_str(), 2,
122 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
123 {
124 ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
125 ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed);
126 ImGui::TableHeadersRow();
127
128 for (size_t i = 0; i < _data.description.size(); i++)
129 {
130 ImGui::TableNextRow();
131 ImGui::TableNextColumn();
132 ImGui::Text("%zu", i);
133 ImGui::TableNextColumn();
134 ImGui::TextUnformatted(_data.description[i].c_str());
135 }
136
137 ImGui::EndTable();
138 }
139}
140
141[[nodiscard]] json NAV::CsvFile::save() const
142{
143 LOG_TRACE("{}: called", nameId());
144
145 json j;
146
147 j["FileReader"] = FileReader::save();
148 j["delimiter"] = _delimiter;
149 j["comment"] = _comment;
150 j["skipLines"] = _skipLines;
151 j["hasHeaderLine"] = _hasHeaderLine;
152
153 return j;
154}
155
157{
158 LOG_TRACE("{}: called", nameId());
159
160 if (j.contains("FileReader"))
161 {
162 FileReader::restore(j.at("FileReader"));
163 }
164 if (j.contains("delimiter"))
165 {
166 j.at("delimiter").get_to(_delimiter);
167 }
168 if (j.contains("comment"))
169 {
170 j.at("comment").get_to(_comment);
171 }
172 if (j.contains("skipLines"))
173 {
174 j.at("skipLines").get_to(_skipLines);
175 }
176 if (j.contains("hasHeaderLine"))
177 {
178 j.at("hasHeaderLine").get_to(_hasHeaderLine);
179 }
180}
181
183{
184 LOG_TRACE("{}: called", nameId());
185
186 _data.description.clear();
187 _data.lines.clear();
188
190 {
191 return false;
192 }
193
194 std::string line;
195 std::vector<size_t> emptyCols{};
196 while (!eof())
197 {
198 getline(line);
199 if (line.empty() || line.at(0) == _comment) { continue; } // Skip empty and comment lines
200
201 auto splittedData = str::split(line, _delimiter);
202 if (!splittedData.empty()) { _data.lines.emplace_back(); }
203
204 for (size_t i = 0; i < splittedData.size(); i++)
205 {
206 const auto& cell = splittedData.at(i);
207
208 if (cell.empty() && std::ranges::find(emptyCols, i) == emptyCols.end())
209 {
210 emptyCols.push_back(i);
211 LOG_WARN("{}: Data missing in column: '{}' at: {} s and possibly afterwards, too.", nameId(), _data.description.at(i), splittedData.front());
212 }
213
215 try
216 {
217 value = std::stod(cell);
218 }
219 catch (...)
220 {
221 value = cell;
222 }
223 _data.lines.back().push_back(value);
224 }
225 }
226
227 LOG_TRACE("{}: initialize() finished. Read {} columns over {} lines.", nameId(), _data.description.size(), _data.lines.size());
228
229 return true;
230}
231
233{
234 LOG_TRACE("{}: called", nameId());
235 return true;
236}
237
239{
240 LOG_TRACE("{}: called", nameId());
241
242 _data.description.clear();
243 _data.lines.clear();
244
246}
247
252
254{
255 for (int i = 0; i < _skipLines; i++) { ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } // Skip lines at the start of the file
256
257 std::string line;
258 if (_hasHeaderLine)
259 {
260 getline(line);
261 _data.description = str::split(line, _delimiter);
262 for (auto& desc : _data.description)
263 {
264 desc.erase(std::ranges::find_if(desc, [](int ch) { return std::iscntrl(ch); }), desc.end());
265 }
266 }
267}
CSV File reader.
Save/Load the Nodes.
nlohmann::json json
json namespace
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
Definition Logger.hpp:71
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Definition Logger.hpp:65
Utility functions for working with std::strings.
static std::string type()
Returns the type of the data class.
Definition CsvData.hpp:28
std::variant< double, std::string > CsvElement
CSV Elements (number or if not convertible to number as std::string)
Definition CsvData.hpp:31
void guiConfig() override
ImGui config window which is shown on double click.
Definition CsvFile.cpp:51
FileType determineFileType() override
Determines the type of the file.
Definition CsvFile.cpp:248
bool initialize() override
Initialize the node.
Definition CsvFile.cpp:182
int _skipLines
Amount of lines to skip at the start.
Definition CsvFile.hpp:86
void deinitialize() override
Deinitialize the node.
Definition CsvFile.cpp:238
static std::string category()
String representation of the Class Category.
Definition CsvFile.cpp:46
CsvFile()
Default constructor.
Definition CsvFile.cpp:20
char _comment
Comment character.
Definition CsvFile.hpp:83
void readHeader() override
Read the Header of the file.
Definition CsvFile.cpp:253
std::string type() const override
String representation of the Class Type.
Definition CsvFile.cpp:41
void restore(const json &j) override
Restores the node from a json object.
Definition CsvFile.cpp:156
~CsvFile() override
Destructor.
Definition CsvFile.cpp:31
char _delimiter
Delimiter character.
Definition CsvFile.hpp:80
CsvData _data
Data container.
Definition CsvFile.hpp:77
bool _hasHeaderLine
Flag whether there is a header line at the start.
Definition CsvFile.hpp:89
bool resetNode() override
Resets the node. It is guaranteed that the node is initialized when this is called.
Definition CsvFile.cpp:232
static std::string typeStatic()
String representation of the Class Type.
Definition CsvFile.cpp:36
json save() const override
Saves the node into a json object.
Definition CsvFile.cpp:141
bool initialize()
Initialize the file reader.
void restore(const json &j)
Restores the node from a json object.
std::string _path
Path to the file.
FileType
File Type Enumeration.
@ ASCII
Ascii text data.
auto & ignore(std::streamsize count, int delim)
Extracts and discards characters from the input stream until and including delim.
auto eof() const
Check whether the end of file is reached.
@ PATH_CHANGED
The path changed and exists.
GuiResult guiConfig(const char *vFilters, const std::vector< std::string > &extensions, size_t id, const std::string &nameId)
ImGui config.
auto & getline(std::string &str)
Reads a line from the filestream.
json save() const
Saves the node into a json object.
void deinitialize()
Deinitialize the file reader.
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
Definition Node.cpp:465
ImVec2 _guiConfigDefaultWindowSize
Definition Node.hpp:522
Node(std::string name)
Constructor.
Definition Node.cpp:29
OutputPin * CreateOutputPin(const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier, OutputPin::PinData data=static_cast< void * >(nullptr), int idx=-1)
Create an Output Pin object.
Definition Node.cpp:278
bool doInitialize(bool wait=false)
Asks the node worker to initialize the node.
Definition Node.cpp:370
std::string nameId() const
Node name and id.
Definition Node.cpp:323
std::string name
Name of the Node.
Definition Node.hpp:507
bool doReinitialize(bool wait=false)
Asks the node worker to reinitialize the node.
Definition Node.cpp:420
bool _hasConfig
Flag if the config window should be shown.
Definition Node.hpp:525
ImGui extensions.
bool InputIntL(const char *label, int *v, int v_min, int v_max, int step, int step_fast, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'int'.
Definition imgui_ex.cpp:242
void ApplyChanges()
Signals that there have been changes to the flow.
static std::vector< std::string > split(const std::string &str, const std::string &delimiter)
Splits a string into parts at a delimiter.
@ Object
Generic Object.
Definition Pin.hpp:57