1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #include "mrilib.h"
8 
9 /***** This program makes a "duplicate" of a dataset, which is
10        nothing more than something that is warped from the parent
11        with the identity warp.
12 
13        Why is this useful?  Because you can then overwrite this
14        warped-on-demand dataset in AFNI.
15 
16        RWCox, June 1995, March 1996, April 1999
17 *****/
18 
19 static char DUP_session[THD_MAX_NAME]  = "./" ;
20 static char DUP_prefix[THD_MAX_PREFIX] = "dup" ;
21 
22 static int anatomy_type  = ILLEGAL_TYPE ;
23 static int function_type = ILLEGAL_TYPE ;
24 static int dataset_type  = ILLEGAL_TYPE ;
25 
26 THD_3dim_dataset * duplicate_dataset( THD_3dim_dataset * parent ) ;
27 
main(int argc,char * argv[])28 int main( int argc , char * argv[] )
29 {
30    int nopt , ii ;
31    THD_3dim_dataset * dset_in , * dset_out ;
32    THD_warp * warp , * twarp ;
33 
34    /** check for help **/
35 
36 WARNING_message("This program (3ddup) is old, not maintained, and probably useless!") ;
37 
38    if( argc < 2 || strncmp(argv[1],"-help",3) == 0 ){
39       printf(
40        "Usage: 3ddup [options] dataset\n"
41        " 'Duplicates' a 3D dataset by making a warp-on-demand copy.\n"
42        " Applications:\n"
43        "   - allows AFNI to resample a dataset to a new grid without\n"
44        "       destroying an existing data .BRIK\n"
45        "   - change a functional dataset to anatomical, or vice-versa\n"
46        "   - THIS PROGRAM IS BASICALLY OBSOLETE !!\n"
47        "\n"
48        "OPTIONS:\n"
49        "  -'type'           = Convert to the given 'type', which must be\n"
50        "                       chosen from the same list as in to3d\n"
51        "  -session dirname  = Write output into given directory (default=./)\n"
52        "  -prefix  pname    = Use 'pname' for the output directory prefix\n"
53        "                       (default=dup)\n"
54        "N.B.: Even if the new dataset is anatomical, it will not contain\n"
55        "      any markers, duplicated from the original, or otherwise.\n"
56      ) ;
57      PRINT_COMPILE_DATE ; exit(0) ;
58    }
59 
60    /** scan command line options **/
61 
62 #define DUPERR(str) \
63    do{ fprintf(stderr,"ERROR: %s\n",(str)) ; exit(1) ; } while(0)
64 
65    nopt = 1 ;
66    while( nopt < argc && argv[nopt][0] == '-' ){
67 
68       /*** the following code is stolen from to3d ***/
69 
70       /* -type from the anatomy prefixes */
71 
72       for( ii=FIRST_ANAT_TYPE ; ii <= LAST_ANAT_TYPE ; ii++ )
73          if( strncmp( &(argv[nopt][1]) ,
74                       ANAT_prefixstr[ii] , THD_MAX_PREFIX ) == 0 ) break ;
75 
76       if( ii <= LAST_ANAT_TYPE ){
77          anatomy_type = ii ;
78          dataset_type = HEAD_ANAT_TYPE ;
79          nopt++ ; continue ;
80       }
81 
82       /* -type from the function prefixes */
83 
84       for( ii=FIRST_FUNC_TYPE ; ii <= LAST_FUNC_TYPE ; ii++ )
85          if( strncmp( &(argv[nopt][1]) ,
86                       FUNC_prefixstr[ii] , THD_MAX_PREFIX ) == 0 ) break ;
87 
88       if( ii <= LAST_FUNC_TYPE ){
89          function_type = ii ;
90          dataset_type  = HEAD_FUNC_TYPE ;
91          nopt++ ; continue ;
92       }
93 
94       /**** -session dirname ****/
95 
96       if( strncmp(argv[nopt],"-session",6) == 0 ){
97          nopt++ ;
98          if( nopt >= argc ) DUPERR("need argument after -session!") ;
99          MCW_strncpy( DUP_session , argv[nopt++] , THD_MAX_NAME ) ;
100          continue ;
101       }
102 
103       /**** -prefix prefix ****/
104 
105       if( strncmp(argv[nopt],"-prefix",6) == 0 ){
106          nopt++ ;
107          if( nopt >= argc ) DUPERR("need argument after -prefix!") ;
108          MCW_strncpy( DUP_prefix , argv[nopt++] , THD_MAX_PREFIX ) ;
109          continue ;
110       }
111 
112       /**** unknown switch ****/
113 
114       fprintf(stderr,"*** unrecognized option %s\n",argv[nopt]) ;
115       exit(1) ;
116    }  /* end of loop over options */
117 
118    if( nopt >= argc ) DUPERR("no input dataset name given!") ;
119 
120    /*** read input dataset ***/
121 
122    dset_in = THD_open_one_dataset( argv[nopt] ) ;
123    if( ! ISVALID_3DIM_DATASET(dset_in) ) DUPERR("cannot read dataset!\n") ;
124 
125    /*** copy header info ***/
126 
127    dset_out = EDIT_empty_copy( dset_in ) ;
128    if( !ISVALID_3DIM_DATASET(dset_out) ) DUPERR("duplication fails!\n");
129 
130    EDIT_dset_items( dset_out ,
131                       ADN_prefix         , DUP_prefix ,
132                       ADN_label1         , DUP_prefix ,   /* label = prefix */
133                       ADN_directory_name , DUP_session ,
134                       ADN_self_name      , DUP_prefix ,
135                     ADN_none ) ;
136 
137    tross_Copy_History( dset_in , dset_out ) ;
138    tross_Make_History( "3ddup" , argc , argv , dset_out ) ;
139 
140    /*** change of type? ***/
141 
142    if( dataset_type>=FIRST_3DIM_TYPE && dataset_type<=LAST_3DIM_TYPE ){
143 
144       int isfunc , new_nvals , old_ntimes ;
145 
146       old_ntimes = DSET_NUM_TIMES(dset_in) ;
147 
148       isfunc    = ISFUNCTYPE(dataset_type) ;
149       new_nvals = (isfunc) ? FUNC_nvals[function_type]
150                            : ANAT_nvals[anatomy_type]  ;
151 
152       if( ( isfunc && function_type == FUNC_BUCK_TYPE) ||
153           (!isfunc && anatomy_type  == ANAT_BUCK_TYPE)   )  /* 30 Nov 1997 */
154          new_nvals = dset_in->dblk->nvals ;
155 
156 
157       if( new_nvals > dset_in->dblk->nvals ){
158          fprintf(stderr,
159                  "ERROR: new dataset type has %d values per voxel,"
160                  " but old has %d!\n"
161                  "  ==> cannot make duplicate!\n" ,
162                  new_nvals , dset_in->dblk->nvals ) ;
163          exit(1) ;
164 
165       } else if( new_nvals < dset_in->dblk->nvals ){
166          if( old_ntimes == 1 )
167             fprintf(stderr,
168                  "WARNING: new dataset type has %d values per voxel,"
169                  " but old has %d!\n"
170                  "  ==> new dataset will not access all data in old!\n",
171                  new_nvals , dset_in->dblk->nvals ) ;
172          else if( new_nvals > 1){
173             fprintf(stderr,
174                  "ERROR: new dataset type has %d values per voxel per time,"
175                  " but old has %d!\n"
176                  "  *** this conversion is not legal for time-dependent data!\n",
177                  new_nvals , DSET_NVALS_PER_TIME(dset_in) ) ;
178             exit(1) ;
179          }
180       }
181 
182       EDIT_dset_items( dset_out ,
183                           ADN_type , dataset_type ,
184                           ADN_func_type ,
185                           ISANATTYPE(dataset_type) ? (anatomy_type)
186                                                    : (function_type) ,
187                        ADN_none ) ;
188    }
189 
190    warp = myRwcNew( THD_warp ) ; *warp = IDENTITY_WARP ;
191 
192    EDIT_dset_items( dset_out ,
193                        ADN_warp        , warp    ,
194                        ADN_warp_parent , dset_in ,
195                     ADN_none ) ;
196 
197    /*** done! ***/
198 
199    THD_write_3dim_dataset( NULL , NULL , dset_out , False ) ;
200 
201    exit(0) ;
202 }
203