Commit a2c1082f authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD]

 * Stub for MedInria Fiber VTK file loader (WLoaderVTK)
 * Refactored the WDHException hierachy
 * improved (platform DEPENDENT) make fixtures target
 * explicitly marked operator() for boost thread startup as virtual again, even if they were already virtual, just for the sake of completeness and better readablity
parent 4d75ce43
......@@ -217,6 +217,7 @@ ADD_CUSTOM_TARGET( cicheck
ADD_CUSTOM_TARGET( fixtures
ALL
COMMAND cp -rf ${PROJECT_SOURCE_DIR}/dataHandler/test/fixtures ${PROJECT_BINARY_DIR}/dataHandler/
COMMAND cp -rf ${PROJECT_SOURCE_DIR}/dataHandler/io/test/fixtures ${PROJECT_BINARY_DIR}/dataHandler/io
COMMENT "Copy fixtures to the right place."
)
......
......@@ -27,18 +27,17 @@
#include "WDataHandler.h"
#include "WSubject.h"
#include "exceptions/WNoSuchDataSetException.h"
#include "exceptions/WDHNoSuchDataSet.h"
#include "WLoaderManager.h"
WDataHandler::WDataHandler()
{
}
boost::shared_ptr< WSubject > WDataHandler::getSubject( const unsigned int subjectId ) const
{
if( subjectId >= m_subjects.size() )
throw WNoSuchDataSetException( "Index too large." );
throw WDHNoSuchDataSet( "Index too large." );
return m_subjects.at( subjectId );
}
......
......@@ -28,10 +28,10 @@
#include <boost/filesystem.hpp>
#include "WLoaderManager.h"
#include "WDataSet.h"
#include "io/WLoaderNIfTI.h"
#include "io/WLoaderBiosig.h"
#include "io/WLoaderEEGASCII.h"
#include "io/WLoaderVTK.h"
std::string getSuffix( std::string name )
{
......@@ -72,6 +72,11 @@ void WLoaderManager::load( std::string fileName, boost::shared_ptr< WDataHandler
std::cout << "VTK not implemented yet" << std::endl;
assert( 0 );
}
else if( suffix == ".fib" )
{
WLoaderVTK vtkLoader( fileName, dataHandler );
boost::thread loaderThread( vtkLoader );
}
else
{
std::cout << "Unknown file type: \"" << suffix << "\"" << std::endl;
......
......@@ -28,7 +28,6 @@
#include <string>
#include <boost/shared_ptr.hpp>
class WDataSet;
class WDataHandler;
/**
......
......@@ -25,7 +25,7 @@
#include <string>
#include "WSubject.h"
#include "exceptions/WNoSuchDataSetException.h"
#include "exceptions/WDHNoSuchDataSet.h"
WSubject::WSubject()
......@@ -48,7 +48,7 @@ std::string WSubject::getName() const
boost::shared_ptr< const WDataSet > WSubject::getDataSet( const unsigned int dataSetId ) const
{
if( dataSetId >= m_dataSets.size() )
throw WNoSuchDataSetException( "Index too large." );
throw WDHNoSuchDataSet( "Index too large." );
return m_dataSets.at( dataSetId );
}
......
......@@ -22,6 +22,17 @@
//
//---------------------------------------------------------------------------
#include <stdexcept>
#include <string>
#include "WNoSuchDataSetException.h"
#include "WDHException.h"
WDHException::WDHException( const std::string& msg ): WException( msg )
{
// initialize members
}
WDHException::~WDHException() throw()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WDHEXCEPTION_H
#define WDHEXCEPTION_H
#include <stdexcept>
#include <string>
#include "../../common/WException.h"
/**
* General purpose exception and therefore base class for all DataHanlder
* related exceptions.
* \ingroup dataHandler
*/
class WDHException: public WException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WDHException( const std::string& msg = "DataHandler Exception" );
/**
* Destructor.
*/
virtual ~WDHException() throw();
protected:
private:
};
#endif // WDHEXCEPTION_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <stdexcept>
#include <string>
#include "WDHIOFailure.h"
WDHIOFailure::WDHIOFailure( const std::string& msg )
: WDHException( msg )
{
// initialize members
}
WDHIOFailure::~WDHIOFailure() throw()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WDHIOFAILURE_H
#define WDHIOFAILURE_H
#include <stdexcept>
#include <string>
#include "WDHException.h"
/**
* Use this for IO error handling.
*/
class WDHIOFailure : public WDHException
{
public:
/**
* Default constructor.
* \param msg the exception message.
*/
explicit WDHIOFailure( const std::string& msg = "DataHandler Exception: IO error occured." );
/**
* Destructor
*/
virtual ~WDHIOFailure() throw();
protected:
private:
};
#endif // WDHIOFAILURE_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <string>
#include "WDHNoSuchDataSet.h"
WDHNoSuchDataSet::WDHNoSuchDataSet( const std::string& msg )
: WDHException( msg )
{
// initialize members
}
WDHNoSuchDataSet::~WDHNoSuchDataSet() throw()
{
// cleanup
}
......@@ -22,12 +22,12 @@
//
//---------------------------------------------------------------------------
#ifndef WNOSUCHDATASETEXCEPTION_H
#define WNOSUCHDATASETEXCEPTION_H
#ifndef WDHNOSUCHDATASET_H
#define WDHNOSUCHDATASET_H
#include <string>
#include "../../common/WException.h"
#include "WDHException.h"
/**
* Should be thrown when an invalid index is used to get a WSubject from
......@@ -35,33 +35,24 @@
* WSubject. An index is invalid if it's greater or equal than the number
* of WDataSets in that WDataHandler.
*
* It's subclassed from std::logic_error since it represents a mistake by a
* programmer, not by the runtime system (e.g. allocation memory) or other
* libraries.
*
* \ingroup dataHandler
*/
class WNoSuchDataSetException : public WException
class WDHNoSuchDataSet : public WDHException
{
public:
/**
* Constructs new exception.
*/
WNoSuchDataSetException( const std::string& s = std::string() ) throw()
: WException( s )
{
}
explicit WDHNoSuchDataSet( const std::string& msg = "DataHandler Exception: Invalid DataSet Access" );
/**
* Destroys this exception
*/
virtual ~WNoSuchDataSetException() throw()
{
};
virtual ~WDHNoSuchDataSet() throw();
protected:
private:
};
#endif // WNOSUCHDATASETEXCEPTION_H
#endif // WDHNOSUCHDATASET_H
......@@ -52,7 +52,7 @@ public:
* This function is automatically called when creating a new thread for the
* loader with boost::thread.
*/
void operator()();
virtual void operator()();
protected:
private:
void biosigLoader();
......
......@@ -48,7 +48,7 @@ public:
* This function is automatically called when creating a new thread for the
* loader with boost::thread.
*/
void operator()();
virtual void operator()();
protected:
private:
......
......@@ -33,10 +33,8 @@
#include "nifti/nifti1_io.h"
class WDataSet;
class WDataHandler;
/**
* Loader for the NIfTI file format. For NIfTI just see http://nifti.nimh.nih.gov/.
* \ingroup dataHandler
......@@ -54,7 +52,7 @@ public:
* This function is automatically called when creating a new thread for the
* loader with boost::thread. It calls the methods of the NIfTI I/O library.
*/
void operator()();
virtual void operator()();
protected:
private:
......
......@@ -22,5 +22,73 @@
//
//---------------------------------------------------------------------------
#include <cassert>
#include <fstream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "WLoaderVTK.h"
#include "../WDataHandler.h"
#include "../../common/WStringUtils.hpp"
WLoaderVTK::WLoaderVTK( std::string fname, boost::shared_ptr< WDataHandler > dataHandler )
: WLoader( fname ),
m_dataHandler( dataHandler )
{
}
void WLoaderVTK::operator()()
{
readHeader();
if( !datasetTypeIs( "POLYDATA" ) )
{
throw WDHException( "Loading VTK files with DATASET != POLYDATA not implemented" );
}
if( !isBinary() )
{
throw WDHException( "Loading VTK files in ASCII format is not yet supported" );
}
}
void WLoaderVTK::readHeader() throw( WDHIOFailure )
{
std::ifstream in( m_fileName.c_str(), std::ifstream::in | std::ifstream::binary );
if( !in || in.bad() )
{
throw WDHIOFailure( "Invalid file or filename: " + m_fileName );
}
std::string line;
try
{
for( int i = 0; i < 4; ++i ) // strip first four lines
{
std::getline( in, line );
m_header.push_back( line );
}
}
catch( std::ios_base::failure e )
{
throw WDHIOFailure( "Error while reading first four lines of " + m_fileName + ": " + e.what() );
}
assert( m_header.size() == 4 );
in.close();
}
bool WLoaderVTK::datasetTypeIs( const std::string& type ) const
{
assert( m_header.size() == 4 );
std::string lastLine = m_header.back();
std::vector< std::string > tokens = string_utils::tokenize( lastLine );
assert( tokens.size() >= 2 );
return tokens[1] == type;
}
bool WLoaderVTK::isBinary() const
{
assert( m_header.size() == 4 );
std::string thirdLine = string_utils::toUpper( string_utils::trim( m_header[2] ) );
return "BINARY" == thirdLine;
}
......@@ -25,7 +25,14 @@
#ifndef WLOADERVTK_H
#define WLOADERVTK_H
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "../WLoader.h"
#include "../exceptions/WDHIOFailure.h"
class WDataHandler;
/**
* Loader for the VTK file formats. For VTK just see http://www.vtk.org
......@@ -33,9 +40,44 @@
*/
class WLoaderVTK : public WLoader
{
friend class WLoaderVTKTest;
public:
/**
* Constructs and makes a new VTK loader for separate thread start.
*/
WLoaderVTK( std::string fname, boost::shared_ptr< WDataHandler > dataHandler );
/**
* This function is automatically called when creating a new thread for the
* loader with boost::thread. It calls the methods of the NIfTI I/O library.
*/
virtual void operator()();
protected:
/**
* Read header from file.
*/
void readHeader() throw( WDHIOFailure );
/**
* Checks if the header defines the specified VTK DATASET type.
*
* \param type VTK DATASET type as string, to check for.
*/
bool datasetTypeIs( const std::string& type ) const;
/**
* Returns true if the VTK file is in BINARY format, otherwise false.
*/
bool isBinary() const;
/**
* First four lines of ASCII text describing this file
*/
std::vector< std::string > m_header;
private:
boost::shared_ptr< WDataHandler > m_dataHandler;
};
#endif // WLOADERVTK_H
......@@ -25,22 +25,101 @@
#ifndef WLOADERVTK_TEST_H
#define WLOADERVTK_TEST_H
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
#include <cxxtest/TestSuite.h>
#include "../WLoaderVTK.h"
#include "../../WDataHandler.h"
/**
* TODO(math): Document this!
* Unit tests the WLoaderVTK class.
*/
class WLoaderVTKTest : public CxxTest::TestSuite
{
public:
/**
* TODO(math): Document this!
* Create test environment.
*/
void setUp( void )
{
m_dataHandler = boost::shared_ptr< WDataHandler >( new WDataHandler() );
m_vtkFile = boost::filesystem::path( "fixtures/VTK/ascii-2nd-order-tensor.vtk" );
assert( boost::filesystem::exists( m_vtkFile ) );
}
/**
* A valid "header" of a VTK file consists of 4 lines of text (this is
* arbitrary specified by me, the author of this class)
* 1. VTK version stuff
* 2. VTK description header stuff (max 256 chars)
* 3. BINARY or ASCII
* 4. DATASET type
*
* Further description about the DATASET e.g. ORIGIN in case of
* STRUCTURED_POINTS does not belong to the header.
*
* FYI: It makes really sense to restrict the header to 4 lines since since
* every VTK file must have at least 4 lines describing in ASCII what comes
* next.
*/
void testReadHeader( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
std::vector< std::string > expected;
expected.push_back( "# vtk DataFile Version 3.0" );
expected.push_back( "vtk output" );
expected.push_back( "ASCII" );
expected.push_back( "DATASET STRUCTURED_POINTS" );
TS_ASSERT_EQUALS( loader.m_header, expected );
}
/**
* If the path is not valid there should be thrown an exception
*/
void testSomething( void )
void testReadHeaderOnInvalidFile( void )
{
WLoaderVTK loader( "no/such/file", m_dataHandler );
TS_ASSERT_THROWS_EQUALS( loader.readHeader(),
const WDHIOFailure &e,
e.what(),
std::string( "Invalid file or filename: no/such/file" ) );
}
/**
* If the header introduces a STRUCTURED_POINTS VTK DATASET then true
* should be returned.
*/
void testCheckDatasetType( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
TS_ASSERT_EQUALS( loader.datasetTypeIs( "STRUCTURED_POINTS" ), true );
}
/**
* A VTK file is typically either in BINARY or ASCII format.
*/
void testBinaryOrAscii( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
TS_ASSERT_EQUALS( loader.isBinary(), false );
}
private:
/**
* Dummy DataHandler instance