34 #include <nifti1_io.h>
36 #include "WMWriteNIfTI.h"
37 #include "core/common/WAssert.h"
38 #include "core/common/WPathHelper.h"
39 #include "core/common/WStringUtils.h"
40 #include "core/dataHandler/WDataSetRawHARDI.h"
41 #include "core/dataHandler/WGridRegular3D.h"
42 #include "core/kernel/WKernel.h"
43 #include "core/kernel/WModule.h"
65 static const char * disc_xpm[] =
67 "16 16 7 1",
" c None",
". c #000080",
"+ c #000000",
"@ c #FFFF00",
"# c #E0E0E0",
68 "$ c #FFFFFF",
"% c #C0C0C0",
"..+++++++++++..+",
"..@@@@@@@@@@@..+",
"..###########..+",
69 "..$$$$$$$$$$$..+",
"..###########..+",
"..$$$$$$$$$$$..+",
"..###########..+",
"..$$$$$$$$$$$..+",
70 "...............+",
"....%%%%%%%....+",
"....%..%%%%....+",
"....%..%%%%....+",
"....%..%%%%....+",
71 "....%..%%%%....+",
"+...%%%%%%%....+",
"++++++++++++++++"
83 return "Writes a data set to a NIfTI file.";
99 debugLog() <<
"Waiting for data ...";
135 std::shared_ptr< WValueSetBase > valsB = ( *m_dataSet ).getValueSet();
136 std::shared_ptr< WValueSet< T > > vals = std::dynamic_pointer_cast< WValueSet< T > >( ( *m_dataSet ).getValueSet() );
137 WAssert( vals,
"Seems that value set type is not yet supported." );
138 const size_t vDim = vals->dimension();
140 std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >(
m_dataSet->getGrid() );
141 const size_t countVoxels = grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ();
142 WAssert( grid,
"Seems that grid is of wrong type." );
145 T* data =
new T[vals->rawSize()];
146 for(
size_t i = 0; i < countVoxels; ++i )
148 for(
size_t j = 0; j < vDim; ++j )
150 data[( j * countVoxels ) + i] =
static_cast< T
> ( vals->getScalar( i * vDim + j ) );
153 returnData =
static_cast< void*
> ( data );
159 nifti_image *outField = nifti_simple_init_nim();
161 std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >(
m_dataSet->getGrid() );
162 WAssert( grid,
"Seems that grid is of wrong type." );
164 size_t nbValues = ( *m_dataSet ).getValueSet()->size();
166 outField->nx = grid->getNbCoordsX();
167 outField->ny = grid->getNbCoordsY();
168 outField->nz = grid->getNbCoordsZ();
169 WAssert( grid->getNbCoordsX() * grid->getNbCoordsY() * grid->getNbCoordsZ() == nbValues,
170 "Overall size incompatible with size in axis directions." );
172 outField->nvox = nbValues*
m_dataSet->getValueSet()->dimension();
174 outField->dx = grid->getOffsetX();
175 outField->dy = grid->getOffsetY();
176 outField->dz = grid->getOffsetZ();
178 outField->nifti_type = 1;
180 outField->freq_dim = 1;
181 outField->phase_dim = 2;
182 outField->slice_dim = 3;
184 outField->qform_code = 1;
185 outField->sform_code = 1;
190 outField->nt =
m_dataSet->getValueSet()->dimension();
191 outField->dim[0] = 4;
197 std::string description =
m_dataSet->getName();
199 description.copy( outField->descrip, 80 );
202 for(
size_t i = 0; i < 4; ++i )
204 for(
size_t j = 0; j < 4; ++j )
206 outField->qto_xyz.m[i][j] = matrix( i, j );
207 outField->sto_xyz.m[i][j] = matrix( i, j );
213 nifti_mat44_to_quatern( outField->qto_xyz, &( outField->quatern_b ),
214 &( outField->quatern_c ), &( outField->quatern_d ),
215 &( outField->qoffset_x ), &( outField->qoffset_y ),
216 &( outField->qoffset_z ),
218 &( outField->qfac ) );
221 outField->qto_ijk = nifti_mat44_inverse( outField->qto_xyz );
222 outField->sto_ijk = nifti_mat44_inverse( outField->sto_xyz );
225 switch( ( *m_dataSet ).getValueSet()->getDataType() )
228 outField->datatype = DT_DOUBLE;
229 castData< double > ( data );
230 outField->nbyper = 8;
233 outField->datatype = DT_FLOAT;
234 castData< float > ( data );
235 outField->nbyper = 4;
237 case W_DT_UNSIGNED_CHAR:
238 outField->datatype = DT_UNSIGNED_CHAR;
239 castData< uint8_t > ( data );
240 outField->nbyper = 1;
243 outField->datatype = DT_INT8;
244 castData< int8_t > ( data );
245 outField->nbyper = 1;
248 outField->datatype = DT_UINT16;
249 castData< uint16_t > ( data );
250 outField->nbyper = 2;
253 outField->datatype = DT_INT16;
254 castData< int16_t > ( data );
255 outField->nbyper = 2;
258 outField->datatype = DT_UINT32;
259 castData< uint32_t > ( data );
260 outField->nbyper = 4;
262 case W_DT_SIGNED_INT:
263 outField->datatype = DT_SIGNED_INT;
264 castData< int32_t > ( data );
265 outField->nbyper = 4;
268 WAssert(
false,
"Data set type not yet supported." );
270 outField->data = data;
273 if( nifti_set_filenames( outField, s.c_str(), 0, 1 ) )
275 throw WException( std::string(
"NIfTI filename Problem" ) );
278 nifti_image_write( outField );
280 std::shared_ptr< WDataSetRawHARDI > h = std::dynamic_pointer_cast< WDataSetRawHARDI >(
m_dataSet );
283 std::fstream f( ( s +
".bvec" ).c_str(), std::ios_base::out );
284 for( std::size_t i = 0; i < 3; ++i )
286 for( std::size_t k = 0; k < h->getNumberOfMeasurements(); ++k )
288 f << h->getGradient( k )[ i ] <<
" ";
295 nifti_image_free( outField );
296 infoLog() <<
"Writing data completed.";
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
~WMWriteNIfTI()
Destructor.
virtual const std::string getName() const
Gives back the name of this module.
std::shared_ptr< WModuleInputData< WDataSetSingle > > m_input
Input connector required by this module.
void castData(void *&returnData)
Allows one to get a void* out of WValueSet.
virtual void moduleMain()
Entry point after loading the module.
WMWriteNIfTI()
Standard constructor.
WPropTrigger m_saveTriggerProp
This property triggers the actual writing,.
WPropFilename m_filename
The filename property -> where to write the nifty file.
virtual void properties()
Initialize the properties for this module.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
std::shared_ptr< WDataSetSingle > m_dataSet
Pointer providing access to the treated data set in the whole module.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual const std::string getDescription() const
Gives back a description of this module.
virtual void connectors()
Initialize the connectors this module is using.
void writeToFile()
This performs all work necessary to actually write the data to the file.
Class representing a single module of OpenWalnut.
virtual void properties()
Initialize properties in this function.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
void removeConnectors()
Removes all connectors properly.
std::shared_ptr< WProperties > m_properties
The property object for the module.
void ready()
Call this whenever your module is ready and can react on property changes.
WConditionSet m_moduleState
The internal state of the module.
wlog::WStreamedLogger infoLog() const
Logger instance for comfortable info logging.
virtual void connectors()
Initialize connectors in this function.
static boost::filesystem::path getAppPath()
The path where the binary file resides in.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)