Skip to content

Commit

Permalink
Loading Files from different .csv formats Part1
Browse files Browse the repository at this point in the history
Changes:
	1. seperate cpp and hpp for loading files
	2. files are loaded directly when the popup closes
	3. Error handling for incorrect formats
	4. Loaded Files are now from datatype externData instead of Scope
  • Loading branch information
AKMaily committed Oct 23, 2024
1 parent a14b275 commit 959a3f5
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 107 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include(cmake_helpers/FindOrFetch.cmake)

add_executable(OmniView
src/main.cpp
src/loadFiles.cpp
src/mainWindow.cpp
src/generateTrainingData.cpp
src/info_popup.cpp
Expand Down
168 changes: 168 additions & 0 deletions src/LoadFiles.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#include "loadFiles.hpp"

namespace fs = std::filesystem;

externData::externData(const std::filesystem::path& path) : filepath(path) {};
externData::~externData(){};

void generateLoadFilesMenu(std::vector<std::filesystem::path> &externDataFilePaths, std::vector<externData> &externDatas, bool &close){
ImGui::OpenPopup(appLanguage[Key::Load_file_data]);

if (ImGui::BeginPopupModal(appLanguage[Key::Load_file_data], nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::SetItemDefaultFocus();
static ImGui::FileBrowser fileBrowser;
static std::vector<std::string> pathArr;

if (pathArr.empty())
pathArr.emplace_back("");

for (auto &path : pathArr) {
ImGui::PushID(&path); // unique IDs
ImGui::InputTextWithHint("##", "Path", &path);
ImGui::SameLine();

if (ImGui::Button("Browse")) {
fileBrowser.Open();
}

fileBrowser.Display();

if (fileBrowser.HasSelected()) {
path = fileBrowser.GetSelected().string();
fileBrowser.ClearSelected();
}

// Validierung des Dateipfads
if (!path.empty()) {
if (fs::path(path).extension() != ".csv") { // only accept .csv data
ImGui::OpenPopup("Wrong File Type");
path.clear();
} else {
if (std::find(externDataFilePaths.begin(), externDataFilePaths.end(), path) == externDataFilePaths.end()) {
// Füge den Pfad nur hinzu, wenn er nicht bereits vorhanden ist
externDataFilePaths.emplace_back(path);
} else {
std::cout << "Path " << path << " was already chosen.\n";
}
}
}
ImGui::PopID();
}

if (ImGui::Button(" + ")) {
pathArr.emplace_back("");
}

if (ImGui::Button("Back")) {
pathArr.clear();
externDataFilePaths.clear();
close = false;
ImGui::CloseCurrentPopup();
}

ImGui::SameLine();

// Load Files
if (ImGui::Button("Load Files")) {
loadMultipleExternFiles(externDataFilePaths, externDatas);
pathArr.clear();
close = false;
ImGui::CloseCurrentPopup();
}

ImGui::EndPopup();
}
}

void loadMultipleExternFiles(std::vector<std::filesystem::path> &paths, std::vector<externData> &dataObjects){

for (const auto& path : paths) {
// new data object for new path
externData data(path);

data.loadDataFromFile();

dataObjects.push_back(data); // Push_back because the dataObjects vector should be dynamically and is changed in other functions as well

std::cout << "Data form file " << path.string() << " was loaded.\n";
}
}

void externData::loadDataFromFile() {

if (isLoaded) {
std::cout << "File " << filepath.string() << " was already loaded.\n";
return;
}

// Öffne die Datei
std::ifstream file(filepath);
if (!file.is_open()) {
throw std::runtime_error("Error: File cant be opened " + filepath.string());
}

std::string line;

// Check for old data format with Omniscope
if (std::getline(file, line)) {
if (line.find("Omniscope") != std::string::npos) {
isOmnAIScope = true;
std::cout << "Old OmnAIScope file detected\n";
sampling_rate = 100000; // sampling rate of the OmnAIScope
}
}

// Try reading units from the second line, else set standard units
if (std::getline(file, line)) {
std::istringstream iss(line);
std::string unit;
units.clear();

while (iss >> unit) {
units.push_back(unit);
}
if (units.size() < 2) {
std::cout << "No units provided, standard units (V) and (s) are set" << std::endl;
units = {"s", "V"}; // Standardwerte setzen (s für Zeit, V für Spannung)
}
} else {
// Falls die Zeile mit den Einheiten fehlt, setze Standardwerte
std::cout << "No Units provided. Standard Units (V) and (s) are set" << std::endl;
units = {"s", "V"}; // Standardwerte setzen
}

double x = 0.0, y = 0.0;
int index = 0;

while (std::getline(file, line)) {
std::istringstream iss(line);

if (isOmnAIScope) {
// OmniScope-Modus: Nur Y-Werte vorhanden, X-Werte basierend auf Sampling-Rate berechnen
x = index / sampling_rate; // X-Wert berechnen
if (!(iss >> y)) {
throw std::runtime_error("Error: Y-Values could not be read correctly");
}
} else {
// Normaler Modus: X- und Y-Werte aus der Datei lesen
if (!(iss >> x >> y)) {
throw std::runtime_error("Error: Y and X-Values could not be read correctly");
}
}

// Speichere die gelesenen Werte
xValues.push_back(x);
yValues.push_back(y);

// Erhöhe den Index für die nächste Berechnung (Sampling-Rate) bei OmniScope
index++;
}

// Schließe die Datei
file.close();

// Bestätige, dass die Daten erfolgreich geladen wurden
std::cout << "Data from file " << filepath.string() << " was loaded sucessfully\n";
}

45 changes: 45 additions & 0 deletions src/LoadFiles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef LOADFILES_HPP
#define LOADFILES_HPP

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <map>
#include <filesystem>
#include <imgui.h>
#include "languages.hpp"
#include "../imgui-stdlib/imgui_stdlib.h"
#include "../imgui-filebrowser/imfilebrowser.h"


class externData{

public:
std::map<std::string, std::string> metaData;
std::vector<std::string> units;
std::vector<double> xValues;
std::vector<double> yValues;
std::filesystem::path filepath;
bool isOmnAIScope, loadChecked, isLoaded{false};
double sampling_rate = 0.0;

externData(const std::filesystem::path&);
~externData();

void loadDataFromFile();


//void filesList(std::vector<externData> &); // generates, shows and functionality of the filesList in the DeviceRegion

//void ShowPlot(); // alternative to AddPlotsFromFile for various .csv formats

};

void generateLoadFilesMenu(std::vector<std::filesystem::path> &, std::vector<externData> &, bool &);

void loadMultipleExternFiles(std::vector<std::filesystem::path> &, std::vector<externData> &);

#endif
98 changes: 3 additions & 95 deletions src/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,101 +244,6 @@ void devicesList(bool const &flagPaused) {
doDevice(device, appLanguage[Key::Ready]);
}

void load_files(decltype(captureData) &loadedFiles,
std::map<Omniscope::Id, std::string> &loadedFilenames,
bool &loadFile) {
static std::set<fs::path> loadedFilePaths;
auto do_load = [&loadedFiles, &loadedFilenames] {
std::pair<Omniscope::Id, std::vector<std::pair<double, double>>> loadedFile;
for (const auto &path : loadedFilePaths) {
std::ifstream readfile(path, std::ios::binary);
if (!readfile.is_open())
fmt::println("Failed to open file {}", path.string());
else {
std::string first_line;
std::getline(readfile, first_line);
std::istringstream input{first_line};
static constexpr size_t fieldsSz{6};
// extract input fields data from the first line
for (size_t i = 0; i < fieldsSz; i++) {
std::string substr;
std::getline(input, substr, ',');
if (i == 3) // fourth element (Type of scope)
loadedFile.first.type = substr;
if (i == 4) // fifth element (serial of scope)
loadedFile.first.serial = substr;
}
// each y-value is recorded at 1/sampleRate time
double step{0.00001}, base{step};
size_t indx{2}; // y_values start from line 2 of the file
while (!readfile.eof()) { // fill the vector of the values
double value{};
readfile >> value;
loadedFile.second.emplace_back(base, value);
static constexpr size_t bigNumber{10'000'000};
readfile.ignore(bigNumber,
'\n'); // new line separator between elements
base += step;
}
readfile.close();
loadedFile.second.pop_back(); // pop the extra last element
loadedFiles.emplace(loadedFile);
loadedFilenames.emplace(loadedFile.first, path.filename().string());
}
}
loadedFilePaths.clear();
};

if (ImGui::BeginPopupModal(appLanguage[Key::Load_file_data], nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::SetItemDefaultFocus();
static ImGui::FileBrowser fileBrowser;
static std::vector<std::string> pathArr;
if (pathArr.empty())
pathArr.emplace_back("");

for (auto &path : pathArr) {
ImGui::PushID(&path); // unique IDs
ImGui::InputTextWithHint("##", appLanguage[Key::Path], &path);
ImGui::SameLine();
if (ImGui::Button(appLanguage[Key::Browse]))
fileBrowser.Open();
fileBrowser.Display();
info_popup(appLanguage[Key::Wrong_file_warning],
appLanguage[Key::Wrong_file_type]);
if (fileBrowser.HasSelected()) {
path = fileBrowser.GetSelected().string();
fileBrowser.ClearSelected();
}
if (!path.empty())
if (fs::path(path).extension() != ".csv") {
ImGui::OpenPopup(appLanguage[Key::Wrong_file_warning],
ImGuiPopupFlags_NoOpenOverExistingPopup);
path.clear();
} else
loadedFilePaths.emplace(path);
ImGui::PopID();
}
if (ImGui::Button(" + "))
pathArr.emplace_back("");
ImGui::SetItemTooltip(appLanguage[Key::Load_another_file]);
if (ImGui::Button(appLanguage[Key::Back])) {
pathArr.clear();
loadedFilePaths.clear();
loadFile = false;
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button(appLanguage[Key::Load_file])) {
pathArr.clear();
do_load();
loadFile = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}

void set_config(mainWindow &mWindow) {
if (fs::exists(mWindow.configpath))
fmt::print("found config.json\n\r");
Expand Down Expand Up @@ -392,6 +297,9 @@ void setupSW(mainWindow &mWindow){
//TODO : Set this also up for saved OmniScope files

void AddPlotFromFile(fs::path &filePath) {

// set object with chosen filePath
//
LoadedFiles loadedFile;
loadedFile.LoadFromFile(filePath);

Expand Down
6 changes: 6 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ int main() {

// temporary solution
// TODO:: Change loadedFiles from datatype Scope to a concrete Filetype

// TODO:: Create Array std::vector<externData> externDatas
auto loadedFiles = captureData;
std::map<Omniscope::Id, std::string> loadedFilenames;

Expand Down Expand Up @@ -91,6 +93,10 @@ int main() {
ImGui::SameLine();
ImGui::Text(appLanguage[Key::Devices_found]);
devicesList(mWindow.flagPaused);

// TODO:: Load File names
// function:: filesCheckboxList(std::vector<externData>)
// instead of captureData.emplace() --> externData[i].loadChecked = true;
if (!loadedFiles.empty()) { // if devices were successfully loaded from file
static std::map<Omniscope::Id, BoolWrapper> loadedFilesChkBxs;
for (auto it = loadedFiles.begin(); it != loadedFiles.end();) {
Expand Down
7 changes: 6 additions & 1 deletion src/mainWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
#include <mutex>
#include "loadFiles.hpp"

class mainWindow{
public:
nlohmann::json config;
const std::string configpath;
nlohmann::json language;
bool flagPaused{true}, open_generate_training_data{false}, open_analyze_menu{false}, open_settings{false}, LOADANALYSISDATA{false};
bool flagPaused{true}, open_generate_training_data{false}, open_analyze_menu{false}, open_settings{false},
LOADANALYSISDATA{false}, open_load_files_menu{false};

bool development{false};
std::once_flag configFlag;

std::filesystem::path AnalyzedFilePath;

std::vector<externData> externDatas;
std::vector<std::filesystem::path> externDataFilePaths;

mainWindow();
~mainWindow();

Expand Down
2 changes: 1 addition & 1 deletion src/saves_popup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <charconv>
#include "popups.hpp"
#include "look_up_saves.hpp"
#include "imgui_stdlib.h"
//#include "imgui_stdlib.h"
#include "languages.hpp"
#include "style.hpp"

Expand Down
Loading

0 comments on commit 959a3f5

Please sign in to comment.