1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
10
// OpenWalnut is free software: you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as published by
12
// the Free Software Foundation, either version 3 of the License, or
13
// (at your option) any later version.
15
// OpenWalnut is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU Lesser General Public License for more details.
20
// You should have received a copy of the GNU Lesser General Public License
21
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
23
//---------------------------------------------------------------------------
28
#include "core/common/WAssert.h"
29
#include "core/common/WIOTools.h"
30
#include "core/common/WPropertyHelper.h"
31
#include "core/dataHandler/WDataSet.h"
32
#include "core/dataHandler/WDataSetSingle.h"
33
#include "core/dataHandler/WDataSetScalar.h"
34
#include "core/dataHandler/WDataSetTimeSeries.h"
35
#include "core/dataHandler/WDataSetVector.h"
36
#include "core/dataHandler/WSubject.h"
37
#include "core/dataHandler/WDataHandler.h"
38
#include "core/dataHandler/WDataTexture3D.h"
39
#include "core/dataHandler/WEEG2.h"
40
#include "core/dataHandler/exceptions/WDHException.h"
41
#include "core/graphicsEngine/WGEColormapping.h"
42
#include "core/kernel/WModuleOutputData.h"
44
#include "io/WReaderBiosig.h"
45
#include "io/WReaderEEGASCII.h"
46
#include "io/WReaderNIfTI.h"
47
#include "io/WReaderELC.h"
48
#include "io/WReaderFiberVTK.h"
49
#include "io/WReaderLibeep.h"
50
#include "io/WPagerEEGLibeep.h"
57
m_fileNameSet( false ),
59
m_transformNoMatrix( 4, 4 ),
60
m_transformSForm( 4, 4 ),
61
m_transformQForm( 4, 4 )
71
boost::shared_ptr< WModule > WMData::factory() const
73
return boost::shared_ptr< WModule >( new WMData() );
76
const char** WMData::getXPMIcon() const
81
const std::string WMData::getName() const
86
const std::string WMData::getDescription() const
88
return "This module encapsulates data.";
91
boost::shared_ptr< WDataSet > WMData::getDataSet()
96
void WMData::setFilename( boost::filesystem::path fname )
100
m_fileNameSet = true;
105
boost::filesystem::path WMData::getFilename() const
110
void WMData::connectors()
112
// initialize connectors
113
m_output= boost::shared_ptr< WModuleOutputData< WDataSet > >( new WModuleOutputData< WDataSet >(
114
shared_from_this(), "out", "A loaded dataset." )
117
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
118
addConnector( m_output );
120
// call WModules initialization
121
WDataModule::connectors();
124
void WMData::properties()
126
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
129
m_dataName = m_infoProperties->addProperty( "Filename", "The filename of the dataset.", std::string( "" ) );
130
m_dataType = m_infoProperties->addProperty( "Data type", "The type of the the single data values.", std::string( "" ) );
132
m_matrixSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
133
m_matrixSelectionsList->addItem( "No matrix", "" );
134
m_matrixSelectionsList->addItem( "sform", "" );
135
m_matrixSelectionsList->addItem( "qform", "" );
137
m_matrixSelection = m_properties->addProperty( "Transformation matrix", "matrix",
138
m_matrixSelectionsList->getSelectorFirst(), m_propCondition );
139
WPropertyHelper::PC_SELECTONLYONE::addTo( m_matrixSelection );
141
// use this callback for the other properties
142
WPropertyBase::PropertyChangeNotifierType propertyCallback = boost::bind( &WMData::propertyChanged, this, _1 );
145
void WMData::propertyChanged( boost::shared_ptr< WPropertyBase > property )
149
if( property == m_active )
151
// forward to texture
152
m_dataSet->getTexture()->active()->set( m_active->get( true ) );
157
if( property == m_active )
159
if( m_active->get() )
161
m_output->updateData( m_dataSet );
165
m_output->updateData( boost::shared_ptr< WDataSet >() );
171
void WMData::moduleMain()
173
WAssert( m_fileNameSet, "No filename specified." );
175
m_transformNoMatrix.makeIdentity();
176
m_transformSForm.makeIdentity();
177
m_transformQForm.makeIdentity();
179
m_moduleState.setResetable( true, true );
180
m_moduleState.add( m_propCondition );
182
std::string fileName = m_fileName.string();
184
debugLog() << "Loading data from \"" << fileName << "\".";
185
m_dataName->set( fileName );
187
// remove the path up to the file name and set it as a convenient name for this module instance
190
m_runtimeName->set( string_utils::tokenize( fileName, "/" ).back() );
194
std::string suffix = getSuffix( fileName );
197
|| ( suffix == ".gz" && ::nifti_compiled_with_zlib() ) )
199
if( suffix == ".gz" ) // it may be a NIfTI file too
201
boost::filesystem::path p( fileName );
202
p.replace_extension( "" );
203
suffix = getSuffix( p.string() );
204
WAssert( suffix == ".nii", "Currently only nii files may be gzipped." );
207
WReaderNIfTI niiLoader( fileName );
208
m_dataSet = niiLoader.load();
209
m_transformNoMatrix = niiLoader.getStandardTransform();
210
m_transformSForm = niiLoader.getSFormTransform();
211
m_transformQForm = niiLoader.getQFormTransform();
213
m_isTexture = m_dataSet->isTexture();
215
boost::shared_ptr< WDataSetSingle > dss = boost::shared_dynamic_cast< WDataSetSingle >( m_dataSet );
218
m_dataType->set( getDataTypeString( dss ) );
219
if( dss->isTexture() )
221
switch( (*dss).getValueSet()->getDataType() )
223
case W_DT_UNSIGNED_CHAR:
227
case W_DT_SIGNED_INT:
228
m_dataSet->getTexture()->colormap()->set(
229
m_dataSet->getTexture()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 0 ) )
234
if( boost::shared_dynamic_cast< WDataSetVector >( m_dataSet ) )
236
m_dataSet->getTexture()->colormap()->set(
237
m_dataSet->getTexture()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 6 ) )
239
m_dataSet->getTexture()->interpolation()->set( false );
243
m_dataSet->getTexture()->colormap()->set(
244
m_dataSet->getTexture()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 5 ) )
249
WAssert( false, "Could not load \"" + fileName + "\". Reason: unknown data type in Data module" );
254
else if( suffix == ".edf" )
256
WReaderBiosig biosigLoader( fileName );
257
m_dataSet = biosigLoader.load();
259
else if( suffix == ".asc" )
261
WReaderEEGASCII eegAsciiLoader( fileName );
262
m_dataSet = eegAsciiLoader.load();
264
else if( suffix == ".cnt" )
266
boost::shared_ptr< WPagerEEG > pager( new WPagerEEGLibeep( fileName ) );
268
std::string elcFileName = fileName;
269
elcFileName.resize( elcFileName.size() - 3 ); // drop suffix
270
elcFileName += "elc"; // add new suffix
271
WReaderELC elcReader( elcFileName );
272
boost::shared_ptr< WEEGPositionsLibrary > eegPositionsLibrary = elcReader.read();
274
m_dataSet = boost::shared_ptr< WEEG2 >( new WEEG2( pager, eegPositionsLibrary ) );
276
else if( suffix == ".fib" )
278
WReaderFiberVTK fibReader( fileName );
279
m_dataSet = fibReader.read();
283
throw WDHException( std::string( "Could not load \"" + fileName + "\". Reason: unknown file type: \"" + suffix + "\"" ) );
286
debugLog() << "Loading data done.";
288
// register the dataset properties
289
m_properties->addProperty( m_dataSet->getProperties() );
290
m_infoProperties->addProperty( m_dataSet->getInformationProperties() );
292
// I am interested in the active property ( manually subscribe signal )
293
m_active->getCondition()->subscribeSignal( boost::bind( &WMData::propertyChanged, this, m_active ) );
295
// textures also provide properties
296
if( m_dataSet->isTexture() )
298
if( !getSuppressColormaps() )
300
WGEColormapping::registerTexture( m_dataSet->getTexture(), m_runtimeName->get() );
302
m_properties->addProperty( m_dataSet->getTexture()->getProperties() );
303
m_infoProperties->addProperty( m_dataSet->getTexture()->getInformationProperties() );
307
m_output->updateData( m_dataSet );
310
WDataSetSingle::SPtr dataSetAsSingle = boost::shared_dynamic_cast< WDataSetSingle >( m_dataSet );
312
while( !m_shutdownFlag() )
314
m_moduleState.wait();
315
if( m_shutdownFlag() )
320
// change transform matrix (only if we have a dataset single which contains the grid)
321
if( m_matrixSelection->changed() && dataSetAsSingle )
323
if( m_dataSet && m_isTexture )
325
// remove dataset from datahandler
326
if( m_dataSet->isTexture() )
328
m_properties->removeProperty( m_dataSet->getTexture()->getProperties() );
329
m_infoProperties->removeProperty( m_dataSet->getTexture()->getInformationProperties() );
330
WGEColormapping::deregisterTexture( m_dataSet->getTexture() );
335
boost::shared_ptr< WGrid > newGrid;
336
boost::shared_ptr< WGridRegular3D > oldGrid = boost::shared_dynamic_cast< WGridRegular3D >( dataSetAsSingle->getGrid() );
338
switch( m_matrixSelection->get( true ).getItemIndexOfSelected( 0 ) )
341
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
342
WGridTransformOrtho( m_transformNoMatrix ) ) );
345
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
346
WGridTransformOrtho( m_transformSForm ) ) );
349
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
350
WGridTransformOrtho( m_transformQForm ) ) );
354
m_dataSet = dataSetAsSingle->clone( newGrid );
356
// the clone() may have returned a zero-pointer, only update if it hasn't
357
// this may happen if the clone() operation has not been implemented in the derived dataset class
360
m_output->updateData( m_dataSet );
364
if( !getSuppressColormaps() )
366
WGEColormapping::registerTexture( m_dataSet->getTexture(), m_runtimeName->get() );
368
m_properties->addProperty( m_dataSet->getTexture()->getProperties() );
369
m_infoProperties->addProperty( m_dataSet->getTexture()->getInformationProperties() );
375
// remove dataset from datahandler
376
if( m_dataSet->isTexture() )
378
m_properties->removeProperty( m_dataSet->getTexture()->getProperties() );
379
m_infoProperties->removeProperty( m_dataSet->getTexture()->getInformationProperties() );
380
WGEColormapping::deregisterTexture( m_dataSet->getTexture() );
384
// TODO(wiebel): move this to some central place.
385
std::string WMData::getDataTypeString( boost::shared_ptr< WDataSetSingle > dss )
388
switch( (*dss).getValueSet()->getDataType() )
394
result = "binary (1 bit)";
396
case W_DT_UNSIGNED_CHAR:
397
result = "unsigned char (8 bits)";
399
case W_DT_SIGNED_SHORT:
400
result = "signed short (16 bits)";
402
case W_DT_SIGNED_INT:
403
result = "signed int (32 bits)";
406
result = "float (32 bits)";
412
result = "double (64 bits)";
415
result = "RGB triple (24 bits)";
418
result = "ALL (not very useful)";
421
result = "signed char (8 bits)";
424
result = "unsigned short (16 bits)";
427
result = "unsigned int (32 bits)";
433
result = "unsigned long long (64 bits)";
436
result = "float (128 bits)";
438
case W_DT_COMPLEX128:
439
result = "double pair (128 bits)";
441
case W_DT_COMPLEX256:
442
result = " long double pair (256 bits)";
445
result = "4 byte RGBA (32 bits)";
448
WAssert( false, "Unknow data type in getDataTypeString" );