aimsdata 6.0.0
Neuroimaging data handling
fdfR.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34/*
35 * FDF data reader class
36 */
37#ifndef AIMS_IO_FDFR_H
38#define AIMS_IO_FDFR_H
39
41#include <aims/data/data.h>
42#include <aims/io/fdfheader.h>
44#include <cartobase/exception/file.h>
45#include <cartobase/exception/format.h>
46#include <cartobase/stream/fileutil.h>
47#include <cartobase/type/byte_order.h>
49#include <stdio.h>
50
51namespace aims
52{
53 template< class T > class FdfReader;
54
55 template< class T > AIMSDATA_API FdfReader< T >&
56 operator >> ( FdfReader< T >&, AimsData< T >& );
57
58 template< class T >
60 {
61 public:
62
63 FdfReader( const std::string& name )
64 : _name( name ) { }
65 virtual ~FdfReader() { }
66
67 void read( AimsData< T >&, const carto::AllocatorContext & context,
68 carto::Object options );
69
70 private:
71
72 std::string _name;
73
74 void readFrame( AimsData< T >& thing, const std::string & file,
75 uint slice, const aims::FdfHeader *hdr );
76 };
77
78
79
80 template< class T > inline
81 FdfReader< T >&
83 {
84 reader.read( thing, thing.allocator(),
86 return reader;
87 }
88
89 template< class T > inline
91 const carto::AllocatorContext & context,
92 carto::Object options )
93 {
94 int borderWidth = 0;
95 options->getProperty( "border", borderWidth );
96
97 // Load the header of the first file
98 std::unique_ptr<aims::FdfHeader> hdr
99 = std::unique_ptr<aims::FdfHeader>( new aims::FdfHeader( _name ) );
100 hdr->read();
101
102 int rank = (int)hdr->getProperty( "rank" )->getScalar();
103
104 // check if data type is compatible with type T
105 int bits_allocated = (int)hdr->getProperty( "bits_allocated" )->getScalar();
106 if ( ( bits_allocated / 8 ) > (int)sizeof( T ) )
107 {
108 throw carto::format_error( _name );
109 }
110
111 std::string dir = carto::FileUtil::dirname( _name );
112 std::vector<std::string> files;
113
114 if ( rank == 2 ) {
115 files = hdr->inputFilenames();
116 }
117 else {
118 files.push_back( carto::FileUtil::basename( _name ) );
119 }
120
121 // create an AimsData
122 carto::AllocatorContext
123 cont( context.accessMode(),
125 ( new carto::FileDataSource
126 ( _name, 0, carto::DataSource::Read ) ), false,
127 context.useFactor() );
128
129 AimsData< T > data( hdr->dimX(), hdr->dimY(), hdr->dimZ(), hdr->dimT(),
130 borderWidth, cont );
131 data.setSizeXYZT( hdr->sizeX(), hdr->sizeY(), hdr->sizeZ(), hdr->sizeT() );
132
133 // Read frames
134 for( uint slice=0; slice < files.size(); slice++ ) {
135 if ( ! carto::FileUtil::fileStat( dir + carto::FileUtil::separator() + files[slice] ).empty() ) {
136 readFrame( data, dir + carto::FileUtil::separator() + files[slice], slice, hdr.get() );
137 }
138 }
139
140 thing = data;
141 thing.setHeader( hdr.release() );
142 }
143
144 template< class T > inline
145 void FdfReader< T >::readFrame( AimsData< T >& thing,
146 const std::string & filename, uint slice,
147 const aims::FdfHeader *hdr )
148 {
149 std::vector< int > dims;
150 hdr->getProperty( "volume_dimension", dims );
151 int bits_allocated = (int)hdr->getProperty( "bits_allocated" )->getScalar();
152 int byte_swapping = (int)hdr->getProperty( "byte_swapping" )->getScalar();
153 int rank = (int)hdr->getProperty( "rank" )->getScalar();
154// uint byte_order;
155// if (byte_swapping) {
156// byte_order = stringToByteOrder( "DCBA" );
157// }
158// else {
159// byte_order = stringToByteOrder( "ABCD" );
160// }
161
162 uint pixels_number = 1;
163
164 for( int dim = 0; dim < rank; dim++ )
165 {
166 pixels_number *= dims[ dim ];
167 }
168
169 std::ifstream inFile(filename.c_str(), std::ios::in | std::ios::binary);
170
171 // Check if there was an error opening the file
172 if (!inFile)
173 {
174 throw carto::open_error( "No image data found in file.", filename );
175 }
176
177 // Get data position
178 int zstart = 0, zend = thing.dimZ();
179 inFile.seekg (0, std::ios::end);
180 long int fileSize = inFile.tellg();
181 size_t dataPosition = fileSize - (pixels_number * ( bits_allocated / 8 ) );
182 inFile.seekg( dataPosition );
183
185 ItemReader<T> *ir
186 = itemr.reader( "binar",
187 byte_swapping );
188
189 if ((rank == 2) && (dims.size() > 2) && (dims[2] > 1)) {
190 zstart = slice;
191 zend = slice + 1;
192 }
193
194 for( int t=0; t < thing.dimT(); ++t )
195 for( int z=zstart; z < zend; ++z ) {
196 for( int y=0; y < thing.dimY(); ++y )
197 {
198 ir->read( inFile, &thing(0, y, z, t), thing.dimX() );
199 if( !inFile || inFile.eof() ) {
201 }
202 }
203 }
204
205 bool success = !inFile.bad();
206 inFile.close();
207
208 if (!success)
209 {
210 throw carto::open_error( "Error reading data.", filename );
211 }
212 }
213}
214
215#endif
#define AIMSDATA_API
const carto::AllocatorContext & allocator() const
void setHeader(aims::Header *hdr)
void setSizeXYZT(float sizex=1.0f, float sizey=1.0f, float sizez=1.0f, float sizet=1.0f)
int dimY() const
int dimX() const
int dimT() const
int dimZ() const
Default low-levels readers.
FdfReader(const std::string &name)
Definition fdfR.h:63
virtual ~FdfReader()
Definition fdfR.h:65
void read(AimsData< T > &, const carto::AllocatorContext &context, carto::Object options)
Definition fdfR.h:90
Low-level "small item" reader, used by higher-level file readers.
Definition itemR.h:99
virtual ItemReader< T > * reader(const std::string &openmode="binar", bool bswap=false) const =0
static char separator()
static std::string dirname(const std::string &)
static std::string fileStat(const std::string &)
static std::string basename(const std::string &)
Object value(const Object &value)
virtual bool getProperty(const std::string &, Object &) const
static void launchErrnoExcept(const std::string &filename="")
The class for EcatSino data write operation.
GenesisReader< T > & operator>>(GenesisReader< T > &reader, AimsData< T > &thing)
Definition genesisR.h:70
unsigned int uint