Commit d494805a authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[MERGE]

parents 29977b64 54159e7c
......@@ -119,3 +119,7 @@ boost::shared_ptr< WProperties > WDataSet::getInformationProperties() const
return m_infoProperties;
}
boost::shared_ptr< WDataSet > WDataSet::clone( boost::shared_ptr< WValueSetBase >, boost::shared_ptr< WGrid > ) const
{
return boost::shared_ptr< WDataSet >();
}
......@@ -149,6 +149,15 @@ public:
*/
boost::shared_ptr< WProperties > getInformationProperties() const;
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
......
......@@ -63,3 +63,9 @@ wmath::WTensorSym< 2, 3, float > WDataSetDTI::getTensor( size_t index ) const
WAssert( values, "The value set of a WDataSetDTI must be a WValueSet< float >, nothing else!" );
return wmath::WTensorSym< 2, 3, float >( values->getWValue( index ) );
}
boost::shared_ptr< WDataSet > WDataSetDTI::clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const
{
return boost::shared_ptr< WDataSet >( new WDataSetDTI( vs, grid ) );
}
......@@ -89,6 +89,15 @@ public:
*/
wmath::WTensorSym< 2, 3, float > getTensor( size_t index ) const;
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
* The prototype as singleton.
......
......@@ -167,3 +167,7 @@ boost::shared_ptr< const WValueSetHistogram > WDataSetScalar::getHistogram( size
return m_histograms[ buckets ];
}
boost::shared_ptr< WDataSet > WDataSetScalar::clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const
{
return boost::shared_ptr< WDataSet >( new WDataSetScalar( vs, grid ) );
}
......@@ -149,6 +149,15 @@ public:
*/
static boost::shared_ptr< WPrototyped > getPrototype();
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
......
......@@ -169,3 +169,8 @@ double WDataSetSingle::getValueAt( size_t id ) const
return 0.0; // should not be reached. Just there to quiet compiler.
}
boost::shared_ptr< WDataSet > WDataSetSingle::clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const
{
return boost::shared_ptr< WDataSet >( new WDataSetSingle( vs, grid ) );
}
......@@ -176,6 +176,15 @@ public:
*/
static boost::shared_ptr< WPrototyped > getPrototype();
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
......
......@@ -150,3 +150,8 @@ bool WDataSetSphericalHarmonics::isTexture() const
{
return false;
}
boost::shared_ptr< WDataSet > WDataSetSphericalHarmonics::clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const
{
return boost::shared_ptr< WDataSet >( new WDataSetSphericalHarmonics( vs, grid ) );
}
......@@ -137,6 +137,15 @@ public:
*/
virtual bool isTexture() const;
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
......
......@@ -46,6 +46,7 @@ class WDataSetTimeSeriesTest;
* A dataset that stores a time series.
*
* \note Only works for scalar datasets at the moment!
* \note this is only a temporary solution
*/
class OWDATAHANDLER_EXPORT WDataSetTimeSeries : public WDataSet
{
......
......@@ -166,3 +166,8 @@ bool WDataSetVector::isTexture() const
{
return true;
}
boost::shared_ptr< WDataSet > WDataSetVector::clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const
{
return boost::shared_ptr< WDataSet >( new WDataSetVector( vs, grid ) );
}
......@@ -124,6 +124,15 @@ public:
*/
boost::shared_ptr< WDataSetVector > isVectorDataSet();
/**
* Returns a new dataset with the given valueset and grid that is of the same type as this dataset.
*
* \param vs The valueset.
* \param grid The grid.
* \return The new dataset.
*/
virtual boost::shared_ptr< WDataSet > clone( boost::shared_ptr< WValueSetBase > vs, boost::shared_ptr< WGrid > grid ) const;
protected:
/**
......
......@@ -51,7 +51,9 @@
#include "WReaderNIfTI.h"
WReaderNIfTI::WReaderNIfTI( std::string fileName )
: WReader( fileName )
: WReader( fileName ),
m_sform( 4, 4 ),
m_qform( 4, 4 )
{
}
......@@ -179,8 +181,10 @@ boost::shared_ptr< WDataSet > WReaderNIfTI::load( DataSetType dataSetType )
throw e;
}
m_sform = convertMatrix( header->sto_xyz );
m_qform = convertMatrix( header->qto_xyz );
newGrid = boost::shared_ptr< WGridRegular3D >(
new WGridRegular3D( columns, rows, frames, WGridTransformOrtho( convertMatrix( header->sto_xyz ) ) ) );
new WGridRegular3D( columns, rows, frames, WGridTransformOrtho( getStandardTransform() ) ) );
boost::shared_ptr< WDataSet > newDataSet;
// known description
......@@ -402,3 +406,18 @@ boost::shared_ptr< WDataSet > WReaderNIfTI::load( DataSetType dataSetType )
return newDataSet;
}
wmath::WMatrix< double > WReaderNIfTI::getStandardTransform() const
{
return wmath::WMatrix< double >( 4, 4 ).makeIdentity();
}
wmath::WMatrix< double > WReaderNIfTI::getSFormTransform() const
{
return m_sform;
}
wmath::WMatrix< double > WReaderNIfTI::getQFormTransform() const
{
return m_qform;
}
......@@ -64,6 +64,27 @@ public:
*/
virtual boost::shared_ptr< WDataSet > load( DataSetType dataSetType = W_DATASET_NONE );
/**
* Returns a standard transformation.
*
* \return A Wmatrix that represents the dataset's transformation.
*/
wmath::WMatrix< double > getStandardTransform() const;
/**
* Returns the SForm transformation stored in the nifti file's header.
*
* \return A Wmatrix that represents the dataset's transformation.
*/
wmath::WMatrix< double > getSFormTransform() const;
/**
* Returns the QForm transformation stored in the nifti file's header.
*
* \return A Wmatrix that represents the dataset's transformation.
*/
wmath::WMatrix< double > getQFormTransform() const;
protected:
private:
/**
......@@ -81,6 +102,12 @@ private:
* \param in this matrix will be converted.
*/
wmath::WMatrix< double > convertMatrix( const mat44& in );
//! the sform transform stored in the file header
wmath::WMatrix< double > m_sform;
//! the qform transform stored in the file header
wmath::WMatrix< double > m_qform;
};
#endif // WREADERNIFTI_H
......@@ -33,6 +33,7 @@
#include "../../../dataHandler/WDataSetScalar.h"
#include "../../../dataHandler/WDataSetTimeSeries.h"
#include "../../../dataHandler/WDataSetVector.h"
#include "../../../dataHandler/WDataSetRawHARDI.h"
#include "../../../dataHandler/WSubject.h"
#include "../../../dataHandler/WDataHandler.h"
#include "../../../dataHandler/WDataTexture3D.h"
......@@ -54,7 +55,10 @@
WMData::WMData():
WModule(),
m_fileNameSet( false ),
m_isTexture()
m_isTexture(),
m_transformNoMatrix( 4, 4 ),
m_transformSForm( 4, 4 ),
m_transformQForm( 4, 4 )
{
// initialize members
}
......@@ -124,88 +128,26 @@ void WMData::connectors()
void WMData::properties()
{
// properties
m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
// properties
m_dataName = m_infoProperties->addProperty( "Filename", "The filename of the dataset.", std::string( "" ) );
m_dataType = m_infoProperties->addProperty( "Data type", "The type of the the single data values.", std::string( "" ) );
// use this callback for the other properties
WPropertyBase::PropertyChangeNotifierType propertyCallback = boost::bind( &WMData::propertyChanged, this, _1 );
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
m_groupTex = m_properties->addPropertyGroup( "Texture Properties ", "Properties only related to the texture representation." );
// several other properties
m_interpolation = m_groupTex->addProperty( "Interpolation",
"If active, the boundaries of single voxels"
" will not be visible in colormaps. The transition between"
" them will be smooth by using interpolation then.",
true,
propertyCallback );
m_threshold = m_groupTex->addProperty( "Threshold", "Values below this threshold will not be "
"shown in colormaps.", 0.0, propertyCallback );
m_threshold->setMax( 1.0 );
m_threshold->setMin( 0.0 );
m_opacity = m_groupTex->addProperty( "Opacity %", "The opacity of this data in colormaps combining"
" values from several data sets.", 100, propertyCallback );
m_opacity->setMax( 100 );
m_opacity->setMin( 0 );
m_colorMapSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
m_colorMapSelectionsList->addItem( "Grayscale", "" );
m_colorMapSelectionsList->addItem( "Rainbow", "" );
m_colorMapSelectionsList->addItem( "Hot iron", "" );
m_colorMapSelectionsList->addItem( "Negative to positive", "" );
m_colorMapSelectionsList->addItem( "Atlas", "" );
m_colorMapSelectionsList->addItem( "Blue-Green-Purple", "" );
m_colorMapSelectionsList->addItem( "Vector", "" );
m_colorMapSelection = m_groupTex->addProperty( "Colormap", "Colormap type.", m_colorMapSelectionsList->getSelectorFirst(), propertyCallback );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorMapSelection );
m_matrixSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
m_matrixSelectionsList->addItem( "No matrix", "" );
m_matrixSelectionsList->addItem( "qform", "" );
m_matrixSelectionsList->addItem( "sform", "" );
m_matrixSelectionsList->addItem( "qform", "" );
m_matrixSelection = m_properties->addProperty( "Transformation matrix", "matrix",
m_matrixSelectionsList->getSelectorFirst(), propertyCallback );
m_matrixSelectionsList->getSelectorFirst(), m_propCondition );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_matrixSelection );
// }
}
void WMData::propertyChanged( boost::shared_ptr< WPropertyBase > property )
{
if( m_isTexture )
{
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
if ( property == m_threshold )
{
m_dataSet->getTexture()->setThreshold( m_threshold->get() );
}
else if ( property == m_opacity )
{
m_dataSet->getTexture()->setOpacity( m_opacity->get() );
}
else if ( property == m_interpolation )
{
m_dataSet->getTexture()->setInterpolation( m_interpolation->get() );
}
else if ( property == m_colorMapSelection )
{
m_dataSet->getTexture()->setSelectedColormap( m_colorMapSelection->get( true ).getItemIndexOfSelected( 0 ) );
}
else if ( property == m_matrixSelection )
{
boost::shared_ptr< WGridRegular3D > grid = m_dataSet->getTexture()->getGrid();
//grid->setActiveMatrix( m_matrixSelection->get( true ).getItemIndexOfSelected( 0 ) );
WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
m_output->triggerUpdate();
}
// }
if ( property == m_active )
{
// forward to texture
......@@ -249,6 +191,9 @@ void WMData::notifyStop()
void WMData::moduleMain()
{
m_moduleState.setResetable( true, true );
m_moduleState.add( m_propCondition );
WAssert( m_fileNameSet, "No filename specified." );
using wiotools::getSuffix;
......@@ -266,17 +211,6 @@ void WMData::moduleMain()
// load it now
std::string suffix = getSuffix( fileName );
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
if( suffix == ".fib"
|| suffix == ".cnt"
|| suffix == ".asc"
|| suffix == ".edf" )
{
// hide other properties since they make no sense fo these data set types.
m_groupTex->setHidden();
}
// }
if( suffix == ".nii"
|| ( suffix == ".gz" && ::nifti_compiled_with_zlib() ) )
{
......@@ -290,6 +224,10 @@ void WMData::moduleMain()
WReaderNIfTI niiLoader( fileName );
m_dataSet = niiLoader.load();
m_transformNoMatrix = niiLoader.getStandardTransform();
m_transformSForm = niiLoader.getSFormTransform();
m_transformQForm = niiLoader.getQFormTransform();
m_isTexture = m_dataSet->isTexture();
boost::shared_ptr< WDataSetSingle > dss = boost::shared_dynamic_cast< WDataSetSingle >( m_dataSet );
......@@ -301,9 +239,6 @@ void WMData::moduleMain()
case W_DT_UNSIGNED_CHAR:
case W_DT_INT16:
case W_DT_SIGNED_INT:
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
m_colorMapSelection->set( m_colorMapSelectionsList->getSelector( 0 ) );
// }
m_dataSet->getTexture2()->colormap()->set(
m_dataSet->getTexture2()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 0 ) )
);
......@@ -312,10 +247,6 @@ void WMData::moduleMain()
case W_DT_DOUBLE:
if( boost::shared_dynamic_cast< WDataSetVector >( m_dataSet ) )
{
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
m_colorMapSelection->set( m_colorMapSelectionsList->getSelector( 6 ) );
m_interpolation->set( false );
// }
m_dataSet->getTexture2()->colormap()->set(
m_dataSet->getTexture2()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 6 ) )
);
......@@ -323,9 +254,6 @@ void WMData::moduleMain()
}
else
{
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
m_colorMapSelection->set( m_colorMapSelectionsList->getSelector( 5 ) );
// }
m_dataSet->getTexture2()->colormap()->set(
m_dataSet->getTexture2()->colormap()->get().newSelector( WItemSelector::IndexList( 1, 5 ) )
);
......@@ -335,15 +263,6 @@ void WMData::moduleMain()
WAssert( false, "Unknow data type in Data module" );
}
}
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
if( boost::shared_dynamic_cast< WDataSetScalar >( m_dataSet ) )
{
m_threshold->setMin( boost::shared_dynamic_cast< WDataSetScalar >( m_dataSet )->getMin() );
m_threshold->setMax( boost::shared_dynamic_cast< WDataSetScalar >( m_dataSet )->getMax() );
m_threshold->set( boost::shared_dynamic_cast< WDataSetScalar >( m_dataSet )->getMin() );
}
// }
}
else if( suffix == ".edf" )
{
......@@ -394,22 +313,69 @@ void WMData::moduleMain()
// I am interested in the active property ( manually subscribe signal )
m_active->getCondition()->subscribeSignal( boost::bind( &WMData::propertyChanged, this, m_active ) );
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
// register at datahandler
WDataHandler::registerDataSet( m_dataSet ); // this will get obsolete soon
// }
// notify
m_output->updateData( m_dataSet );
ready();
// go to idle mode
waitForStop(); // WThreadedRunner offers this for us. It uses boost::condition to avoid wasting CPU cycles with while loops.
while( !m_shutdownFlag() )
{
m_moduleState.wait();
if( m_shutdownFlag() )
{
break;
}
// change transform matrix
if( m_matrixSelection->changed() )
{
// a new grid
boost::shared_ptr< WGrid > newGrid;
boost::shared_ptr< WDataSetSingle > ds = boost::shared_dynamic_cast< WDataSetSingle >( m_dataSet );
boost::shared_ptr< WGridRegular3D > oldGrid = boost::shared_dynamic_cast< WGridRegular3D >( ds->getGrid() );
switch( m_matrixSelection->get( true ).getItemIndexOfSelected( 0 ) )
{
case 0:
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
WGridTransformOrtho( m_transformNoMatrix ) ) );
break;
case 1:
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
WGridTransformOrtho( m_transformSForm ) ) );
break;
case 2:
newGrid = boost::shared_ptr< WGrid >( new WGridRegular3D( oldGrid->getNbCoordsX(), oldGrid->getNbCoordsY(), oldGrid->getNbCoordsZ(),
WGridTransformOrtho( m_transformQForm ) ) );
break;
}
if( boost::shared_dynamic_cast< WDataSetRawHARDI >( m_dataSet ) )
{
typedef std::vector< wmath::WVector3D > OrientationType;
// hardi datasets are a morre difficult case because of additional parameters
boost::shared_ptr< WDataSetRawHARDI > hardi = boost::shared_dynamic_cast< WDataSetRawHARDI >( m_dataSet );
m_dataSet = boost::shared_ptr< WDataSet >(
new WDataSetRawHARDI( hardi->getValueSet(), newGrid,
boost::shared_ptr< OrientationType >( new OrientationType( hardi->getOrientations() ) ),
hardi->getDiffusionBValue() ) );
// TODO( reichenbach ): remove copying orientations
}
else
{
// this creates a dataset of the same type as m_dataSet without explicit knowledge of the correct type
m_dataSet = m_dataSet->clone( ds->getValueSet(), newGrid );
}
// the clone() may have returned a zero-pointer, only update if it hasn't
// this may happen if the clone() operation has not been implemented in the derived dataset class
if( m_dataSet )
{
m_output->updateData( m_dataSet );
}
}
}
// remove dataset from datahandler
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
WDataHandler::deregisterDataSet( m_dataSet );
// }
if ( m_dataSet->isTexture() )
{
m_properties->removeProperty( m_dataSet->getTexture2()->getProperties() );
......
......@@ -159,6 +159,9 @@ protected:
*/
virtual void notifyStop();
//! a condition for property changes
boost::shared_ptr< WCondition > m_propCondition;
/**
* The filename of the dataset to load.
*/
......@@ -179,28 +182,6 @@ protected:
*/
WPropString m_dataType;
// { TODO(ebaum): this is deprecated and will be replaced by WGEColormapping
/**
* \deprecated Be aware that this will be replaced by WGEColormapping
* Grouping the texture display properties
*/
WPropGroup m_groupTex;
/**
* Interpolation?
*/
WPropBool m_interpolation;
/**
* A list of color map selection types
*/
boost::shared_ptr< WItemSelection > m_colorMapSelectionsList;
/**
* Selection property for color map
*/
WPropSelection m_colorMapSelection;
/**
* A list of color map selection types
*/
......@@ -211,18 +192,6 @@ protected:
*/
WPropSelection m_matrixSelection;
/**
* Threshold value for this data.
*/
WPropDouble m_threshold;
/**
* Opacity value for this data.
*/
WPropInt m_opacity;
// }
bool m_isTexture; //!< Indicates whether the loaded dataSet will be available as texture.
/**
......@@ -232,6 +201,16 @@ protected:
*/
void propertyChanged( boost::shared_ptr< WPropertyBase > property );
// in case of a nifti file, there may be several transforms specified in the file
//! a standard transform (should be an identity transform)
wmath::WMatrix< double > m_transformNoMatrix;
//! a standard transform (should be an identity transform)
wmath::WMatrix< double > m_transformSForm;
//! a standard transform (should be an identity transform)
wmath::WMatrix< double > m_transformQForm;
private:
/**
......
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