1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/stat.h>
4 #include <stdlib.h>
5 #include <math.h>
6 #include "siemens_vision.h"
7 #include "mrilib.h"
8
byteswap8(double * x)9 static void byteswap8 (double *x) {
10 char *p1,*p2; double d; int i;
11 p1=(char *)x; p2=(char *)&d;
12 for(i=0;i<8;i++) p2[7-i]=p1[i];
13 (*x)=d;
14 }
15
byteswap4(u_int * x)16 static void byteswap4( u_int * x ) {
17 char *p1,*p2 ; u_int d ; int i ;
18 p1=(char *)x; p2=(char *)&d;
19 for(i=0;i<4;i++) p2[3-i]=p1[i];
20 (*x)=d;
21 }
22
23 /*----------------------------------------------------------------------------
24 12 Mar 2001: Program siemens_vision.c, to print info from Siemens .ima header
25 Adapted from program thor.cpp by CELS (?)
26 Compile this with
27 cc -o siemens_vision siemens_vision.c -I. -lm
28 or
29 make siemens_vision
30 (if you are getting this as part of the AFNI package) -- RWCox
31 ------------------------------------------------------------------------------*/
32
main(int argc,char * argv[])33 int main( int argc , char * argv[] )
34 {
35 struct Siemens_vision_header head ;
36 FILE * fp ;
37 char orients[7] ;
38 int i,j,xx,yy , matrix , swap , slices=0 ;
39 double dd=0.0 , qq=0.0 ;
40 struct stat file_stat ;
41 int imagesize=64 ;
42 short *imar=NULL ;
43 char *prefix=NULL ; int iarg=1 , nfiles=0 ;
44
45 if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
46 printf("Usage: siemens_vision [options] filename ...\n"
47 "Prints out information from the Siemens .ima file header(s).\n"
48 "\n"
49 "The only option is to rename the file according to the\n"
50 "TextImageNumber field stored in the header. The option is:\n"
51 "\n"
52 " -rename ppp\n"
53 "\n"
54 "which will rename each file to the form 'ppp.nnnn.ima',\n"
55 "where 'nnnn' is the image number expressed with 4 digits.\n"
56 "\n"
57 "When '-rename' is used, the header info from the input files\n"
58 "will not be printed.\n"
59 ) ;
60 exit(0) ;
61 }
62
63 if( strcmp(argv[iarg],"-rename") == 0 ){
64 if( iarg+2 >= argc ){
65 fprintf(stderr,"** ERROR: not enough arguments after '-rename'\n") ;
66 exit(1) ;
67 }
68 prefix = strdup(argv[++iarg]) ;
69 if( !THD_filename_ok(prefix) ){
70 fprintf(stderr,"** ERROR: prefix after '-rename' is illegal\n") ;
71 exit(1) ;
72 }
73 iarg++ ;
74 }
75
76 /*--- check file size ---*/
77
78 for( ; iarg < argc ; iarg++ ){ /* loop over input filenames */
79
80 nfiles++ ;
81
82 i = stat( argv[iarg] , &file_stat ) ;
83 if( i < 0 ){
84 fprintf(stderr,"** Can't access file %s\n",argv[iarg]) ; exit(1) ;
85 }
86
87 /*--- read header data ---*/
88
89 fp = fopen( argv[iarg] , "r" ) ;
90 if( fp == NULL ) exit(1) ;
91 fread( &head , sizeof(struct Siemens_vision_header) , 1 , fp ) ;
92
93 /*-- check some integer in header to determine if we need to byteswap --*/
94
95 swap = ( head.SiemensStudyDateMM < 0 || head.SiemensStudyDateMM > 12 ) ;
96 if( swap ){
97 byteswap4( &(head.SiemensStudyDateMM) ) ;
98 if( head.SiemensStudyDateMM < 0 || head.SiemensStudyDateMM > 12 ){
99 printf("** Can't determine byte swap status of file %s\n",argv[iarg]) ;
100 byteswap4( &(head.SiemensStudyDateMM) ) ;
101 swap = 0 ;
102 }
103 }
104
105 /*-- renaming? --*/
106
107 if( prefix != NULL ){
108 char *cpt , fname[2048] ;
109 int num = (int)strtol( head.TextImageNumber , &cpt , 10 ) ;
110 if( *cpt != '\0' && num == 0 ){
111 printf("** Can't get TextImageNumber from file %s\n",argv[iarg]) ;
112 num = iarg ;
113 }
114 sprintf(fname,"%s.%04d.ima",prefix,num) ;
115 if( THD_is_ondisk(fname) ){
116 printf("** Can't rename %s to pre-existing filename %s\n",
117 argv[iarg],fname ) ;
118 } else {
119 printf("++ Renaming %s to %s\n",argv[iarg],fname) ;
120 rename(argv[iarg],fname) ;
121 }
122 fclose(fp) ; continue ; /* skip to next iarg */
123 }
124
125 /*** Below here: print out header info from file ***/
126
127 /*-- find image size from header --*/
128
129 if( swap ) byteswap4( &(head.DisplayMatrixSize) ) ;
130 imagesize = head.DisplayMatrixSize ;
131
132 /*-- determine number of sub-images in file --*/
133
134 if( file_stat.st_size==(imagesize * imagesize * 64 * 2 + SIEMENS_HEADERSIZE) ){
135 matrix = 8 ;
136 } else if( file_stat.st_size==(imagesize * imagesize * 16 * 2 + SIEMENS_HEADERSIZE) ){
137 matrix = 4;
138 } else {
139 matrix = 0 ;
140 printf("Don't recognize file size. Is this a Siemens Magnetom Vision .ima file?\n") ;
141 }
142
143 /*-- read image data from file (but don't byteswap it) --*/
144
145 if( matrix > 0 ){
146 imar = (short *) calloc(sizeof(short),matrix*matrix*imagesize*imagesize) ;
147 fseek( fp , SIEMENS_HEADERSIZE , SEEK_SET ) ;
148 fread( imar , sizeof(short) , matrix*matrix*imagesize*imagesize , fp ) ;
149 }
150
151 fclose(fp) ;
152
153 /*--- swap random info ---*/
154
155 if (swap) {
156 #if 0
157 byteswap4(&(head.SiemensStudyDateYYYY)) ; /* these are unsigned ints */
158 byteswap4(&(head.SiemensStudyDateMM)) ;
159 byteswap4(&(head.SiemensStudyDateDD)) ;
160 byteswap4(&(head.AcquisitionDateYYYY)) ;
161 byteswap4(&(head.AcquisitionDateMM)) ;
162 byteswap4(&(head.AcquisitionDateDD)) ;
163 byteswap4(&(head.ImageDateYYYY)) ;
164 byteswap4(&(head.ImageDateMM)) ;
165 byteswap4(&(head.ImageDateDD)) ;
166 byteswap4(&(head.SiemensStudyTimeHH)) ;
167 byteswap4(&(head.SiemensStudyTimeMM)) ;
168 byteswap4(&(head.SiemensStudyTimeSS)) ;
169 byteswap4(&(head.AcquisitionTimeHH)) ;
170 byteswap4(&(head.AcquisitionTimeMM)) ;
171 byteswap4(&(head.AcquisitionTimeSS)) ;
172 byteswap4(&(head.ImageTimeHH)) ;
173 byteswap4(&(head.ImageTimeMM)) ;
174 byteswap4(&(head.ImageTimeSS)) ;
175 #endif
176
177 byteswap8(&(head.FOVRow));
178 byteswap8(&(head.FOVColumn));
179 byteswap8(&(head.SliceThickness));
180 byteswap8(&(head.RepetitionTime)) ;
181 byteswap8(&(head.FrequencyMHz)) ;
182 byteswap8(&(head.EchoTime)) ;
183 byteswap8(&(head.CenterPointX)) ;
184 byteswap8(&(head.CenterPointY)) ;
185 byteswap8(&(head.CenterPointZ)) ;
186 byteswap8(&(head.NormalVectorX));
187 byteswap8(&(head.NormalVectorY));
188 byteswap8(&(head.NormalVectorZ));
189 byteswap8(&(head.PixelSizeRow)) ;
190 byteswap8(&(head.PixelSizeColumn)) ;
191 byteswap8(&(head.RowVectorX)) ;
192 byteswap8(&(head.RowVectorY)) ;
193 byteswap8(&(head.RowVectorZ)) ;
194 byteswap8(&(head.ColumnVectorX)) ;
195 byteswap8(&(head.ColumnVectorY)) ;
196 byteswap8(&(head.ColumnVectorZ)) ;
197 byteswap8(&(head.DistanceFromIsocenter)) ;
198 }
199
200 /*--- print random info ---*/
201
202 printf("Manufact = %s\n",head.Manufacturer) ;
203 printf("Institut = %s\n",head.InstitutionName) ;
204
205 printf("Date = %s\n"
206 "Time = %s\n"
207 "Sequence = %s\n"
208 "Patient = %s\n"
209 "ImageNum = %s\n" ,
210 head.TextDate , head.TextTime ,
211 head.SequenceType , head.PatientName , head.TextImageNumber ) ;
212 printf("SubjectID= %s\n",head.PatientID) ;
213 printf("RF Coil = %s\n",head.ReceivingCoil) ;
214
215 orients[0]= head.OrientationSet1Left[0]; orients[1]=head.OrientationSet2Right[0];
216 orients[2]= head.OrientationSet1Top[0] ; orients[3]=head.OrientationSet2Down[0] ;
217 orients[4]= head.OrientationSet1Back[0]; orients[5]=head.OrientationSet2Front[0];
218 for (i=0; i<6; i++) {
219 if (orients[i]=='H') orients[i]='S';
220 if (orients[i]=='F') orients[i]='I';
221 }
222 orients[6] = '\0' ;
223 printf("Orient = %s\n",orients) ;
224
225 printf("FOV Row = %g\n"
226 "FOV Col = %g\n"
227 "SliceThk = %g\n" , head.FOVRow , head.FOVColumn , head.SliceThickness ) ;
228
229 printf("TR = %g\n",head.RepetitionTime) ;
230 printf("TE = %g\n",head.EchoTime) ;
231 printf("Cen X = %g\n",head.CenterPointX) ;
232 printf("Cen Y = %g\n",head.CenterPointY) ;
233 printf("Cen Z = %g\n",head.CenterPointZ) ;
234 printf("Delta X = %g\n",head.PixelSizeRow) ;
235 printf("Delta Y = %g\n",head.PixelSizeColumn) ;
236 printf("RowVec X = %g\n",head.RowVectorX) ;
237 printf("RowVec Y = %g\n",head.RowVectorY) ;
238 printf("RowVec Z = %g\n",head.RowVectorZ) ;
239 printf("ColVec X = %g\n",head.ColumnVectorX) ;
240 printf("ColVec Y = %g\n",head.ColumnVectorY) ;
241 printf("ColVec Z = %g\n",head.ColumnVectorZ) ;
242 printf("Normal X = %g\n",head.NormalVectorX);
243 printf("Normal Y = %g\n",head.NormalVectorY);
244 printf("Normal Z = %g\n",head.NormalVectorZ);
245
246 #if 0
247 dd = head.RowVectorX * head.ColumnVectorX /* vector dot products */
248 +head.RowVectorY * head.ColumnVectorY
249 +head.RowVectorZ * head.ColumnVectorZ ;
250 printf("Row*Col = %g\n",dd) ;
251
252 dd = head.RowVectorX * head.NormalVectorX
253 +head.RowVectorY * head.NormalVectorY
254 +head.RowVectorZ * head.NormalVectorZ ;
255 printf("Row*Nor = %g\n",dd) ;
256
257 dd = head.ColumnVectorX * head.NormalVectorX
258 +head.ColumnVectorY * head.NormalVectorY
259 +head.ColumnVectorZ * head.NormalVectorZ ;
260 printf("Col*Nor = %g\n",dd) ;
261 #endif
262
263 printf("D-IsoCen = %g\n",head.DistanceFromIsocenter) ;
264 printf("SlicePos = %s\n",head.TextSlicePosition) ;
265
266 /*-- scan images for being all zero (blank) [doesn't depend on byteswap] --*/
267
268 slices = matrix*matrix ;
269
270 if( imar != NULL ){
271 int nxx = matrix*imagesize , blank ;
272 printf("Recognized %dx%d mosaic of %dx%d images:\n",matrix,matrix,imagesize,imagesize) ;
273 for( yy=0 ; yy < matrix ; yy++ ){
274 printf(" ") ;
275 for( xx=0 ; xx < matrix ; xx++ ){
276 blank = 1 ;
277 for( j=0 ; j < imagesize ; j++ ){
278 for( i=0 ; i < imagesize ; i++ ){
279 if( imar[i+xx*imagesize+(j+yy*imagesize)*nxx] ) blank = 0 ;
280 }
281 }
282 printf(" %s" , (blank) ? "blank" : "full ") ;
283 if( !blank ) slices = 1 + xx + yy*matrix ;
284 }
285 printf("\n") ;
286 }
287 }
288
289 dd = fabs(strtod(head.TextSlicePosition,NULL)) ;
290 qq = dd - (slices-1)*head.SliceThickness ;
291 if( qq > 0.0 ){
292 orients[5] = orients[4] ;
293 } else {
294 qq = -qq ;
295 }
296
297 } /* end of loop over files */
298
299 if( prefix == NULL ){
300 printf("\nto3d -epan"
301 " -time:zt %d %d %0.3fs alt+z"
302 " -xFOV %0.2f%c-%c"
303 " -yFOV %0.2f%c-%c"
304 " -zSLAB %0.2f%c-%0.2f%c \n" ,
305
306 slices , nfiles , 0.001*head.RepetitionTime ,
307 0.5*head.FOVRow , orients[0] , orients[1] ,
308 0.5*head.FOVColumn , orients[2] , orients[3] ,
309 dd , orients[4] , qq , orients[5] ) ;
310 }
311
312 exit(0) ;
313 }
314