newimage
 
Loading...
Searching...
No Matches
newimageio.h
1/* General IO functions (images and transformation files)
2
3 Mark Jenkinson and Matthew Webster, FMRIB Image Analysis Group
4
5 Copyright (C) 2000-2012 University of Oxford */
6
7/* CCOPYRIGHT */
8
9
10#if !defined(__newimageio_h)
11#define __newimageio_h
12
13#include <string>
14#include <cstdlib>
15#include <iostream>
16#include <fstream>
17#include <sstream>
18#include "NewNifti/NewNifti.h"
19#include "armawrap/newmatio.h"
20#include "miscmaths/miscmaths.h"
21#include "newimage.h"
22#include "complexvolume.h"
23
24namespace NEWIMAGE {
25
26bool FslIsSingleFileType(int filetype);
27int FslNiftiVersionFileType(int filetype);
28int FslFiletypeFromHeader(const NiftiIO::NiftiHeader& header);
29int fslFileType(std::string filename);
30int FslGetEnvOutputType(void);
31std::string outputExtension(const int filetype);
32
33bool FslFileExists(const std::string& filename);
34bool FslImageExists(const std::string& filename);
35inline bool fsl_imageexists(const std::string& filename) { return FslImageExists(filename); }
36bool FslIsCompressedFileType(int filetype);
37std::string return_validimagefilename(const std::string& filename, const bool quiet=false, const bool strict=false);
38std::string make_basename(std::string& filename);
39std::string make_basename(const std::string& filename);
40std::string appendFSLfilename(const std::string inputName, const std::string addendum);
41int find_pathname(std::string& filename);
42int fslFileType(std::string filename);
43template <class T>
44void ConvertAndScaleNewNiftiBuffer(char* buffer, T*& tbuffer, const NiftiIO::NiftiHeader& niihdr, const size_t & imagesize);
45 // read
46template <class T>
47int read_volume(volume<T>& target, const std::string& filename, const bool& legacyRead=true);
48template <class T>
49int read_volumeROI(volume<T>& target, const std::string& filename,
50 int64_t x0, int64_t y0, int64_t z0, int64_t x1, int64_t y1, int64_t z1);
51template <class T>
52int read_volumeROI(volume<T>& target, const std::string& filename,
53 int64_t x0, int64_t y0, int64_t z0, int64_t x1, int64_t y1, int64_t z1,
54 int64_t xskip, int64_t yskip, int64_t zskip);
55template <class T>
56int read_volumeROI(volume<T>& target, const std::string& filename,
57 int64_t x0, int64_t y0, int64_t z0, int64_t t0,
58 int64_t x1, int64_t y1, int64_t z1, int64_t t1);
59
60template <class T>
61int read_volumeROI(volume<T>& target, const std::string& filename, short& dtype,
62 int64_t x0, int64_t y0, int64_t z0, int64_t t0,
63 int64_t x1, int64_t y1, int64_t z1, int64_t t1,
64 const bool swap2radiological, const bool readAs4D=false) {
65 return readGeneralVolume(target,filename,dtype,swap2radiological,x0,y0,z0,t0,-1L,-1L,-1L,x1,y1,z1,t1,-1L,-1L,-1L,readAs4D);
66 }
67
68template <class T>
69int read_volumeROI(volume<T>& target, const std::string& filename,
70 int64_t x0, int64_t y0, int64_t z0, int64_t t0,
71 int64_t x1, int64_t y1, int64_t z1, int64_t t1,
72 const int64_t xskip, int64_t yskip, int64_t zskip, int64_t tskip);
73
74int read_complexvolume(volume<float>& realvols, volume<float>& imagvols,
75 const std::string& filename, bool read_img_data=true);
76int read_complexvolume(complexvolume& vol, const std::string& filename);
77
78template <class T>
79void set_volume_properties(const NiftiIO::NiftiHeader& niihdr, volume<T>& target);
80
81
82template <class T>
83int read_volume_hdr_only(volume<T>& target, const std::string& filename)
84{
85 int64_t nthreads = target.nthreads();
86 target.destroy();
87 NiftiIO::NiftiHeader niihdr;
88 try {
89 niihdr = NiftiIO::loadHeader(return_validimagefilename(filename));
90 } catch ( std::exception& e ) { imthrow("Failed to read volume "+filename+"\nError : "+e.what(),22); }
91 for (int n=1; n<=7; n++) {
92 if (niihdr.dim[n]<1) niihdr.dim[n]=1; // make it robust to dim[n]=0
93 }
94 T* tbuffer=new T[1];
95 target.initialize(niihdr.dim[1],niihdr.dim[2],niihdr.dim[3],niihdr.dim[4],niihdr.dim[5],niihdr.dim[6],niihdr.dim[7],tbuffer,true,nthreads);
96 set_volume_properties(niihdr,target);
97 if (!target.RadiologicalFile) target.makeradiological(true);
98 return 0;
99 }
100
101template <class T>
102int read_volume4D_hdr_only(volume<T>& target, const std::string& filename) {
103 return read_volume_hdr_only(target,filename);
104}
105
106
107 // save
108
109template <class T>
110int save_volume(const volume<T>& source, const std::string& filename, const int filetype=-1);
111
112int save_complexvolume(const volume<float>& realvol,
113 const volume<float>& imagvol, const std::string& filename);
114int save_complexvolume(const complexvolume& vol, const std::string& filename);
115
116
117
118
119
120// Helper functions
121short closestTemplatedType(const short inputType);
122
123int read_volume_size(const std::string& filename,
124 int64_t& sx, int64_t& sy, int64_t& sz, int64_t& st, int64_t& s5, int64_t& s6, int64_t& s7);
125
126short dtype(const char* T);
127short dtype(const short* T);
128short dtype(const int* T);
129short dtype(const float* T);
130short dtype(const double* T);
131
132short dtype(const volume<char>& vol);
133short dtype(const volume<short>& vol);
134short dtype(const volume<int>& vol);
135short dtype(const volume<float>& vol);
136short dtype(const volume<double>& vol);
137
138short dtype(const std::string& filename);
139
140// Boring overloads to enable different names (load and write)
141
142
143// load
144
145template <class T>
146int load_volume(volume<T>& target, const std::string& filename);
147
148// write
149
150template <class T>
151int write_volume(const volume<T>& source, const std::string& filename);
152
153
157
158
159// External functions
160
161// READ FUNCTIONS
162
163
164template <class T>
165int read_volumeROI(volume<T>& target, const std::string& filename,
166 int64_t x0, int64_t y0, int64_t z0, int64_t x1, int64_t y1, int64_t z1,
167 int64_t xskip, int64_t yskip, int64_t zskip)
168{
169 int retval=read_volumeROI(target,filename,x0,y0,z0,x1,y1,z1);
170 if (retval==0) {
171 if (xskip<1) xskip=1;
172 if (yskip<1) yskip=1;
173 if (zskip<1) zskip=1;
174 int64_t sx=(target.maxx()-target.minx())/xskip + 1;
175 int64_t sy=(target.maxy()-target.miny())/yskip + 1;
176 int64_t sz=(target.maxz()-target.minz())/zskip + 1;
177 volume<T> tmpvol(sx,sy,sz);
178 int64_t xx=0, yy=0, zz=0, x=0, y=0, z=0;
179 for (z=target.minz(), zz=0; z<=target.maxz(); z+=zskip, zz++) {
180 for (y=target.miny(), yy=0; y<=target.maxy(); y+=yskip, yy++) {
181 for (x=target.minx(), xx=0; x<=target.maxx(); x+=xskip, xx++) {
182 tmpvol(xx,yy,zz) = target(x,y,z);
183 }
184 }
185 }
186 tmpvol.copyproperties(target);
187 target = tmpvol;
188 }
189 return retval;
190}
191
192
193
194
195
196
197template <class T>
198int read_volumeROI(volume<T>& target, const std::string& filename,
199 int64_t x0, int64_t y0, int64_t z0,
200 int64_t x1, int64_t y1, int64_t z1)
201{
202 short dtype;
203 return read_volumeROI(target,filename,dtype,
204 x0,y0,z0,0,x1,y1,z1,0);
205}
206
207
208template <class T>
209int read_volumeROI(volume<T>& target, const std::string& filename,
210 int64_t x0, int64_t y0, int64_t z0, int64_t t0,
211 int64_t x1, int64_t y1, int64_t z1, int64_t t1,
212 int64_t xskip, int64_t yskip, int64_t zskip, int64_t tskip)
213{
214 read_volumeROI(target,filename,x0,y0,z0,t0,x1,y1,z1,t1);
215 if (xskip<1) xskip=1;
216 if (yskip<1) yskip=1;
217 if (zskip<1) zskip=1;
218 if (tskip<1) tskip=1;
219 int64_t sx=(target.maxx()-target.minx())/xskip + 1;
220 int64_t sy=(target.maxy()-target.miny())/yskip + 1;
221 int64_t sz=(target.maxz()-target.minz())/zskip + 1;
222 int64_t st=(target.maxt()-target.mint())/tskip + 1;
223 volume<T> tmpvol(sx,sy,sz,st);
224 int64_t xx=0, yy=0, zz=0, tt=0, x=0, y=0, z=0, t=0;
225 for (t=target.mint(), tt=0; t<=target.maxt(); t+=tskip, tt++) {
226 for (z=target.minz(), zz=0; z<=target.maxz(); z+=zskip, zz++) {
227 for (y=target.miny(), yy=0; y<=target.maxy(); y+=yskip, yy++) {
228 for (x=target.minx(), xx=0; x<=target.maxx(); x+=xskip, xx++) {
229 tmpvol(xx,yy,zz,tt) = target(x,y,z,t);
230 }
231 }
232 }
233 }
234 tmpvol.copyproperties(target[0]);
235 target = tmpvol;
236 return 0;
237}
238
239template <class T>
240int read_volumeROI(volume<T>& target, const std::string& filename,
241 int64_t x0, int64_t y0, int64_t z0, int64_t t0,
242 int64_t x1, int64_t y1, int64_t z1, int64_t t1)
243{
244 short dtype;
245 return (read_volumeROI(target,filename,dtype,
246 x0,y0,z0,t0,x1,y1,z1,t1,true));
247}
248
249
250template <class T>
251int read_volume(volume<T>& target, const std::string& filename, const bool& legacyRead)
252{
253 short dtype;
254 read_volumeROI(target,filename,dtype,0,0,0,0,-1,-1,-1,-1,true);
255 if ( legacyRead && target.tsize() > 1 ) {
256 std::cerr << "Warning: An input intended to be a single 3D volume has " <<
257 "multiple timepoints. Input will be truncated to first volume, but " <<
258 "this functionality is deprecated and will be removed in a future release." << std::endl;
259 target=volume<T>(target[0]);
260 }
261 return 0;
262}
263
264
265// SAVE FUNCTIONS
266
267
268NiftiIO::mat44 newmat2mat44(const NEWMAT::Matrix& nmat);
269
270template <class T>
271int set_fsl_hdr(const volume<T>& source, NiftiIO::NiftiHeader& niihdr)
272{
273 niihdr.dim[0]=source.dimensionality();
274 niihdr.dim[1]=source.size1();
275 niihdr.dim[2]=source.size2();
276 niihdr.dim[3]=source.size3();
277 niihdr.dim[4]=source.size4();
278 niihdr.dim[5]=source.size5();
279 niihdr.dim[6]=source.size6();
280 niihdr.dim[7]=source.size7();
281
282 niihdr.datatype=dtype(source);
283
284 niihdr.pixdim[1]=source.pixdim1();
285 niihdr.pixdim[2]=source.pixdim2();
286 niihdr.pixdim[3]=source.pixdim3();
287 niihdr.pixdim[4]=source.pixdim4();
288 niihdr.pixdim[5]=source.pixdim5();
289 niihdr.pixdim[6]=source.pixdim6();
290 niihdr.pixdim[7]=source.pixdim7();
291
292
293 niihdr.sformCode = source.sform_code();
294 niihdr.qformCode = source.qform_code();
295 niihdr.setSForm(newmat2mat44(source.sform_mat()));
296 niihdr.setQForm(newmat2mat44(source.qform_mat()));
297
298 niihdr.intentCode = source.intent_code();
299 niihdr.intent_p1 = source.intent_param(1);
300 niihdr.intent_p2 = source.intent_param(2);
301 niihdr.intent_p3 = source.intent_param(3);
302
303 niihdr.sclSlope = 1.0;
304 niihdr.sclInter = 0.0;
305
306 niihdr.cal_min = source.getDisplayMinimum();
307 niihdr.cal_max = source.getDisplayMaximum();
308 niihdr.auxillaryFile = source.getAuxFile();
309
310 niihdr.units= NiftiIO::NIFTI_UNITS_SEC | NiftiIO::NIFTI_UNITS_MM; //NIFTI unit setting is formed by bitwise addition of defined values, in this case 10
311 niihdr.sliceOrdering=0;
312
313 return 0;
314}
315
316template <class T>
317int save_basic_volume(const volume<T>& source, const std::string& filename,
318 int filetype, bool save_orig=false);
319
320template <class T>
321int save_volume(const volume<T>& source, const std::string& filename, const int filetype) {
322 return save_basic_volume(source,filename,filetype,false);
323}
324
325template <class T, class dType>
326struct typedSave {
327 int operator()(const volume<T> source, const std::string& filename,const int filetype) {
328 volume<dType> output;
329 copyconvert(source,output);
330 return save_volume(output,filename,filetype);
331 }
332};
333
334template <class T>
335struct typedSave<T,T> {
336 int operator()(const volume<T> source, const std::string& filename,const int filetype) {
337 return save_volume(source,filename,filetype);
338 }
339};
340
341template <class T>
342int save_volume_dtype(const volume<T>& source, const std::string& filename,short datatype,const int filetype=-1)
343{
344 switch(closestTemplatedType(datatype)) {
345 case NiftiIO::DT_UNSIGNED_CHAR: return typedSave<T,char>()(source,filename,filetype);
346 case NiftiIO::DT_SIGNED_SHORT: return typedSave<T,short>()(source,filename,filetype);
347 case NiftiIO::DT_SIGNED_INT: return typedSave<T,int>()(source,filename,filetype);
348 case NiftiIO::DT_FLOAT: return typedSave<T,float>()(source,filename,filetype);
349 case NiftiIO::DT_DOUBLE: return typedSave<T,double>()(source,filename,filetype);
350 default:
351 std::ostringstream errmsg;
352 errmsg << "NEWIMAGE::save_volume_dtype: DT " << datatype << " not supported";
353 perror(errmsg.str().c_str());
354 }
355 return -1; // should never get here
356}
357
358template <class T>
359int save_volume_and_splines(const volume<T>& source, const std::string& filename)
360{
361 if (!source.hasSplines()) {
362 std::cerr << "NEWIMAGE::save_volume_and_splines: volume has no valid splines" << std::endl;
363 return(-1);
364 }
365 if (source.tsize() > 1) {
366 std::cerr << "NEWIMAGE::save_volume_and_splines: writing of 4D files not supported" << std::endl;
367 return(-1);
368 }
369 volume<T> ovol(source.xsize(),source.ysize(),source.zsize(),2);
370 copybasicproperties(source,ovol);
371 for (int k=0; k<source.zsize(); k++) {
372 for (int j=0; j<source.ysize(); j++) {
373 for (int i=0; i<source.xsize(); i++) {
374 ovol(i,j,k,0) = source(i,j,k);
375 ovol(i,j,k,1) = source.splineCoef(i,j,k);
376 }
377 }
378 }
379 return(save_volume(ovol,filename));
380}
381
382// functions to save without doing any swapping (i.e. just as passed in)
383
384template <class T>
385int save_orig_volume(const volume<T>& source, const std::string& filename, const int filetype = -1)
386{
387 return save_basic_volume(source,filename,filetype,true);
388}
389
390
394
395// load
396template <class T>
397int load_volume(volume<T>& target, const std::string& filename)
398{ return read_volume(target,filename); }
399
400 // write
401template <class T>
402int write_volume(const volume<T>& source, const std::string& filename)
403{ return save_volume(source,filename); }
404
405// Basic I/O functions
406// read original storage order - do not swap to radiological
407template <class T>
408int read_orig_volume(volume<T>& target, const std::string& filename)
409{
410 short dtype;
411 read_volumeROI(target,filename,dtype,0,0,0,0,-1,-1,-1,-1,false);
412 return 0;
413}
414
415
416//TODO REMOVE after 4D is dead
417template <class T>
418int write_volume4D(const volume<T>& source, const std::string& filename) {
419 return save_volume(source,filename); }
420template <class T>
421int save_volume4D(const volume<T>& source, const std::string& filename) {
422 return save_volume(source,filename); }
423template <class T>
424int load_volume4D(volume<T>& source, const std::string& filename) {
425 return read_volume(source,filename,false); }
426template <class T>
427int read_volume4D(volume<T>& source, const std::string& filename) {
428 return read_volume(source,filename,false); }
429template <class T>
430int read_orig_volume4D(volume<T>& target, const std::string& filename) {
431 return read_orig_volume(target,filename);}
432
433}
434
435#endif
Definition: newimage.h:100
Definition: newimageio.h:326