Commit 8c9b5b7c authored by Alexander Wiebel's avatar Alexander Wiebel
Browse files

[ADD #163] possibility to load more than one dipole

parent c0d4db71
......@@ -35,13 +35,13 @@ WDataSetDipole::WDataSetDipole()
}
WDataSetDipole::WDataSetDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times )
: m_dipolePosition( dipPos ), m_magnitudes( mags ), m_times( times )
{
WAssert( mags.size() == times.size(), "There has to be a magnitude for every time and vice versa." );
for( size_t id = 0; id < times.size() - 1; ++id )
{
WAssert( times[id] < times[id+1], "Times need to be ascending." );
}
addDipole( dipPos, mags, times );
}
WDataSetDipole::~WDataSetDipole()
......@@ -58,30 +58,48 @@ boost::shared_ptr< WPrototyped > WDataSetDipole::getPrototype()
return m_prototype;
}
WPosition WDataSetDipole::getPosition()
size_t WDataSetDipole::addDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times )
{
return m_dipolePosition;
Dipole dipole;
dipole.m_dipolePosition = dipPos;
dipole.m_magnitudes = mags;
dipole.m_times = times;
m_dipoles.push_back( dipole );
return m_dipoles.size() - 1;
}
float WDataSetDipole::getMagnitude( float time )
WPosition WDataSetDipole::getPosition( size_t dipoleId )
{
if( time < m_times[0] || time > m_times.back() )
return m_dipoles[dipoleId].m_dipolePosition;
}
size_t WDataSetDipole::getNumberOfDipoles()
{
return m_dipoles.size();
}
float WDataSetDipole::getMagnitude( float time, size_t dipoleId )
{
std::vector<float>& times = m_dipoles[dipoleId].m_times;
std::vector<float>& magnitudes = m_dipoles[dipoleId].m_magnitudes;
if( time < times[0] || time > times.back() )
{
return 0;
}
else
{
size_t upperBoundId;
for( size_t id = 0; id < m_times.size(); ++id )
for( size_t id = 0; id < times.size(); ++id )
{
if( time < m_times[id] )
if( time < times[id] )
{
upperBoundId = id - 1;
break;
}
}
float scale = ( time - m_times[upperBoundId-1] ) / ( m_times[upperBoundId] - m_times[upperBoundId-1] );
float magnitude = m_magnitudes[upperBoundId-1] + scale * ( m_magnitudes[upperBoundId] - m_magnitudes[upperBoundId-1] );
float scale = ( time - times[upperBoundId-1] ) / ( times[upperBoundId] - times[upperBoundId-1] );
float magnitude = magnitudes[upperBoundId-1] + scale * ( magnitudes[upperBoundId] - magnitudes[upperBoundId-1] );
return magnitude;
}
}
......@@ -43,7 +43,8 @@ public:
WDataSetDipole();
/**
* Creates a new dipole with given information and checks consistency of the information.
* Creates a new dipole data set containing one dipole
* with the given information and checks consistency of the information.
*
* \param dipPos Spatial location of the dipole
* \param mags Magnitudes of dipole over time
......@@ -63,20 +64,40 @@ public:
*/
static boost::shared_ptr< WPrototyped > getPrototype();
/**
* Adds a new dipole with given information and checks consistency of the information.
*
* \param dipPos Spatial location of the dipole
* \param mags Magnitudes of dipole over time
* \param times Times for the dipole activity
*
* \return Id of the added dipole.
*/
size_t addDipole( WPosition dipPos, std::vector<float> mags, std::vector<float> times );
/**
* Return position of dipole.
*
* \param dipoleId Id number of dipole
* \return Position of the dipole.
*/
WPosition getPosition();
WPosition getPosition( size_t dipoleId = 0 );
/**
* Return magnitude of dipole for a given time.
*
* \param time The selected time.
* \param dipoleId Id number of dipole
* \return Magnitude of the dipole.
*/
float getMagnitude( float time );
float getMagnitude( float time, size_t dipoleId = 0 );
/**
* Return number of dipoles in this dataset
*
* \return number of dipoles in this dataset.
*/
size_t getNumberOfDipoles();
protected:
/**
......@@ -85,9 +106,18 @@ protected:
static boost::shared_ptr< WPrototyped > m_prototype;
private:
WPosition m_dipolePosition; //!< The location of the dipole
std::vector<float> m_magnitudes; //!< The magnitude of the dipole
std::vector<float> m_times; //!< Times for the different magnitudes
/**
* Internal class representing one dipole
*/
class Dipole
{
public:
WPosition m_dipolePosition; //!< The location of the dipole
std::vector<float> m_magnitudes; //!< The magnitude of the dipole
std::vector<float> m_times; //!< Times for the different magnitudes
};
std::vector< Dipole > m_dipoles; //!< List of dipoles representeing this dipoles dataset
};
#endif // WDATASETDIPOLE_H
......@@ -81,6 +81,8 @@ void WMReadDipoles::properties()
m_dataFile = m_properties->addProperty( "File", "", WPathHelper::getAppPath(), m_propCondition );
WPropertyHelper::PC_PATHEXISTS::addTo( m_dataFile );
m_metaFile = m_properties->addProperty( "Use meta file", "File containing multiple filenames to load.", true );
WModule::properties();
}
......@@ -104,7 +106,14 @@ void WMReadDipoles::moduleMain()
boost::shared_ptr< WProgress > progress = boost::shared_ptr< WProgress >( new WProgress( "Read Dipoles", 2 ) );
++*progress;
m_dataSet = readData( m_dataFile->get().string() );
if( !m_metaFile->get() )
{
m_dataSet = readFiles( std::vector< std::string >( 1, m_dataFile->get().string() ) );
}
else
{
m_dataSet = readMetaData( m_dataFile->get().string() );
}
++*progress;
m_dipoles->updateData( m_dataSet );
progress->finish();
......@@ -112,7 +121,27 @@ void WMReadDipoles::moduleMain()
}
boost::shared_ptr< WDataSetDipole > WMReadDipoles::readData( std::string filename )
boost::shared_ptr< WDataSetDipole > WMReadDipoles::readMetaData( std::string filename )
{
std::vector< std::string > names;
std::ifstream ifs;
ifs.open( filename.c_str(), std::ifstream::in );
if( !ifs || ifs.bad() )
{
throw WDHIOFailure( std::string( "Internal error while opening file" ) );
}
std::string line;
while( std::getline( ifs, line ) )
{
names.push_back( line );
}
ifs.close();
return readFiles( names );
}
void WMReadDipoles::readFile( std::string filename, WPosition* pos, std::vector< float >* times, std::vector< float >* magnitudes )
{
std::ifstream ifs;
ifs.open( filename.c_str(), std::ifstream::in );
......@@ -144,23 +173,19 @@ boost::shared_ptr< WDataSetDipole > WMReadDipoles::readData( std::string filenam
float timeFirst = string_utils::fromString< float >( tokens[0].c_str() );
float timeDistance = string_utils::fromString< float >( tokens[1].c_str() );
float timeLast = string_utils::fromString< float >( tokens[2].c_str() );
std::vector< float > times( nbTimeSteps );
times->resize( nbTimeSteps );
for( size_t timeStep = 0; timeStep < nbTimeSteps; ++timeStep )
{
times[timeStep] = timeFirst + timeStep * timeDistance;
(*times)[timeStep] = timeFirst + timeStep * timeDistance;
}
std::cout << times[nbTimeSteps-1]<< " " << timeLast << std::endl;
WAssert( std::abs( times[nbTimeSteps-1] - timeLast ) < 1e-4, "Error during filling times vector." );
WAssert( std::abs( (*times)[nbTimeSteps-1] - timeLast ) < 1e-4, "Error during filling times vector." );
while( line.find( "PositionsFixed" ) )
{
std::getline( ifs, line, '\n' );
}
WPosition pos;
ifs >> pos[0] >> pos[1] >> pos[2];
std::vector< float > magnitudes;
ifs >> (*pos)[0] >> (*pos)[1] >> (*pos)[2];
while( line.find( "Magnitudes" ) )
{
......@@ -168,18 +193,33 @@ boost::shared_ptr< WDataSetDipole > WMReadDipoles::readData( std::string filenam
}
std::getline( ifs, line, '\n' );
magnitudes->clear();
tokens = string_utils::tokenize( line );
for( unsigned int tokenId = 0; tokenId < tokens.size(); ++tokenId )
{
magnitudes.push_back( string_utils::fromString< float >( tokens[tokenId].c_str() ) );
magnitudes->push_back( string_utils::fromString< float >( tokens[tokenId].c_str() ) );
}
WAssert( magnitudes.size() == nbTimeSteps, "Number of time steps and magnitudes must be equal" );
WAssert( times.size() == nbTimeSteps, "Number of time steps and times must be equal" );
WAssert( magnitudes->size() == nbTimeSteps, "Number of time steps and magnitudes must be equal" );
WAssert( times->size() == nbTimeSteps, "Number of time steps and times must be equal" );
ifs.close();
}
boost::shared_ptr< WDataSetDipole > WMReadDipoles::readFiles( std::vector< std::string > filenames )
{
WPosition pos;
std::vector< float > times;
std::vector< float > magnitudes;
readFile( filenames[0], &pos, &times, &magnitudes );
boost::shared_ptr< WDataSetDipole > loadedData( new WDataSetDipole( pos, magnitudes, times ) );
for( size_t fileId = 1; fileId < filenames.size(); ++fileId )
{
readFile( filenames[fileId], &pos, &times, &magnitudes );
loadedData->addDipole( pos, times, magnitudes );
}
return loadedData;
}
......@@ -26,6 +26,7 @@
#define WMREADDIPOLES_H
#include <string>
#include <vector>
#include <osg/Geode>
......@@ -109,12 +110,34 @@ protected:
private:
/**
* Function doing the actual reading
* Function that composes the data read by readFile() from the different files to one WDataSetDipole
*
* \param filename Name and location of file to read.
* \param filenames Names and locations of files to read.
* \return A pointer to the loaded dataset
*/
boost::shared_ptr< WDataSetDipole > readData( std::string filename );
boost::shared_ptr< WDataSetDipole > readFiles( std::vector< std::string > filenames );
/**
* Function doing the actual reading from one file
*
* \param filename Name and locations of file to read.
* \param pos position of the dipole
* \param times time values of the time steps
* \param magnitudes magnitudes of the dipole at the different time steps.
* \return A pointer to the loaded dataset
*/
void readFile( std::string filename,
WPosition* pos,
std::vector< float >* times,
std::vector< float >* magnitudes );
/**
* Function reading meta file with filenames of dipole files
*
* \param filename Name and location of meta file to read.
* \return A pointer to the loaded dataset
*/
boost::shared_ptr< WDataSetDipole > readMetaData( std::string filename );
/**
* Output connector for dipoles of EEG data
......@@ -128,6 +151,7 @@ private:
boost::shared_ptr< WCondition > m_propCondition; //!< A condition used to notify about changes in several properties.
WPropFilename m_dataFile; //!< The data will be read from this file.
WPropBool m_metaFile; //!< Use meta file containing fileNames.
};
#endif // WMREADDIPOLES_H
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