00001 #include "mrilib.h"
00002
00003
00004
00005 void A2A_help(void)
00006 {
00007 printf("** DON'T USE THIS PROGRAM! REALLY!\n"
00008 "USE 3dcopy OR to3d INSTEAD.\n\n"
00009 "IF YOU CHOOSE TO USE IT ANYWAY, PERHAPS\n"
00010 "BECAUSE IT WORKS BETTER ON YOUR 12th\n"
00011 "CENTURY PLANTAGENET ANALYZE FILES,\n"
00012 "ADD THE OPTION -OK TO YOUR COMMAND\n"
00013 "LINE.\n\n"
00014 "Usage: 3dANALYZEtoAFNI [options] file1.hdr file2.hdr ...\n"
00015 "This program constructs a 'volumes' stored AFNI dataset\n"
00016 "from the ANALYZE-75 files file1.img file2.img ....\n"
00017 "In this type of dataset, there is only a .HEAD file; the\n"
00018 ".BRIK file is replaced by the collection of .img files.\n"
00019 "- Other AFNI programs can read (but not write) this type\n"
00020 " of dataset.\n"
00021 "- The advantage of using this type of dataset vs. one created\n"
00022 " with to3d is that you don't have to duplicate the image data\n"
00023 " into a .BRIK file, thus saving disk space.\n"
00024 "- The disadvantage of using 'volumes' for a multi-brick dataset\n"
00025 " is that all the .img files must be kept with the .HEAD file\n"
00026 " if you move the dataset around.\n"
00027 "- The .img files must be in the same directory as the .HEAD file.\n"
00028 "- Note that you put the .hdr files on the command line, but it is\n"
00029 " the .img files that will be named in the .HEAD file.\n"
00030 "- After this program is run, you must keep the .img files with\n"
00031 " the output .HEAD file. AFNI doesn't need the .hdr files, but\n"
00032 " other programs (e.g., FSL, SPM) will want them as well.\n"
00033 "\n"
00034 "Options:\n"
00035 " -prefix ppp = Save the dataset with the prefix name 'ppp'.\n"
00036 " [default='a2a']\n"
00037 " -view vvv = Save the dataset in the 'vvv' view, where\n"
00038 " 'vvv' is one of 'orig', 'acpc', or 'tlrc'.\n"
00039 " [default='orig']\n"
00040 "\n"
00041 " -TR ttt = For multi-volume datasets, create it as a\n"
00042 " 3D+time dataset with TR set to 'ttt'.\n"
00043 " -fbuc = For multi-volume datasets, create it as a\n"
00044 " functional bucket dataset.\n"
00045 " -abuc = For multi-volume datasets, create it as an\n"
00046 " anatomical bucket dataset.\n"
00047 " ** If more than one ANALYZE file is input, and none of the\n"
00048 " above options is given, the default is as if '-TR 1s'\n"
00049 " was used.\n"
00050 " ** For single volume datasets (1 ANALYZE file input), the\n"
00051 " default is '-abuc'.\n"
00052 "\n"
00053 " -geomparent g = Use the .HEAD file from dataset 'g' to set\n"
00054 " the geometry of this dataset.\n"
00055 " ** If you don't use -geomparent, then the following options\n"
00056 " can be used to specify the geometry of this dataset:\n"
00057 " -orient code = Tells the orientation of the 3D volumes. The code\n"
00058 " must be 3 letters, one each from the pairs {R,L}\n"
00059 " {A,P} {I,S}. The first letter gives the orientation\n"
00060 " of the x-axis, the second the orientation of the\n"
00061 " y-axis, the third the z-axis:\n"
00062 " R = right-to-left L = left-to-right\n"
00063 " A = anterior-to-posterior P = posterior-to-anterior\n"
00064 " I = inferior-to-superior S = superior-to-inferior\n"
00065 " -zorigin dz = Puts the center of the 1st slice off at the\n"
00066 " given distance ('dz' in mm). This distance\n"
00067 " is in the direction given by the corresponding\n"
00068 " letter in the -orient code. For example,\n"
00069 " -orient RAI -zorigin 30\n"
00070 " would set the center of the first slice at\n"
00071 " 30 mm Inferior.\n"
00072 " ** If the above options are NOT used to specify the geometry\n"
00073 " of the dataset, then the default is '-orient RAI', and the\n"
00074 " z origin is set to center the slices about z=0.\n"
00075 "\n"
00076 " It is likely that you will want to patch up the .HEAD file using\n"
00077 " program 3drefit.\n"
00078 "\n"
00079 " -- RWCox - June 2002.\n\n\n"
00080 "** DON'T USE THIS PROGRAM! REALLY!\n"
00081 "USE 3dcopy OR to3d INSTEAD.\n\n"
00082 "IF YOU CHOOSE TO USE IT ANYWAY, PERHAPS\n"
00083 "BECAUSE IT WORKS BETTER ON YOUR 12th\n"
00084 "CENTURY PLANTAGENET ANALYZE FILES,\n"
00085 "ADD THE OPTION -OK TO YOUR COMMAND\n"
00086 "LINE.-- KRH - April 2005.\n\n"
00087 ) ;
00088 }
00089
00090
00091
00092 int main( int argc , char *argv[] )
00093 {
00094 int force=0 ;
00095 int iarg=1 ;
00096 THD_3dim_dataset *dset ;
00097 int nvals , ii , jj , kk ;
00098
00099 MRI_IMARR *anar ;
00100 MRI_IMAGE *anim ;
00101 int nxan,nyan,nzan , an_datum , an_swapped ;
00102 float dxan=-1.0,dyan,dzan ;
00103 char anor[8] = "\0" ;
00104
00105 THD_ivec3 nxyz , orixyz ;
00106 THD_fvec3 dxyz , orgxyz ;
00107
00108 float TR=1.0 ; int tunits=UNITS_SEC_TYPE ;
00109 int is_fbuc=0 , is_abuc=0 , is_3dtime=0 ;
00110 int view_type=VIEW_ORIGINAL_TYPE ;
00111 char *prefix="a2a" ;
00112 int xorient=-1, yorient=-1, zorient=-1 ;
00113 int use_zoff=0,use_xoff=0,use_yoff=0 ; float zoff,xoff,yoff ;
00114 THD_3dim_dataset *gset=NULL ;
00115 float *fac ;
00116
00117 char **flab , *fatr ;
00118
00119
00120
00121 if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ A2A_help(); exit(0); }
00122
00123 mainENTRY("3dANALYZEtoAFNI main"); machdep(); PRINT_VERSION("3dANALYZEtoAFNI");
00124
00125
00126
00127 while( iarg < argc && argv[iarg][0] == '-' ){
00128
00129
00130
00131 if( strcmp(argv[iarg],"-prefix") == 0 ){
00132 if( ++iarg >= argc ){
00133 fprintf(stderr,"** -prefix needs an argument!\n"); exit(1);
00134 }
00135 prefix = argv[iarg] ;
00136 if( !THD_filename_ok(prefix) ){
00137 fprintf(stderr,"** Illegal prefix!\n"); exit(1);
00138 }
00139 if( strstr(prefix,"/") != NULL ){
00140 fprintf(stderr,"** Can't use directory names in the prefix!\n"); exit(1);
00141 }
00142 iarg++ ; continue ;
00143 }
00144
00145
00146
00147 if( strcmp(argv[iarg],"-view") == 0 ){
00148 char *str ;
00149 if( ++iarg >= argc ){
00150 fprintf(stderr,"** -view needs an argument!\n"); exit(1);
00151 }
00152 str = argv[iarg] ; if( str[0] == '+' ) str++ ;
00153 for( ii=FIRST_VIEW_TYPE ; ii <= LAST_VIEW_TYPE ; ii++ )
00154 if( strcmp(str,VIEW_codestr[ii]) == 0 ) break ;
00155
00156 if( ii <= LAST_VIEW_TYPE ){
00157 view_type = ii ;
00158 } else {
00159 fprintf(stderr,"** Illegal -view code!\n"); exit(1);
00160 }
00161 iarg++ ; continue ;
00162 }
00163
00164
00165
00166 if( strcmp(argv[iarg],"-zorigin") == 0 ){
00167 if( ++iarg >= argc ){
00168 fprintf(stderr,"** -zorigin needs an argument!\n"); exit(1);
00169 }
00170 zoff = strtod( argv[iarg] , NULL ) ;
00171 use_zoff = 1 ;
00172 iarg++ ; continue ;
00173 }
00174
00175
00176
00177 #define ORCODE(aa) \
00178 ( (aa)=='R' ? ORI_R2L_TYPE : (aa)=='L' ? ORI_L2R_TYPE : \
00179 (aa)=='P' ? ORI_P2A_TYPE : (aa)=='A' ? ORI_A2P_TYPE : \
00180 (aa)=='I' ? ORI_I2S_TYPE : (aa)=='S' ? ORI_S2I_TYPE : ILLEGAL_TYPE )
00181
00182 #define OR3OK(x,y,z) ( ((x)&6) + ((y)&6) + ((z)&6) == 6 )
00183
00184 if( strcmp(argv[iarg],"-orient") == 0 ){
00185 char acod ;
00186
00187 if( ++iarg >= argc ){
00188 fprintf(stderr,"** -orient needs an argument!\n"); exit(1);
00189 }
00190 if( strlen(argv[iarg]) != 3 ){
00191 fprintf(stderr,"** Illegal -orient code!\n"); exit(1);
00192 }
00193 acod = toupper(argv[iarg][0]) ; xorient = ORCODE(acod) ;
00194 acod = toupper(argv[iarg][1]) ; yorient = ORCODE(acod) ;
00195 acod = toupper(argv[iarg][2]) ; zorient = ORCODE(acod) ;
00196 if( xorient<0 || yorient<0 || zorient<0 ||
00197 ! OR3OK(xorient,yorient,zorient) ){
00198 fprintf(stderr,"** Unusable -orient code!\n"); exit(1);
00199 }
00200 iarg++ ; continue ;
00201 }
00202
00203
00204
00205 if( strcmp(argv[iarg],"-geomparent") == 0 ){
00206 if( ++iarg >= argc ){
00207 fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1);
00208 }
00209 gset = THD_open_dataset( argv[iarg] ) ;
00210 if( !ISVALID_DSET(gset) ){
00211 fprintf(stderr,"** Can't open -geomparent dataset!\n"); exit(1);
00212 }
00213 iarg++ ; continue ;
00214 }
00215
00216
00217
00218 if( strcmp(argv[iarg],"-TR") == 0 ){
00219 char *eptr ;
00220 if( ++iarg >= argc ){
00221 fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1);
00222 }
00223 TR = strtod( argv[iarg] , &eptr ) ;
00224 if( TR <= 0.0 ){
00225 fprintf(stderr,"** -TR needs a positive value after it!\n"); exit(1);
00226 }
00227
00228 if( strcmp(eptr,"ms")==0 || strcmp(eptr,"msec")==0 ){
00229 tunits = UNITS_MSEC_TYPE ;
00230 } else if( strcmp(eptr,"s")==0 || strcmp(eptr,"sec")==0 ){
00231 tunits = UNITS_SEC_TYPE ;
00232 } else if( strcmp(eptr,"Hz")==0 || strcmp(eptr,"Hertz")==0 ){
00233 tunits = UNITS_HZ_TYPE ;
00234 }
00235
00236 is_3dtime = 1 ; is_abuc = is_fbuc = 0 ;
00237 iarg++ ; continue ;
00238 }
00239
00240
00241
00242 if( strcmp(argv[iarg],"-fbuc") == 0 ){
00243 is_fbuc = 1 ; is_abuc = is_3dtime = 0 ;
00244 iarg++ ; continue ;
00245 }
00246
00247
00248
00249 if( strcmp(argv[iarg],"-abuc") == 0 ){
00250 is_abuc = 1 ; is_fbuc = is_3dtime = 0 ;
00251 iarg++ ; continue ;
00252 }
00253
00254
00255
00256 if( strcmp(argv[iarg],"-OK") == 0 ){
00257 force = 1 ;
00258 iarg++ ; continue ;
00259 }
00260
00261
00262
00263 fprintf(stderr,"** Illegal option %s\n",argv[iarg]); exit(1);
00264 }
00265
00266 if (!force) { A2A_help(); exit(0);
00267 }
00268
00269
00270
00271 nvals = argc - iarg ;
00272 if( nvals <= 0 ){
00273 fprintf(stderr,"** No ANALYZE files on command line!?\n"); exit(1);
00274 }
00275
00276
00277
00278 CLEAR_MRILIB_globals ;
00279
00280 fac = (float *) malloc(sizeof(float)*nvals) ;
00281
00282 for( ii=iarg ; ii < argc ; ii++ ){
00283
00284 if( strstr(argv[ii],"/") != NULL ){
00285 fprintf(stderr,"** ANALYZE files must all be in current directory!\n") ;
00286 exit(1) ;
00287 }
00288
00289 anar = mri_read_analyze75( argv[ii] ) ;
00290
00291 if( anar == NULL || IMARR_COUNT(anar) == 0 ){
00292 fprintf(stderr,"** Can't read %s as ANALYZE-75 format .hdr file!\n",argv[ii]);
00293 exit(1) ;
00294 }
00295
00296 anim = IMARR_SUBIM(anar,0) ;
00297
00298 fac[ii-iarg] = anim->dv ;
00299
00300 if( ii == iarg ){
00301
00302 nxan = anim->nx ; nyan = anim->ny ; nzan = IMARR_COUNT(anar) ;
00303 if( MRILIB_orients[0] != '\0' ) strcpy(anor,MRILIB_orients) ;
00304 an_datum = anim->kind ;
00305 if( anim->dw > 0.0 ){ dxan = anim->dx; dyan = anim->dy; dzan = anim->dz; }
00306 an_swapped = anim->was_swapped ;
00307
00308 } else {
00309
00310 if( nxan != anim->nx || nyan != anim->ny || nzan != IMARR_COUNT(anar) ){
00311 fprintf(stderr,"** File %s has different dimensions than %s\n",
00312 argv[ii] , argv[iarg] ) ;
00313 exit(1) ;
00314 }
00315 if( an_datum != anim->kind ){
00316 fprintf(stderr,"** File %s has different kind of data than %s\n",
00317 argv[ii] , argv[iarg] ) ;
00318 exit(1) ;
00319 }
00320 if( an_swapped != anim->was_swapped ){
00321 fprintf(stderr,"** File %s %s byte-swapped, but %s %s\n",
00322 argv[ii] , (anim->was_swapped) ? "is" : "isn't" ,
00323 argv[iarg] , (an_swapped) ? "is" : "isn't" ) ;
00324 exit(1) ;
00325 }
00326 if( anim->dw > 0.0 ){
00327 if( dxan < 0.0 ){
00328 dxan = anim->dx; dyan = anim->dy; dzan = anim->dz;
00329 } else {
00330 if( dxan != anim->dx || dyan != anim->dy || dzan != anim->dz ){
00331 fprintf(stderr,"++ WARNING: File %s has variant voxel sizes!\n",
00332 argv[ii]) ;
00333 }
00334 }
00335 }
00336 if( anor[0] == '\0' && MRILIB_orients[0] != '\0' )
00337 strcpy(anor,MRILIB_orients) ;
00338
00339 }
00340
00341
00342
00343 DESTROY_IMARR(anar) ;
00344
00345 }
00346
00347
00348
00349 if( gset != NULL ){
00350
00351 if( DSET_NX(gset)!=nxan || DSET_NY(gset)!=nyan || DSET_NZ(gset)!=nzan ){
00352 fprintf(stderr,"** geomparent and ANALYZE files have different dimensions!\n");
00353 exit(1) ;
00354 }
00355
00356 if( xorient >= 0 ){
00357 fprintf(stderr,"++ WARNING: geomparent overrides -orient!\n") ;
00358 }
00359 xorient = gset->daxes->xxorient ;
00360 yorient = gset->daxes->yyorient ;
00361 zorient = gset->daxes->zzorient ;
00362
00363 if( use_zoff ){
00364 fprintf(stderr,"++ WARNING: geomparent overrides -zorigin!\n") ;
00365 }
00366 use_xoff = use_yoff = use_zoff = 1 ;
00367 xoff = gset->daxes->xxorg ;
00368 yoff = gset->daxes->yyorg ;
00369 zoff = gset->daxes->zzorg ;
00370
00371 dxan = gset->daxes->xxdel ;
00372 dyan = gset->daxes->yydel ;
00373 dzan = gset->daxes->zzdel ;
00374
00375 if( gset->taxis != NULL ){
00376 TR = gset->taxis->ttdel ;
00377 tunits = gset->taxis->units_type ;
00378 }
00379
00380 DSET_delete(gset) ;
00381
00382 } else {
00383
00384 if( xorient < 0 ){
00385 xorient = ORI_R2L_TYPE ;
00386 yorient = ORI_A2P_TYPE ;
00387 zorient = ORI_I2S_TYPE ;
00388 fprintf(stderr,"++ WARNING: orientation defaults to RAI\n") ;
00389 }
00390
00391 if( dxan <= 0.0 ){
00392 dxan = dyan = dzan = 1.0 ;
00393 fprintf(stderr,"++ WARNING: voxel size defaults to 1 mm\n") ;
00394 }
00395
00396 if( ORIENT_sign[xorient] == '-' ) dxan = -dxan ;
00397 if( ORIENT_sign[yorient] == '-' ) dyan = -dyan ;
00398 if( ORIENT_sign[zorient] == '-' ) dzan = -dzan ;
00399
00400 }
00401
00402
00403
00404 dset = EDIT_empty_copy(NULL) ;
00405
00406 nxyz.ijk[0] = nxan ; dxyz.xyz[0] = dxan ;
00407 nxyz.ijk[1] = nyan ; dxyz.xyz[1] = dyan ;
00408 nxyz.ijk[2] = nzan ; dxyz.xyz[2] = dzan ;
00409
00410 orixyz.ijk[0] = xorient ;
00411 orixyz.ijk[1] = yorient ;
00412 orixyz.ijk[2] = zorient ;
00413
00414 orgxyz.xyz[0] = (use_xoff) ? xoff : -0.5*(nxan-1)*dxan ;
00415 orgxyz.xyz[1] = (use_yoff) ? yoff : -0.5*(nyan-1)*dyan ;
00416 orgxyz.xyz[2] = (use_zoff) ? zoff : -0.5*(nzan-1)*dzan ;
00417
00418 EDIT_dset_items( dset ,
00419 ADN_prefix , prefix ,
00420 ADN_datum_all , an_datum ,
00421 ADN_nxyz , nxyz ,
00422 ADN_xyzdel , dxyz ,
00423 ADN_xyzorg , orgxyz ,
00424 ADN_xyzorient , orixyz ,
00425 ADN_nvals , nvals ,
00426 ADN_view_type , view_type ,
00427 ADN_brick_fac , fac ,
00428 ADN_none ) ;
00429
00430
00431
00432 if( nvals == 1 && is_3dtime ){
00433 is_3dtime = 0; is_abuc = 1;
00434 fprintf(stderr,"++ WARNING: can't make a 3D+time dataset from 1 volume!\n") ;
00435 }
00436
00437 if( !is_3dtime && !is_abuc && !is_fbuc ){
00438 if( nvals > 1 ) is_3dtime = 1 ;
00439 else is_abuc = 1 ;
00440 }
00441
00442 if( is_3dtime ){
00443 EDIT_dset_items( dset ,
00444 ADN_ntt , nvals ,
00445 ADN_ttorg , 0.0 ,
00446 ADN_ttdel , TR ,
00447 ADN_ttdur , 0.0 ,
00448 ADN_tunits , tunits ,
00449 ADN_type , HEAD_ANAT_TYPE ,
00450 ADN_func_type, ANAT_EPI_TYPE ,
00451 ADN_none ) ;
00452 } else if( is_abuc ){
00453 EDIT_dset_items( dset ,
00454 ADN_type , HEAD_ANAT_TYPE ,
00455 ADN_func_type, ANAT_BUCK_TYPE ,
00456 ADN_none ) ;
00457 } else if( is_fbuc ){
00458 EDIT_dset_items( dset ,
00459 ADN_type , HEAD_FUNC_TYPE ,
00460 ADN_func_type, FUNC_BUCK_TYPE ,
00461 ADN_none ) ;
00462 }
00463
00464
00465
00466 flab = (char **) malloc(sizeof(char *)*nvals) ;
00467
00468 kk = 0 ;
00469 for( ii=0 ; ii < nvals ; ii++ ){
00470 jj = strlen( argv[iarg+ii] ) ;
00471 flab[ii] = strdup( argv[iarg+ii] ) ;
00472 strcpy( flab[ii]+jj-3 , "img" ) ;
00473 kk += (jj+2) ;
00474 THD_store_datablock_label( dset->dblk , ii , flab[ii] ) ;
00475 }
00476
00477 fatr = malloc(kk) ; fatr[0] = '\0' ;
00478 for( ii=0 ; ii < nvals ; ii++ ){
00479 strcat(fatr,flab[ii] ); strcat(fatr," ");
00480 free(flab[ii]) ;
00481 }
00482
00483
00484
00485
00486 THD_set_string_atr( dset->dblk , "VOLUME_FILENAMES" , fatr ) ;
00487 free(fatr) ; free(flab) ;
00488
00489
00490
00491 jj = mri_short_order() ;
00492
00493 if( an_swapped )
00494 dset->dblk->diskptr->byte_order = REVERSE_ORDER(jj) ;
00495 else
00496 dset->dblk->diskptr->byte_order = jj ;
00497
00498
00499
00500 tross_Make_History( "3dANALYZEtoAFNI" , argc,argv , dset ) ;
00501
00502
00503
00504 THD_write_3dim_dataset( NULL,NULL , dset , False ) ;
00505 fprintf(stderr,"++ Wrote dataset header %s\n",DSET_HEADNAME(dset)) ;
00506 exit(0) ;
00507 }