45#include <cartobase/exception/ioexcept.h>
46#include <cartobase/stream/fileutil.h>
55 std::string res = name;
57 if ( res.length() > 4 )
58 ext = res.substr( res.length() - 4, 4 );
59 if (ext ==
".hdr" || ext ==
".img")
60 res = res.substr( 0, res.length() - 4 );
67 const carto::AllocatorContext & context,
78 catch( std::exception & e )
88 hdr->
setProperty(
"bits_allocated", (
int)
sizeof( T ) );
90 std::vector<int> dims;
91 std::vector<float> vs;
92 if( ! hdr->
getProperty(
"volume_dimension", dims ) )
93 throw std::logic_error(
"Internal error: getProperty volume_dimension failed" );
95 throw std::logic_error(
"Internal error: getProperty voxel_size failed" );
97 int frame = -1, border = 0;
98 options->getProperty(
"frame", frame );
99 options->getProperty(
"border", border );
101 int dimt = 1, tmin = 0;
104 if ( frame >= dims[3] )
106 throw std::domain_error(
"Frame number exceeds "
107 "volume time dimension" );
117 std::string filename = name +
".img";
120 std::vector<carto::Object> fnames;
122 if ( tmin > 0 || dimt > 1 )
124 series = hdr->
getProperty(
"series_filenames", fnames );
127 if ( fnames.size() < (
unsigned) ( dimt + tmin ) )
128 throw std::domain_error(
"SPM reader: not enough filenames for "
136 carto::AllocatorContext al
137 ( context.accessMode(),
139 (
new carto::FileDataSource( filename, 0, carto::DataSource::Read ) ),
140 false, context.useFactor() );
143 AimsData<T> data( dims[0], dims[1], dims[2], dimt, border, al );
149 is.open( filename.c_str(), std::ios::in | std::ios::binary );
154 is.unsetf( std::ios::skipws );
156 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
157 * data.
dimX() *
sizeof( int8_t ), std::ios::cur );
158 else if (
type ==
"U8")
159 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
160 * data.
dimX() *
sizeof( uint8_t ), std::ios::cur );
161 else if (
type ==
"S16" )
162 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
163 * data.
dimX() *
sizeof( int16_t ), std::ios::cur );
164 else if (
type ==
"U16" )
165 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
166 * data.
dimX() *
sizeof( uint16_t ), std::ios::cur );
167 else if (
type ==
"S32" )
168 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
169 * data.
dimX() *
sizeof( int32_t ), std::ios::cur );
170 else if (
type ==
"U32" )
171 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
172 * data.
dimX() *
sizeof( uint32_t ), std::ios::cur );
173 else if (
type ==
"FLOAT" )
174 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
175 * data.
dimX() *
sizeof(
float ), std::ios::cur );
176 else if (
type ==
"DOUBLE" )
177 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
178 * data.
dimX() *
sizeof(
double ), std::ios::cur );
180 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
181 * data.
dimX() *
sizeof( T ), std::ios::cur );
184 std::vector<T> buffer ( dims[0] );
187 std::vector<float> vstom;
189 if( hdr->
getProperty(
"storage_to_memory", vstom ) )
201 radio = (bool) hdr->
getProperty(
"spm_radio_convention" )->getScalar();
203 catch( std::exception & )
213 for (
int t=0; t<dimt; ++t )
219 is.open( ( fnm ).c_str(), std::ios::in | std::ios::binary );
224 is.unsetf( std::ios::skipws );
226 hdr->
setProperty(
"scale_factor_applied",
false ) ;
227 readFrame( is, data, t,
type, hdr, bswap, stom );
240 template<
typename T>
void
241 SpmReader<T>::readFrame( std::ifstream & is,
AimsData<T> & data,
int t,
242 const std::string &,
SpmHeader*,
bool bswap,
247 = itemR.
reader(
"binar", bswap );
252 int16_t( rint( incf[1] ) ),
253 int16_t( rint( incf[2] ) ), 0 );
256 std::unique_ptr<AffineTransformation3d> m2s = stom.
inverse();
260 short( rint( fabs( df[1] ) ) ),
261 short( rint( fabs( df[2] ) ) ), (
short) data.
dimT() );
262 int x, dx = tdims[0];
263 std::vector<T> buffer( dx );
265 for (
int z=0;z<tdims[2];++z)
266 for (
int y=0;y<tdims[1];++y)
269 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
270 int16_t( rint( d0f[2] ) ), t );
271 if( inc ==
Point4d( 1, 0, 0, 0 ) )
272 ir->
read( is, &data( d0 ), dx );
275 ir->
read( is, &buffer[0], dx );
276 for ( x=0; x<dx; ++x, d0+=inc )
277 data( d0 ) = buffer[ x ];
284 template <
typename T>
template<
typename U>
286 SpmReader<T>::readScaledFrame( std::ifstream & is, AimsData<T>& data,
290 float scaleFactor = 1;
291 bool scaleFactorApplied =
false;
293 hdr->getProperty(
"scale_factor", scaleFactor );
294 hdr->getProperty(
"scale_factor_applied", scaleFactorApplied );
295 if ( scaleFactorApplied || scaleFactor == 0. )
300 = itemR.
reader(
"binar", bswap );
303 - stom.transform(
Point3df( 0, 0, 0 ) );
305 int16_t( rint( incf[1] ) ),
306 int16_t( rint( incf[2] ) ), 0 );
309 std::unique_ptr<AffineTransformation3d> m2s = stom.inverse();
313 short( rint( fabs( df[1] ) ) ),
314 short( rint( fabs( df[2] ) ) ), data.
dimT() );
315 int x, dx = tdims[0];
316 std::vector<U> buffer( dx );
318 for (
int z=0;z<tdims[2];++z)
319 for (
int y=0;y<tdims[1];++y)
321 d0f = stom.transform(
Point3df( 0, y, z ) );
322 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
323 int16_t( rint( d0f[2] ) ), t );
324 ir->read( is, &buffer[0] , dx );
325 for ( x=0; x<dx; ++x, d0+=inc )
326 data( d0 ) = (T) ( scaleFactor * buffer[ x ] );
329 hdr->setProperty(
"scale_factor_applied",
true ) ;
334 SpmReader<float>::readFrame( std::ifstream & is, AimsData<float> & data,
335 int t,
const std::string & type,
340 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
341 else if ( type ==
"U8")
342 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
343 else if ( type ==
"S16" )
344 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
345 else if ( type ==
"U16" )
346 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
347 else if ( type ==
"S32" )
348 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
349 else if ( type ==
"U32" )
350 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
351 else if ( type ==
"FLOAT" )
352 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
353 else if ( type ==
"DOUBLE" )
354 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
356 std::cerr <<
"SPM read not implemented: " << type <<
" as FLOAT"
361 SpmReader<double>::readFrame( std::ifstream & is, AimsData<double>& data,
362 int t,
const std::string & type,
367 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
368 else if ( type ==
"U8")
369 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
370 else if ( type ==
"S16" )
371 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
372 else if ( type ==
"U16" )
373 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
374 else if ( type ==
"S32" )
375 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
376 else if ( type ==
"U32" )
377 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
378 else if ( type ==
"FLOAT" )
379 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
380 else if ( type ==
"DOUBLE" )
381 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
383 std::cerr <<
"SPM read not implemented: " << type <<
" as DOUBLE"
void setHeader(aims::Header *hdr)
void setSizeXYZT(float sizex=1.0f, float sizey=1.0f, float sizez=1.0f, float sizet=1.0f)
Default low-levels readers.
virtual ItemReader< T > * reader(const std::string &openmode="binar", bool bswap=false) const
Low-level "small item" reader, used by higher-level file readers.
virtual void read(std::istream &is, T &item) const
virtual ItemReader< T > * reader(const std::string &openmode="binar", bool bswap=false) const =0
void read(AimsData< T > &thing, const carto::AllocatorContext &context, carto::Object options)
Read the data with "name" file name from disk.
std::string removeExtension(const std::string &name)
Return a name without .hdr or .img extension.
static std::string dirname(const std::string &)
static std::string basename(const std::string &)
virtual bool getProperty(const std::string &, Object &) const
virtual bool removeProperty(const std::string &)
virtual void setProperty(const std::string &, Object)
static void launchErrnoExcept(const std::string &filename="")
The class for EcatSino data write operation.
AimsVector< float, 3 > Point3df
AimsVector< int16_t, 4 > Point4d