/*********************** 3dExchange.c **********************************************/ /* Author: Daniel Glen - May 09 2019 */ #include "mrilib.h" static float find_float_in_list(float voxval, float *srclist, float *replacelist, int nx); void Exchange_help(void) { printf( "Usage: 3dExchange [-prefix PREFIX] <-input DATASET>\n" "\n" "Replaces voxel values using mapping file with two columns of numbers\n" "with the first column of the input value and the second has the output value\n" "\n" " -input DATASET : Input dataset\n" " Acceptable data types are:\n" " byte, short, and floats.\n" " -map MAPCOLS.1D : Mapping columns - input is first column\n" " output is second column\n" " -prefix PREFIX: Output prefix\n" "\n" " -ver = print author and version info\n" " -help = print this help screen\n" ) ; printf("\n" MASTER_SHORTHELP_STRING ) ; PRINT_COMPILE_DATE ; return; } /*! Replace a voxel's value by the value's exchange in the entire set of input datasets */ int main( int argc , char * argv[] ) { THD_3dim_dataset *dset=NULL, *new_dset=NULL; /*input and output datasets*/ MRI_IMAGE *data_im = NULL, *out_data_im = NULL; MRI_IMAGE *mapping_1D = NULL; int nopt=0, nbriks=0, ib=0; int i,k, nvox=0, nmaps=0, nx=0, ny=0; float fac, voxval, prev_voxval=-9999.0, prev_replace=-9999.0 ; short *sar=NULL, *outsar; byte *bar=NULL, *outbar; float *far=NULL, *outfar, *mapptr, *srclist, *replacelist; char *mapstr=NULL; char *prefix=NULL; char stmp[THD_MAX_PREFIX+1]={""}; byte badsb_type=0; void *var=NULL; int floatize = 0; /*----- Read command line -----*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ Exchange_help (); exit(0) ; } mainENTRY("3dExchange main"); machdep(); AFNI_logger("3dExchange",argc,argv); nopt = 1 ; while( nopt < argc && argv[nopt][0] == '-' ){ if( strcmp(argv[nopt],"-ver") == 0 ){ PRINT_VERSION("3dExchange"); AUTHOR("Daniel Glen"); exit(0); } if( strcmp(argv[nopt],"-help") == 0 ){ Exchange_help(); exit(0) ; } if( strcmp(argv[nopt],"-prefix") == 0 ){ ++nopt; if (nopt>=argc) { fprintf(stderr,"**ERROR: Need string after -prefix\n"); exit(1); } prefix = argv[nopt] ; ++nopt; continue; } if( strcmp(argv[nopt],"-input") == 0 ){ ++nopt; nbriks=0; dset = THD_open_dataset( argv[nopt] ); if( !ISVALID_DSET(dset) ){ fprintf(stderr,"**ERROR: can't open dataset %s\n",argv[nopt]) ; exit(1); } ++nopt; ++nbriks; continue; } if( strcmp(argv[nopt],"-map") == 0 ){ ++nopt; nmaps=0; mapstr = argv[nopt]; ++nopt; ++nmaps; continue; } if( strcmp(argv[nopt],"-float") == 0 ){ floatize = 1; ++nopt; continue; } ERROR_exit( " Error - unknown option %s", argv[nopt]); } if (nopt < argc) { ERROR_exit( " Error unexplained trailing option: %s\n", argv[nopt]); } if (!dset) ERROR_exit("Error - no dataset given!"); if (!mapstr) ERROR_exit("Error - no mapping file given!"); /* check out the 1D mapping file */ mapping_1D = mri_read_1D (mapstr); if (mapping_1D == NULL) { ERROR_exit("Error reading mapping file. These should be 2 columns of numbers"); } nx = mapping_1D->nx; ny = mapping_1D->ny; mapptr = MRI_FLOAT_PTR (mapping_1D); /* I think this is the way 1D files are stored in memory */ srclist = mapptr; replacelist = mapptr+nx; if (ny < 2) { mri_free (mapping_1D); ERROR_message("Error - Not enough columns in mapping file"); ERROR_exit(" %d rows and %d columns found in mapping file", nx, ny); } DSET_mallocize (dset); DSET_load (dset); /* load dataset */ if (prefix) { /* usual case - assign a prefix */ snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "%s", prefix); } else { /* no prefix given, so use default name */ snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "exchange.%.900s", DSET_PREFIX(new_dset)); } new_dset = EDIT_full_copy( dset, prefix ) ; /* make a copy of its header */ tross_Copy_History( dset , new_dset ) ; /* if data type has not been selected by user */ if(floatize) EDIT_floatize_dataset( new_dset ); /* Exchange data across all the subbricks of the input dataset */ for(i=0;idblk->nvals; i++) { /* for each sub-brik in dataset */ data_im = DSET_BRICK (dset, i); /* set pointer to the ith sub-brik of the dataset */ out_data_im = DSET_BRICK(new_dset, i); fac = DSET_BRICK_FACTOR(dset, i); /* get scale factor for each sub-brik*/ if(fac==0.0) fac=1.0; nvox = data_im->nvox; /* number of voxels in the sub-brik */ outbar = (byte *) mri_data_pointer(out_data_im); outfar = (float *) mri_data_pointer(out_data_im); outsar = (short *) mri_data_pointer(out_data_im); badsb_type = 0; switch(data_im->kind){ case MRI_short:{ sar = mri_data_pointer(data_im) ; var = sar; } break ; case MRI_byte:{ bar = mri_data_pointer(data_im) ; var = bar; } break ; case MRI_float:{ far = mri_data_pointer(data_im) ; var = far; } break ; default: /* unknown type */ WARNING_message("Unknown type, %s, in sub-brik %d", MRI_TYPE_name[data_im->kind], i); badsb_type = 1; break; } if (var==NULL){ ERROR_exit("Can not read dataset data"); } switch( data_im->kind ){ case MRI_short:{ for(k=0;kkind], i); break; } /* change storage mode, this way prefix will determine format of output dset */ new_dset->dblk->diskptr->storage_mode = STORAGE_BY_BRICK; tross_Make_History( "3dExchange" , argc, argv , new_dset ) ; if (!DSET_write( new_dset )) { ERROR_message("Failed to write %s", stmp); exit(1); } else { WROTE_DSET(new_dset); } } exit(0); } /* return floating point value in replacelist wherever * voxval matches value in srclist */ static float find_float_in_list(float voxval, float *srclist, float *replacelist, int nx) { int i; for(i=0;i