diff --git a/Modules/IGT/IO/mitkNavigationDataReaderCSV.cpp b/Modules/IGT/IO/mitkNavigationDataReaderCSV.cpp index 610bd67bab..08d82ec814 100644 --- a/Modules/IGT/IO/mitkNavigationDataReaderCSV.cpp +++ b/Modules/IGT/IO/mitkNavigationDataReaderCSV.cpp @@ -1,17 +1,162 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "mitkNavigationDataReaderCSV.h" \ No newline at end of file +#include "mitkNavigationDataReaderCSV.h" + +mitk::NavigationDataReaderCSV::NavigationDataReaderCSV() +{ + +} + +mitk::NavigationDataReaderCSV::~NavigationDataReaderCSV() +{ + +} + +int mitk::NavigationDataReaderCSV::getNumberOfToolsInLine(std::string line) +{ + std::vector tokens=splitLine(line); + int size = tokens.size(); + int NumOfTools = (size-1)/8; + + if ( (size-1)%8 != 0 ) + { + MITK_ERROR("mitkNavigationDataReader") << "Illegal csv-file! Unexpected number of columns found! Assuming " << NumOfTools << " tools!"; + } + + return NumOfTools ; +} + +std::vector mitk::NavigationDataReaderCSV::splitLine(std::string line) +{ + std::vector elems; + std::stringstream ss(line); + std::string item; + while (std::getline(ss, item, ';')) { + elems.push_back(item); + } + return elems; +} + +mitk::NavigationData::Pointer mitk::NavigationDataReaderCSV::CreateNd(std::string timestamp, std::string valid, std::string X, std::string Y, std::string Z, std::string QX, std::string QY, std::string QZ, std::string QR) +{ + mitk::NavigationData::Pointer result= mitk::NavigationData::New(); + + mitk::Point3D position; + mitk::Quaternion orientation; + bool isValid = false; + double time; + + time = StringToDouble(timestamp); + + if (valid == "1") isValid = true; + else isValid = false; + + position[0] = StringToDouble(X); + position[1] = StringToDouble(Y); + position[2] = StringToDouble(Z); + + orientation[0] = StringToDouble(QX); + orientation[1] = StringToDouble(QY); + orientation[2] = StringToDouble(QZ); + orientation[3] = StringToDouble(QR); + + result->SetIGTTimeStamp(time); + result->SetDataValid(isValid); + result->SetPosition(position); + result->SetOrientation(orientation); + return result; +} + +double mitk::NavigationDataReaderCSV::StringToDouble( const std::string& s ) +{ + std::istringstream i(s); + double x; + if (!(i >> x)) + return 0; + return x; +} + +std::vector mitk::NavigationDataReaderCSV::parseLine(std::string line, int NumOfTools) +{ + std::vector parts= splitLine(line); + std::vector result; + std::string time= parts[0]; + + + + for (int n= 0; n=NumOfTools; n++) + { + mitk::NavigationData::Pointer nd; + nd = CreateNd(time, parts[n+1],parts[n+2],parts[n+3], parts[n+4], parts[n+5], parts[n+6], parts[n+7], parts[n+8]); + result.push_back(nd); + } + return result; +} + + +mitk::NavigationDataSet::Pointer mitk::NavigationDataReaderCSV::Read(std::string fileName) +{ + std::vector fileContent = GetFileContentLineByLine(fileName); + int NumOfTools = getNumberOfToolsInLine(fileContent[0]); + + mitk::NavigationDataSet::Pointer returnValue = mitk::NavigationDataSet::New(NumOfTools); + + for (int i = 1; iAddNavigationDatas( parseLine( fileContent[i], NumOfTools) ); + } + + + return returnValue; +} + + +std::vector mitk::NavigationDataReaderCSV::GetFileContentLineByLine(std::string filename) +{ +std::vector readData = std::vector(); + +//save old locale +char * oldLocale; +oldLocale = setlocale( LC_ALL, 0 ); + +//define own locale +std::locale C("C"); +setlocale( LC_ALL, "C" ); + +//read file +std::ifstream file; +file.open(filename.c_str(), std::ios::in); +if (file.good()) + { + //read out file + file.seekg(0L, std::ios::beg); // move to begin of file + while (! file.eof()) + { + std::string buffer; + std::getline(file,buffer); // read out file line by line + if (buffer.size() > 0) readData.push_back(buffer); + + } + } + +file.close(); + +//switch back to old locale +setlocale( LC_ALL, oldLocale ); + +return readData; +} diff --git a/Modules/IGT/IO/mitkNavigationDataReaderCSV.h b/Modules/IGT/IO/mitkNavigationDataReaderCSV.h index 36133667a0..91f6eb9077 100644 --- a/Modules/IGT/IO/mitkNavigationDataReaderCSV.h +++ b/Modules/IGT/IO/mitkNavigationDataReaderCSV.h @@ -1,30 +1,78 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKNavigationDataReaderCSV_H_HEADER_INCLUDED_ #define MITKNavigationDataReaderCSV_H_HEADER_INCLUDED_ #include "mitkNavigationDataReaderInterface.h" namespace mitk { + /** This class reads csv logged navigation datas from the hard disc and returns + * the navigation data set. + * + * Caution: at the moment only one navigation data is supported which means that only + * the data of the first navigation tool in the file is read! + */ class MitkIGT_EXPORT NavigationDataReaderCSV : public NavigationDataReaderInterface { + public: + mitkClassMacro(NavigationDataReaderCSV, NavigationDataReaderInterface); + itkNewMacro(Self); + + /** @return Returns the NavigationDataSet of the first tool in the given file. + * Returns an empty NavigationDataSet if the file could not be read. + */ + virtual mitk::NavigationDataSet::Pointer Read(std::string fileName); + + protected: + NavigationDataReaderCSV(); + virtual ~NavigationDataReaderCSV(); + + /** + * /brief Creates a NavigationData Pointer based on the given Input. + */ + mitk::NavigationData::Pointer CreateNd(std::string timestamp, std::string valid, std::string X, std::string Y, std::string Z, std::string QX, std::string QY, std::string QZ, std::string QR); + + /** + * /brief Presents File Content line by line + */ + std::vector GetFileContentLineByLine(std::string filename); + + /** + * /brief Calculates the Number of Tools based on the number of colums per line. + */ + int getNumberOfToolsInLine(std::string line); + + /** + * /brief Converts string to double returns zero if failing + */ + std::vector parseLine(std::string line, int NumOfTools); + + /** + * /brief Converts string to double returns zero if failing + */ + double StringToDouble( const std::string& s ); + + /** + * /brief Split line in elemens based on a given delim + */ + std::vector splitLine(std::string line); }; } #endif // MITKNavigationDataReaderCSV_H_HEADER_INCLUDED_ diff --git a/Modules/IGT/Testing/files.cmake b/Modules/IGT/Testing/files.cmake index 4e8287a28f..541be85d93 100644 --- a/Modules/IGT/Testing/files.cmake +++ b/Modules/IGT/Testing/files.cmake @@ -1,63 +1,64 @@ set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## ON THE FENCE TESTS ################################################# # none ################## DISABLED TESTS ##################################################### # mitkNavigationToolStorageDeserializerTest.cpp # This test was disabled because of bug 17303. # mitkNavigationToolStorageSerializerAndDeserializerIntegrationTest.cpp # This test was disabled because of bug 17181. ################# RUNNING TESTS ####################################################### mitkCameraVisualizationTest.cpp mitkClaronInterfaceTest.cpp mitkClaronToolTest.cpp mitkClaronTrackingDeviceTest.cpp mitkInternalTrackingToolTest.cpp mitkNavigationDataDisplacementFilterTest.cpp mitkNavigationDataLandmarkTransformFilterTest.cpp mitkNavigationDataObjectVisualizationFilterTest.cpp mitkNavigationDataSetTest.cpp mitkNavigationDataTest.cpp mitkNavigationDataRecorderTest.cpp mitkNavigationDataReferenceTransformFilterTest.cpp mitkNavigationDataSequentialPlayerTest.cpp - mitkNavigationDataSetReaderWriterTest.cpp + mitkNavigationDataSetReaderWriterXMLTest.cpp + mitkNavigationDataSetReaderWriterCSVTest.cpp mitkNavigationDataSourceTest.cpp mitkNavigationDataToMessageFilterTest.cpp mitkNavigationDataToNavigationDataFilterTest.cpp mitkNavigationDataToPointSetFilterTest.cpp mitkNavigationDataTransformFilterTest.cpp mitkNDIPassiveToolTest.cpp mitkNDIProtocolTest.cpp mitkNDITrackingDeviceTest.cpp mitkTimeStampTest.cpp mitkTrackingVolumeGeneratorTest.cpp mitkTrackingDeviceTest.cpp mitkTrackingToolTest.cpp mitkVirtualTrackingDeviceTest.cpp # mitkNavigationDataPlayerTest.cpp # random fails see bug 16485. # We decided to won't fix because of complete restructuring via bug 15959. mitkTrackingDeviceSourceTest.cpp mitkTrackingDeviceSourceConfiguratorTest.cpp mitkNavigationDataEvaluationFilterTest.cpp mitkTrackingTypesTest.cpp # ------------------ Navigation Tool Management Tests ------------------- mitkNavigationToolStorageTest.cpp mitkNavigationToolTest.cpp mitkNavigationToolReaderAndWriterTest.cpp mitkNavigationToolStorageSerializerTest.cpp # ----------------------------------------------------------------------- ) set(MODULE_CUSTOM_TESTS mitkNDIAuroraHardwareTest.cpp mitkNDIPolarisHardwareTest.cpp mitkClaronTrackingDeviceHardwareTest.cpp ) diff --git a/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp new file mode 100644 index 0000000000..1bb41f2b58 --- /dev/null +++ b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterCSVTest.cpp @@ -0,0 +1,142 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +//testing headers +//#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +//for exceptions +#include "mitkIGTException.h" +#include "mitkIGTIOException.h" + +class mitkNavigationDataSetReaderWriterCSVTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkNavigationDataSetReaderWriterCSVTestSuite); + // MITK_TEST(TestCompareFunction); + MITK_TEST(TestReadWrite); + CPPUNIT_TEST_SUITE_END(); + +private: + + std::string pathRead; + std::string pathWrite; + std::string pathWrong; + mitk::NavigationDataSetWriterCSV writer; + mitk::NavigationDataReaderCSV::Pointer reader; + + mitk::NavigationDataReaderXML::Pointer xmlReader; + + mitk::NavigationDataSet::Pointer set; + +public: + + void setUp() + { + pathRead = GetTestDataFilePath("IGT-Data/RecordedNavigationData.xml"); + + pathWrong = GetTestDataFilePath("IGT-Data/NavigationDataTestData.CSV"); + pathWrite="C:\\test.csv"; + + reader = mitk::NavigationDataReaderCSV::New(); + xmlReader= mitk::NavigationDataReaderXML::New(); + } + + void tearDown() + { + } + + + void TestReadWrite() + { + // Aim is to read an CSV into a pointset, write that CSV again, and compare the output + + set = xmlReader->Read(pathRead); + + writer.Write(pathWrite, set); + + //FIXME: Commented out, because test fails under linux. binary comparison of files is probably not the wa to go + // See Bug 17775 + //CPPUNIT_ASSERT_MESSAGE( "Testing if read/write cycle creates identical files", CompareFiles(pathRead, pathWrite)); + //remove(pathWrite.c_str()); + } + + + + + + bool CompareFiles(std::string file) + { + set = reader->Read(file); + + double sample[2][30] ={ + {5134019.44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5134019.44, 0, 1, 101.2300034, -62.63999939, -203.2400055, -0.3059000075, 0.5752000213, 0, 0.7585999966, 5134019.44, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5134082.84, 5134073.64, 1, -172.6100006, 12.60999966, -299.4500122, -0.1588999927, 0.4370000064, 0, 0.8852000237, 5134082.84, 5134073.64, 1, 101.2300034, -62.63999939, -203.2400055, -0.3059000075, 0.5752000213, 0, 0.7585999966, 5134082.84, 5134073.64, 0, 0, 0, 0, 0, 0, 0, 0} + }; + + bool returnValue = true; + for(int line = 0 ; line < 2; line++) + { + + for (int tool =0; tool < 3; tool ++) + { + mitk::NavigationData::Pointer testline = set->GetNavigationDataForIndex(line,tool) ; + + returnValue = returnValue && mitk::Equal( testline->GetIGTTimeStamp() , sample [line] [(tool*10)] ); + returnValue = returnValue && mitk::Equal( testline->IsDataValid() , sample [line] [(tool*10)+1] ); + + mitk::NavigationData::PositionType pos = testline->GetPosition(); + returnValue = returnValue && mitk::Equal( pos[0] , sample [line] [(tool*10)+2] ); + returnValue = returnValue && mitk::Equal( pos[1] , sample [line] [(tool*10)+3] ); + returnValue = returnValue && mitk::Equal( pos[2] , sample [line] [(tool*10)+4] ); + + mitk::NavigationData::OrientationType ori = testline->GetOrientation(); + returnValue = returnValue && mitk::Equal( ori[0] , sample [line] [(tool*10)+5] ); + returnValue = returnValue && mitk::Equal( ori[1] , sample [line] [(tool*10)+6] ); + returnValue = returnValue && mitk::Equal( ori[2] , sample [line] [(tool*10)+7] ); + returnValue = returnValue && mitk::Equal( ori[3] , sample [line] [(tool*10)+8] ); + } + + return returnValue; + } + } + + + void TestCompareFunction() + { + CPPUNIT_ASSERT_MESSAGE("Checking if csv-file reader is working properly", CompareFiles(pathRead)); + //CPPUNIT_ASSERT_MESSAGE("Asserting that compare function for files works correctly - Negative Test", ! CompareFiles(pathWrong) ); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataSetReaderWriterCSV) \ No newline at end of file diff --git a/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterTest.cpp b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterXMLTest.cpp similarity index 94% rename from Modules/IGT/Testing/mitkNavigationDataSetReaderWriterTest.cpp rename to Modules/IGT/Testing/mitkNavigationDataSetReaderWriterXMLTest.cpp index 8ac8b94228..b4b17c8bc8 100644 --- a/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataSetReaderWriterXMLTest.cpp @@ -1,142 +1,142 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //testing headers //#include #include #include #include #include #include #include #include #include #include #include #include #include #include //for exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" -class mitkNavigationDataSetReaderWriterTestSuite : public mitk::TestFixture +class mitkNavigationDataSetReaderWriterXMLTestSuite : public mitk::TestFixture { - CPPUNIT_TEST_SUITE(mitkNavigationDataSetReaderWriterTestSuite); + CPPUNIT_TEST_SUITE(mitkNavigationDataSetReaderWriterXMLTestSuite); MITK_TEST(TestCompareFunction); MITK_TEST(TestReadWrite); MITK_TEST(TestSetXMLStringException); CPPUNIT_TEST_SUITE_END(); private: std::string pathRead; std::string pathWrite; std::string pathWrong; mitk::NavigationDataSetWriterXML writer; mitk::NavigationDataReaderXML::Pointer reader; mitk::NavigationDataSet::Pointer set; public: void setUp() { pathRead = GetTestDataFilePath("IGT-Data/RecordedNavigationData.xml"); pathWrite = pathRead; pathWrite.insert(pathWrite.end()-4,'2');;//Insert 2: IGT-Data/NavigationDataSet2.xml std::ifstream FileTest(pathWrite.c_str()); if(FileTest){ //remove file if it already exists. TODO: Löschen funktioniert nicht!!!! xxxxxxxxxxxxxxxx FileTest.close(); std::remove(pathWrite.c_str()); } pathWrong = GetTestDataFilePath("IGT-Data/NavigationDataTestData.xml"); reader = mitk::NavigationDataReaderXML::New(); } void tearDown() { } void TestReadWrite() { // Aim is to read an xml into a pointset, write that xml again, and compare the output set = reader->Read(pathRead); writer.Write(pathWrite, set); //FIXME: Commented out, because test fails under linux. binary comparison of files is probably not the wa to go // See Bug 17775 //CPPUNIT_ASSERT_MESSAGE( "Testing if read/write cycle creates identical files", CompareFiles(pathRead, pathWrite)); remove(pathWrite.c_str()); } bool CompareFiles(std::string file1, std::string file2) { FILE* f1 = fopen (file1.c_str() , "r"); FILE* f2 = fopen (file2.c_str() , "r"); char buf1[10000]; char buf2[10000]; do { size_t r1 = fread(buf1, 1, 10000, f1); size_t r2 = fread(buf2, 1, 10000, f2); if (r1 != r2 || memcmp(buf1, buf2, r1)) { fclose(f1); fclose(f2); return false; // Files are not equal } } while (!feof(f1) && !feof(f2)); bool returnValue = feof(f1) && feof(f2); fclose(f1); fclose(f2); return returnValue; } void TestSetXMLStringException() { bool exceptionThrown3=false; try { std::string file = GetTestDataFilePath("IGT-Data/InvalidVersionNavigationDataTestData.xml"); mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); reader->Read(file); } catch(mitk::IGTIOException) { exceptionThrown3=true; } MITK_TEST_CONDITION(exceptionThrown3, "Reading an invalid XML string and expecting a exception"); } void TestCompareFunction() { CPPUNIT_ASSERT_MESSAGE("Asserting that compare function for files works correctly - Positive Test", CompareFiles(pathRead, pathRead)); CPPUNIT_ASSERT_MESSAGE("Asserting that compare function for files works correctly - Negative Test", ! CompareFiles(pathRead, pathWrong) ); } }; -MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataSetReaderWriter) \ No newline at end of file +MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataSetReaderWriterXML) \ No newline at end of file