diff --git a/examples/CSVFiles/main.cpp b/examples/CSVFiles/main.cpp index d457785..e07a25f 100644 --- a/examples/CSVFiles/main.cpp +++ b/examples/CSVFiles/main.cpp @@ -1,157 +1,267 @@ -//===-- examples/CSVFiles/main.cpp --------------------------------*- C++ -*-===// -// -// The RoSA Framework -- Example CSVFiles -// -//===----------------------------------------------------------------------===// -/// -/// \file examples/CSVFiles/main.cpp -/// -/// \author Edwin Willegger (edwin.willegger@tuwien.ac.at) -/// -/// \date 2019 -/// -/// \brief This example shows how you could use the CSVIterator class to -/// get data into RoSA from a CSV-file. -//===----------------------------------------------------------------------===// - // To compile with dumping record layout: // $ clang++ -o variadic-tuple -Xclang -fdump-record-layouts variadic-tuple.cpp // -Wall -g -std=c++11 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +//includes for an complete example to read and write +//with sensors and agents. +#include "rosa/deluxe/DeluxeContext.hpp" + +#include "rosa/config/version.h" + +//includes to test the basic functionality +//to read and write tuples. #include "rosa/support/csv/CSVReader.hpp" #include "rosa/support/csv/CSVWriter.hpp" +#include "rosa/support/iterator/split_tuple_iterator.hpp" +#include "rosa/support/writer/split_tuple_writer.hpp" + +/// the name of the example +const std::string ExampleName = "csvfiles"; -const std::string AppName = "test-csvfiles"; +/// How many cycles of simulation to perform. +const size_t NumberOfSimulationCycles = 10; -//the example will be executed in the bin directory, but the data files are located in another the examples folder +/// Paths for the CSV files for simulation. +/// input csv files +const std::string csvPath = "../examples/CSVFiles/"; +const std::string csvFileWithHeader = csvPath + "HR-New.csv"; +const std::string csvFileNoHeader = csvPath + "HR.csv"; +const std::string csvFileHeaderSemi = csvPath + "HR-New-Semicolon.csv"; +/// output csv file +const std::string csvFileWriteNoHea = csvPath + "csvwriter_noheader.csv"; -const std::string Path = "../examples/CSVFiles/"; +using namespace rosa; void testtupleCSVReader(){ //different streams to get the csv data out of the files //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data("HR-New.csv"); + std::ifstream file_header_data(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data_2("HR-New.csv"); + std::ifstream file_header_data_2(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data_3("HR-New.csv"); + std::ifstream file_header_data_3(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data_4("HR-New.csv"); + std::ifstream file_header_data_4(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data_5("HR-New.csv"); + std::ifstream file_header_data_5(csvFileWithHeader); //file contains header and valid data entries, delimter = ',' - std::ifstream file_header_data_6("HR-New.csv"); + std::ifstream file_header_data_6(csvFileWithHeader); //file contains no header an valid data entries, delimter = ',' - std::ifstream file2("HR.csv"); + std::ifstream file2(csvFileNoHeader); //file contains header and valid data entries, delimter = ';' - std::ifstream file3("HR-New-Semicolon.csv"); + std::ifstream file3(csvFileHeaderSemi); - rosa::csv::CSVIterator it(file_header_data); + csv::CSVIterator it(file_header_data); it.setDelimeter(','); it++; it++; //if you iterate over the end of file, the last values //of the file will remain in the data structure but no //error occurs. it++; it++; //------------------------------------------------------------------- // a possiblity to get the data out of the iterator std::tuple value = *it; - std::cout << "Values are: " << std::get<0>(value) << " " - << std::get<1>(value) << " ,are you now happy?" << std::endl; + // + // Show the value of one iterator + // + LOG_INFO( "Values are: "); + LOG_INFO(std::get<0>(value) ); + LOG_INFO(std::get<1>(value) ); //-------------------------------------------------------------------- //testing differnet parameters to the constructor //uncomment to see that it is not possible to iterate over an vector in the tuple. //rosa::csv::CSVIterator> it2(file, 1); //try to skip a valid number of lines after the header - rosa::csv::CSVIterator it2_0(file_header_data_2, 1); + csv::CSVIterator it2_0(file_header_data_2, 1); //try to skip a valid number of lines after the header, but you assume that the file has no header //uncomment this line to crash the programm - //rosa::csv::CSVIterator it2_1(file_header_data_3, 0, rosa::csv::HeaderInformation::HasNoHeader); + //csv::CSVIterator it2_1(file_header_data_3, 0, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines after the header, but you assume that the file has no header //uncomment this line to crash the program - // rosa::csv::CSVIterator it2_2(file_header_data_4, 1, rosa::csv::HeaderInformation::HasNoHeader); + //csv::CSVIterator it2_2(file_header_data_4, 1, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines of a file without header - rosa::csv::CSVIterator it2_3(file2, 1, rosa::csv::HeaderInformation::HasNoHeader); + csv::CSVIterator it2_3(file2, 1, csv::HeaderInformation::HasNoHeader); //try to skip a valid number of lines after the header, but with different delimeter - rosa::csv::CSVIterator it2_4(file3, 2,rosa::csv::HeaderInformation::HasHeader, ';'); + csv::CSVIterator it2_4(file3, 2, csv::HeaderInformation::HasHeader, ';'); // if you skip more lines than valid, you generate an infinte loop - //rosa::csv::CSVIterator it3(file_header_data_5, 500); + //csv::CSVIterator it3(file_header_data_5, 500); //if you don't need data from all columns just select the number of columns you //need. You get the data back from the first column (index 0) to the fourth column //all values from the fifth column are ignored. - rosa::csv::CSVIterator it4(file_header_data_6); + csv::CSVIterator it4(file_header_data_6); } void testtupleCSVWriter(){ - std::ofstream file_header_out("csvwriter_noheader.csv"); - rosa::csv::CSVTupleWriter wri(file_header_out); + // + // Create output writer with an file + // + std::ofstream file_header_out(csvFileWriteNoHea); + csv::CSVTupleWriter wri(file_header_out); + + // + // Create test tuples + // std::tuple values(5, 8.3, "hallo"); std::tuple values2(3, 8.3, "end"); + // + // Create test header lines for the test tuples + // std::array header {"first column", "second column", "third column"}; - //wrong header size, which is unable to write as a header to the tuples above. std::array headerWrong {"first column", "second column", "third column", "fourth column"}; + std::array headerWrongShort {"first column", "second column"}; wri.writeHeader(header); wri.write(values); wri.write(values); wri.write(values); wri << values; wri << values2; - //uncomment this line to see, that you can't write a header with the wrong number of elements. + //uncomment this line to see, that you can't write a header with the too many elements. //wri.writeHeader(headerWrong); + //uncomment this line to see, that you can't write a header with the too few elements. + //wri.writeHeader(headerWrongShort); + +} + + +void testsplitTupleIterator() +{ + // + // Create deluxe context + // + std::unique_ptr C = + deluxe::DeluxeContext::create(ExampleName); + + // + // Create deluxe sensors. + // + LOG_INFO("Creating sensors."); + + + // All sensors are created without defining a normal generator function, but + // with the default value of the second argument. That, however, requires the + // data type to be explicitly defined. This is good for simulation only. + // Three different sensors were created, this is just a random number taken. + AgentHandle Elem0Sensor = C->createSensor("Element1 Sensor"); + AgentHandle Elem1Sensor = C->createSensor("Element2 Sensor"); + AgentHandle Elem2Sensor = C->createSensor("Element3 Sensor"); + + + // + // Initialize deluxe context for simulation. + // + C->initializeSimulation(); + + // Type aliases for iterators + using Iterator = rosa::csv::CSVIterator; + using IteratorValue = std::tuple; + static_assert (std::is_same::value, "Iterator must provide tuples" ); + + // + // Open CSV file and register the columns to the corresponding sensors. + // + std::ifstream TestCSV(csvFileWithHeader); + + // + // Test data looks like: + // Element1, Element2, Element3, Element4, Element5 -- is the header line + // 3, 5, 8, 9.5, 17 -- first line of values + // 100, -8, 30, 18.8, 29 -- other line of values were also in the file + // 5, 20, -100, -200.1, -30 -- if you have less number of values than simulation rounds all values + // -- beyond your last value will be zero. + + //get element iterator ranges + auto [Elem0Range, Elem1Range, Elem2Range] = iterator::splitTupleIterator(Iterator(TestCSV), Iterator()); + + //dissect ranges into begin and end iterators by structred bindings + auto[Elem0Begin, Elem0End] = Elem0Range; + auto[Elem1Begin, Elem1End] = Elem1Range; + auto[Elem2Begin, Elem2End] = Elem2Range; + + + C->registerSensorValues(Elem0Sensor, std::move(Elem0Begin), Elem0End); + C->registerSensorValues(Elem1Sensor, std::move(Elem1Begin), Elem1End); + C->registerSensorValues(Elem2Sensor, std::move(Elem2Begin), Elem2End); + + // + // Simulate. + // + C->simulate(NumberOfSimulationCycles); } -int main(void) { - std::cout << "This is a short example to show you how you could use the CSVIterator class." << std::endl; - std::cout << "There are also some limitations explained in the source code of the example." << std::endl; - std::cout << "Testing CSVWriter CSVTupleItrator implementation: " << std::endl; +int main(void){ + LOG_INFO_STREAM << library_string() << " -- " << terminal::Color::Red + << ExampleName << " example" << terminal::Color::Default << '\n'; + + // + // Testing CSVWriter. + // + LOG_INFO("Testing CSVWriter CSVTupleItrator implementation: "); + testtupleCSVWriter(); - std::cout << "Testing CSVReader CSVTupleIterator implementation: " << std::endl; + // + // Testing CSVReader. + // + LOG_INFO("Testing CSVReader CSVTupleIterator implementation: "); + testtupleCSVReader(); - std::cout << "All tests finished sucessfully" << std::endl; + // + // Testing SplitTupleIterator. + // + LOG_INFO("Testing SplitTupleIterator: "); + + testsplitTupleIterator(); + + + // + // info that user knows programm has finished. + // + LOG_INFO( "All tests finished."); + + return 0; }