1 #include "mrilib.h"
2 
3 /*
4   [PT: Oct 15, 2018]
5   + added '-extent_ijk_to_file FF' option to get slice numbers of
6     auto-bboxing in a nice text file.
7 
8   [PT: Oct 15, 2018]
9   + change where+how input dset check occurs, so subbrick selection is
10     possible
11 
12   [PT: Oct 15, 2018]
13   + added a couple other slice info things:
14     '-extent_ijk' to put bounding box slices to screen
15     '-extent_ijk_midslice' to put midslice of bounding box to screen
16 
17  */
18 
help_autobox()19 void help_autobox()
20 {
21    printf(
22     "Usage: 3dAutobox [options] DATASET\n"
23      "Computes size of a box that fits around the volume.\n"
24      "Also can be used to crop the volume to that box.\n"
25      "\n"
26      "OPTIONS:\n"
27      "--------\n"
28      "-prefix PREFIX = Crop the input dataset to the size of the box, and\n"
29      "                 write an output dataset with PREFIX for the name.\n"
30      "               * If -prefix is not used, no new volume is written out,\n"
31      "                 just the (x,y,z) extents of the voxels to be kept.\n"
32      "\n"
33      "-input DATASET = An alternate way to specify the input dataset.\n"
34      "                 The default method is to pass DATASET as\n"
35      "                 the last parameter on the command line.\n"
36      "\n"
37      "-noclust       = Don't do any clustering to find box. Any non-zero\n"
38      "                 voxel will be preserved in the cropped volume.\n"
39      "                 The default method uses some clustering to find the\n"
40      "                 cropping box, and will clip off small isolated blobs.\n"
41      "\n"
42      "-extent: Write to standard out the spatial extent of the box\n"
43      "\n"
44      "-extent_ijk    = Write out the 6 auto bbox ijk slice numbers to\n"
45      "                 screen:\n"
46      "                     imin imax jmin jmax kmin kmax\n"
47      "                 Note that resampling would affect the ijk vals (but\n"
48      "                 not necessarily the xyz ones).\n"
49      "                 Also note that this value is calculated before\n"
50      "                 any '-npad ...' option, so it would ignore that.\n"
51      "\n"
52      "-extent_ijk_to_file FF = Write out the 6 auto bbox ijk slice numbers to\n"
53      "                 a simple-formatted text file FF (single row file):\n"
54      "                     imin imax jmin jmax kmin kmax\n"
55      "                 (same notes as above apply).\n"
56      "\n"
57      "-extent_ijk_midslice = Write out the 3 ijk midslices of the autobox to\n"
58      "                 the screen:\n"
59      "                     imid jmid kmid\n"
60      "                 These are obtained via: (imin + imax)/2, etc.\n"
61      "\n"
62      "-extent_xyz_midslice = Write out the 3 xyz midslices of the autobox to\n"
63      "                 the screen:\n"
64      "                     xmid ymid zmid\n"
65      "                 These are obtained via: (xmin + xmax)/2, etc.\n"
66      "                 These follow the same meaning as '-extent'.\n"
67      "\n"
68      "-npad NNN      = Number of extra voxels to pad on each side of box,\n"
69      "                 since some troublesome people (that's you, LRF) want\n"
70      "                 this feature for no apparent reason.\n"
71      "               * With this option, it is possible to get a dataset that\n"
72      "                 is actually bigger than the input.\n"
73      "               * You can input a negative value for NNN, which will\n"
74      "                 crop the dataset even more than the automatic method.\n"
75      "\n"
76    ) ;
77    PRINT_COMPILE_DATE ; return ;
78 }
79 
80 /*----------------------------------------------------------------------------*/
81 
main(int argc,char * argv[])82 int main( int argc , char * argv[] )
83 {
84    THD_3dim_dataset *dset, *outset=NULL;
85    int iarg=1, npad = 0, extent=0;
86    char *prefix=NULL, *iname=NULL;
87 
88    char *oijkext = NULL;
89    FILE *fout_ijkext=NULL;
90    int extent_ijk=0;
91    int extent_ijk_midslice=0;
92    int imid=0, jmid=0, kmid=0;
93    int extent_xyz_midslice=0;
94    float xmid=0, ymid=0, zmid=0;
95 
96 
97    /*-- startup bureaucracy --*/
98 
99    mainENTRY("3dAutobox main"); machdep(); AFNI_logger("3dAutobox",argc,argv);
100    PRINT_VERSION("3dAutobox") ;
101 
102    /*-- read command line options --*/
103 
104    iarg = 1 ;
105    while( iarg < argc && argv[iarg][0] == '-' ){
106 
107       if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
108          help_autobox();
109          exit(0) ;
110       }
111 
112       if( strcmp(argv[iarg],"-prefix") == 0 ){
113          prefix = argv[++iarg] ;
114          if( !THD_filename_ok(prefix) ){
115             fprintf(stderr,"** 3dAutobox: Illegal string after -prefix!\n");
116             exit(1) ;
117          }
118          iarg++ ; continue ;
119       }
120 
121       if( strcmp(argv[iarg],"-input") == 0 ){
122          iname = argv[++iarg] ;
123          // This is a bad check, because it doesn't permit subbrick
124          // selection!  Will do check later.
125          /*if( !THD_filename_ok(iname) ){
126             fprintf(stderr,"** 3dAutobox: Illegal string after -input!\n");
127             exit(1) ;
128             }*/
129          iarg++ ; continue ;
130       }
131 
132       if( strcmp(argv[iarg],"-noclust") == 0 ){
133          MRI_autobbox_clust(0) ;  /* turn of clustering and clipping */
134          THD_autobbox_clip(0) ;
135          iarg++ ; continue ;
136       }
137 
138       if( strcmp(argv[iarg],"-npad") == 0 ){
139         npad = (int)strtod(argv[++iarg],NULL) ;
140         iarg++ ; continue ;
141       }
142 
143       if( strcmp(argv[iarg],"-extent_ijk") == 0 ){
144         extent_ijk = 1 ;
145         iarg++ ; continue ;
146       }
147 
148       if( strcmp(argv[iarg],"-extent_ijk_to_file") == 0 ){
149 			if( ++iarg >= argc )
150 				ERROR_exit("Need argument after '-extent_ijk_to_file'\n") ;
151          oijkext = argv[iarg];
152          iarg++ ; continue ;
153       }
154 
155       if( strcmp(argv[iarg],"-extent_ijk_midslice") == 0 ){
156         extent_ijk_midslice = 1 ;
157         iarg++ ; continue ;
158       }
159 
160       if( strcmp(argv[iarg],"-extent_xyz_midslice") == 0 ){
161         extent_xyz_midslice = 1 ;
162         iarg++ ; continue ;
163       }
164 
165       if( strcmp(argv[iarg],"-extent") == 0 ){
166         extent = 1 ;
167         iarg++ ; continue ;
168       }
169 
170      /*- washappenin, dood? -*/
171 
172       ERROR_message("** 3dAutobox: %s makes no sense here.\n",
173                  argv[iarg]) ;
174       suggest_best_prog_option(argv[0], argv[iarg]);
175       exit(1);
176    }
177 
178    if( argc < 2){ help_autobox(); exit(0); }
179 
180    /* got input ? */
181 
182    if( iarg == argc-1 )
183      iname = argv[iarg] ;
184    else if (iarg != argc)
185      ERROR_exit("** 3dAutobox: %s is nonsense on the line \n"
186                 "   I know you're John; stop pretending you have an accent!",
187                 argv[iarg]) ;
188 
189    if( !iname )
190      ERROR_exit("** 3dAutobox: Where is my input?") ;
191 
192    /*-- read data --*/
193 
194    dset = THD_open_dataset(iname);
195    // Check here instead of after -input.
196    if( dset == NULL )
197       ERROR_exit("Can't open time series dataset '%s'.",iname);
198    CHECK_OPEN_ERROR(dset,iname);
199 
200    if( DSET_BRICK_TYPE(dset,0) != MRI_short &&
201        DSET_BRICK_TYPE(dset,0) != MRI_byte  &&
202        DSET_BRICK_TYPE(dset,0) != MRI_float   )
203        ERROR_exit("** ILLEGAL dataset type: %s :-(",
204                   MRI_type_name[DSET_BRICK_TYPE(dset,0)]) ;
205 
206    DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;
207 
208    {
209       int nx=DSET_NX(dset), ny=DSET_NY(dset), nz=DSET_NZ(dset), nxy=nx*ny ;
210       int xm=-1,xp=-1,ym=-1,yp=-1,zm=-1,zp=-1;
211       THD_autobbox( dset , &xm,&xp , &ym,&yp , &zm,&zp, NULL ) ;
212 
213       xm -= npad; ym -= npad; zm -= npad;  /* for LRF */
214       xp += npad; yp += npad; zp += npad;
215 
216       INFO_message("Auto bbox: x=%d..%d  y=%d..%d  z=%d..%d\n",
217                    xm,xp,ym,yp,zm,zp ) ;
218 
219       // [PT: Oct 18, 2018] New output text file, if desired
220       if( oijkext ) {
221          if( (fout_ijkext = fopen(oijkext, "w")) == NULL ) {
222             fprintf(stderr, "\n\nError opening file %s.\n", oijkext);
223             exit(1);
224          }
225          fprintf( fout_ijkext, "%8d %8d %8d %8d %8d %8d\n",
226                   xm, xp, ym, yp, zm, zp );
227          fclose(fout_ijkext);
228          INFO_message("Wrote ijk extents file: %s", oijkext);
229       }
230 
231       if( extent_ijk )
232          printf( "%8d %8d %8d %8d %8d %8d\n",
233                  xm, xp, ym, yp, zm, zp );
234 
235       if( extent_ijk_midslice ) {
236          imid = (xm + xp) / 2;  // integer division fine, b/c we need ints
237          jmid = (ym + yp) / 2;
238          kmid = (zm + zp) / 2;
239          printf( "%8d %8d %8d\n", imid, jmid, kmid );
240       }
241 
242 
243       if ( (extent && !prefix) || (extent_xyz_midslice && !prefix) )
244          prefix = "EXTENT_ONLY";
245 
246       if( prefix ){
247          outset = THD_zeropad( dset ,
248                             -xm, xp-nx+1,
249                             -ym, yp-ny+1,
250                             -zm, zp-nz+1,
251                             prefix , ZPAD_IJK ) ;
252          if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) )
253             ERROR_exit("3dAutobox: output file %s already exists :-(",
254                        DSET_HEADNAME(outset) ) ;
255 
256          if( outset == NULL )
257             ERROR_exit("3dAutobox: Some error occurred in processing :-(") ;
258 
259          tross_Copy_History( dset , outset ) ;       /* 31 Jan 2001 - RWCox */
260          tross_Make_History( "3dAutobox" , argc,argv , outset ) ;
261 
262          if (!strstr(prefix,"EXTENT_ONLY")) {
263             DSET_write(outset) ;
264             INFO_message("3dAutobox: output dataset = %s",
265                          DSET_BRIKNAME(outset)) ;
266          }
267          if (extent) {
268           float RL_AP_IS[6];
269           THD_dset_extent(outset, '-', RL_AP_IS);
270           printf("Extent auto bbox: R=%f L=%f  A=%f P=%f  I=%f S=%f\n",
271                     RL_AP_IS[0],RL_AP_IS[1],
272                     RL_AP_IS[2],RL_AP_IS[3],
273                     RL_AP_IS[4],RL_AP_IS[5] ) ;
274          }
275          if( extent_xyz_midslice ) {
276             INFO_message("aaa" );
277             float RL_AP_IS2[6];
278             THD_dset_extent(outset, '-', RL_AP_IS2);
279             xmid = (RL_AP_IS2[0] + RL_AP_IS2[1]) / 2.;
280             ymid = (RL_AP_IS2[2] + RL_AP_IS2[3]) / 2.;
281             zmid = (RL_AP_IS2[4] + RL_AP_IS2[5]) / 2.;
282             printf( "%10.5f %10.5f %10.5f\n", xmid, ymid, zmid );
283          }
284       }
285    }
286 
287    exit(0) ;
288 }
289