image_metadata * read_minc(char *filename, float **image, int *sizes){ VIO_Volume volume; VIO_Real dummy[3]; image_metadata *meta; if( input_volume(filename, 3, NULL, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &volume, (minc_input_options *) NULL ) != VIO_OK ) return( NULL ); meta = (image_metadata *)calloc( 1 , sizeof(image_metadata) ) ; meta->start = calloc(3,sizeof(float)); meta->step = calloc(3,sizeof(float)); meta->length = calloc(3,sizeof(int)); get_volume_sizes(volume,sizes); *image=malloc(sizes[0]*sizes[1]*sizes[2]*sizeof(**image)); set_volume(*image, volume, sizes); meta->length[0]=sizes[0]; meta->length[1]=sizes[1]; meta->length[2]=sizes[2]; get_volume_starts(volume,dummy); meta->start[0]=dummy[0]; meta->start[1]=dummy[1]; meta->start[2]=dummy[2]; get_volume_separations(volume,dummy); meta->step[0]=dummy[0]; meta->step[1]=dummy[1]; meta->step[2]=dummy[2]; delete_volume(volume); return meta; }
static void build_mask(VIO_Volume vol, VIO_Real mask_f[3][3][3], VIO_Real mask_b[3][3][3]) { int i,j,k; VIO_Real steps[VIO_MAX_DIMENSIONS], d1; get_volume_separations(vol, steps); for(i=-1; i<=1; i++) for(j=-1; j<=1; j++) for(k=-1; k<=1; k++) { d1 = sqrt(i*i*steps[0]*steps[0] + j*j*steps[1]*steps[1]); mask_f[i+1][j+1][k+1] = sqrt( d1*d1 + k*k*steps[2]*steps[2] ); mask_b[i+1][j+1][k+1] = mask_f[i+1][j+1][k+1]; } mask_f[1][1][1] = mask_b[1][1][1] = 0.0; for(j=-1; j<=1; j++) for(k=-1; k<=1; k++) { mask_f[2][j+1][k+1] = 1000.0; mask_b[0][j+1][k+1] = 1000.0; } mask_f[1][1][2] = 1000.0; mask_f[1][2][0] = 1000.0; mask_f[1][2][1] = 1000.0; mask_f[1][2][2] = 1000.0; mask_b[1][1][0] = 1000.0; mask_b[1][0][0] = 1000.0; mask_b[1][0][1] = 1000.0; mask_b[1][0][2] = 1000.0; if (debug) { print ("%20s %35s\n","forward","reverse"); for(i=2; i>=0; i--) { print ("slice %d\n",i); for(j=0; j<=2; j++) { for(k=0; k<=2; k++) print ("%10.4f ",mask_f[i][j][k]); print (" "); for(k=0; k<=2; k++) print ("%10.4f ",mask_b[i][j][k]); print ("\n"); } print ("\n"); } } }
VIO_Status gradient3D_volume(FILE *ifd, VIO_Volume data, int xyzv[VIO_MAX_DIMENSIONS], char *infile, char *outfile, int ndim, char *history, int curvature_flg) { float *fdata, /* floating point storage for blurred volume */ *f_ptr, /* pointer to fdata */ tmp, max_val, min_val, *dat_vector, /* temp storage of original row, col or slice vect. */ *dat_vecto2, /* storage of result of dat_vector*kern */ *kern; /* convolution kernel */ int total_voxels, vector_size_data, /* original size of row, col or slice vector */ array_size_pow2, /* actual size of vector/kernel data used in FFT */ /* routines - needs to be a power of two */ array_size; int data_offset; /* offset required to place original data (size n) */ /* into array (size m=2^n) so that data is centered*/ register int slice_limit, row,col,slice, /* counters to access original data */ vindex; /* counter to access vector and vecto2 */ int slice_size, /* size of each data step - in bytes */ row_size, col_size; char full_outfilename[256]; /* name of output file */ progress_struct progress; /* used to monitor progress of calculations */ VIO_Status status; int sizes[3], /* number of rows, cols and slices */ pos[3]; /* Input order of rows, cols, slices */ VIO_Real steps[3]; /* size of voxel step from center to center in x,y,z */ /*---------------------------------------------------------------------------------*/ /* start by setting up the raw data. */ /*---------------------------------------------------------------------------------*/ get_volume_sizes(data, sizes); /* rows,cols,slices */ get_volume_separations(data, steps); slice_size = sizes[xyzv[VIO_Y]] * sizes[xyzv[VIO_X]]; /* sizeof one slice */ col_size = sizes[xyzv[VIO_Y]]; /* sizeof one column */ row_size = sizes[xyzv[VIO_X]]; /* sizeof one row */ total_voxels = sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Z]]; ALLOC(fdata, total_voxels); f_ptr = fdata; /* read in data of input file. */ set_file_position(ifd,(long)0); status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels); if (status != OK) print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__); /*--------------------------------------------------------------------------------------*/ /* get ready to start up the transformation. */ /*--------------------------------------------------------------------------------------*/ initialize_progress_report( &progress, FALSE, sizes[xyzv[VIO_Z]] + sizes[xyzv[VIO_Y]] + sizes[xyzv[VIO_X]] + 1, "Gradient volume" ); /* note data is stored by rows (along x), then by cols (along y) then slices (along z) */ /*--------------------------------------------------------------------------------------*/ /* start with rows - i.e. the d/dx volume */ /*--------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/ /* determine size of data structures needed */ vector_size_data = sizes[xyzv[VIO_X]]; /* array_size_pow2 will hold the size of the arrays for FFT convolution, remember that ffts require arrays 2^n in length */ array_size_pow2 = next_power_of_two(vector_size_data); array_size = 2*array_size_pow2+1; /* allocate 2*, since each point is a */ /* complex number for FFT, and the plus 1*/ /* is for the zero offset FFT routine */ ALLOC(dat_vector, array_size); ALLOC(dat_vecto2, array_size); ALLOC(kern , array_size); /* 1st calculate kern array for FT of 1st derivitive */ make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_X]])); if (curvature_flg) /* 2nd derivative kernel */ muli_vects(kern,kern,kern,array_size_pow2); /* calculate offset for original data to be placed in vector */ data_offset = (array_size_pow2-sizes[xyzv[VIO_X]])/2; max_val = -FLT_MAX; min_val = FLT_MAX; /* 2nd now convolve this kernel with the rows of the dataset */ slice_limit = 0; switch (ndim) { case 1: slice_limit = 0; break; case 2: slice_limit = sizes[xyzv[VIO_Z]]; break; case 3: slice_limit = sizes[xyzv[VIO_Z]]; break; } for (slice = 0; slice < slice_limit; slice++) { /* for each slice */ for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) { /* for each row */ f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]]; memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float)); for (col=0; col< sizes[xyzv[VIO_X]]; col++) { /* extract the row */ dat_vector[1 +2*(col+data_offset) ] = *f_ptr++; } fft1(dat_vector,array_size_pow2,1); muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2); fft1(dat_vecto2,array_size_pow2,-1); f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]]; for (col=0; col< sizes[xyzv[VIO_X]]; col++) { /* put the row back */ vindex = 1 + 2*(col+data_offset); *f_ptr = dat_vecto2[vindex]/array_size_pow2; if (max_val<*f_ptr) max_val = *f_ptr; if (min_val>*f_ptr) min_val = *f_ptr; f_ptr++; } } update_progress_report( &progress, slice+1 ); } FREE(dat_vector); FREE(dat_vecto2); FREE(kern ); f_ptr = fdata; set_volume_real_range(data, min_val, max_val); printf("Making byte volume dx..." ); for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) { pos[xyzv[VIO_Z]] = slice; for(row=0; row<sizes[xyzv[VIO_Y]]; row++) { pos[xyzv[VIO_Y]] = row; for(col=0; col<sizes[xyzv[VIO_X]]; col++) { pos[xyzv[VIO_X]] = col; tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr); SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp); f_ptr++; } } } if (!curvature_flg) sprintf(full_outfilename,"%s_dx.mnc",outfile); else sprintf(full_outfilename,"%s_dxx.mnc",outfile); if (debug) print ("dx: min = %f, max = %f\n",min_val, max_val); status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, min_val, max_val, data, infile, history, NULL); if (status != OK) print_error_and_line_num("problems writing dx gradient data...\n",__FILE__, __LINE__); /*--------------------------------------------------------------------------------------*/ /* now do cols - i.e. the d/dy volume */ /*--------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/ /* determine size of data structures needed */ set_file_position(ifd,0); status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels); if (status != OK) print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__); f_ptr = fdata; vector_size_data = sizes[xyzv[VIO_Y]]; /* array_size_pow2 will hold the size of the arrays for FFT convolution, remember that ffts require arrays 2^n in length */ array_size_pow2 = next_power_of_two(vector_size_data); array_size = 2*array_size_pow2+1; /* allocate 2*, since each point is a */ /* complex number for FFT, and the plus 1*/ /* is for the zero offset FFT routine */ ALLOC(dat_vector, array_size); ALLOC(dat_vecto2, array_size); ALLOC(kern , array_size); /* 1st calculate kern array for FT of 1st derivitive */ make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Y]])); if (curvature_flg) /* 2nd derivative kernel */ muli_vects(kern,kern,kern,array_size_pow2); /* calculate offset for original data to be placed in vector */ data_offset = (array_size_pow2-sizes[xyzv[VIO_Y]])/2; /* 2nd now convolve this kernel with the rows of the dataset */ max_val = -FLT_MAX; min_val = FLT_MAX; switch (ndim) { case 1: slice_limit = 0; break; case 2: slice_limit = sizes[xyzv[VIO_Z]]; break; case 3: slice_limit = sizes[xyzv[VIO_Z]]; break; } for (slice = 0; slice < slice_limit; slice++) { /* for each slice */ for (col = 0; col < sizes[xyzv[VIO_X]]; col++) { /* for each col */ /* f_ptr = fdata + slice*slice_size + row*sizeof(float); */ f_ptr = fdata + slice*slice_size + col; memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float)); for (row=0; row< sizes[xyzv[VIO_Y]]; row++) { /* extract the col */ dat_vector[1 +2*(row+data_offset) ] = *f_ptr; f_ptr += row_size; } fft1(dat_vector,array_size_pow2,1); muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2); fft1(dat_vecto2,array_size_pow2,-1); f_ptr = fdata + slice*slice_size + col; for (row=0; row< sizes[xyzv[VIO_Y]]; row++) { /* put the col back */ vindex = 1 + 2*(row+data_offset); *f_ptr = dat_vecto2[vindex]/array_size_pow2; if (max_val<*f_ptr) max_val = *f_ptr; if (min_val>*f_ptr) min_val = *f_ptr; f_ptr += row_size; } } update_progress_report( &progress, slice+sizes[xyzv[VIO_Z]]+1 ); } FREE(dat_vector); FREE(dat_vecto2); FREE(kern ); f_ptr = fdata; set_volume_real_range(data, min_val, max_val); printf("Making byte volume dy..." ); for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) { pos[xyzv[VIO_Z]] = slice; for(row=0; row<sizes[xyzv[VIO_Y]]; row++) { pos[xyzv[VIO_Y]] = row; for(col=0; col<sizes[xyzv[VIO_X]]; col++) { pos[xyzv[VIO_X]] = col; tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr); SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp); f_ptr++; } } } if (!curvature_flg) sprintf(full_outfilename,"%s_dy.mnc",outfile); else sprintf(full_outfilename,"%s_dyy.mnc",outfile); if (debug) print ("dy: min = %f, max = %f\n",min_val, max_val); status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, min_val, max_val, data, infile, history, NULL); if (status != OK) print_error_and_line_num("problems writing dy gradient data...",__FILE__, __LINE__); /*--------------------------------------------------------------------------------------*/ /* now do slices - i.e. the d/dz volume */ /*--------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/ /* determine size of data structures needed */ set_file_position(ifd,0); status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels); if (status != OK) print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__); f_ptr = fdata; vector_size_data = sizes[xyzv[VIO_Z]]; /* array_size_pow2 will hold the size of the arrays for FFT convolution, remember that ffts require arrays 2^n in length */ array_size_pow2 = next_power_of_two(vector_size_data); array_size = 2*array_size_pow2+1; /* allocate 2*, since each point is a */ /* complex number for FFT, and the plus 1*/ /* is for the zero offset FFT routine */ ALLOC(dat_vector, array_size); ALLOC(dat_vecto2, array_size); ALLOC(kern , array_size); if (ndim==1 || ndim==3) { /* 1st calculate kern array for FT of 1st derivitive */ make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Z]])); if (curvature_flg) /* 2nd derivative kernel */ muli_vects(kern,kern,kern,array_size_pow2); /* calculate offset for original data to be placed in vector */ data_offset = (array_size_pow2-sizes[xyzv[VIO_Z]])/2; /* 2nd now convolve this kernel with the slices of the dataset */ max_val = -FLT_MAX; min_val = FLT_MAX; for (col = 0; col < sizes[xyzv[VIO_X]]; col++) { /* for each column */ for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) { /* for each row */ f_ptr = fdata + col*col_size + row; memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float)); for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) { /* extract the slice vector */ dat_vector[1 +2*(slice+data_offset) ] = *f_ptr; f_ptr += slice_size; } fft1(dat_vector,array_size_pow2,1); muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2); fft1(dat_vecto2,array_size_pow2,-1); f_ptr = fdata + col*col_size + row; for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) { /* put the vector back */ vindex = 1 + 2*(slice+data_offset); *f_ptr = dat_vecto2[vindex]/array_size_pow2; if (max_val<*f_ptr) max_val = *f_ptr; if (min_val>*f_ptr) min_val = *f_ptr; f_ptr += slice_size; } } update_progress_report( &progress, col + 2*sizes[xyzv[VIO_Z]] + 1 ); } } /* if ndim */ else { max_val = 0.00001; min_val = 0.00000; for (col = 0; col < sizes[xyzv[VIO_X]]; col++) { /* for each column */ for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) { /* for each row */ *f_ptr = 0.0; f_ptr++; } } } FREE(dat_vector); FREE(dat_vecto2); FREE(kern ); /* set up the correct info to copy the data back out in mnc */ f_ptr = fdata; set_volume_real_range(data, min_val, max_val); printf("Making byte volume dz..." ); for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) { pos[xyzv[VIO_Z]] = slice; for(row=0; row<sizes[xyzv[VIO_Y]]; row++) { pos[xyzv[VIO_Y]] = row; for(col=0; col<sizes[xyzv[VIO_X]]; col++) { pos[xyzv[VIO_X]] = col; tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr); SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp); f_ptr++; } } } if (!curvature_flg) sprintf(full_outfilename,"%s_dz.mnc",outfile); else sprintf(full_outfilename,"%s_dzz.mnc",outfile); if (debug) print ("dz: min = %f, max = %f\n",min_val, max_val); status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, min_val, max_val, data, infile, history, NULL); if (status != OK) print_error_and_line_num("problems writing dz gradient data...",__FILE__, __LINE__); terminate_progress_report( &progress ); FREE(fdata); return(status); }
VIO_BOOL vol_to_cov(VIO_Volume d1, VIO_Volume m1, float centroid[4], float covar[4][4], double *step) { VectorR vector_step, slice_step, row_step, col_step; PointR starting_offset, starting_origin, starting_position, slice, row, col, voxel; VIO_Real tx,ty,tz; int i,r,c,s, limits[VOL_NDIMS]; float t, sxx,syy,szz, sxy,syz,sxz, sx,sy,sz,si; VIO_Real thickness[3]; int sizes[3]; VIO_Real true_value; get_volume_separations(d1, thickness); get_volume_sizes(d1, sizes); /* build sampling lattice info */ for(i=0; i<3; i++) { step[i] *= thickness[i] / fabs( thickness[i]); } fill_Vector( col_step, step[COL_IND], 0.0, 0.0 ); fill_Vector( row_step, 0.0, step[ROW_IND], 0.0 ); fill_Vector( slice_step, 0.0, 0.0, step[SLICE_IND] ); convert_3D_voxel_to_world(d1, 0.0, 0.0, 0.0, &tx, &ty, &tz); fill_Point( starting_origin, tx, ty, tz); for(i=0; i<3; i++) { /* for each dim, get # of steps in that direction, and set starting offset */ t = sizes[i] * thickness[i] / step[i]; limits[i] = abs( t ); Point_coord( starting_offset, (i) ) = ( (sizes[i]-1)*thickness[i] - (limits[i] * step[i] ) ) / 2.0; } ADD_POINTS( starting_position, starting_origin, starting_offset ); /* */ /* calculate centroids first */ sx = 0.0; sy = 0.0; sz = 0.0; si = 0.0; for(s=0; s<=limits[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[ROW_IND]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[COL_IND]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sx += Point_x(col) * true_value; sy += Point_y(col) * true_value; sz += Point_z(col) * true_value; si += true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } if (si!=0.0) { centroid[1] = sx/ si; centroid[2] = sy/ si; centroid[3] = sz/ si; sxx = syy = szz = 0.0; sxy = syz = sxz = 0.0; /* now calculate variances and co-variances */ for(s=0; s<=limits[VIO_Z]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[VIO_Y]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[VIO_X]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sxx += (Point_x( col )-centroid[1]) * (Point_x( col )-centroid[1]) * true_value; syy += (Point_y( col )-centroid[2]) * (Point_y( col )-centroid[2]) * true_value; szz += (Point_z( col )-centroid[3]) * (Point_z( col )-centroid[3]) * true_value; sxy += (Point_x( col )-centroid[1]) * (Point_y( col )-centroid[2]) * true_value; syz += (Point_y( col )-centroid[2]) * (Point_z( col )-centroid[3]) * true_value; sxz += (Point_x( col )-centroid[1]) * (Point_z( col )-centroid[3]) * true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } covar[1][1] = sxx/si; covar[1][2] = sxy/si; covar[1][3] = sxz/si; covar[2][1] = sxy/si; covar[2][2] = syy/si; covar[2][3] = syz/si; covar[3][1] = sxz/si; covar[3][2] = syz/si; covar[3][3] = szz/si; return(TRUE); } else { return(FALSE); } }
int main(int argc, char *argv[]) { int v1, v2, v3, v4; int sizes[VIO_MAX_DIMENSIONS], grid_sizes[4]; int n_concat_transforms, i; VIO_STR arg_string; char *input_volume_name; char *input_xfm; VIO_STR outfile; VIO_Real w1, w2, w3; VIO_Real nw1, nw2, nw3; VIO_Real original[3], transformed[3]; VIO_Real value; VIO_Real cosine[3]; VIO_Real original_separation[3], grid_separation[4]; VIO_Real original_starts[3], grid_starts[4]; VIO_Volume eval_volume, new_grid; VIO_General_transform xfm, *voxel_to_world; VIO_STR *dimnames, dimnames_grid[4]; VIO_progress_struct progress; arg_string = time_stamp(argc, argv); /* Check arguments */ if(ParseArgv(&argc, argv, argTable, 0) || (argc != 4)){ fprintf(stderr, "\nUsage: %s [options] input.mnc input.xfm output_grid.mnc\n", argv[0]); fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } input_volume_name = argv[1]; input_xfm = argv[2]; outfile = argv[3]; /* check for the infile and outfile */ if(access(input_volume_name, F_OK) != 0){ fprintf(stderr, "%s: Couldn't find %s\n\n", argv[0], input_volume_name); exit(EXIT_FAILURE); } if(access(input_xfm, F_OK) != 0) { fprintf(stderr, "%s: Couldn't find %s\n\n", argv[0], input_xfm); exit(EXIT_FAILURE); } if(access(outfile, F_OK) == 0 && !clobber){ fprintf(stderr, "%s: %s exists! (use -clobber to overwrite)\n\n", argv[0], outfile); exit(EXIT_FAILURE); } /*--- input the volume */ /* if( input_volume( input_volume_name, 3, NULL, MI_ORIGINAL_TYPE, FALSE, 0.0, 0.0, TRUE, &eval_volume,(minc_input_options *) NULL ) != OK ) return( 1 ); */ if (input_volume_header_only( input_volume_name, 3, NULL, &eval_volume,(minc_input_options *) NULL ) != VIO_OK ) { return( 1 ); } /* get information about the volume */ get_volume_sizes( eval_volume, sizes ); voxel_to_world = get_voxel_to_world_transform(eval_volume); dimnames = get_volume_dimension_names(eval_volume); get_volume_separations(eval_volume, original_separation); get_volume_starts(eval_volume, original_starts); /* create new 4D volume, last three dims same as other volume, first dimension being the vector dimension. */ for(i=1; i < 4; i++) { dimnames_grid[i] = dimnames[i-1]; grid_separation[i] = original_separation[i-1]; grid_sizes[i] = sizes[i-1]; grid_starts[i] = original_starts[i-1]; } dimnames_grid[0] = "vector_dimension"; grid_sizes[0] = 3; grid_separation[0] = 1; grid_starts[0] = 0; new_grid = create_volume(4, dimnames_grid, NC_SHORT, FALSE, 0.0, 0.0); //set_voxel_to_world_transform(new_grid, voxel_to_world); // initialize the new grid volume, otherwise the output will be // garbage... set_volume_real_range(new_grid, -100, 100); set_volume_sizes(new_grid, grid_sizes); set_volume_separations(new_grid, grid_separation); set_volume_starts(new_grid, grid_starts); /* for (i=0; i < 3; i++) { get_volume_direction_cosine(eval_volume, i, cosine); set_volume_direction_cosine(new_grid, i+1, cosine); } */ alloc_volume_data(new_grid); /* get the transforms */ if( input_transform_file( input_xfm, &xfm ) != VIO_OK ) return( 1 ); /* see how many transforms will be applied */ n_concat_transforms = get_n_concated_transforms( &xfm ); printf("Number of transforms to be applied: %d\n", n_concat_transforms); initialize_progress_report(&progress, FALSE, sizes[0], "Processing"); /* evaluate the transform at every voxel, keep the displacement in the three cardinal directions */ for( v1 = 0; v1 < sizes[0]; ++v1 ) { update_progress_report(&progress, v1 + 1); for( v2 = 0; v2 < sizes[1]; ++v2 ) { for( v3 = 0; v3 < sizes[2]; ++v3 ) { convert_3D_voxel_to_world(eval_volume, v1, v2, v3, &original[0], &original[1], &original[2]); general_transform_point(&xfm, original[0], original[1], original[2], &transformed[0], &transformed[1], &transformed[2]); for(i=0; i < 3; i++) { value = transformed[i] - original[i]; set_volume_real_value(new_grid, i, v1, v2, v3, 0, value); } } } } terminate_progress_report(&progress); printf("Outputting volume.\n"); output_volume(outfile, MI_ORIGINAL_TYPE, TRUE, 0.0, 0.0, new_grid, arg_string, NULL); return(0); }
void make_zscore_volume(VIO_Volume d1, VIO_Volume m1, VIO_Real *threshold) { unsigned long count; int stat_count, sizes[VIO_MAX_DIMENSIONS], s,r,c; VIO_Real wx,wy,wz, valid_min_dvoxel, valid_max_dvoxel, min,max, sum, sum2, mean, var, std, data_vox,data_val, thick[VIO_MAX_DIMENSIONS]; PointR voxel; VIO_Volume vol; VIO_progress_struct progress; /* get default information from data and mask */ /* build temporary working volume */ vol = copy_volume_definition(d1, NC_UNSPECIFIED, FALSE, 0.0, 0.0); set_volume_real_range(vol, MIN_ZRANGE, MAX_ZRANGE); get_volume_sizes(d1, sizes); get_volume_separations(d1, thick); get_volume_voxel_range(d1, &valid_min_dvoxel, &valid_max_dvoxel); /* initialize counters and sums */ count = 0; sum = 0.0; sum2 = 0.0; min = 1e38; max = -1e38; stat_count = 0; initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Tally stats" ); /* do first pass, to get mean and std */ for(s=0; s<sizes[0]; s++) { for(r=0; r<sizes[1]; r++) { for(c=0; c<sizes[2]; c++) { stat_count++; update_progress_report( &progress, stat_count); convert_3D_voxel_to_world(d1, (VIO_Real)s, (VIO_Real)r, (VIO_Real)c, &wx, &wy, &wz); if (m1 != NULL) { convert_3D_world_to_voxel(m1, wx, wy, wz, &Point_x(voxel), &Point_y(voxel), &Point_z(voxel)); } else { wx = 0.0; wy = 0.0; wz = 0.0; } if (point_not_masked(m1, wx,wy,wz)) { GET_VOXEL_3D( data_vox, d1 , s, r, c ); if (data_vox >= valid_min_dvoxel && data_vox <= valid_max_dvoxel) { data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); if (data_val > *threshold) { sum += data_val; sum2 += data_val*data_val; count++; if (data_val < min) min = data_val; else if (data_val > max) max = data_val; } } } } } } terminate_progress_report( &progress ); stat_count = 0; initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Zscore convert" ); /* calc mean and std */ mean = sum / (float)count; var = ((float)count*sum2 - sum*sum) / ((float)count*((float)count-1)); std = sqrt(var); min = 1e38; max = -1e38; /* replace the voxel values */ for(s=0; s<sizes[0]; s++) { for(r=0; r<sizes[1]; r++) { for(c=0; c<sizes[2]; c++) { stat_count++; update_progress_report( &progress, stat_count); GET_VOXEL_3D( data_vox, d1, s, r, c ); if (data_vox >= valid_min_dvoxel && data_vox <= valid_max_dvoxel) { data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); if (data_val > *threshold) { /* instead of data_val = CONVERT_VALUE_TO_VOXEL(d1, data_vox); i will use data_val = CONVERT_VALUE_TO_VOXEL(d1, vol); since the values in vol are changed with respect to the new z-score volume */ data_val = (data_val - mean) / std; if (data_val< MIN_ZRANGE) data_val = MIN_ZRANGE; if (data_val> MAX_ZRANGE) data_val = MAX_ZRANGE; data_vox = CONVERT_VALUE_TO_VOXEL( vol, data_val); if (data_val < min) { min = data_val; } else { if (data_val > max) max = data_val; } } else data_vox = -DBL_MAX; /* should be fill_value! */ SET_VOXEL_3D( d1 , s, r, c, data_vox ); } } } } terminate_progress_report( &progress ); set_volume_real_range(d1, MIN_ZRANGE, MAX_ZRANGE); /* reset the data volume's range */ *threshold = (*threshold - mean) / std; delete_volume(vol); }
void get_zscore_values(VIO_Volume d1, VIO_Volume m1, VIO_Real threshold, VIO_Real *mean, VIO_Real *std) { unsigned long count; int sizes[VIO_MAX_DIMENSIONS], s,r,c; VIO_Real wx,wy,wz, valid_min_dvoxel, valid_max_dvoxel, min,max, sum, sum2, var, data_vox,data_val, thick[VIO_MAX_DIMENSIONS]; /* get default information from data and mask */ get_volume_sizes(d1, sizes); get_volume_separations(d1, thick); get_volume_voxel_range(d1, &valid_min_dvoxel, &valid_max_dvoxel); /* initialize counters and sums */ count = 0; sum = 0.0; sum2 = 0.0; min = FLT_MAX; max = -FLT_MAX; /* get mean and std */ for(s=0; s<sizes[0]; s++) { for(r=0; r<sizes[1]; r++) { for(c=0; c<sizes[2]; c++) { convert_3D_voxel_to_world(d1, (VIO_Real)s, (VIO_Real)r, (VIO_Real)c, &wx, &wy, &wz); if (point_not_masked(m1, wx,wy,wz)) { GET_VOXEL_3D( data_vox, d1 , s, r, c ); if (data_vox >= valid_min_dvoxel && data_vox <= valid_max_dvoxel) { data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); if (data_val > threshold) { sum += data_val; sum2 += data_val*data_val; count++; if (data_val < min) min = data_val; else if (data_val > max) max = data_val; } } } } } } /* calc mean and std */ *mean = sum / (float)count; var = ((float)count*sum2 - sum*sum) / ((float)count*((float)count-1)); *std = sqrt(var); }
int main(int argc, char *argv[]) { VIO_General_transform transform, *grid_transform_ptr, forward_transform; VIO_Volume target_vol, volume; volume_input_struct input_info; VIO_Real voxel[VIO_MAX_DIMENSIONS], steps[VIO_MAX_DIMENSIONS], start[VIO_N_DIMENSIONS], target_steps[VIO_MAX_DIMENSIONS], wx,wy,wz, inv_x, inv_y, inv_z, def_values[VIO_MAX_DIMENSIONS]; static int clobber_flag = FALSE, verbose = TRUE, debug = FALSE; static char *target_file; int parse_flag, prog_count, sizes[VIO_MAX_DIMENSIONS], target_sizes[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS], target_xyzv[VIO_MAX_DIMENSIONS], index[VIO_MAX_DIMENSIONS], i, trans_count; VIO_progress_struct progress; static ArgvInfo argTable[] = { {"-like", ARGV_STRING, (char *) 0, (char *) &target_file, "Specify target volume sampling information."}, {"-no_clobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber_flag, "Do not overwrite output file (default)."}, {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber_flag, "Overwrite output file."}, {"-verbose", ARGV_CONSTANT, (char *) TRUE, (char *) &verbose, "Write messages indicating progress (default)"}, {"-quiet", ARGV_CONSTANT, (char *) FALSE, (char *) &verbose, "Do not write log messages"}, {"-debug", ARGV_CONSTANT, (char *) TRUE, (char *) &debug, "Print out debug info."}, {NULL, ARGV_END, NULL, NULL, NULL} }; prog_name = argv[0]; target_file = malloc(1024); strcpy(target_file,""); /* Call ParseArgv to interpret all command line args (returns TRUE if error) */ parse_flag = ParseArgv(&argc, argv, argTable, 0); /* Check remaining arguments */ if (parse_flag || argc != 3) print_usage_and_exit(prog_name); /* Read in file that has a def field to invert */ if (input_transform_file(argv[1], &transform) != OK) { (void) fprintf(stderr, "%s: Error reading transform file %s\n", argv[0], argv[1]); exit(EXIT_FAILURE); } for(trans_count=0; trans_count<get_n_concated_transforms(&transform); trans_count++ ) { grid_transform_ptr = get_nth_general_transform(&transform, trans_count ); if (grid_transform_ptr->type == GRID_TRANSFORM) { copy_general_transform(grid_transform_ptr, &forward_transform); /* this is the call that should be made with the latest version of internal_libvolume_io invert_general_transform(&forward_transform); */ forward_transform.inverse_flag = !(forward_transform.inverse_flag); volume = grid_transform_ptr->displacement_volume; if (strlen(target_file)!=0) { if (debug) print ("Def field will be resampled like %s\n",target_file); if (!file_exists( target_file ) ) { (void) fprintf(stderr, "%s: Target file '%s' does not exist\n", prog_name,target_file); exit(EXIT_FAILURE); } start_volume_input(target_file, 3, (char **)NULL, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &target_vol, (minc_input_options *)NULL, &input_info); get_volume_XYZV_indices(volume, xyzv); get_volume_separations (volume, steps); get_volume_sizes (volume, sizes); get_volume_XYZV_indices(target_vol, target_xyzv); get_volume_separations (target_vol, target_steps); get_volume_sizes (target_vol, target_sizes); for(i=0; i<VIO_MAX_DIMENSIONS; i++) { index[i] = 0; voxel[i] = 0.0; } convert_voxel_to_world(target_vol, voxel, &start[VIO_X], &start[VIO_Y], &start[VIO_Z]); if( volume != (void *) NULL ){ free_volume_data( volume ); } for(i=VIO_X; i<=VIO_Z; i++) { steps[ xyzv[i] ] = target_steps[ target_xyzv[i] ] ; sizes[ xyzv[i] ] = target_sizes[ target_xyzv[i] ] ; } set_volume_separations(volume, steps); set_volume_sizes( volume, sizes); set_volume_starts(volume, start); alloc_volume_data( volume ); } get_volume_sizes(volume, sizes); get_volume_XYZV_indices(volume,xyzv); for(i=0; i<VIO_MAX_DIMENSIONS; i++){ index[i] = 0; } if (verbose){ initialize_progress_report(&progress, FALSE, sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_Z]]+1, "Inverting def field"); } prog_count = 0; for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<sizes[xyzv[VIO_X]]; index[xyzv[VIO_X]]++) for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<sizes[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++) for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<sizes[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) { index[ xyzv[VIO_Z+1] ] = 0; for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = (VIO_Real)index[i]; convert_voxel_to_world(volume, voxel, &wx, &wy, &wz); if (sizes[ xyzv[VIO_Z] ] ==1) general_inverse_transform_point_in_trans_plane(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); else grid_inverse_transform_point(&forward_transform, wx, wy, wz, &inv_x, &inv_y, &inv_z); def_values[VIO_X] = inv_x - wx; def_values[VIO_Y] = inv_y - wy; def_values[VIO_Z] = inv_z - wz; for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++) set_volume_real_value(volume, index[0],index[1],index[2],index[3],index[4], def_values[ index[ xyzv[VIO_Z+1] ]]); prog_count++; if (verbose) update_progress_report(&progress, prog_count); } if (verbose) terminate_progress_report(&progress); delete_general_transform(&forward_transform); grid_transform_ptr->inverse_flag = !(grid_transform_ptr->inverse_flag); } } /* Write out the transform */ if (output_transform_file(argv[2], NULL, &transform) != OK) { (void) fprintf(stderr, "%s: Error writing transform file %s\n", argv[0], argv[2]); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
/* regrid a point in a file using the input co-ordinate and data */ void regrid_point(VIO_Volume * totals, VIO_Volume * weights, double x, double y, double z, int v_size, double *data_buf) { int sizes[MAX_VAR_DIMS]; VIO_Real steps[MAX_VAR_DIMS]; VIO_Real starts[MAX_VAR_DIMS]; int start_idx[3]; int stop_idx[3]; double value, weight; double euc_dist; double euc[3]; double c_pos[3]; int i, j, k, v; double coord[3]; /* target point in mm coordinates, in X, Y, Z order */ VIO_Transform dircos, invdircos; VIO_Vector vector; VIO_Real dir[3]; /* the coord used below has to be in mm coordinates in the dircos space of the target volume. Hence the manipulations with the vols direction_cosines */ make_identity_transform(&dircos); get_volume_direction_cosine(*totals, perm[0], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_x_axis(&dircos, &vector); get_volume_direction_cosine(*totals, perm[1], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_y_axis(&dircos, &vector); get_volume_direction_cosine(*totals, perm[2], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_z_axis(&dircos, &vector); for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ Transform_elem(invdircos, i, j) = Transform_elem(dircos, j, i); } } transform_point(&invdircos, x, y, z, &coord[0], &coord[1], &coord[2]); get_volume_sizes(*totals, sizes); /* in volume voxel order, ie z,y,x with x fastest */ get_volume_separations(*totals, steps); get_volume_starts(*totals, starts); /* figure out the neighbouring voxels start and stop (in voxel co-ordinates) */ for(i = 0; i < 3; i++){ /* go through x, y and z */ start_idx[i] = (int)rint((coord[i] - starts[perm[i]] - regrid_radius[i]) / steps[perm[i]]); stop_idx[i] = start_idx[i] + rint((regrid_radius[i] * 2) / steps[perm[i]]); /* flip if required */ if(start_idx[i] > stop_idx[i]){ value = start_idx[i]; start_idx[i] = stop_idx[i]; stop_idx[i] = value; } /* check that we aren't off the edge */ if(start_idx[i] < 0){ start_idx[i] = 0; } if(stop_idx[i] >= sizes[perm[i]]){ stop_idx[i] = sizes[perm[i]] - 1; } } /* loop over the neighbours, getting euclidian distance */ c_pos[0] = starts[perm[0]] + (start_idx[0] * steps[perm[0]]); for(i = start_idx[0]; i <= stop_idx[0]; i++){ euc[0] = fabs(c_pos[0] - coord[0]); c_pos[1] = starts[perm[1]] + (start_idx[1] * steps[perm[1]]); for(j = start_idx[1]; j <= stop_idx[1]; j++){ euc[1] = fabs(c_pos[1] - coord[1]); c_pos[2] = starts[perm[2]] + (start_idx[2] * steps[perm[2]]); for(k = start_idx[2]; k <= stop_idx[2]; k++){ euc[2] = fabs(c_pos[2] - coord[2]); euc_dist = sqrt(SQR2(euc[0]) + SQR2(euc[1]) + SQR2(euc[2])); if((regrid_radius[0] == 0 || euc[0] <= regrid_radius[0]) && (regrid_radius[1] == 0 || euc[1] <= regrid_radius[1]) && (regrid_radius[2] == 0 || euc[2] <= regrid_radius[2])){ /* calculate the weighting factor */ switch (regrid_type){ default: fprintf(stderr, "Erk! unknown regrid_type. File: %s Line: %d\n", __FILE__, __LINE__); exit(EXIT_FAILURE); break; case NEAREST_FUNC: case LINEAR_FUNC: weight = euc_dist; break; case KAISERBESSEL_FUNC: weight = gsl_sf_bessel_I0(regrid_sigma[0] * sqrt(1 - SQR2(euc[0] / regrid_radius[0]))) * gsl_sf_bessel_I0(regrid_sigma[1] * sqrt(1 - SQR2(euc[1] / regrid_radius[1]))) * gsl_sf_bessel_I0(regrid_sigma[2] * sqrt(1 - SQR2(euc[2] / regrid_radius[2]))) / SQR3((regrid_radius[0] + regrid_radius[1] + regrid_radius[2]) / 3); break; case GAUSSIAN_FUNC: weight = exp(-SQR2(euc[0]) / SQR2(regrid_sigma[0])) * exp(-SQR2(euc[1]) / SQR2(regrid_sigma[1])) * exp(-SQR2(euc[2]) / SQR2(regrid_sigma[2])); break; } /* set data values */ if(regrid_type == NEAREST_FUNC){ value = get_volume_real_value(*weights, k, j, i, 0, 0); if(weight < value){ set_volume_real_value(*weights, k, j, i, 0, 0, weight); for(v = 0; v < v_size; v++){ set_volume_real_value(*totals, k, j, i, v, 0, data_buf[0 + v] * weight); } } } else{ for(v = 0; v < v_size; v++){ value = get_volume_real_value(*totals, k, j, i, v, 0); set_volume_real_value(*totals, k, j, i, v, 0, value + (data_buf[0 + v] * weight)); } /* increment count value */ value = get_volume_real_value(*weights, k, j, i, 0, 0); set_volume_real_value(*weights, k, j, i, 0, 0, value + weight); } } c_pos[2] += steps[perm[2]]; } c_pos[1] += steps[perm[1]]; } c_pos[0] += steps[perm[0]]; } }
static void resample_the_deformation_field(Arg_Data *globals) { VIO_Volume existing_field, new_field; VIO_Real vector_val[3], XYZstart[ VIO_MAX_DIMENSIONS ], wstart[ VIO_MAX_DIMENSIONS ], start[ VIO_MAX_DIMENSIONS ], XYZstep[ VIO_MAX_DIMENSIONS ], step[ VIO_MAX_DIMENSIONS ], step2[ VIO_MAX_DIMENSIONS ], s1[ VIO_MAX_DIMENSIONS ], voxel[ VIO_MAX_DIMENSIONS ], dir[3][3]; int i, siz[ VIO_MAX_DIMENSIONS ], index[ VIO_MAX_DIMENSIONS ], xyzv[ VIO_MAX_DIMENSIONS ], XYZcount[ VIO_MAX_DIMENSIONS ], count[ VIO_MAX_DIMENSIONS ]; VIO_General_transform *non_lin_part; VectorR XYZdirections[ VIO_MAX_DIMENSIONS ]; VIO_Real del_x, del_y, del_z, wx, wy,wz; VIO_progress_struct progress; char **data_dim_names; /* get the nonlinear part of the transformation */ existing_field = (VIO_Volume)NULL; non_lin_part = get_nth_general_transform(globals->trans_info.transformation, get_n_concated_transforms( globals->trans_info.transformation) -1); if (get_transform_type( non_lin_part ) == GRID_TRANSFORM){ existing_field = (VIO_Volume)(non_lin_part->displacement_volume); } else { for(i=0; i<get_n_concated_transforms(globals->trans_info.transformation); i++) print ("Transform %d is of type %d\n",i, get_transform_type( get_nth_general_transform(globals->trans_info.transformation, i) )); print_error_and_line_num("Cannot find the deformation field transform to resample", __FILE__, __LINE__); } /* build a vector volume to store the Grid VIO_Transform */ new_field = create_volume(4, dim_name_vector_vol, NC_DOUBLE, TRUE, 0.0, 0.0); get_volume_XYZV_indices(new_field, xyzv); for(i=0; i<VIO_N_DIMENSIONS; i++) step2[i] = globals->step[i]; /* get new start, count, step and directions, all returned in X, Y, Z order. */ set_up_lattice(existing_field, step2, XYZstart, wstart, XYZcount, XYZstep, XYZdirections); /* reset count and step to be in volume order */ for(i=0; i<VIO_N_DIMENSIONS; i++) { start[ i ] = wstart[ i ]; count[ xyzv[i] ] = XYZcount[ i ]; step[ xyzv[i] ] = XYZstep[ i ]; } /* add info for the vector dimension */ count[xyzv[VIO_Z+1]] = 3; step[xyzv[VIO_Z+1]] = 0.0; /* use the sign of the step returned to set the true step size */ for(i=0; i<VIO_N_DIMENSIONS; i++) { if (step[xyzv[i]]<0) step[xyzv[i]] = -1.0 * fabs(globals->step[i]); else step[xyzv[i]] = fabs(globals->step[i]); } for(i=0; i<VIO_MAX_DIMENSIONS; i++) /* set the voxel origin, used in the vol def */ voxel[i] = 0.0; set_volume_sizes( new_field, count); set_volume_separations( new_field, step); /* set_volume_voxel_range( new_field, -MY_MAX_VOX, MY_MAX_VOX); set_volume_real_range( new_field, -1.0*globals->trans_info.max_def_magnitude, globals->trans_info.max_def_magnitude); - no longer needed, because now using doubles*/ set_volume_translation( new_field, voxel, start); for(i=0; i<VIO_N_DIMENSIONS; i++) { dir[VIO_X][i]=XYZdirections[VIO_X].coords[i]; dir[VIO_Y][i]=XYZdirections[VIO_Y].coords[i]; dir[VIO_Z][i]=XYZdirections[VIO_Z].coords[i]; } set_volume_direction_cosine(new_field,xyzv[VIO_X],dir[VIO_X]); set_volume_direction_cosine(new_field,xyzv[VIO_Y],dir[VIO_Y]); set_volume_direction_cosine(new_field,xyzv[VIO_Z],dir[VIO_Z]); /* make sure that the vector dimension is named! */ data_dim_names = get_volume_dimension_names(new_field); if( strcmp( data_dim_names[ xyzv[VIO_Z+1] ] , MIvector_dimension ) != 0 ) { ALLOC((new_field)->dimension_names[xyzv[VIO_Z+1]], \ strlen(MIvector_dimension ) + 1 ); (void) strcpy( (new_field)->dimension_names[xyzv[VIO_Z+1]], MIvector_dimension ); } delete_dimension_names(new_field, data_dim_names); if (globals->flags.debug) { print ("in resample_deformation_field:\n"); print ("xyzv[axes] = %d, %d, %d, %d\n",xyzv[VIO_X],xyzv[VIO_Y],xyzv[VIO_Z],xyzv[VIO_Z+1]); get_volume_sizes(new_field, siz); get_volume_separations(new_field, s1); print ("seps: %7.3f %7.3f %7.3f %7.3f %7.3f \n",s1[0],s1[1],s1[2],s1[3],s1[4]); print ("size: %7d %7d %7d %7d %7d \n",siz[0],siz[1],siz[2],siz[3],siz[4]); } alloc_volume_data(new_field); if (globals->flags.verbose>0) initialize_progress_report( &progress, FALSE, count[xyzv[VIO_X]], "Interpolating new field" ); /* now resample the values from the input deformation */ for(i=0; i<VIO_MAX_DIMENSIONS; i++) { voxel[i] = 0.0; index[i] = 0; } for(index[xyzv[VIO_X]]=0; index[xyzv[VIO_X]]<count[xyzv[VIO_X]]; index[xyzv[VIO_X]]++) { voxel[xyzv[VIO_X]] = (VIO_Real)index[xyzv[VIO_X]]; for(index[xyzv[VIO_Y]]=0; index[xyzv[VIO_Y]]<count[xyzv[VIO_Y]]; index[xyzv[VIO_Y]]++) { voxel[xyzv[VIO_Y]] = (VIO_Real)index[xyzv[VIO_Y]]; for(index[xyzv[VIO_Z]]=0; index[xyzv[VIO_Z]]<count[xyzv[VIO_Z]]; index[xyzv[VIO_Z]]++) { voxel[xyzv[VIO_Z]] = (VIO_Real)index[xyzv[VIO_Z]]; convert_voxel_to_world(new_field, voxel, &wx,&wy,&wz); grid_transform_point(non_lin_part, wx, wy, wz, &del_x, &del_y, &del_z); /* get just the deformation part */ del_x = del_x - wx; del_y = del_y - wy; del_z = del_z - wz; /* del_x = del_y = del_z = 0.0; */ vector_val[0] = CONVERT_VALUE_TO_VOXEL(new_field, del_x); vector_val[1] = CONVERT_VALUE_TO_VOXEL(new_field, del_y); vector_val[2] = CONVERT_VALUE_TO_VOXEL(new_field, del_z); for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<3; index[xyzv[VIO_Z+1]]++) { SET_VOXEL(new_field, \ index[0], index[1], index[2], index[3], index[4], \ vector_val[ index[ xyzv[ VIO_Z+1] ] ]); } } } if (globals->flags.verbose>0) update_progress_report( &progress,index[xyzv[VIO_X]]+1); } if (globals->flags.verbose>0) terminate_progress_report( &progress ); /* delete and free up old data */ delete_volume(non_lin_part->displacement_volume); /* set new volumes into transform */ non_lin_part->displacement_volume = new_field; }