1 #ifndef __MINC_1_SIMPLE_RW_H__
2 #define __MINC_1_SIMPLE_RW_H__
3 
4 #include "minc_1_simple.h"
5 #include "minc_io_simple_volume.h"
6 #include "minc_io_fixed_vector.h"
7 #include "minc_io_4d_volume.h"
8 
9 namespace minc
10 {
11 
load_simple_volume(minc_1_reader & rw,simple_volume<T> & vol)12   template<class T> void load_simple_volume(minc_1_reader& rw,simple_volume<T>& vol)
13   {
14     if(rw.ndim(1)<=0||rw.ndim(2)<=0||rw.ndim(3)<=0||rw.ndim(4)>0)
15       REPORT_ERROR("Need 3D minc file");
16 
17     vol.resize(rw.ndim(1),rw.ndim(2),rw.ndim(3));
18 
19     if(typeid(T)==typeid(unsigned char))
20     {
21       rw.setup_read_byte();
22       load_standard_volume(rw,vol.c_buf());
23     }
24     else if(typeid(T)==typeid(int))
25     {
26       rw.setup_read_int();
27       load_standard_volume(rw,vol.c_buf());
28     }
29     else if(typeid(T)==typeid(fixed_vec<3,float>))
30     {
31       rw.setup_read_float();
32       load_standard_volume<float>(rw,(float*)vol.c_buf());
33     }
34     else if(typeid(T)==typeid(float))
35     {
36       rw.setup_read_float();
37       load_standard_volume(rw,vol.c_buf());
38     }
39     else if(typeid(T)==typeid(fixed_vec<3,double>))
40     {
41       rw.setup_read_double();
42       load_standard_volume<double>(rw,(double*)vol.c_buf());
43     }
44     else if(typeid(T)==typeid(double))
45     {
46       rw.setup_read_double();
47       load_standard_volume(rw,vol.c_buf());
48     } else
49 			REPORT_ERROR("Data type not supported for minc io");
50 
51     //set coordinate transfer parameters
52     for(int i=0;i<3;i++)
53     {
54       vol.step()[i]=rw.nspacing(i+1);
55       vol.start()[i]=rw.nstart(i+1);
56 
57       if(rw.have_dir_cos(i+1))
58       {
59         for(int j=0;j<3;j++)
60           vol.direction_cosines(i)[j]=rw.ndir_cos(i+1,j);
61       } else {
62         for(int j=0;j<3;j++)
63           vol.direction_cosines(i)[j]=(i==j?1.0:0.0); //identity
64       }
65     }
66   }
67 
save_simple_volume(minc_1_writer & rw,const simple_volume<T> & vol)68   template<class T> void save_simple_volume(minc_1_writer& rw,const simple_volume<T>& vol)
69   {
70     if(typeid(T)==typeid(unsigned char))
71     {
72       rw.setup_write_byte();
73       save_standard_volume(rw,vol.c_buf());
74     }
75     else if(typeid(T)==typeid(int))
76     {
77       rw.setup_write_int();
78       save_standard_volume(rw,vol.c_buf());
79     }
80     else if(typeid(T)==typeid(fixed_vec<3,float>))
81     {
82       rw.setup_write_float();
83       save_standard_volume<float>(rw,(float*)vol.c_buf());
84     }
85     else if(typeid(T)==typeid(float))
86     {
87       rw.setup_write_float();
88       save_standard_volume(rw,vol.c_buf());
89     }
90     else if(typeid(T)==typeid(fixed_vec<3,double>))
91     {
92       rw.setup_write_double();
93       save_standard_volume<double>(rw,(double*)vol.c_buf());
94     }
95     else if(typeid(T)==typeid(double))
96     {
97       rw.setup_write_double();
98       save_standard_volume(rw,vol.c_buf());
99     }
100     else
101 			REPORT_ERROR("Data type not supported for minc io");
102   }
103 
104 
load_4d_volume(minc_1_reader & rw,simple_4d_volume<T> & vol)105   template<class T> void load_4d_volume(minc_1_reader& rw,simple_4d_volume<T>& vol)
106   {
107     //if(rw.ndim(1)<=0||rw.ndim(2)<=0||rw.ndim(3)<=0||rw.ndim(4)<=0)
108     //  REPORT_ERROR("Need 4D minc file");
109 
110     vol.resize(rw.ndim(1),rw.ndim(2),rw.ndim(3),rw.ndim(4)>0?rw.ndim(4):1); //always assume 4 dimensions
111 
112     if(typeid(T)==typeid(unsigned char))
113       rw.setup_read_byte();
114     else if(typeid(T)==typeid(int))
115       rw.setup_read_int();
116     else if(typeid(T)==typeid(fixed_vec<3,float>))
117       rw.setup_read_float();
118     else if(typeid(T)==typeid(float))
119       rw.setup_read_float();
120     else if(typeid(T)==typeid(fixed_vec<3,double>))
121       rw.setup_read_double();
122     else if(typeid(T)==typeid(double))
123       rw.setup_read_double();
124 		else
125 			REPORT_ERROR("Data type not supported for minc io");
126 
127     std::vector<size_t> strides(MAX_VAR_DIMS,0);
128     size_t str=1;
129 
130     for(size_t i=0;i<5;i++) //T is a special case
131     {
132       if(rw.map_space(i)<0) continue;
133       strides[rw.map_space(i)]=str;
134       str*=rw.ndim(i);
135     }
136 
137     if(rw.map_space(4)>=0)
138       strides[rw.map_space(4)]=0; //t dimension
139 
140     minc_input_iterator<T> in(rw);
141     for(in.begin();!in.last();in.next())
142     {
143       size_t address=0;
144       size_t slice=0;
145       for(size_t i=0;i<rw.dim_no();i++)
146       {
147         if(strides[i]>0)
148           address+=in.cur()[i]*strides[i];
149         else //
150           slice=in.cur()[i];
151       }
152       vol.frame(slice).c_buf()[address]=in.value();
153     }
154 
155     //set coordinate transfer parameters
156     for(int i=0;i<3;i++)
157     {
158       vol.step()[i]=rw.nspacing(i+1);
159       vol.start()[i]=rw.nstart(i+1);
160 
161       if(rw.have_dir_cos(i+1))
162       {
163         for(int j=0;j<3;j++)
164           vol.direction_cosines(i)[j]=rw.ndir_cos(i+1,j);
165       } else {
166         for(int j=0;j<3;j++)
167           vol.direction_cosines(i)[j]=(i==j?1.0:0.0); //identity
168       }
169     }
170     if(rw.ndim(4)>0)
171     {
172       vol.t_start()=rw.nstart(4);//T
173       vol.t_step()=rw.nspacing(4);//T
174     } else {
175       vol.t_start()=0;//T
176       vol.t_step()=0;//T
177     }
178   }
179 
save_4d_volume(minc_1_writer & rw,const simple_4d_volume<T> & vol)180   template<class T> void save_4d_volume(minc_1_writer& rw,const simple_4d_volume<T>& vol)
181   {
182     if(typeid(T)==typeid(unsigned char))
183       rw.setup_write_byte();
184     else if(typeid(T)==typeid(int))
185       rw.setup_write_int();
186     else if(typeid(T)==typeid(fixed_vec<3,float>))
187       rw.setup_write_float();
188     else if(typeid(T)==typeid(float))
189       rw.setup_write_float();
190     else if(typeid(T)==typeid(fixed_vec<3,double>))
191       rw.setup_write_double();
192     else if(typeid(T)==typeid(double))
193       rw.setup_write_double();
194     else
195 			REPORT_ERROR("Data type not supported for minc io");
196 
197     std::vector<size_t> strides(MAX_VAR_DIMS,0);
198     size_t str=1;
199     for(size_t i=0;i<4;i++)//T is a special
200     {
201       if(rw.map_space(i)<0) continue;
202       strides[rw.map_space(i)]=str;
203       str*=rw.ndim(i);
204     }
205 
206     if(rw.map_space(4)>=0)
207       strides[rw.map_space(4)]=0; //t dimension
208 
209     minc_output_iterator<T> out(rw);
210     for(out.begin();!out.last();out.next())
211     {
212       size_t address=0;
213       size_t slice=0;
214       for(size_t i=0;i<rw.dim_no();i++)
215       {
216         if(strides[i]>0)
217           address+=out.cur()[i]*strides[i];
218         else //
219           slice=out.cur()[i];
220       }
221       out.value(vol.frame(slice).c_buf()[address]);
222     }
223   }
224 
225   bool is_same(minc_1_reader& one,minc_1_reader& two,bool verbose=true);
226 
load_minc_file(const char * file,simple_4d_volume<T> & vol)227   template<class T> void load_minc_file(const char *file,simple_4d_volume<T>& vol)
228   {
229       minc_1_reader rdr;
230       rdr.open(file);
231       load_4d_volume(rdr,vol);
232   }
233 
generate_info(const simple_4d_volume<T> & vol,minc_info & info)234   template<class T> void generate_info(const simple_4d_volume<T>& vol,minc_info& info)
235   {
236      bool have_time=vol.frames()>1||vol.t_step()!=0.0; //assume that it is 3D file otherwise
237 
238      bool is_vector=false;
239 
240       if(typeid(T)==typeid(fixed_vec<3,float>)) {
241         is_vector=true;
242       }
243 
244       info.resize(3+(is_vector?1:0)+(have_time?1:0));
245 
246       if(is_vector)
247       {
248         info[0].dim=dim_info::DIM_VEC;
249         info[0].length=3;
250         info[0].step=1;
251 
252       }
253 
254       for(int i=0;i<3;i++)
255       {
256         int ii=i+(is_vector?1:0);
257         info[ii].dim=dim_info::dimensions( dim_info::DIM_X+i);
258 
259         info[ii].length=vol.dim(i);
260         info[ii].step  =vol.step()[i];
261         info[ii].start =vol.start()[i];
262         info[ii].have_dir_cos=true;
263 
264         for(int j=0;j<3;j++)
265           info[ii].dir_cos[j]=vol.direction_cosines(i)[j];
266       }
267 
268       if(have_time)
269       {
270         info[3+(is_vector?1:0)].dim=dim_info::DIM_TIME;
271         info[3+(is_vector?1:0)].step=vol.t_step();
272         info[3+(is_vector?1:0)].start=vol.t_start();
273         info[3+(is_vector?1:0)].length=vol.frames();
274       }
275 
276   }
277 
278   template<class T> void save_minc_file(const char *file,const simple_4d_volume<T>& vol,
279                                         const char* history=NULL,const minc_1_reader* original=NULL,
280                                         nc_type datatype=NC_NAT,bool is_signed=false)
281   {
282       minc_1_writer wrt;
283       //convert parameters to info
284 
285       if(typeid(T)==typeid(unsigned char))
286       {
287         if(datatype==NC_NAT) datatype=NC_BYTE;
288 
289       } else if(typeid(T)==typeid(int)) {
290         if(datatype==NC_NAT) datatype=NC_INT;
291 
292         is_signed=true;
293       } else if(typeid(T)==typeid(unsigned int))  {
294         if(datatype==NC_NAT) datatype=NC_INT;
295 
296         is_signed=false;
297       } else if(typeid(T)==typeid(float))  {
298         if(datatype==NC_NAT) datatype=NC_FLOAT;
299 
300         is_signed=true;
301       } else if(typeid(T)==typeid(fixed_vec<3,float>)) {
302         if(datatype==NC_NAT) datatype=NC_FLOAT;
303 
304         is_signed=true;
305       } else if(typeid(T)==typeid(double))  {
306         if(datatype==NC_NAT) datatype=NC_DOUBLE;
307 
308         is_signed=true;
309       } else if(typeid(T)==typeid(fixed_vec<3,double>)) {
310         if(datatype==NC_NAT) datatype=NC_DOUBLE;
311 
312         is_signed=true;
313       } else
314         REPORT_ERROR("Unsupported data type!");
315 
316       minc_info info;
317       generate_info<T>(vol,info);
318 
319       wrt.open(file,info,2,datatype,is_signed);
320 
321       if(original)
322       {
323         wrt.copy_headers(*original);
324       }
325 
326       if(history)
327         wrt.append_history(history);
328 
329       save_4d_volume(wrt,vol);
330   }
331 
332 };
333 
334 #endif //__MINC_1_SIMPLE_RW_H__
335