OpenWalnut  1.5.0dev
WReaderNIfTI.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
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.
14 //
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.
19 //
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/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <fstream>
26 #include <iostream>
27 #include <memory>
28 #include <stdint.h>
29 #include <string>
30 #include <vector>
31 
32 
33 #include "WReaderNIfTI.h"
34 #include "core/common/WIOTools.h"
35 #include "core/common/WLogger.h"
36 #include "core/dataHandler/WDataHandlerEnums.h"
37 #include "core/dataHandler/WDataSet.h"
38 #include "core/dataHandler/WDataSetDTI.h"
39 #include "core/dataHandler/WDataSetRawHARDI.h"
40 #include "core/dataHandler/WDataSetScalar.h"
41 #include "core/dataHandler/WDataSetSegmentation.h"
42 #include "core/dataHandler/WDataSetSingle.h"
43 #include "core/dataHandler/WDataSetSphericalHarmonics.h"
44 #include "core/dataHandler/WDataSetTimeSeries.h"
45 #include "core/dataHandler/WDataSetVector.h"
46 #include "core/dataHandler/WGrid.h"
47 #include "core/dataHandler/WGridRegular3D.h"
48 #include "core/dataHandler/WSubject.h"
49 #include "core/dataHandler/WValueSet.h"
50 #include "core/dataHandler/WValueSetBase.h"
51 
52 WReaderNIfTI::WReaderNIfTI( std::string fileName )
53  : WReader( fileName ),
54  m_sform( 4, 4 ),
55  m_qform( 4, 4 )
56 {
57 }
58 
59 template< typename T > std::shared_ptr< std::vector< T > > WReaderNIfTI::copyArray( const T* dataArray, const size_t countVoxels,
60  const size_t vDim )
61 {
62  std::shared_ptr< std::vector< T > > data( new std::vector< T >( countVoxels * vDim ) );
63  for( unsigned int i = 0; i < countVoxels; ++i )
64  {
65  for( unsigned int j = 0; j < vDim; ++j )
66  {
67  (*data)[i * vDim + j] = dataArray[( j * countVoxels ) + i];
68  }
69  }
70  return data;
71 }
72 
73 
75 {
76  WMatrix< double > out( 4, 4 );
77 
78  bool isZero = true;
79  for( size_t i = 0; i < 4; ++i )
80  {
81  for( size_t j = 0; j < 4; ++j )
82  {
83  out( i, j ) = in.m[i][j];
84  isZero = isZero && out( i, j ) == 0.0;
85  }
86  }
87 
88  if( isZero )
89  {
90  out.makeIdentity();
91  }
92  return out;
93 }
94 
96 {
97  std::string gradientFileName = m_fname;
98  std::string suffix = getSuffix( m_fname );
99 
100  if( suffix == ".gz" )
101  {
102  WAssert( gradientFileName.length() > 3, "" );
103  gradientFileName.resize( gradientFileName.length() - 3 );
104  suffix = getSuffix( gradientFileName );
105  }
106  WAssert( suffix == ".nii", "Input file is not a nifti file." );
107 
108  WAssert( gradientFileName.length() > 4, "" );
109  gradientFileName.resize( gradientFileName.length() - 4 );
110  gradientFileName += ".bvec";
111 
112  GradVec result; // incase of error return NULL_ptr
113 
114  // check if the file exists
115  std::ifstream i( gradientFileName.c_str() );
116  if( i.bad() || !i.is_open() )
117  {
118  if( i.is_open() )
119  {
120  i.close();
121  }
122  wlog::debug( "WReaderNIfTI" ) << "Could not find gradient file expected at: \"" << gradientFileName << "\", skipping this.";
123  }
124  else
125  {
126  wlog::debug( "WReaderNIfTI" ) << "Found b-vectors file: " << gradientFileName << " will try reading...";
127  result = GradVec( new std::vector< WVector3d >( vDim ) );
128 
129  // the file should contain the x-coordinates in line 0, y-coordinates in line 1,
130  // z-coordinates in line 2
131  for( unsigned int j = 0; j < 3; ++j )
132  {
133  for( unsigned int k = 0; k < vDim; ++k )
134  {
135  i >> result->operator[] ( k )[ j ];
136  }
137  }
138  bool success = !i.eof();
139  i.close();
140  if( !success )
141  {
142  wlog::error( "WReaderNIfTI" ) << "Error while reading gradient file: did not contain enough gradients: " << result->size();
143  return GradVec(); // return Null_ptr
144  }
145  else
146  {
147  wlog::debug( "WReaderNIfTI" ) << "Successfully loaded " << result->size() << " gradients";
148  }
149  }
150  return result;
151 }
152 
154 {
155  std::string bvaluesFileName = m_fname;
156  std::string suffix = getSuffix( m_fname );
157 
158  if( suffix == ".gz" )
159  {
160  WAssert( bvaluesFileName.length() > 3, "" );
161  bvaluesFileName.resize( bvaluesFileName.length() - 3 );
162  suffix = getSuffix( bvaluesFileName );
163  }
164  WAssert( suffix == ".nii", "Input file is not a nifti file." );
165 
166  WAssert( bvaluesFileName.length() > 4, "" );
167  bvaluesFileName.resize( bvaluesFileName.length() - 4 );
168  bvaluesFileName += ".bval";
169 
170  BValues result; // return NULL_ptr in case of error
171 
172  // check if the file exists
173  std::ifstream i( bvaluesFileName.c_str() );
174  if( i.bad() || !i.is_open() )
175  {
176  if( i.is_open() )
177  {
178  i.close();
179  }
180  wlog::debug( "WReaderNIfTI" ) << "Could not find b-values file expected at: \"" << bvaluesFileName << "\", skipping this.";
181  }
182  else
183  {
184  //read b-values
185  char value[ 8 ];
186  // there should be 3 * vDim values in the file
187  result = BValues( new std::vector< float >( vDim * 3, 0 ) );
188  size_t numValues = 0;
189  while( i.good() && !i.eof() )
190  {
191  i.getline( value, 8 );
192  float fVal;
193  std::istringstream( value ) >> fVal;
194  ( *result )[ numValues ] = fVal;
195  if( numValues > vDim * 3 )
196  {
197  wlog::error( "WReaderNIfTI" ) << "Too many b-Values: " << numValues << " but expected: " << vDim * 3;
198  return BValues(); // return Null_ptr
199  }
200  numValues++;
201  }
202 
203  i.close();
204 
205  wlog::debug( "WReaderNIfTI" ) << "Found b-values file and loaded " << result->size() << " values.";
206  }
207  return result;
208 }
209 
210 std::shared_ptr< WDataSet > WReaderNIfTI::load( DataSetType dataSetType )
211 {
212  std::shared_ptr< nifti_image > filedata( nifti_image_read( m_fname.c_str(), 1 ), &nifti_image_free );
213 
214  WAssert( filedata, "Error during file access to NIfTI file. This probably means that the file is corrupted." );
215 
216  WAssert( filedata->ndim >= 3,
217  "The NIfTI file contains data that has less than the three spatial dimension. OpenWalnut is not able to handle this." );
218 
219  int columns = filedata->dim[1];
220  int rows = filedata->dim[2];
221  int frames = filedata->dim[3];
222 
223  std::shared_ptr< WValueSetBase > newValueSet;
224  std::shared_ptr< WGrid > newGrid;
225 
226  unsigned int vDim;
227  if( filedata->ndim >= 4 )
228  {
229  vDim = filedata->dim[4];
230  }
231  else
232  {
233  vDim = 1;
234  }
235 
236  unsigned int order = ( ( vDim == 1 ) ? 0 : 1 ); // TODO(all): Does recognize vectors and scalars only so far.
237  unsigned int countVoxels = columns * rows * frames;
238 
239  // don't rearrange if this is a time series
240  if( filedata->dim[ 5 ] <= 1 )
241  {
242  switch( filedata->datatype )
243  {
244  case DT_UINT8:
245  {
246  std::shared_ptr< std::vector< uint8_t > > data = copyArray( reinterpret_cast< uint8_t* >( filedata->data ), countVoxels, vDim );
247  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< uint8_t >( order, vDim, data, W_DT_UINT8 ) );
248  break;
249  }
250  case DT_INT8:
251  {
252  std::shared_ptr< std::vector< int8_t > > data = copyArray( reinterpret_cast< int8_t* >( filedata->data ), countVoxels, vDim );
253  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< int8_t >( order, vDim, data, W_DT_INT8 ) );
254  break;
255  }
256  case DT_INT16:
257  {
258  std::shared_ptr< std::vector< int16_t > > data = copyArray( reinterpret_cast< int16_t* >( filedata->data ), countVoxels, vDim );
259  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< int16_t >( order, vDim, data, W_DT_INT16 ) );
260  break;
261  }
262  case DT_UINT16:
263  {
264  std::shared_ptr< std::vector< uint16_t > > data
265  = copyArray( reinterpret_cast< uint16_t* >( filedata->data ), countVoxels, vDim );
266  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< uint16_t >( order, vDim, data, W_DT_UINT16 ) );
267  break;
268  }
269  case DT_SIGNED_INT:
270  {
271  std::shared_ptr< std::vector< int32_t > > data = copyArray( reinterpret_cast< int32_t* >( filedata->data ), countVoxels, vDim );
272  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< int32_t >( order, vDim, data, W_DT_SIGNED_INT ) );
273  break;
274  }
275  case DT_UINT32:
276  {
277  std::shared_ptr< std::vector< uint32_t > > data
278  = copyArray( reinterpret_cast< uint32_t* >( filedata->data ), countVoxels, vDim );
279  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< uint32_t >( order, vDim, data, W_DT_UINT32 ) );
280  break;
281  }
282  case DT_INT64:
283  {
284  std::shared_ptr< std::vector< int64_t > > data = copyArray( reinterpret_cast< int64_t* >( filedata->data ), countVoxels, vDim );
285  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< int64_t >( order, vDim, data, W_DT_INT64 ) );
286  break;
287  }
288  case DT_UINT64:
289  {
290  std::shared_ptr< std::vector< uint64_t > > data =
291  copyArray( reinterpret_cast< uint64_t* >( filedata->data ), countVoxels, vDim );
292  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< uint64_t >( order, vDim, data, W_DT_UINT64 ) );
293  break;
294  }
295  case DT_FLOAT:
296  {
297  std::shared_ptr< std::vector< float > > data = copyArray( reinterpret_cast< float* >( filedata->data ), countVoxels, vDim );
298  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< float >( order, vDim, data, W_DT_FLOAT ) );
299  break;
300  }
301  case DT_DOUBLE:
302  {
303  std::shared_ptr< std::vector< double > > data = copyArray( reinterpret_cast< double* >( filedata->data ), countVoxels, vDim );
304  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< double >( order, vDim, data, W_DT_DOUBLE ) );
305  break;
306  }
307  case DT_FLOAT128:
308  {
309  std::shared_ptr< std::vector< long double > > data =
310  copyArray( reinterpret_cast< long double* >( filedata->data ), countVoxels, vDim );
311  newValueSet = std::shared_ptr< WValueSetBase >( new WValueSet< long double >( order, vDim, data, W_DT_FLOAT128 ) );
312  break;
313  }
314  default:
315  wlog::error( "WReaderNIfTI" ) << "unknown data type " << filedata->datatype << std::endl;
316  newValueSet = std::shared_ptr< WValueSetBase >();
317  }
318  }
319 
320  m_sform = convertMatrix( filedata->sto_xyz );
321  m_qform = convertMatrix( filedata->qto_xyz );
322  newGrid = std::shared_ptr< WGridRegular3D >(
323  new WGridRegular3D( columns, rows, frames, WGridTransformOrtho( getStandardTransform() ) ) );
324 
325  std::shared_ptr< WDataSet > newDataSet;
326  // known description
327  std::string description( filedata->descrip );
328  if( !description.compare( "WDataSetSegmentation" ) )
329  {
330  wlog::debug( "WReaderNIfTI" ) << "Load as segmentation" << std::endl;
331  newDataSet = std::shared_ptr< WDataSet >( new WDataSetSegmentation( newValueSet, newGrid ) );
332  }
333  else if( description.compare( "WDataSetSphericalHarmonics" ) == 0 || dataSetType == W_DATASET_SPHERICALHARMONICS )
334  {
335  wlog::debug( "WReaderNIfTI" ) << "Load as spherical harmonics" << std::endl;
336  newDataSet = std::shared_ptr< WDataSet >( new WDataSetSphericalHarmonics( newValueSet, newGrid ) );
337  }
338  // 4th dimension is the time
339  // note that in the nifti standard, dim[ 4 ] is the temporal dimension
340  // we use dim[ 5 ] here
341  else if( filedata->dim[ 5 ] > 1 )
342  {
343  WAssert( filedata->dim[ 4 ] == 1, "Only scalar datasets are supported for time series so far." );
344  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetTimeSeries";
345  std::size_t numTimeSlices = filedata->dim[ 5 ];
346  float tw = filedata->pixdim[ 5 ];
347  WAssert( tw != 0.0f, "" );
348 
349  std::vector< std::shared_ptr< WDataSetScalar const > > ds;
350  std::vector< float > times;
351  float t = 0.0f;
352  for( std::size_t k = 0; k < numTimeSlices; ++k )
353  {
354  times.push_back( t );
355  t += tw;
356  std::shared_ptr< WValueSetBase > vs;
357  switch( filedata->datatype )
358  {
359  case DT_UINT8:
360  {
361  uint8_t* ptr = reinterpret_cast< uint8_t* >( filedata->data );
362  std::shared_ptr< std::vector< uint8_t > > values =
363  std::shared_ptr< std::vector< uint8_t > >(
364  new std::vector< uint8_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
365  vs = std::shared_ptr< WValueSetBase >( new WValueSet< uint8_t >( 0, 1, values, W_DT_UINT8 ) );
366  }
367  break;
368  case DT_INT8:
369  {
370  int8_t* ptr = reinterpret_cast< int8_t* >( filedata->data );
371  std::shared_ptr< std::vector< int8_t > > values =
372  std::shared_ptr< std::vector< int8_t > >(
373  new std::vector< int8_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
374  vs = std::shared_ptr< WValueSetBase >( new WValueSet< int8_t >( 0, 1, values, W_DT_INT8 ) );
375  }
376  break;
377  case DT_UINT16:
378  {
379  uint16_t* ptr = reinterpret_cast< uint16_t* >( filedata->data );
380  std::shared_ptr< std::vector< uint16_t > >values =
381  std::shared_ptr< std::vector< uint16_t > >(
382  new std::vector< uint16_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
383  vs = std::shared_ptr< WValueSetBase >( new WValueSet< uint16_t >( 0, 1, values, W_DT_UINT16 ) );
384  }
385  break;
386  case DT_INT16:
387  {
388  int16_t* ptr = reinterpret_cast< int16_t* >( filedata->data );
389  std::shared_ptr< std::vector< int16_t > > values =
390  std::shared_ptr< std::vector< int16_t > >(
391  new std::vector< int16_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
392  vs = std::shared_ptr< WValueSetBase >( new WValueSet< int16_t >( 0, 1, values, W_DT_INT16 ) );
393  }
394  break;
395  case DT_UINT32:
396  {
397  uint32_t* ptr = reinterpret_cast< uint32_t* >( filedata->data );
398  std::shared_ptr< std::vector< uint32_t > > values =
399  std::shared_ptr< std::vector< uint32_t > >(
400  new std::vector< uint32_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
401  vs = std::shared_ptr< WValueSetBase >( new WValueSet< uint32_t >( 0, 1, values, W_DT_UINT32 ) );
402  }
403  break;
404  case DT_SIGNED_INT:
405  {
406  int32_t* ptr = reinterpret_cast< int32_t* >( filedata->data );
407  std::shared_ptr< std::vector< int32_t > > values =
408  std::shared_ptr< std::vector< int32_t > >(
409  new std::vector< int32_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
410  vs = std::shared_ptr< WValueSetBase >( new WValueSet< int32_t >( 0, 1, values, W_DT_SIGNED_INT ) );
411  }
412  break;
413  case DT_UINT64:
414  {
415  uint64_t* ptr = reinterpret_cast< uint64_t* >( filedata->data );
416  std::shared_ptr< std::vector< uint64_t > > values =
417  std::shared_ptr< std::vector< uint64_t > >(
418  new std::vector< uint64_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
419  vs = std::shared_ptr< WValueSetBase >( new WValueSet< uint64_t >( 0, 1, values, W_DT_UINT64 ) );
420  }
421  break;
422  case DT_INT64:
423  {
424  int64_t* ptr = reinterpret_cast< int64_t* >( filedata->data );
425  std::shared_ptr< std::vector< int64_t > > values =
426  std::shared_ptr< std::vector< int64_t > >(
427  new std::vector< int64_t >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
428  vs = std::shared_ptr< WValueSetBase >( new WValueSet< int64_t >( 0, 1, values, W_DT_INT64 ) );
429  }
430  break;
431  case DT_FLOAT:
432  {
433  float* ptr = reinterpret_cast< float* >( filedata->data );
434  std::shared_ptr< std::vector< float > > values =
435  std::shared_ptr< std::vector< float > >(
436  new std::vector< float >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
437  vs = std::shared_ptr< WValueSetBase >( new WValueSet< float >( 0, 1, values, W_DT_FLOAT ) );
438  }
439  break;
440  case DT_DOUBLE:
441  {
442  double* ptr = reinterpret_cast< double* >( filedata->data );
443  std::shared_ptr< std::vector< double > > values =
444  std::shared_ptr< std::vector< double > >(
445  new std::vector< double >( ptr + k * countVoxels, ptr + ( k + 1 ) * countVoxels ) );
446  vs = std::shared_ptr< WValueSetBase >( new WValueSet< double >( 0, 1, values, W_DT_DOUBLE ) );
447  }
448  break;
449  default:
450  throw WException( std::string( "Unsupported datatype in WReaderNIfTI" ) );
451  break;
452  }
453  ds.push_back( std::shared_ptr< WDataSetScalar >( new WDataSetScalar( vs, newGrid ) ) );
454  }
455  newDataSet = std::shared_ptr< WDataSet >( new WDataSetTimeSeries( ds, times ) );
456  }
457  // unknown description
458  else
459  {
460  if( vDim == 3 )
461  {
462  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetVector";
463  newDataSet = std::shared_ptr< WDataSet >( new WDataSetVector( newValueSet, newGrid ) );
464  }
465  else if( vDim == 1 )
466  {
467  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetScalar";
468  newDataSet = std::shared_ptr< WDataSet >( new WDataSetScalar( newValueSet, newGrid ) );
469  }
470  else if( vDim > 20 && filedata->dim[ 5 ] <= 1 ) // hardi data, order 1
471  {
472  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetRawHARDI";
473 
474  GradVec newGradients = readGradientsIfAvailable( vDim );
475  BValues newBValues = readBValuesIfAvailable( vDim );
476 
477  if( !newGradients )
478  {
479  // cannot find the appropriate gradient vectors and/or bvalues, build a dataSetSingle instead of hardi
480  newDataSet = std::shared_ptr< WDataSet >( new WDataSetSingle( newValueSet, newGrid ) );
481  wlog::debug( "WReaderNIfTI" ) << "No gradients given. See above for expected filename. Loading as WDataSetSingle instead.";
482  }
483  else
484  {
485  if( !newBValues )
486  {
487  newDataSet = std::shared_ptr< WDataSet >( new WDataSetRawHARDI( newValueSet, newGrid, newGradients ) );
488  }
489  else
490  {
491  newDataSet = std::shared_ptr< WDataSet >( new WDataSetRawHARDI( newValueSet, newGrid, newGradients, newBValues ) );
492  }
493  }
494 
495  if( newBValues && newGradients && ( newBValues->size() > 1 && newBValues->size() != newGradients->size() * 3 ) )
496  {
497  wlog::warn( "WReaderNIfTI" ) << "Be careful: there are " << newBValues->size() / 3 << " b-values but only "
498  << newGradients->size() << " gradients.";
499  }
500  }
501  else if( filedata->intent_code == NIFTI_INTENT_SYMMATRIX )
502  {
503  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetDTI";
504  newDataSet = std::shared_ptr< WDataSetDTI >( new WDataSetDTI( newValueSet, newGrid ) );
505  }
506  else
507  {
508  wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetSingle";
509  newDataSet = std::shared_ptr< WDataSet >( new WDataSetSingle( newValueSet, newGrid ) );
510  }
511  }
512  newDataSet->setFilename( m_fname );
513 
514  return newDataSet;
515 }
516 
518 {
519  return WMatrix< double >( 4, 4 ).makeIdentity();
520 }
521 
523 {
524  return m_sform;
525 }
526 
528 {
529  return m_qform;
530 }
Represents a Diffusion-Tensor-Image dataset.
Definition: WDataSetDTI.h:40
This data set type contains raw HARDI and its gradients.
This data set type contains scalars as values.
A dataset that stores the segmentation of the brain into CSF, white and gray matter.
A data set consisting of a set of values based on a grid.
This data set type contains spherical harmonic coefficients as values.
A dataset that stores a time series.
This data set type contains vectors as values.
Basic exception handler.
Definition: WException.h:39
A grid that has parallelepiped cells which all have the same proportion.
Implements an orthogonal grid transformation.
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352
WMatrix< double > getQFormTransform() const
Returns the QForm transformation stored in the nifti file's header.
WMatrix< double > convertMatrix(const mat44 &in)
This function converts a 4x4 matrix from the NIfTI libs into the format used by OpenWalnut.
WMatrix< double > m_sform
the sform transform stored in the file header
Definition: WReaderNIfTI.h:179
WReaderNIfTI(std::string fileName)
Constructs a loader to be executed in its own thread and ets the data needed for the loader when exec...
GradVec readGradientsIfAvailable(unsigned int vDim)
Reads the additional gradient file if available.
WMatrix< double > getSFormTransform() const
Returns the SForm transformation stored in the nifti file's header.
WMatrix< double > m_qform
the qform transform stored in the file header
Definition: WReaderNIfTI.h:182
std::shared_ptr< std::vector< T > > copyArray(const T *dataArray, const size_t countVoxels, const size_t vDim)
This function allows one to copy the data given as a T* by niftilibio into a std::vector< T >
std::shared_ptr< std::vector< WVector3d > > GradVec
Shorthand type for a vector of gradients.
Definition: WReaderNIfTI.h:91
std::shared_ptr< std::vector< float > > BValues
Shorthand type for a vector of bvalues.
Definition: WReaderNIfTI.h:96
WMatrix< double > getStandardTransform() const
Returns a standard transformation.
virtual std::shared_ptr< WDataSet > load(DataSetType dataSetType=W_DATASET_NONE)
Loads the dataset.
BValues readBValuesIfAvailable(unsigned int vDim)
Reads the additional bval file if available.
Read some data from a given file.
Definition: WReader.h:40
std::string m_fname
Absolute path of the file to read from.
Definition: WReader.h:68
Base Class for all value set types.
Definition: WValueSet.h:47
DataSetType
Data set types.
WStreamedLogger debug(const std::string &source)
Logging a debug message.
Definition: WLogger.h:331
WStreamedLogger warn(const std::string &source)
Logging a warning message.
Definition: WLogger.h:309
WStreamedLogger error(const std::string &source)
Logging an error message.
Definition: WLogger.h:298