Commit 043f5bba authored by Alexander Wiebel's avatar Alexander Wiebel
Browse files

[ADD] first start of a NIfTI writing module that uses niftilif

parent 802af003
......@@ -44,6 +44,7 @@
#include "../modules/prototypeBoxManipulation/WMPrototypeBoxManipulation.h"
#include "../modules/textureList/WMTextureList.h"
#include "../modules/voxelizer/WMVoxelizer.h"
#include "../modules/writeNIfTI/WMWriteNIfTI.h"
#include "WModuleFactory.h"
#include "exceptions/WPrototypeNotUnique.h"
#include "exceptions/WPrototypeUnknown.h"
......@@ -86,6 +87,7 @@ void WModuleFactory::load()
m_prototypes.insert( boost::shared_ptr< WModule >( new WMPrototypeBoxManipulation() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMVoxelizer() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDirectVolumeRendering() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMWriteNIfTI() ) );
lock.unlock();
......
//---------------------------------------------------------------------------
//
// 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 <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <utility>
#include <cmath>
#include "../../common/WStringUtils.h"
#include "../../dataHandler/WGridRegular3D.h"
#include "../../kernel/WKernel.h"
#include "../../math/WPosition.h"
#include "../../math/WVector3D.h"
#include "../data/WMData.h"
#include "../../dataHandler/io/nifti/nifti1_io.h"
#include "WMWriteNIfTI.h"
WMWriteNIfTI::WMWriteNIfTI():
WModule()
{
// WARNING: initializing connectors inside the constructor will lead to an exception.
// Implement WModule::initializeConnectors instead.
}
WMWriteNIfTI::~WMWriteNIfTI()
{
// cleanup
removeConnectors();
}
boost::shared_ptr< WModule > WMWriteNIfTI::factory() const
{
return boost::shared_ptr< WModule >( new WMWriteNIfTI() );
}
const std::string WMWriteNIfTI::getName() const
{
return "Write NIfTI";
}
const std::string WMWriteNIfTI::getDescription() const
{
return "Writes a data set to a NIfTI file.";
}
void WMWriteNIfTI::moduleMain()
{
// use the m_input "data changed" flag
m_moduleState.add( m_input->getDataChangedCondition() );
// signal ready state
ready();
// loop until the module container requests the module to quit
while ( !m_shutdownFlag() )
{
sleep( 3 ); // TODO(wiebel): remove this
// acquire data from the input connector
m_dataSet = m_input->getData();
if ( !m_dataSet )
{
// ok, the output has not yet sent data
// NOTE: see comment at the end of this while loop for m_moduleState
debugLog() << "Waiting for data ...";
m_moduleState.wait();
continue;
}
assert( m_dataSet );
// this waits for m_moduleState to fire. By default, this is only the m_shutdownFlag condition.
// NOTE: you can add your own conditions to m_moduleState using m_moduleState.add( ... )
m_moduleState.wait();
}
}
void WMWriteNIfTI::connectors()
{
// initialize connectors
m_input = boost::shared_ptr< WModuleInputData < WDataSetSingle > >(
new WModuleInputData< WDataSetSingle >( shared_from_this(),
"in", "The dataset to filter" )
);
// add it to the list of connectors. Please note, that a connector NOT added via addConnector will not work as expected.
addConnector( m_input );
// call WModules initialization
WModule::connectors();
}
void WMWriteNIfTI::properties()
{
( m_properties->addString( "File Name" ) )->connect( boost::bind( &WMWriteNIfTI::slotPropertyChanged, this, _1 ) );
}
void WMWriteNIfTI::slotPropertyChanged( std::string propertyName )
{
if( propertyName == "File Name" )
{
writeToFile( m_properties->getValue< std::string >( propertyName ) );
}
else
{
std::cout << propertyName << std::endl;
assert( 0 && "This property name is not supported by this function yet." );
}
}
void WMWriteNIfTI::writeToFile( std::string fileName )
{
nifti_image *outField = nifti_simple_init_nim();
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( m_dataSet->getGrid() );
assert( grid && "Seems that grid is of wrong type." );
boost::shared_ptr< WValueSet< uint8_t > > vals = boost::shared_dynamic_cast< WValueSet< uint8_t > >( ( *m_dataSet ).getValueSet() );
assert( vals && "Seems that value set is of wrong type." );
size_t nbValues = vals->size();
outField->nx = grid->getNbCoordsX();
outField->ny = grid->getNbCoordsY();
outField->nz = grid->getNbCoordsZ();
assert( grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ() == nbValues );
// TODO(wiebel): only able to handle scalars now.
outField->nt = 1;
outField->nvox = nbValues;
outField->dx = grid->getOffsetX();
outField->dy = grid->getOffsetY();
outField->dz = grid->getOffsetZ();
outField->nifti_type = 1; // 1==NIFTI-1 (1 file)
outField->freq_dim = 1;
outField->phase_dim = 2;
outField->slice_dim = 3;
outField->qform_code = 1;
outField->datatype = DT_UNSIGNED_CHAR;
outField->nbyper = 1;
uint8_t* data = new uint8_t[nbValues];
for( unsigned int i = 0; i < nbValues; ++i )
{
data[i] = static_cast<uint8_t>( vals->getScalar( i ) );
}
outField->data = static_cast<void*>( data );
if( nifti_set_filenames( outField, fileName.c_str(), 0, 1 ) )
{
throw WException( "NIfTI filename Problem" );
}
nifti_image_write( outField );
nifti_image_free( outField );
infoLog() << "Writing data completed." << std::endl;
}
//---------------------------------------------------------------------------
//
// 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 WMWRITENIFTI_H
#define WMWRITENIFTI_H
#include <map>
#include <string>
#include <vector>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Uniform>
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
#include "../../math/WVector3D.h"
class WPickHandler;
/**
* Write the input dataset to a NIfTI file
* \problem It works only on uint8_t values sets so far.
* \problem Might crash OpenWalnut
*
* \ingroup modules
*/
class WMWriteNIfTI : public WModule
{
public:
/**
* Standard constructor.
*/
WMWriteNIfTI();
/**
* Destructor.
*/
~WMWriteNIfTI();
/**
* Gives back the name of this module.
* \return the module's name.
*/
virtual const std::string getName() const;
/**
* Gives back a description of this module.
* \return description of module.
*/
virtual const std::string getDescription() const;
/**
* Determine what to do if a property was changed.
* \param propertyName Name of the property.
*/
void slotPropertyChanged( std::string propertyName );
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
* should never be initialized or modified in some other way. A simple new instance is required.
*
* \return the prototype used to create every module in OpenWalnut.
*/
virtual boost::shared_ptr< WModule > factory() const;
protected:
/**
* Entry point after loading the module. Runs in separate thread.
*/
virtual void moduleMain();
/**
* Initialize the connectors this module is using.
*/
virtual void connectors();
/**
* Initialize the properties for this module.
*/
virtual void properties();
private:
/**
* This performs all work neccessary to actually write the data to the file
* \param fileName The data set will be written to this file.
*/
void writeToFile( std::string fileName );
boost::shared_ptr< WModuleInputData< WDataSetSingle > > m_input; //!< Input connector required by this module.
boost::shared_ptr< WDataSetSingle > m_dataSet; //!< Pointer providing access to the treated data set in the whole module.
};
#endif // WMWRITENIFTI_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