00001 #include "mrilib.h"
00002
00003 int main( int argc , char * argv[] )
00004 {
00005 int iarg ;
00006 THD_3dim_dataset *inset , *outset ;
00007 int add_I=0 , add_S=0 , add_A=0 , add_P=0 , add_L=0 , add_R=0 ;
00008 int RLsiz=0, APsiz=0, ISsiz=0 ;
00009 char * prefix="zeropad" ;
00010
00011 int add_z=0 ;
00012 int mm_flag=0 ;
00013 int flag ;
00014
00015 THD_3dim_dataset *mset=NULL ;
00016
00017
00018
00019 if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
00020 printf("Usage: 3dZeropad [options] dataset\n"
00021 "Adds planes of zeros to a dataset (i.e., pads it out).\n"
00022 "\n"
00023 "Options:\n"
00024 " -I n = adds 'n' planes of zero at the Inferior edge\n"
00025 " -S n = adds 'n' planes of zero at the Superior edge\n"
00026 " -A n = adds 'n' planes of zero at the Anterior edge\n"
00027 " -P n = adds 'n' planes of zero at the Posterior edge\n"
00028 " -L n = adds 'n' planes of zero at the Left edge\n"
00029 " -R n = adds 'n' planes of zero at the Right edge\n"
00030 " -z n = adds 'n' planes of zeros on EACH of the\n"
00031 " dataset z-axis (slice-direction) faces\n"
00032 "\n"
00033 " -RL a = These options specify that planes should be added/cut\n"
00034 " -AP b = symmetrically to make the resulting volume have\n"
00035 " -IS c = 'a', 'b', and 'c' slices in the respective directions.\n"
00036 "\n"
00037 " -mm = pad counts 'n' are in mm instead of slices:\n"
00038 " * each 'n' is an integer\n"
00039 " * at least 'n' mm of slices will be added/removed:\n"
00040 " n = 3 and slice thickness = 2.5 mm ==> 2 slices added\n"
00041 " n = -6 and slice thickness = 2.5 mm ==> 3 slices removed\n"
00042 "\n"
00043 " -master mset = match the volume described in dataset 'mset':\n"
00044 " * mset must have the same orientation and grid\n"
00045 " spacing as dataset to be padded\n"
00046 " * the goal of -master is to make the output dataset\n"
00047 " from 3dZeropad match the spatial 'extents' of\n"
00048 " mset (cf. 3dinfo output) as much as possible,\n"
00049 " by adding/subtracting slices as needed.\n"
00050 " * you can't use -I,-S,..., or -mm with -master\n"
00051 "\n"
00052 " -prefix ppp = write result into dataset with prefix 'ppp'\n"
00053 " [default = 'zeropad']\n"
00054 "\n"
00055 "Nota Bene:\n"
00056 " * You can use negative values of n to cut planes off the edges\n"
00057 " of a dataset. At least one plane must be added/removed\n"
00058 " or the program won't do anything.\n"
00059 " * Anat parent and Talairach markers are NOT preserved in the\n"
00060 " new dataset.\n"
00061 #if 0
00062 " * If the old dataset has z-slice-dependent time offsets, and\n"
00063 " if new z-planes are added, all the slice-dependent time\n"
00064 " offsets will be removed.\n"
00065 #else
00066 " * If the old dataset has z-slice-dependent time offsets, and\n"
00067 " if new (zero filled) z-planes are added, the time offsets\n"
00068 " of the new slices will be set to zero.\n"
00069 #endif
00070 " * You can use program '3dinfo' to find out how many planes\n"
00071 " a dataset has in each direction.\n"
00072 " * Program works for byte-, short-, float-, and complex-valued\n"
00073 " datasets.\n"
00074 " * You can use a sub-brick selector on the input dataset.\n"
00075 " * 3dZeropad won't overwrite an existing dataset (I hope).\n"
00076 "\n"
00077 " Author: RWCox - July 2000\n"
00078 ) ;
00079 exit(0) ;
00080 }
00081
00082 mainENTRY("3dZeropad main"); machdep(); AFNI_logger("3dZeropad",argc,argv);
00083 PRINT_VERSION("3dZeropad") ;
00084
00085
00086
00087 iarg = 1 ;
00088 while( iarg < argc && argv[iarg][0] == '-' ){
00089
00090
00091
00092 if( strlen(argv[iarg]) == 2 ){
00093 switch( argv[iarg][1] ){
00094 case 'I': add_I = (int) strtod(argv[++iarg],NULL) ; break ;
00095 case 'S': add_S = (int) strtod(argv[++iarg],NULL) ; break ;
00096 case 'A': add_A = (int) strtod(argv[++iarg],NULL) ; break ;
00097 case 'P': add_P = (int) strtod(argv[++iarg],NULL) ; break ;
00098 case 'L': add_L = (int) strtod(argv[++iarg],NULL) ; break ;
00099 case 'R': add_R = (int) strtod(argv[++iarg],NULL) ; break ;
00100
00101
00102
00103 case 'z':
00104 case 'Z': add_z = (int) strtod(argv[++iarg],NULL) ; break ;
00105
00106 default:
00107 fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; exit(1) ;
00108 }
00109
00110 if( mset != NULL ){
00111 fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg-1]) ;
00112 exit(1) ;
00113 }
00114
00115 iarg++ ; continue ;
00116 }
00117
00118
00119
00120 if( strcmp(argv[iarg],"-RL") == 0 || strcmp(argv[iarg],"-LR") == 0 ){
00121 if( add_R || add_L || mset != NULL ){
00122 fprintf(stderr,"** 3dZeropad: Can't use -RL with -R, -L, or -master!\n");
00123 exit(1) ;
00124 }
00125 RLsiz = (int) strtod(argv[++iarg],NULL) ;
00126 if( RLsiz < 1 ){
00127 fprintf(stderr,"** 3dZeropad: value after -RL is illegal!\n") ;
00128 exit(1) ;
00129 }
00130 iarg++ ; continue ;
00131 }
00132
00133 if( strcmp(argv[iarg],"-AP") == 0 || strcmp(argv[iarg],"-PA") == 0 ){
00134 if( add_A || add_P || mset != NULL ){
00135 fprintf(stderr,"** 3dZeropad: Can't use -AP with -A, -P, or -master!\n");
00136 exit(1) ;
00137 }
00138 APsiz = (int) strtod(argv[++iarg],NULL) ;
00139 if( APsiz < 1 ){
00140 fprintf(stderr,"** 3dZeropad: value after -AP is illegal!\n") ;
00141 exit(1) ;
00142 }
00143 iarg++ ; continue ;
00144 }
00145
00146 if( strcmp(argv[iarg],"-IS") == 0 || strcmp(argv[iarg],"-SI") == 0 ){
00147 if( add_S || add_I || mset != NULL ){
00148 fprintf(stderr,"** 3dZeropad: Can't use -IS with -I, -S, or -master!\n");
00149 exit(1) ;
00150 }
00151 ISsiz = (int) strtod(argv[++iarg],NULL) ;
00152 if( ISsiz < 1 ){
00153 fprintf(stderr,"** 3dZeropad: value after -IS is illegal!\n") ;
00154 exit(1) ;
00155 }
00156 iarg++ ; continue ;
00157 }
00158
00159
00160
00161 if( strcmp(argv[iarg],"-mm") == 0 ){
00162 if( mset != NULL ){
00163 fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg]) ;
00164 exit(1) ;
00165 }
00166 mm_flag = 1 ;
00167 iarg++ ; continue ;
00168 }
00169
00170
00171
00172 if( strcmp(argv[iarg],"-prefix") == 0 ){
00173 prefix = argv[++iarg] ;
00174 if( !THD_filename_ok(prefix) ){
00175 fprintf(stderr,"** 3dZeropad: Illegal string after -prefix!\n"); exit(1) ;
00176 }
00177 iarg++ ; continue ;
00178 }
00179
00180
00181
00182 if( strcmp(argv[iarg],"-master") == 0 ){
00183 if( add_I || add_S || add_A || mm_flag ||
00184 add_P || add_R || add_L || add_z ||
00185 RLsiz || APsiz || ISsiz ){
00186
00187 fprintf(stderr,"** 3dZeropad: Can't use -master with -I,-S,-A,-P,-R,-L, or -mm!\n");
00188 exit(1) ;
00189 }
00190 if( mset != NULL ){
00191 fprintf(stderr,"** 3dZeropad: Can't use -master twice!\n"); exit(1);
00192 }
00193
00194 mset = THD_open_dataset( argv[++iarg] ) ;
00195 if( !ISVALID_DSET(mset) ){
00196 fprintf(stderr,"** 3dZeropad: Can't open -master %s\n",argv[iarg]); exit(1);
00197 }
00198 iarg++ ; continue ;
00199 }
00200
00201
00202
00203 fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; exit(1) ;
00204 }
00205
00206
00207
00208 if( mset == NULL ){
00209 if( add_I==0 && add_S==0 && add_P==0 &&
00210 add_A==0 && add_L==0 && add_R==0 && add_z==0 &&
00211 RLsiz==0 && APsiz==0 && ISsiz==0 ){
00212
00213 fprintf(stderr,"++ 3dZeropad: All inputs are zero? Making a copy!\n") ;
00214 }
00215 }
00216
00217
00218
00219 if( RLsiz > 0 && (add_R || add_L || add_z) ){
00220 fprintf(stderr,"** 3dZeropad: Can't use -R or -L or -z with -RL!\n"); exit(1);
00221 }
00222 if( APsiz > 0 && (add_A || add_P || add_z) ){
00223 fprintf(stderr,"** 3dZeropad: Can't use -A or -P or -z with -AP!\n"); exit(1);
00224 }
00225 if( ISsiz > 0 && (add_I || add_S || add_z) ){
00226 fprintf(stderr,"** 3dZeropad: Can't use -I or -S or -z with -IS!\n"); exit(1);
00227 }
00228
00229
00230
00231 if( iarg >= argc ){
00232 fprintf(stderr,"** 3dZeropad: No input dataset on command line!\n"); exit(1);
00233 }
00234
00235 #if 0
00236 if( strncmp(argv[iarg],"3dcalc(",7) == 0 ){
00237 fprintf(stderr,"** 3dZeropad: Can't use '3dcalc()' input datasets here!\n"); exit(1);
00238 }
00239 #endif
00240
00241 inset = THD_open_dataset( argv[iarg] ) ;
00242 if( inset == NULL ){
00243 fprintf(stderr,"** 3dZeropad: Can't open dataset %s\n",argv[iarg]); exit(1);
00244 }
00245
00246 #if 0
00247 if( DSET_IS_MASTERED(inset) ){
00248 fprintf(stderr,"** 3dZeropad: Can't use partial datasets!\n"); exit(1);
00249 }
00250 #endif
00251
00252
00253
00254 if( mset != NULL ){
00255 THD_dataxes *max=mset->daxes, *iax=inset->daxes ;
00256 int nerr=0 ;
00257 float mxbot,mybot,mzbot , mxtop,mytop,mztop , mdx,mdy,mdz ;
00258 float ixbot,iybot,izbot , ixtop,iytop,iztop , idx,idy,idz ;
00259 int mnx,mny,mnz , inx,iny,inz ;
00260 int add_xb,add_xt , add_yb,add_yt , add_zb,add_zt ;
00261
00262
00263
00264 if( max->xxorient != iax->xxorient ||
00265 max->yyorient != iax->yyorient ||
00266 max->zzorient != iax->zzorient ){
00267
00268 fprintf(stderr,"** 3dZeropad: Master and Input datasets not oriented the same!\n");
00269 nerr++ ;
00270 }
00271
00272
00273
00274 mdx = max->xxdel ; mdy = max->yydel ; mdz = max->zzdel ;
00275 idx = iax->xxdel ; idy = iax->yydel ; idz = iax->zzdel ;
00276 mnx = max->nxx ; mny = max->nyy ; mnz = max->nzz ;
00277 inx = iax->nxx ; iny = iax->nyy ; inz = iax->nzz ;
00278
00279 if( fabs(mdx-idx) > 0.01*fabs(mdx) ||
00280 fabs(mdy-idy) > 0.01*fabs(mdy) ||
00281 fabs(mdz-idz) > 0.01*fabs(mdz) ){
00282
00283 fprintf(stderr,"** 3dZeropad: Master and Input datasets don't have same voxel size!\n");
00284 nerr++ ;
00285 }
00286
00287 if( nerr ) exit(1) ;
00288
00289
00290
00291 mxbot = max->xxorg ; mxtop = mxbot + mnx*mdx ;
00292 mybot = max->yyorg ; mytop = mybot + mny*mdy ;
00293 mzbot = max->zzorg ; mztop = mzbot + mnz*mdz ;
00294
00295 ixbot = iax->xxorg ; ixtop = ixbot + inx*idx ;
00296 iybot = iax->yyorg ; iytop = iybot + iny*idy ;
00297 izbot = iax->zzorg ; iztop = izbot + inz*idz ;
00298
00299
00300
00301 add_xb = (int) rint((ixbot-mxbot)/idx) ;
00302 add_xt = (int) rint((mxtop-ixtop)/idx) ;
00303 add_yb = (int) rint((iybot-mybot)/idy) ;
00304 add_yt = (int) rint((mytop-iytop)/idy) ;
00305 add_zb = (int) rint((izbot-mzbot)/idz) ;
00306 add_zt = (int) rint((mztop-iztop)/idz) ;
00307
00308
00309
00310 switch( iax->xxorient ){
00311 case ORI_R2L_TYPE: add_R = add_xb ; add_L = add_xt ; break ;
00312 case ORI_L2R_TYPE: add_L = add_xb ; add_R = add_xt ; break ;
00313 case ORI_I2S_TYPE: add_I = add_xb ; add_S = add_xt ; break ;
00314 case ORI_S2I_TYPE: add_S = add_xb ; add_I = add_xt ; break ;
00315 case ORI_A2P_TYPE: add_A = add_xb ; add_P = add_xt ; break ;
00316 case ORI_P2A_TYPE: add_P = add_xb ; add_A = add_xt ; break ;
00317 }
00318
00319 switch( iax->yyorient ){
00320 case ORI_R2L_TYPE: add_R = add_yb ; add_L = add_yt ; break ;
00321 case ORI_L2R_TYPE: add_L = add_yb ; add_R = add_yt ; break ;
00322 case ORI_I2S_TYPE: add_I = add_yb ; add_S = add_yt ; break ;
00323 case ORI_S2I_TYPE: add_S = add_yb ; add_I = add_yt ; break ;
00324 case ORI_A2P_TYPE: add_A = add_yb ; add_P = add_yt ; break ;
00325 case ORI_P2A_TYPE: add_P = add_yb ; add_A = add_yt ; break ;
00326 }
00327
00328 switch( iax->zzorient ){
00329 case ORI_R2L_TYPE: add_R = add_zb ; add_L = add_zt ; break ;
00330 case ORI_L2R_TYPE: add_L = add_zb ; add_R = add_zt ; break ;
00331 case ORI_I2S_TYPE: add_I = add_zb ; add_S = add_zt ; break ;
00332 case ORI_S2I_TYPE: add_S = add_zb ; add_I = add_zt ; break ;
00333 case ORI_A2P_TYPE: add_A = add_zb ; add_P = add_zt ; break ;
00334 case ORI_P2A_TYPE: add_P = add_zb ; add_A = add_zt ; break ;
00335 }
00336
00337 fprintf(stderr,"++ 3dZeropad -master => -I %d -S %d -A %d -P %d -R %d -L %d\n",
00338 add_I,add_S,add_A,add_P,add_R,add_L ) ;
00339
00340 DSET_delete(mset) ;
00341 }
00342
00343
00344
00345 if( add_z != 0 ){
00346 switch( inset->daxes->zzorient ){
00347 case ORI_R2L_TYPE:
00348 case ORI_L2R_TYPE:
00349 if( add_R != 0 && add_R != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -R\n");
00350 if( add_L != 0 && add_L != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -L\n");
00351 add_R = add_L = add_z ;
00352 break ;
00353
00354 case ORI_P2A_TYPE:
00355 case ORI_A2P_TYPE:
00356 if( add_P != 0 && add_P != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -P\n");
00357 if( add_A != 0 && add_A != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -A\n");
00358 add_P = add_A = add_z ;
00359 break ;
00360
00361 case ORI_I2S_TYPE:
00362 case ORI_S2I_TYPE:
00363 if( add_I != 0 && add_I != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -I\n");
00364 if( add_I != 0 && add_S != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -S\n");
00365 add_I = add_S = add_z ;
00366 break ;
00367 }
00368 }
00369
00370
00371
00372 if( RLsiz > 0 ){
00373 int nold=0 ;
00374 if( inset->daxes->xxorient == ORI_R2L_TYPE || inset->daxes->xxorient == ORI_L2R_TYPE )
00375 nold = inset->daxes->nxx ;
00376 else if( inset->daxes->yyorient == ORI_R2L_TYPE || inset->daxes->yyorient == ORI_L2R_TYPE )
00377 nold = inset->daxes->nyy ;
00378 else if( inset->daxes->zzorient == ORI_R2L_TYPE || inset->daxes->zzorient == ORI_L2R_TYPE )
00379 nold = inset->daxes->nzz ;
00380 if( nold > 0 ){
00381 add_R = (RLsiz-nold) / 2 ;
00382 add_L = RLsiz-(nold+add_R) ;
00383 }
00384 }
00385
00386 if( APsiz > 0 ){
00387 int nold=0 ;
00388 if( inset->daxes->xxorient == ORI_A2P_TYPE || inset->daxes->xxorient == ORI_P2A_TYPE )
00389 nold = inset->daxes->nxx ;
00390 else if( inset->daxes->yyorient == ORI_A2P_TYPE || inset->daxes->yyorient == ORI_P2A_TYPE )
00391 nold = inset->daxes->nyy ;
00392 else if( inset->daxes->zzorient == ORI_A2P_TYPE || inset->daxes->zzorient == ORI_P2A_TYPE )
00393 nold = inset->daxes->nzz ;
00394 if( nold > 0 ){
00395 add_A = (APsiz-nold) / 2 ;
00396 add_P = APsiz-(nold+add_A) ;
00397 }
00398 }
00399
00400 if( ISsiz > 0 ){
00401 int nold=0 ;
00402 if( inset->daxes->xxorient == ORI_I2S_TYPE || inset->daxes->xxorient == ORI_S2I_TYPE )
00403 nold = inset->daxes->nxx ;
00404 else if( inset->daxes->yyorient == ORI_I2S_TYPE || inset->daxes->yyorient == ORI_S2I_TYPE )
00405 nold = inset->daxes->nyy ;
00406 else if( inset->daxes->zzorient == ORI_I2S_TYPE || inset->daxes->zzorient == ORI_S2I_TYPE )
00407 nold = inset->daxes->nzz ;
00408 if( nold > 0 ){
00409 add_I = (ISsiz-nold) / 2 ;
00410 add_S = ISsiz-(nold+add_I) ;
00411 }
00412 }
00413
00414
00415
00416 flag = ZPAD_PURGE ;
00417 if( mm_flag ) flag |= ZPAD_MM ;
00418
00419 outset = THD_zeropad( inset ,
00420 add_I, add_S, add_A, add_P, add_L, add_R,
00421 prefix , flag ) ;
00422
00423 if( THD_is_file(DSET_HEADNAME(outset)) ){
00424 fprintf(stderr,
00425 "** 3dZeropad: output file %s already exists - FATAL ERROR!\n",
00426 DSET_HEADNAME(outset) ) ;
00427 exit(1) ;
00428 }
00429
00430 if( outset == NULL ){
00431 fprintf(stderr,"** 3dZeropad: Some error occurred in processing!\n") ;
00432 exit(1) ;
00433 }
00434
00435 tross_Copy_History( inset , outset ) ;
00436 tross_Make_History( "3dZeropad" , argc,argv , outset ) ;
00437
00438 DSET_write(outset) ;
00439 fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ;
00440 exit(0) ;
00441 }