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,
70 std::string name = removeExtension( _name );
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 );
144 data.setSizeXYZT( vs[0], vs[1] , vs[2], vs[3] );
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 ) )
196 stom.
matrix()(1, 3) = data.dimY() - 1;
197 stom.
matrix()(2, 3) = data.dimZ() - 1;
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 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 );
261 short( rint( fabs( df[1] ) ) ),
262 short( rint( fabs( df[2] ) ) ), (
short) data.
dimT() );
263 int x, dx = tdims[0];
264 std::vector<T> buffer( dx );
266 for (
int z=0;z<tdims[2];++z)
267 for (
int y=0;y<tdims[1];++y)
270 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
271 int16_t( rint( d0f[2] ) ), t );
272 if( inc ==
Point4d( 1, 0, 0, 0 ) )
273 ir->
read( is, &data( d0 ), dx );
276 ir->
read( is, &buffer[0], dx );
277 for ( x=0; x<dx; ++x, d0+=inc )
278 data( d0 ) = buffer[ x ];
285 template <
typename T>
template<
typename U>
291 float scaleFactor = 1;
292 bool scaleFactorApplied =
false;
295 hdr->
getProperty(
"scale_factor_applied", scaleFactorApplied );
296 if ( scaleFactorApplied || scaleFactor == 0. )
301 = itemR.
reader(
"binar", bswap );
306 int16_t( rint( incf[1] ) ),
307 int16_t( rint( incf[2] ) ), 0 );
315 short( rint( fabs( df[1] ) ) ),
316 short( rint( fabs( df[2] ) ) ), data.
dimT() );
317 int x, dx = tdims[0];
318 std::vector<U> buffer( dx );
320 for (
int z=0;z<tdims[2];++z)
321 for (
int y=0;y<tdims[1];++y)
324 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
325 int16_t( rint( d0f[2] ) ), t );
326 ir->
read( is, &buffer[0] , dx );
327 for ( x=0; x<dx; ++x, d0+=inc )
328 data( d0 ) = (T) ( scaleFactor * buffer[ x ] );
337 int t,
const std::string & type,
342 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
343 else if ( type ==
"U8")
344 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
345 else if ( type ==
"S16" )
346 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
347 else if ( type ==
"U16" )
348 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
349 else if ( type ==
"S32" )
350 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
351 else if ( type ==
"U32" )
352 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
353 else if ( type ==
"FLOAT" )
354 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
355 else if ( type ==
"DOUBLE" )
356 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
358 std::cerr <<
"SPM read not implemented: " << type <<
" as FLOAT" 364 int t,
const std::string & type,
369 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
370 else if ( type ==
"U8")
371 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
372 else if ( type ==
"S16" )
373 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
374 else if ( type ==
"U16" )
375 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
376 else if ( type ==
"S32" )
377 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
378 else if ( type ==
"U32" )
379 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
380 else if ( type ==
"FLOAT" )
381 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
382 else if ( type ==
"DOUBLE" )
383 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
385 std::cerr <<
"SPM read not implemented: " << type <<
" as DOUBLE"
virtual void read(std::istream &is, T &item) const
virtual bool getProperty(const std::string &, Object &) const
static std::string basename(const std::string &)
The class for EcatSino data write operation.
Default low-levels readers.
virtual bool removeProperty(const std::string &)
void setHeader(aims::Header *hdr)
static void launchErrnoExcept(const std::string &filename="")
aims::AffineTransformation3d Motion
static std::string dirname(const std::string &)
void read(AimsData< T > &thing, const carto::AllocatorContext &context, carto::Object options)
Read the data with "name" file name from disk.
The template class for SPM read operation.
virtual void setProperty(const std::string &, Object)
virtual ItemReader< T > * reader(const std::string &openmode="binar", bool bswap=false) const
std::string removeExtension(const std::string &name)
Return a name without .hdr or .img extension.
Low-level "small item" reader, used by higher-level file readers.