33 #include "WReaderVTK.h" 
   34 #include "core/common/WAssert.h" 
   35 #include "core/common/WIOTools.h" 
   36 #include "core/common/WLimits.h" 
   37 #include "core/common/WLogger.h" 
   38 #include "core/common/WStringUtils.h" 
   39 #include "core/dataHandler/WDataSet.h" 
   40 #include "core/dataHandler/WDataSetDTI.h" 
   41 #include "core/dataHandler/WDataSetRawHARDI.h" 
   42 #include "core/dataHandler/WDataSetScalar.h" 
   43 #include "core/dataHandler/WDataSetVector.h" 
   44 #include "core/dataHandler/WGridRegular3D.h" 
   45 #include "core/dataHandler/exceptions/WDHIOFailure.h" 
   46 #include "core/dataHandler/exceptions/WDHNoSuchFile.h" 
   47 #include "core/dataHandler/exceptions/WDHParseError.h" 
   60     std::shared_ptr< WDataSet > ds;
 
   62     m_ifs = std::shared_ptr< std::ifstream >( 
new std::ifstream() );
 
   63     m_ifs->open( 
m_fname.c_str(), std::ifstream::in | std::ifstream::binary );
 
   66         throw WDHIOFailure( std::string( 
"internal error while opening" ) );
 
   75     std::shared_ptr< WGridRegular3D > grid;
 
   95     std::shared_ptr< WValueSetBase > values = 
readData( grid );
 
  107         ds = std::shared_ptr< WDataSet >( 
new WDataSetScalar( values, grid ) );
 
  110         ds = std::shared_ptr< WDataSet >( 
new WDataSetVector( values, grid ) );
 
  113         ds = std::shared_ptr< WDataSet >( 
new WDataSetDTI( values, grid ) );
 
  116         if( values->dimension() > 6 )
 
  118             std::shared_ptr< std::vector< WVector3d > > grads = 
readGradients();
 
  119             ds = std::shared_ptr< WDataSet >( 
new WDataSetRawHARDI( values, grid, grads ) );
 
  123             ds = std::shared_ptr< WDataSet >( 
new WDataSetDTI( values, grid ) );
 
  136     typedef std::vector< WVector3d > GradVec;
 
  138     std::string gradientFileName = 
m_fname;
 
  139     std::string suffix = getSuffix( 
m_fname );
 
  141     WAssert( suffix == 
".vtk", 
"Input file is not a vtk file." );
 
  143     WAssert( gradientFileName.length() > 4, 
"" );
 
  144     gradientFileName.resize( gradientFileName.length() - 4 );
 
  145     gradientFileName += 
".bvec";
 
  148     std::ifstream i( gradientFileName.c_str() );
 
  149     if( i.bad() || !i.is_open() )
 
  160         std::vector< double > values;
 
  165             values.push_back( d );
 
  169         if( values.size() % 3 != 0 )
 
  171             values.resize( values.size() / 3 );
 
  174         std::shared_ptr< GradVec > newGradients( 
new GradVec( values.size() / 3 ) );
 
  176         for( std::size_t j = 0; j < values.size() / 3; ++j )
 
  178             ( *newGradients )[ j ] = 
WVector3d( values[ 3 * j + 0 ], values[ 3 * j + 1 ], values[ 3 * j + 2 ] );
 
  183     return std::shared_ptr< GradVec >();
 
  188     for( 
int i = 0; i < 4; ++i )  
 
  194     if( ( 
m_header.at( 0 ) != 
"# vtk DataFile Version 3.0" )
 
  195             && ( 
m_header.at( 0 ) != 
"# vtk DataFile Version 2.0" ) )
 
  197         wlog::error( 
"WReaderVTK" ) << 
"Unsupported format version string in VTK file: " 
  205         wlog::warn( 
"WReaderVTK" ) << 
"Invalid header size of VTK file: " 
  207             << 
", max. 256 but got: " 
  211     if( ( su::toUpper( su::trim( 
m_header.at( 2 ) ) ) != 
"BINARY" )
 
  212             &&( su::toUpper( su::trim( 
m_header.at( 2 ) ) ) != 
"ASCII" ) )
 
  214         wlog::error( 
"WReaderVTK" ) << 
"VTK files in '" << 
m_header.at( 2 ) << 
"' format are not yet supported. Must be BINARY or ASCII";
 
  220     if( su::tokenize( 
m_header.at( 3 ) ).size() == 2 )
 
  222         if( su::toUpper( su::tokenize( 
m_header.at( 3 ) )[1] ) == 
"STRUCTURED_POINTS" )
 
  226         else if( su::toUpper( su::tokenize( 
m_header.at( 3 ) )[1] ) == 
"RECTILINEAR_GRID" )
 
  232             wlog::error( 
"WReaderVTK" ) << 
"Cannot read this VTK DATASET type: " << su::tokenize( 
m_header.back() )[1];
 
  238         wlog::error( 
"WReaderVTK" ) << 
"Cannot read this VTK DATASET type: " << su::tokenize( 
m_header.back() )[1];
 
  247     std::string line = 
getLine( 
"reading DIMENSIONS" );
 
  249     if( (  dimensions_line.size() != 4 ) && 
string_utils::toLower( dimensions_line.at( 0 ) ) != 
"dimensions" )
 
  251         throw WDHParseError( std::string( 
"invalid DIMENSIONS token: " + line + 
", expected DIMENSIONS." ) );
 
  254     size_t dimensions[ 3 ];
 
  255     dimensions[ 0 ] = getLexicalCast< size_t >( dimensions_line.at( 1 ), 
"" );
 
  256     dimensions[ 1 ] = getLexicalCast< size_t >( dimensions_line.at( 2 ), 
"" );
 
  257     dimensions[ 2 ] = getLexicalCast< size_t >( dimensions_line.at( 3 ), 
"" );
 
  259     line = 
getLine( 
"reading ORIGIN" );
 
  263         throw WDHParseError( std::string( 
"invalid ORIGIN token: " + line + 
", expected ORIGIN." ) );
 
  267     origin[ 0 ] = getLexicalCast< float >( origin_line.at( 1 ), 
"" );
 
  268     origin[ 1 ] = getLexicalCast< float >( origin_line.at( 2 ), 
"" );
 
  269     origin[ 2 ] = getLexicalCast< float >( origin_line.at( 3 ), 
"" );
 
  271     line = 
getLine( 
"reading SPACING" );
 
  275         throw WDHParseError( std::string( 
"invalid DIMENSIONS token: " + line + 
", expected DIMENSIONS." ) );
 
  278     double spacings[ 3 ];
 
  279     spacings[ 0 ] = getLexicalCast< float >( spacings_line.at( 1 ), 
"" );
 
  280     spacings[ 1 ] = getLexicalCast< float >( spacings_line.at( 2 ), 
"" );
 
  281     spacings[ 2 ] = getLexicalCast< float >( spacings_line.at( 3 ), 
"" );
 
  286     return std::shared_ptr< WGridRegular3D >( 
new WGridRegular3D( dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], transform ) );
 
  291     std::string line = 
getLine( 
"reading DIMENSIONS" );
 
  293     if( (  dimensions_line.size() != 4 ) && 
string_utils::toLower( dimensions_line.at( 0 ) ) != 
"dimensions" )
 
  295         throw WDHParseError( std::string( 
"invalid DIMENSIONS token: " + line + 
", expected DIMENSIONS." ) );
 
  298     size_t dimensions[ 3 ];
 
  299     dimensions[ 0 ] = getLexicalCast< size_t >( dimensions_line.at( 1 ), 
"" );
 
  300     dimensions[ 1 ] = getLexicalCast< size_t >( dimensions_line.at( 2 ), 
"" );
 
  301     dimensions[ 2 ] = getLexicalCast< size_t >( dimensions_line.at( 3 ), 
"" );
 
  303     std::vector< float > xcoords;
 
  304     readCoords( 
"X_COORDINATES", dimensions[ 0 ], xcoords );
 
  305     std::vector< float > ycoords;
 
  306     readCoords( 
"Y_COORDINATES", dimensions[ 1 ], ycoords );
 
  307     std::vector< float > zcoords;
 
  308     readCoords( 
"Z_COORDINATES", dimensions[ 2 ], zcoords );
 
  310     wlog::warn( 
"WReaderVTK" ) << 
"Assuming evenly spaced rectilinear grid! This may not adhere to the domain data in the file!";
 
  312     WGridTransformOrtho transform( xcoords.at( 1 ) - xcoords.at( 0 ), ycoords.at( 1 ) - ycoords.at( 0 ), zcoords.at( 1 ) - zcoords.at( 0 ) ); 
 
  313     return std::shared_ptr< WGridRegular3D >( 
new WGridRegular3D( dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], transform ) );
 
  318     std::string line = 
getLine( std::string( 
"reading " ) + name );
 
  322         throw WDHParseError( std::string( 
"invalid " ) + name + 
" token: " + line + 
", expected " + name + 
"!" );
 
  336         std::string line = 
getLine( 
"Data" );
 
  340         while( point < numValues )
 
  342             for( 
size_t token = 0; token < tokens.size(); ++token )
 
  344                 values.push_back( getLexicalCast< float >( tokens.at( token ), 
"invalid data point" ) );
 
  346                 if( point > numValues )
 
  348                     throw WDHException( std::string( 
"Too many points in file" ) );
 
  351             if( point < numValues )
 
  361         m_ifs->read( 
reinterpret_cast<char*
>(  &values[ 0 ] ), values.size() * 
sizeof( values[ 0 ] ) );
 
  370     std::size_t pos = 
m_ifs->tellg();
 
  372     std::string line = 
getLine( 
"LookupTableOrData" );
 
  376         pos = 
m_ifs->tellg(); 
 
  379     m_ifs->seekg( pos, std::ios::beg );
 
  381     std::shared_ptr< std::vector< float > > data( 
new std::vector< float >() );
 
  385     return std::shared_ptr< WValueSetBase >( 
new WValueSet< float >( 0, 1, data, W_DT_FLOAT ) );
 
  390     int pos = 
m_ifs->tellg(); 
 
  393     std::string line = 
getLine( 
"LookupTableOrData" );
 
  399         pos = 
m_ifs->tellg(); 
 
  402     m_ifs->seekg( pos, std::ios::beg );
 
  407     const size_t dimension = 3;
 
  408     std::shared_ptr< std::vector< float > > data( 
new std::vector< float >( nbPoints * dimension ) );
 
  412     return std::shared_ptr< WValueSetBase >( 
new WValueSet< float >( 1, 3, data, W_DT_FLOAT ) );
 
  420     int pos = 
m_ifs->tellg(); 
 
  423     std::string line = 
getLine( 
"LookupTableOrData" );
 
  427         pos = 
m_ifs->tellg(); 
 
  430     m_ifs->seekg( pos, std::ios::beg );
 
  432     std::size_t dimension = 9;
 
  438     std::shared_ptr< std::vector< float > > data( 
new std::vector< float >( nbPoints * dimension ) );
 
  445         for( std::size_t k = 0; k < data->size(); ++k )
 
  447             std::size_t m = k % 9;
 
  448             if( m != 3 && m != 6 && m != 7 )
 
  450                 ( *data )[ idx ] = ( *data )[ k ];
 
  454         data->resize( nbPoints * 6 );
 
  457     return std::shared_ptr< WValueSetBase >( 
new WValueSet< float >( 1, 6, data, W_DT_FLOAT ) );
 
  463 std::shared_ptr< WValueSetBase > 
WReaderVTK::readHARDI( std::size_t nbPoints, std::size_t nbGradients, 
const std::string&  )
 
  465     int pos = 
m_ifs->tellg(); 
 
  468     std::string line = 
getLine( 
"LookupTableOrData" );
 
  474         pos = 
m_ifs->tellg(); 
 
  477     m_ifs->seekg( pos, std::ios::beg );
 
  482     std::shared_ptr< std::vector< float > > data( 
new std::vector< float >( nbPoints * nbGradients ) );
 
  486     return std::shared_ptr< WValueSetBase >( 
new WValueSet< float >( 1, nbGradients, data, W_DT_FLOAT ) );
 
  495     std::string line = 
getLine( 
"POINT_DATA declaration" );
 
  500         throw WDHException( std::string( 
"Invalid SCALARS tag" ) );
 
  503     size_t nbPoints = getLexicalCast< size_t >( tokens.at( 1 ), 
"parsing number of points" );
 
  505     line = 
getLine( 
"SCALARS declaration" );
 
  508     std::string name = 
"Default";
 
  509     if( tokens.size() >= 2 )
 
  511         name = tokens.at( 1 );
 
  528     else if( tokens.size() == 4 && 
string_utils::toUpper( tokens.at( 0 ) ) == 
"ARRAYS" && tokens.at( 2 ) == 
"6" )
 
  533     else if( tokens.size() == 4 && 
string_utils::toUpper( tokens.at( 0 ) ) == 
"ARRAYS" && getLexicalCast< std::size_t >( tokens.at( 2 ), 
"" ) > 6 )
 
  536         std::size_t k = getLexicalCast< std::size_t >( tokens.at( 2 ), 
"" );
 
  541         throw WDHException( std::string( 
"Invalid SCALARS or VECTORS tag" ) );
 
  552         std::getline( *
m_ifs, line, 
'\n' );
 
  554     catch( 
const std::ios_base::failure &e )
 
  556         throw WDHIOFailure( std::string( 
"IO error while " + desc + 
" of VTK fiber file: " + 
m_fname + 
", " + e.what() ) );
 
General purpose exception and therefore base class for all DataHandler related exceptions.
 
Use this for IO error handling.
 
Use this for IO error handling.
 
Represents a Diffusion-Tensor-Image dataset.
 
This data set type contains raw HARDI and its gradients.
 
This data set type contains scalars as values.
 
This data set type contains vectors as values.
 
A grid that has parallelepiped cells which all have the same proportion.
 
std::shared_ptr< WValueSetBase > readVectors(size_t nbVectors, const std::string &name)
Read VTK SCALARS field.
 
std::shared_ptr< std::ifstream > m_ifs
Pointer to the input file stream reader.
 
WReaderVTK(std::string fname)
Constructs and makes a new VTK reader for separate thread start.
 
void readCoords(std::string const &name, std::size_t dim, std::vector< float > &coords)
Read the coordinates of the dataset's domain.
 
std::shared_ptr< WGridRegular3D > readStructuredPoints()
Read VTK Domain specification and create a matching grid.
 
bool readHeader()
Read VTK header from file.
 
std::shared_ptr< WValueSetBase > readTensors(size_t nbTensors, const std::string &name)
Read VTK TENSORS field.
 
@ RECTILINEAR_GRID
rectilinear grid
 
@ STRUCTURED_POINTS
structured points
 
std::shared_ptr< WGridRegular3D > readRectilinearGrid()
Read VTK Domain specification and create a matching grid.
 
void readValuesFromFile(std::vector< float > &values, std::size_t numValues)
Read values from the file.
 
AttributeType m_attributeType
The type of the attributes first read from the file.
 
bool m_isASCII
internal flag whether we read ascii or binary
 
std::shared_ptr< WValueSetBase > readHARDI(std::size_t nbPoints, std::size_t nbGradients, const std::string &)
Read HARDI data from the file.
 
std::shared_ptr< std::vector< WVector3d > > readGradients()
Read gradients from a gradients file which has the same basename as the data file and ends in ....
 
std::shared_ptr< WValueSetBase > readScalars(size_t nbScalars, const std::string &name)
Read VTK SCALARS field.
 
DomainType m_domainType
The type of domain specified in the file.
 
virtual std::shared_ptr< WDataSet > read()
Reads the data file and creates a dataset out of it.
 
virtual ~WReaderVTK()
Destroys this instance and closes the file.
 
std::shared_ptr< WValueSetBase > readData(std::shared_ptr< WGridRegular3D > const &grid)
Read domain information for structured points.
 
std::string getLine(const std::string &desc)
Reads the next line from current position in stream of the fiber VTK file.
 
std::vector< std::string > m_header
VTK header of the read file.
 
Read some data from a given file.
 
std::string m_fname
Absolute path of the file to read from.
 
Base Class for all value set types.
 
Some utilities for string manipulation and output operations.
 
std::string toLower(const std::string &source)
Transforms all characters in the given string into lower case characters.
 
std::string toUpper(const std::string &source)
Transforms all characters in the given string into upper case characters.
 
std::vector< std::string > tokenize(const std::string &source, const std::string &delim=WHITESPACE, bool compress=true)
Splits the given string into a vector of strings (so called tokens).
 
WStreamedLogger debug(const std::string &source)
Logging a debug message.
 
WStreamedLogger warn(const std::string &source)
Logging a warning message.
 
WStreamedLogger error(const std::string &source)
Logging an error message.