Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

3dcopy.c

Go to the documentation of this file.
00001 #include "mrilib.h"
00002 
00003 int THD_copy_file( char *old , char *newFile ) ; /* prototype */
00004 
00005 /*---------------------------------------------------------------------*/
00006 
00007 int main( int argc , char * argv[] )
00008 {
00009    int nopt=1 , old_view , new_view , vbot,vtop ;
00010    char * old_name , * new_name ;
00011    char old_prefix[THD_MAX_PREFIX] , new_prefix[THD_MAX_PREFIX] ;
00012    int ii,jj , old_len , new_len ;
00013    THD_3dim_dataset *dset[LAST_VIEW_TYPE+1] ;
00014    MCW_idcode        idc [LAST_VIEW_TYPE+1] ;
00015    char dname[THD_MAX_NAME] ;
00016    char old_brikname[THD_MAX_NAME] ;
00017    char new_brikname[THD_MAX_NAME] ;
00018    char *old_bname=NULL ;
00019    int brick_ccode , verb=0 ;
00020    int denote=0 ;   /* 08 Jul 2005 */
00021 
00022    /*-- help? --*/
00023 
00024    if( argc < 3 || strcmp(argv[1],"-help") == 0 ){
00025       printf(
00026        "Usage 1: 3dcopy [-verb] [-denote] old_prefix new_prefix\n"
00027        "  Will copy all datasets using the old_prefix to use the new_prefix;\n"
00028        "    3dcopy fred ethel\n"
00029        "  will copy   fred+orig.HEAD    to ethel+orig.HEAD\n"
00030        "              fred+orig.BRIK    to ethel+orig.BRIK\n"
00031        "              fred+tlrc.HEAD    to ethel+tlrc.HEAD\n"
00032        "              fred+tlrc.BRIK.gz to ethel+tlrc.BRIK.gz\n"
00033        "\n"
00034        "Usage 2: 3dcopy old_prefix+view new_prefix\n"
00035        "  Will copy only the dataset with the given view (orig, acpc, tlrc).\n"
00036        "\n"
00037        "Usage 3: 3dcopy old_dataset new_prefix\n"
00038        "  Will copy the non-AFNI formatted dataset (e.g., MINC, ANALYZE, CTF)\n"
00039        "  to the AFNI formatted dataset with the given new prefix.\n"
00040        "\n"
00041        "Notes:\n"
00042        "* The new datasets have new ID codes.  If you are renaming\n"
00043        "   multiple datasets (as in Usage 1), then if the old +orig\n"
00044        "   dataset is the warp parent of the old +acpc and/or +tlrc\n"
00045        "   datasets, then the new +orig dataset will be the warp\n"
00046        "   parent of the new +acpc and +tlrc datasets.  If any other\n"
00047        "   datasets point to the old datasets as anat or warp parents,\n"
00048        "   they will still point to the old datasets, not these new ones.\n"
00049        "* The BRIK files are copied if they exist, keeping the compression\n"
00050        "   suffix unchanged (if any).\n"
00051        "* The old_prefix may have a directory name attached in front,\n"
00052        "   as in 'gerard/manley/hopkins'.\n"
00053        "* If the new_prefix does not have a directory name attached\n"
00054        "   (i.e., does NOT look like 'homer/simpson'), then the new\n"
00055        "   datasets will be written in the current directory ('./').\n"
00056        "* The new_prefix cannot JUST be a directory (unlike the Unix\n"
00057        "   utility 'cp'); you must supply a filename prefix, even if\n"
00058        "   is identical to the filename prefix in old_prefix.\n"
00059        "* The '-verb' option will print progress reports; otherwise, the\n"
00060        "   program operates silently (unless an error is detected).\n"
00061        "* The '-denote' option will remove any Notes from the file.\n"
00062       ) ;
00063       exit(0) ;
00064    }
00065 
00066    mainENTRY("3dcopy") ; machdep() ; AFNI_logger("3dcopy",argc,argv) ;
00067    PRINT_VERSION("3dcopy") ;
00068 
00069    /* input arguments */
00070 
00071    while( nopt < argc && argv[nopt][0] == '-' ){
00072      if( strcmp(argv[nopt],"-verb")   == 0 ){ verb   = 1; nopt++; continue; }
00073      if( strcmp(argv[nopt],"-denote") == 0 ){ denote = 1; nopt++; continue; }
00074    }
00075    if( nopt+1 >= argc )
00076      ERROR_exit("3copy needs input AND output filenames!\n") ;
00077 
00078    old_name = argv[nopt++] ; old_len = strlen(old_name) ;
00079    new_name = argv[nopt++] ; new_len = strlen(new_name) ;
00080 
00081    if( old_len < 1 || old_len > THD_MAX_PREFIX || !THD_filename_ok(old_name) )
00082      ERROR_exit("Illegal old dataset name! - EXIT\n") ;
00083    if( new_len < 1 || new_len > THD_MAX_PREFIX || !THD_filename_ok(new_name) )
00084      ERROR_exit("Illegal new dataset name! - EXIT\n") ;
00085 
00086    if( strstr(new_name,"/") == NULL ){        /* put cwd on new name, if no */
00087      char *str = malloc(new_len+16) ;         /* directory present at all   */
00088      strcpy(str,"./") ; strcat(str,new_name) ;
00089      new_name = str ;
00090    }
00091 
00092    /* check old_name for a +view suffix somewhere */
00093 
00094    MCW_strncpy(old_prefix,old_name,THD_MAX_PREFIX) ;
00095    if( strstr(old_name,"+") == NULL ){
00096       old_view = ILLEGAL_TYPE ;               /* no +view ==> do all views */
00097    } else {
00098       char * qq ;
00099       for( qq=old_name+old_len ; *qq != '+' ; qq-- ) ; /* find last '+' */
00100       qq++ ;                                           /* point to view */
00101       for( old_view=0 ; old_view <= LAST_VIEW_TYPE ; old_view++ )
00102          if( strncmp(qq,VIEW_codestr[old_view],
00103                         strlen(VIEW_codestr[old_view])) == 0 ) break ;
00104 
00105       if( old_view > LAST_VIEW_TYPE ){
00106          old_view = ILLEGAL_TYPE ;               /* the '+' is a fake! */
00107       } else {
00108          old_prefix[ (qq-old_name)-1 ] = '\0' ;  /* truncate prefix */
00109       }
00110    }
00111 
00112    /* check new_name for a +view suffix, also */
00113 
00114    MCW_strncpy(new_prefix,new_name,THD_MAX_PREFIX) ;
00115    if( strstr(new_name,"+") == NULL ){
00116       new_view = ILLEGAL_TYPE ;               /* no +view */
00117    } else {
00118       char * qq ;
00119       for( qq=new_name+new_len ; *qq != '+' ; qq-- ) ; /* find last '+' */
00120       qq++ ;                                           /* point to view */
00121       for( new_view=0 ; new_view <= LAST_VIEW_TYPE ; new_view++ )
00122          if( strncmp(qq,VIEW_codestr[new_view],
00123                         strlen(VIEW_codestr[new_view])) == 0 ) break ;
00124 
00125       if( new_view > LAST_VIEW_TYPE ){
00126          new_view = ILLEGAL_TYPE ;               /* the '+' is a fake! */
00127       } else {
00128          new_prefix[ (qq-new_name)-1 ] = '\0' ;  /* truncate prefix */
00129       }
00130    }
00131    if( !THD_filename_ok( new_prefix ) )  /* 28 Jan 2003 */
00132      ERROR_exit("Illegal new prefix: %s\n",new_prefix) ;
00133    if( strstr(new_prefix,".nii") != NULL )  /* 06 Apr 2005 */
00134      ERROR_exit("You can't use 3dcopy to create a .nii file!\n"
00135                 " *        Use program 3dAFNItoNIFTI for that purpose.\n") ;
00136 
00137    /* 28 Jan 2003:
00138       to allow for non-AFNI datasets input,
00139       we now check if we can read the input dataset without a view */
00140 
00141    if( old_view == ILLEGAL_TYPE ){
00142      THD_3dim_dataset *qset , *cset ;
00143      qset = THD_open_one_dataset( old_prefix ) ;
00144      if( qset != NULL ){
00145        if( verb ) INFO_message("Opened dataset %s\n",old_prefix) ;
00146        cset = EDIT_empty_copy( qset ) ;
00147        if( new_view < 0 ) new_view = qset->view_type ;
00148        EDIT_dset_items( cset ,
00149                           ADN_prefix    , new_prefix ,
00150                           ADN_view_type , new_view   ,
00151                         ADN_none ) ;
00152        tross_Make_History( "3dcopy" , argc,argv , cset ) ;
00153        DSET_mallocize(qset); DSET_load(qset);
00154        if( !DSET_LOADED(qset) )
00155          ERROR_exit("Can't load dataset %s\n",old_prefix) ;
00156        for( ii=0 ; ii < DSET_NVALS(qset) ; ii++ )
00157          EDIT_substitute_brick( cset , ii ,
00158                                 DSET_BRICK_TYPE(qset,ii) ,
00159                                 DSET_BRICK_ARRAY(qset,ii) ) ;
00160        if( verb ) INFO_message("Writing %s and %s\n",
00161                           DSET_HEADNAME(cset) , DSET_BRIKNAME(cset) ) ;
00162 
00163        if( cset->type      == HEAD_ANAT_TYPE     &&
00164            cset->view_type == VIEW_ORIGINAL_TYPE &&
00165            DSET_NUM_TIMES(cset) == 1               ){  /* add markers? */
00166 
00167          THD_marker_set *markers ;
00168          int ii , jj ;
00169 
00170          markers = cset->markers = myXtNew( THD_marker_set ) ;
00171          markers->numdef = 0 ;
00172 
00173          for( ii=0 ; ii < MARKS_MAXNUM ; ii++ ){       /* null all data out */
00174            markers->valid[ii] = 0 ;
00175            for( jj=0 ; jj < MARKS_MAXLAB  ; jj++ )
00176              markers->label[ii][jj] = '\0';
00177            for( jj=0 ; jj < MARKS_MAXHELP ; jj++ )
00178              markers->help[ii][jj]  = '\0';
00179          }
00180 
00181          for( ii=0 ; ii < NMARK_ALIGN ; ii++ ){       /* copy strings in */
00182            MCW_strncpy( &(markers->label[ii][0]) ,
00183                         THD_align_label[ii] , MARKS_MAXLAB ) ;
00184            MCW_strncpy( &(markers->help[ii][0]) ,
00185                         THD_align_help[ii] , MARKS_MAXHELP ) ;
00186          }
00187 
00188          for( ii=0 ; ii < MARKS_MAXFLAG ; ii++ )     /* copy flags in */
00189            markers->aflags[ii] = THD_align_aflags[ii] ;
00190        }
00191 
00192        if( denote ) THD_anonymize_write(1) ;  /* 08 Jul 2005 */
00193 
00194        DSET_write(cset) ; exit(0) ;
00195      }
00196    }
00197 
00198    /* of course, we don't actually use the +view suffix on the output */
00199 
00200    if( new_view >= 0 ){
00201      if( verb ) INFO_message("ignoring +view on new_prefix.\n") ;
00202      new_view = ILLEGAL_TYPE ;
00203    }
00204 
00205    if( old_view >= 0 ){
00206      vbot = vtop = old_view ;
00207    } else {
00208      vbot = 0 ; vtop = LAST_VIEW_TYPE ;
00209    }
00210 
00211    /*-- loop over views, open and rename datasets internally --*/
00212 
00213    for( ii=vbot ; ii <= vtop ; ii++ ){
00214 
00215       /*-- open the ii-th view dataset --*/
00216 
00217       sprintf(dname,"%s+%s" , old_prefix , VIEW_codestr[ii] ) ;
00218 
00219       if( verb ) INFO_message("Opening dataset %s\n",dname) ;
00220 
00221       dset[ii] = THD_open_one_dataset( dname ) ;
00222       if( dset[ii] == NULL ){
00223         ERROR_message("Can't open dataset %s - SKIPPING \n",dname) ; continue ;
00224       }
00225       idc[ii] = dset[ii]->idcode ; /* save old ID code */
00226 
00227       /*-- rename it (but don't save to disk yet) --*/
00228 
00229       dset[ii]->idcode = MCW_new_idcode() ;
00230       dset[ii]->dblk->diskptr->storage_mode = STORAGE_BY_BRICK ; /* 14 Jan 2004 */
00231       EDIT_dset_items( dset[ii] , ADN_prefix,new_prefix , ADN_none ) ;
00232 
00233       /*-- check if new header already exists --*/
00234 
00235       if( THD_is_file( DSET_HEADNAME(dset[ii]) ) )
00236          ERROR_exit("Output dataset %s already exists! - EXIT\n",
00237                  DSET_HEADNAME(dset[ii]) ) ;
00238 
00239       /*-- check if current dataset has a warp
00240            parent in one of the previous datasets;
00241            if so, alter it to be that datasets new idcode;
00242            otherwise, leave the warp parent idcode unchanged --*/
00243 
00244       if( ii > 0 && !ISZERO_IDCODE(dset[ii]->warp_parent_idcode) ){
00245         for( jj=vbot ; jj < ii ; jj++ ){
00246           if( EQUIV_IDCODES(idc[jj],dset[ii]->warp_parent_idcode) ){
00247              if( verb )
00248                INFO_message("Changing warp parent of %s to %s\n",
00249                        DSET_HEADNAME(dset[ii]) , DSET_HEADNAME(dset[jj]) ) ;
00250 
00251              dset[ii]->warp_parent_idcode = idc[jj] ; break ;
00252           }
00253         }
00254       }
00255    }
00256 
00257    /*-- get to here means all datasets are ready to be
00258         written back out to disk under their new names --*/
00259 
00260    /*-- loop over views, rewrite dataset HEADs and copy dataset BRIKs --*/
00261 
00262    for( ii=vbot ; ii <= vtop ; ii++ ){
00263 
00264       if( dset[ii] == NULL ) continue ;  /* skip */
00265 
00266       tross_Make_History( "3dcopy" , argc,argv , dset[ii] ) ;
00267 
00268       if( verb )
00269         INFO_message("Writing new header %s\n",DSET_HEADNAME(dset[ii])) ;
00270 
00271       if( denote ) THD_anonymize_write(1) ;  /* 08 Jul 2005 */
00272 
00273       DSET_write_header( dset[ii] ) ;  /* new header is written */
00274 
00275       /*-- create the .BRIK filename for the old and new datasets --*/
00276 
00277       sprintf( old_brikname , "%s+%s.%s" ,
00278                old_prefix , VIEW_codestr[ii] , DATASET_BRICK_SUFFIX ) ;
00279 
00280       /*-- however, the .BRIK might have a compression suffix on it,
00281            which affects both its old name and its new name         --*/
00282 
00283       brick_ccode = COMPRESS_filecode(old_brikname) ;
00284       if( brick_ccode == COMPRESS_NOFILE ){
00285          new_brikname[0] = '\0' ;  /* flag to do nothing */
00286       } else {
00287          old_bname = COMPRESS_filename( old_brikname ) ;
00288          if( old_bname == NULL )  /* should not happen */
00289            ERROR_exit("COMPRESS_filename() fails! - EXIT\n");
00290          sprintf( new_brikname , "%s+%s.%s" ,
00291                   new_prefix , VIEW_codestr[ii] , DATASET_BRICK_SUFFIX ) ;
00292          if( brick_ccode >= 0 )
00293             strcat(new_brikname,COMPRESS_suffix[brick_ccode]) ;
00294 
00295          if( THD_is_file(new_brikname) )
00296             ERROR_exit("New brick %s already exists! - EXIT\n",
00297                     new_brikname) ;
00298       }
00299 
00300       if( new_brikname[0] == '\0' ){ /* skip BRIK copy */
00301          if( verb )
00302            ERROR_message("Old brick file %s does not exist - SKIPPING\n",
00303                    old_brikname ) ;
00304          continue ;
00305       }
00306 
00307       if( verb )
00308         INFO_message("Copying file %s to %s\n",old_bname,new_brikname) ;
00309 
00310       THD_copy_file( old_bname , new_brikname ) ;
00311       free(old_bname) ;
00312    }
00313 
00314    exit(0) ;
00315 }
00316 
00317 /*------------------------------------------------------------*/
00318 
00319 #undef NBUF
00320 #define NBUF 1048576  /* 2^20 */
00321 
00322 int THD_copy_file( char *old , char *newFile )
00323 {
00324    FILE *fold , *fnew ;
00325    char *buf ;
00326    int ii,jj ;
00327 
00328    if( old == NULL || old[0] == '\0' ||
00329        newFile == NULL || newFile[0] == '\0'   ) return 1 ;
00330 
00331    fold = fopen( old , "rb" ) ;
00332    if( fold == NULL ){ perror("Old open fails"); return 1; }
00333 
00334    fnew = fopen( newFile , "wb" ) ;
00335    if( fnew == NULL ){ perror("New open fails"); fclose(fold); return 1; }
00336 
00337    buf = malloc(NBUF) ;
00338    if( buf == NULL )
00339       ERROR_exit("Can't malloc() buffer for file copy! - EXIT\n");
00340    while(1){  /*- loop: read buffer, write buffer -*/
00341 
00342      ii = fread( buf , 1 , NBUF , fold ) ; /* read buffer  */
00343      if( ii <= 0 ) break ;                 /* read failed  */
00344      jj = fwrite( buf , 1 , ii , fnew ) ;  /* write buffer */
00345      if( jj != ii ){
00346         perror("New write fails") ; break ;
00347      }
00348    }
00349 
00350    fsync(fileno(fnew)) ;
00351    free(buf); fclose(fnew); fclose(fold) ; return 0 ;
00352 }
 

Powered by Plone

This site conforms to the following standards: