56 std::string res = name;
58 if ( res.length() > 4 )
59 ext = res.substr( res.length() - 4, 4 );
60 if (ext ==
".hdr" || ext ==
".img")
61 res = res.substr( 0, res.length() - 4 );
68 const carto::AllocatorContext & context,
71 std::string name = removeExtension( _name );
79 catch( std::exception & e )
89 hdr->
setProperty(
"bits_allocated", (
int)
sizeof( T ) );
91 std::vector<int> dims;
92 std::vector<float> vs;
93 if( ! hdr->
getProperty(
"volume_dimension", dims ) )
94 throw std::logic_error(
"Internal error: getProperty volume_dimension failed" );
96 throw std::logic_error(
"Internal error: getProperty voxel_size failed" );
98 int frame = -1, border = 0;
99 options->getProperty(
"frame", frame );
100 options->getProperty(
"border", border );
102 int dimt = 1, tmin = 0;
105 if ( frame >= dims[3] )
107 throw std::domain_error(
"Frame number exceeds "
108 "volume time dimension" );
118 std::string filename = name +
".img";
121 std::vector<carto::Object> fnames;
123 if ( tmin > 0 || dimt > 1 )
125 series = hdr->
getProperty(
"series_filenames", fnames );
128 if ( fnames.size() < (
unsigned) ( dimt + tmin ) )
129 throw std::domain_error(
"SPM reader: not enough filenames for "
137 carto::AllocatorContext al
138 ( context.accessMode(),
140 (
new carto::FileDataSource( filename, 0, carto::DataSource::Read ) ),
141 false, context.useFactor() );
144 AimsData<T> data( dims[0], dims[1], dims[2], dimt, border, al );
150 is.open( filename.c_str(), std::ios::in | std::ios::binary );
155 is.unsetf( std::ios::skipws );
157 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
158 * data.
dimX() *
sizeof( int8_t ), std::ios::cur );
159 else if ( type ==
"U8")
160 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
161 * data.
dimX() *
sizeof( uint8_t ), std::ios::cur );
162 else if ( type ==
"S16" )
163 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
164 * data.
dimX() *
sizeof( int16_t ), std::ios::cur );
165 else if ( type ==
"U16" )
166 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
167 * data.
dimX() *
sizeof( uint16_t ), std::ios::cur );
168 else if ( type ==
"S32" )
169 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
170 * data.
dimX() *
sizeof( int32_t ), std::ios::cur );
171 else if ( type ==
"U32" )
172 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
173 * data.
dimX() *
sizeof( uint32_t ), std::ios::cur );
174 else if ( type ==
"FLOAT" )
175 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
176 * data.
dimX() *
sizeof(
float ), std::ios::cur );
177 else if ( type ==
"DOUBLE" )
178 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
179 * data.
dimX() *
sizeof(
double ), std::ios::cur );
181 is.seekg( (std::ifstream::pos_type) tmin * data.
dimZ() * data.
dimY()
182 * data.
dimX() *
sizeof( T ), std::ios::cur );
185 std::vector<T> buffer ( dims[0] );
188 std::vector<float> vstom;
190 if( hdr->
getProperty(
"storage_to_memory", vstom ) )
202 radio = (bool) hdr->
getProperty(
"spm_radio_convention" )->getScalar();
204 catch( std::exception & )
214 for (
int t=0; t<dimt; ++t )
220 is.open( ( fnm ).c_str(), std::ios::in | std::ios::binary );
225 is.unsetf( std::ios::skipws );
227 hdr->
setProperty(
"scale_factor_applied",
false ) ;
228 readFrame( is, data, t, type, hdr, bswap, stom );
241 template<
typename T>
void
243 const std::string &,
SpmHeader*,
bool bswap,
248 = itemR.
reader(
"binar", bswap );
253 int16_t( rint( incf[1] ) ),
254 int16_t( rint( incf[2] ) ), 0 );
262 short( rint( fabs( df[1] ) ) ),
263 short( rint( fabs( df[2] ) ) ), (
short) data.
dimT() );
264 int x, dx = tdims[0];
265 std::vector<T> buffer( dx );
267 for (
int z=0;z<tdims[2];++z)
268 for (
int y=0;y<tdims[1];++y)
271 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
272 int16_t( rint( d0f[2] ) ), t );
273 if( inc ==
Point4d( 1, 0, 0, 0 ) )
274 ir->
read( is, &data( d0 ), dx );
277 ir->
read( is, &buffer[0], dx );
278 for ( x=0; x<dx; ++x, d0+=inc )
279 data( d0 ) = buffer[ x ];
286 template <
typename T>
template<
typename U>
288 SpmReader<T>::readScaledFrame( std::ifstream & is,
AimsData<T>& data,
289 int t, SpmHeader *hdr,
bool bswap,
290 const AffineTransformation3d & stom )
292 float scaleFactor = 1;
293 bool scaleFactorApplied =
false;
295 hdr->getProperty(
"scale_factor", scaleFactor );
296 hdr->getProperty(
"scale_factor_applied", scaleFactorApplied );
297 if ( scaleFactorApplied || scaleFactor == 0. )
300 DefaultItemReader<U> itemR ;
302 = itemR.
reader(
"binar", bswap );
305 - stom.transform(
Point3df( 0, 0, 0 ) );
307 int16_t( rint( incf[1] ) ),
308 int16_t( rint( incf[2] ) ), 0 );
311 AffineTransformation3d m2s = stom.
inverse();
314 - m2s.transform(
Point3df( 0, 0, 0 ) );
316 short( rint( fabs( df[1] ) ) ),
317 short( rint( fabs( df[2] ) ) ), data.
dimT() );
318 int x, dx = tdims[0];
319 std::vector<U> buffer( dx );
321 for (
int z=0;z<tdims[2];++z)
322 for (
int y=0;y<tdims[1];++y)
324 d0f = stom.transform(
Point3df( 0, y, z ) );
325 d0 =
Point4d( int16_t( rint( d0f[0] ) ), int16_t( rint( d0f[1] ) ),
326 int16_t( rint( d0f[2] ) ), t );
327 ir->read( is, &buffer[0] , dx );
328 for ( x=0; x<dx; ++x, d0+=inc )
329 data( d0 ) = (T) ( scaleFactor * buffer[ x ] );
332 hdr->setProperty(
"scale_factor_applied",
true ) ;
337 SpmReader<float>::readFrame( std::ifstream & is,
AimsData<float> & data,
338 int t,
const std::string & type,
339 SpmHeader* hdr,
bool bswap,
340 const AffineTransformation3d & stom )
343 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
344 else if ( type ==
"U8")
345 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
346 else if ( type ==
"S16" )
347 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
348 else if ( type ==
"U16" )
349 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
350 else if ( type ==
"S32" )
351 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
352 else if ( type ==
"U32" )
353 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
354 else if ( type ==
"FLOAT" )
355 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
356 else if ( type ==
"DOUBLE" )
357 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
359 std::cerr <<
"SPM read not implemented: " << type <<
" as FLOAT"
365 int t,
const std::string & type,
366 SpmHeader* hdr,
bool bswap,
367 const AffineTransformation3d & stom )
370 readScaledFrame<int8_t>( is, data, t, hdr, bswap, stom );
371 else if ( type ==
"U8")
372 readScaledFrame<uint8_t>( is, data, t, hdr, bswap, stom );
373 else if ( type ==
"S16" )
374 readScaledFrame<int16_t>( is, data, t, hdr, bswap, stom );
375 else if ( type ==
"U16" )
376 readScaledFrame<uint16_t>( is, data, t, hdr, bswap, stom );
377 else if ( type ==
"S32" )
378 readScaledFrame<int32_t>( is, data, t, hdr, bswap, stom );
379 else if ( type ==
"U32" )
380 readScaledFrame<uint32_t>( is, data, t, hdr, bswap, stom );
381 else if ( type ==
"FLOAT" )
382 readScaledFrame<float>( is, data, t, hdr, bswap, stom );
383 else if ( type ==
"DOUBLE" )
384 readScaledFrame<double>( is, data, t, hdr, bswap, stom );
386 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
The template class for SPM read operation.
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.