Commit 848a7d72 authored by cornimueller's avatar cornimueller
Browse files

[ADD] The libeep loader now loads the electrode positions from an ELC file of the same name

parent cebc16c0
......@@ -23,12 +23,10 @@
//---------------------------------------------------------------------------
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include "WLoaderBiosig.h"
#include "../WEEG.h"
......@@ -37,8 +35,9 @@
#include "../../common/WLogger.h"
#include "../../common/WStringUtils.h"
WLoaderBiosig::WLoaderBiosig( std::string fileName )
: WLoader( fileName ),
: WLoaderEEG( fileName ),
m_columns( 0 ),
m_rows( 0 )
{
......@@ -70,80 +69,9 @@ void WLoaderBiosig::fillSegmentRowBased( std::vector<std::vector<double> >* segm
}
}
WEEGElectrodeLibrary extractElectrodePositions( std::string elcFileName )
{
namespace su = string_utils;
std::ifstream ifs;
ifs.open( elcFileName.c_str(), std::ifstream::in );
if( !ifs || ifs.bad() )
{
WLogger::getLogger()->addLogMessage( "Try load broken file '" + elcFileName + "'", "BiosigLoader", LL_ERROR );
throw std::runtime_error( "Problem during reading file. Probably file not found." );
}
std::string line = "";
while( ifs.good() && line.substr( 0, 16 ) != "NumberPositions=" ) // go to number of positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "BiosigLoader", LL_ERROR );
}
}
std::vector< std::string > tokens = su::tokenize( line );
size_t numPositions = boost::lexical_cast< size_t >( tokens.at( 1 ) );
while( ifs.good() && line.substr( 0, 9 ) != "Positions" ) // go to line before start of positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "BiosigLoader", LL_ERROR );
}
}
size_t posCounter = 0;
WEEGElectrodeLibrary elecPos;
while( posCounter != numPositions && ifs.good() && line.substr( 0, 9 ) != "Labels" ) // run through all positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "BiosigLoader", LL_ERROR );
}
else
{
++posCounter;
std::vector< std::string > lineTokens = su::tokenize( line, ":" );
std::string label = lineTokens.at( 0 );
label = su::rTrim( label );
// std::cout << "Loading positions: " << label << std::endl;
std::vector< std::string > posTokens = su::tokenize( lineTokens.at( 1 ) );
double posX = boost::lexical_cast< double >( posTokens.at( 1 ) );
double posY = boost::lexical_cast< double >( posTokens.at( 2 ) );
double posZ = boost::lexical_cast< double >( posTokens.at( 3 ) );
wmath::WPosition pos( posX, posY, posZ );
elecPos.push_back( WEEGElectrodeObject( pos ) );
// std::cout << "Loading positions: " << pos << std::endl;
}
}
std::getline( ifs, line );
assert( elecPos.size() == numPositions );
assert( line.substr( 0, 6 ) == "Labels" );
return elecPos;
}
boost::shared_ptr< WDataSet > WLoaderBiosig::load()
{
assert( m_fileName.substr( m_fileName.size() - 4 ) == ".edf" && "We expect only EDF so far." );
std::string elcFileName = m_fileName;
elcFileName.resize( elcFileName.size() - 3 ); // drop suffix
elcFileName += "elc"; // add new suffix
hd = sopen( m_fileName.c_str(), "r", 0 );
......@@ -205,7 +133,7 @@ boost::shared_ptr< WDataSet > WLoaderBiosig::load()
segments.push_back( segment );
WEEGElectrodeLibrary lib = extractElectrodePositions( elcFileName );
WEEGElectrodeLibrary lib = extractElectrodePositions();
if( hd->NS != lib.size() )
throw WDHException( "Contents of edf and elc files are not compatible: Different number of channels." );
......
......@@ -27,17 +27,19 @@
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "../WLoader.h"
#include "WLoaderEEG.h"
#include "biosig/biosig.h"
/**
* Loader for several formats for biological signal.
* Uses BiosigC++ 4.
* \ingroup dataHandler
*/
class WLoaderBiosig : public WLoader
class WLoaderBiosig : public WLoaderEEG
{
public:
/**
......
//---------------------------------------------------------------------------
//
// 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 <fstream>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include "../../common/WLogger.h"
#include "WLoaderEEG.h"
WLoaderEEG::WLoaderEEG( std::string fileName ) throw( WDHIOFailure )
: WLoader( fileName )
{
}
WEEGElectrodeLibrary WLoaderEEG::extractElectrodePositions()
{
namespace su = string_utils;
std::string elcFileName = m_fileName;
elcFileName.resize( elcFileName.size() - 3 ); // drop suffix
elcFileName += "elc"; // add new suffix
std::ifstream ifs;
ifs.open( elcFileName.c_str(), std::ifstream::in );
if( !ifs || ifs.bad() )
{
WLogger::getLogger()->addLogMessage( "Try load broken file '" + elcFileName + "'", "EEG Loader", LL_ERROR );
throw std::runtime_error( "Problem during reading file. Probably file not found." );
}
std::string line = "";
while( ifs.good() && line.substr( 0, 16 ) != "NumberPositions=" ) // go to number of positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "EEG Loader", LL_ERROR );
}
}
std::vector< std::string > tokens = su::tokenize( line );
size_t numPositions = boost::lexical_cast< size_t >( tokens.at( 1 ) );
while( ifs.good() && line.substr( 0, 9 ) != "Positions" ) // go to line before start of positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "EEG Loader", LL_ERROR );
}
}
size_t posCounter = 0;
WEEGElectrodeLibrary elecPos;
while( posCounter != numPositions && ifs.good() && line.substr( 0, 9 ) != "Labels" ) // run through all positions
{
std::getline( ifs, line );
if( !ifs.good() )
{
WLogger::getLogger()->addLogMessage( "Unexpected end of file: " + elcFileName, "EEG Loader", LL_ERROR );
}
else
{
++posCounter;
std::vector< std::string > lineTokens = su::tokenize( line, ":" );
std::string label = lineTokens.at( 0 );
label = su::rTrim( label );
// std::cout << "Loading positions: " << label << std::endl;
std::vector< std::string > posTokens = su::tokenize( lineTokens.at( 1 ) );
double posX = boost::lexical_cast< double >( posTokens.at( 1 ) );
double posY = boost::lexical_cast< double >( posTokens.at( 2 ) );
double posZ = boost::lexical_cast< double >( posTokens.at( 3 ) );
wmath::WPosition pos( posX, posY, posZ );
elecPos.push_back( WEEGElectrodeObject( pos ) );
// std::cout << "Loading positions: " << pos << std::endl;
}
}
std::getline( ifs, line );
assert( elecPos.size() == numPositions );
assert( line.substr( 0, 6 ) == "Labels" );
return elecPos;
}
//---------------------------------------------------------------------------
//
// 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 WLOADEREEG_H
#define WLOADEREEG_H
#include <string>
#include "../WEEG.h"
#include "../WLoader.h"
/**
* Abstract base class for all Loaders who handle with EEG data
* \ingroup dataHandler
*/
class WLoaderEEG : public WLoader
{
public:
protected:
/**
* Constructs basic eeg Loader with a file name.
*
* \param fileName Path to be loaded
* \throw WDHIOFailure in case of an error
*/
explicit WLoaderEEG( std::string fileName ) throw( WDHIOFailure );
/**
* Load electrode positions from ELC file with same name
*
* \return electrode library containig the loaded positions
*/
WEEGElectrodeLibrary extractElectrodePositions();
private:
};
#endif // WLOADEREEG_H
......@@ -35,8 +35,9 @@
#include "../WSubject.h"
#include "WLoaderEEGASCII.h"
WLoaderEEGASCII::WLoaderEEGASCII( std::string fileName )
: WLoader( fileName )
: WLoaderEEG( fileName )
{
}
......@@ -86,4 +87,3 @@ boost::shared_ptr< WDataSet > WLoaderEEGASCII::load()
eeg->setFileName( m_fileName );
return eeg;
}
......@@ -25,16 +25,18 @@
#ifndef WLOADEREEGASCII_H
#define WLOADEREEGASCII_H
#include <string>
#include <boost/shared_ptr.hpp>
#include "../WLoader.h"
#include "WLoaderEEG.h"
/**
* Loader for EEG data in ASCII fromat.
* \ingroup dataHandler
*/
class WLoaderEEGASCII : public WLoader
class WLoaderEEGASCII : public WLoaderEEG
{
public:
/**
......
......@@ -36,13 +36,13 @@ extern "C"
WLoaderLibeep::WLoaderLibeep( std::string fileName )
: WLoader( fileName )
: WLoaderEEG( fileName )
{
}
boost::shared_ptr< WDataSet > WLoaderLibeep::load()
{
WLogger::getLogger()->addLogMessage( "Opening " + m_fileName, "Libeep Loader" );
wlog::debug( "Libeep Loader" ) << "Opening " << m_fileName;
// initialize
FILE* file = fopen( m_fileName.c_str(), "rb" );
......@@ -58,15 +58,15 @@ boost::shared_ptr< WDataSet > WLoaderLibeep::load()
}
// read data
int numberOfChannels = eep_get_chanc( eeg );
unsigned int numberOfChannels = eep_get_chanc( eeg );
slen_t numberOfSamples = eep_get_samplec( eeg );
if( numberOfSamples > 32768 )
if( numberOfSamples > 8192 )
{
// limit maximum size of the dataset
// TODO(cornimueller): Don't load EEG data as a whole, use blocks instead
// TODO(wiebel): Don't load EEG data as a whole, use blocks instead
numberOfSamples = 32768;
numberOfSamples = 8192;
}
sraw_t* buffer = new sraw_t[CNTBUF_ARRAYSIZE( eeg, numberOfSamples )];
......@@ -74,7 +74,7 @@ boost::shared_ptr< WDataSet > WLoaderLibeep::load()
WEEGChannelLabels channelLabels( numberOfChannels );
WEEGSegment segment( numberOfChannels );
for( int channel = 0; channel < numberOfChannels; ++channel )
for( unsigned int channel = 0; channel < numberOfChannels; ++channel )
{
channelLabels[channel].first = eep_get_chan_label( eeg, channel );
......@@ -91,10 +91,17 @@ boost::shared_ptr< WDataSet > WLoaderLibeep::load()
delete[] buffer;
eep_fclose( eeg );
WEEGElectrodeLibrary electrodeLibrary = extractElectrodePositions();
if( electrodeLibrary.size() != numberOfChannels )
{
throw WDHException( "Contents of cnt and elc files are not compatible: Different number of channels." );
}
// construct WEEG object and return it
boost::shared_ptr< WEEG > out( new WEEG(
WEEGSegmentArray( 1, segment ),
WEEGElectrodeLibrary( numberOfChannels, WEEGElectrodeObject( wmath::WPosition() ) ),
electrodeLibrary,
channelLabels
) );
out->setFileName( m_fileName );
......
......@@ -27,14 +27,14 @@
#include <string>
#include "../WLoader.h"
#include "WLoaderEEG.h"
/**
* Loader for the CNT format supported by the libeep library.
* \ingroup dataHandler
*/
class WLoaderLibeep : public WLoader
class WLoaderLibeep : public WLoaderEEG
{
public:
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment