/* Build the target lattice by transforming the source points through the current non-linear transformation stored in: Glinear_transform and Gsuper_d{x,y,z} deformation volumes both input (px,py,pz) and output (tx,ty,tz) coordinate lists are in WORLD COORDINATES */ void build_target_lattice_using_super_sampled_def( float px[], float py[], float pz[], float tx[], float ty[], float tz[], int len, int dim) { int i,j, sizes[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS]; VIO_Real def_vector[VIO_N_DIMENSIONS], voxel[VIO_MAX_DIMENSIONS], x,y,z; long index[VIO_MAX_DIMENSIONS]; get_volume_sizes(Gsuper_sampled_vol,sizes); get_volume_XYZV_indices(Gsuper_sampled_vol,xyzv); for(i=1; i<=len; i++) { /* apply linear part of the transformation */ general_transform_point(Glinear_transform, (VIO_Real)px[i], (VIO_Real)py[i], (VIO_Real)pz[i], &x, &y, &z); /* now get the non-linear part, using nearest neighbour interpolation in the super-sampled deformation volume. */ convert_world_to_voxel(Gsuper_sampled_vol, x,y,z, voxel); if ((voxel[ xyzv[VIO_X] ] >= -0.5) && (voxel[ xyzv[VIO_X] ] < sizes[xyzv[VIO_X]]-0.5) && (voxel[ xyzv[VIO_Y] ] >= -0.5) && (voxel[ xyzv[VIO_Y] ] < sizes[xyzv[VIO_Y]]-0.5) && (voxel[ xyzv[VIO_Z] ] >= -0.5) && (voxel[ xyzv[VIO_Z] ] < sizes[xyzv[VIO_Z]]-0.5) ) { for(j=0; j<3; j++) index[ xyzv[j] ] = (long) (voxel[ xyzv[j] ]+0.5); for(index[xyzv[VIO_Z+1]]=0; index[xyzv[VIO_Z+1]]<sizes[xyzv[VIO_Z+1]]; index[xyzv[VIO_Z+1]]++) GET_VALUE_4D(def_vector[ index[ xyzv[VIO_Z+1] ] ], \ Gsuper_sampled_vol, \ index[0], index[1], index[2], index[3]); x += def_vector[VIO_X]; y += def_vector[VIO_Y]; z += def_vector[VIO_Z]; } tx[i] = (float)x; ty[i] = (float)y; tz[i] = (float)z; } }
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); }
static void append_new_default_deformation_field(Arg_Data *globals) { VIO_Volume new_field; VIO_Real zero, st[VIO_MAX_DIMENSIONS], wst[VIO_MAX_DIMENSIONS], step[VIO_MAX_DIMENSIONS], XYZstart[ VIO_MAX_DIMENSIONS ], XYZstep[ VIO_MAX_DIMENSIONS ], voxel[VIO_MAX_DIMENSIONS], point[VIO_N_DIMENSIONS], dir[3][3]; int index[VIO_MAX_DIMENSIONS], xyzv[VIO_MAX_DIMENSIONS], i, count[VIO_MAX_DIMENSIONS], XYZcount[VIO_MAX_DIMENSIONS], count_extended[VIO_MAX_DIMENSIONS]; VIO_General_transform *grid_trans; VectorR XYZdirections[ VIO_MAX_DIMENSIONS ]; /* build a vector volume to store the Grid VIO_Transform */ /* ALLOC(new_field,1); not needed since create volume allocs it internally and returns a pointer*/ if (globals->flags.debug) { print ("In append_new_default_deformation_field...\n"); } new_field = create_volume(4, dim_name_vector_vol, NC_DOUBLE, TRUE, 0.0, 0.0); get_volume_XYZV_indices(new_field, xyzv); /* get the global voxel count and voxel size */ for(i=0; i<VIO_N_DIMENSIONS; i++) { count[xyzv[i]] = globals->count[i]; count_extended[xyzv[i]] = count[xyzv[i]]; step[xyzv[i]] = globals->step[i]; } /* add info for the vector dimension */ count[xyzv[VIO_Z+1]] = 3; count_extended[xyzv[VIO_Z+1]] = 3; step[xyzv[VIO_Z+1]] = 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, now using floats */ for(i=0; i<VIO_N_DIMENSIONS; i++) { dir[VIO_X][i]=globals->directions[VIO_X].coords[i]; dir[VIO_Y][i]=globals->directions[VIO_Y].coords[i]; dir[VIO_Z][i]=globals->directions[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]); for(i=0; i<VIO_MAX_DIMENSIONS; i++) /* set the voxel origin, used in the vol def */ voxel[i] = 0.0; set_volume_translation( new_field, voxel, globals->start); if (globals->flags.debug) { print("in append new def, the start is: %8.3f %8.3f %8.3f\n", globals->start[VIO_X], globals->start[VIO_Y], globals->start[VIO_Z]); } /* now pad the volume along the spatial axis to ensure good coverage of the data space with the deformation field */ for(i=0; i<VIO_N_DIMENSIONS; i++) { if (globals->count[i]>1) { voxel[xyzv[i]] = -2.5; count_extended[xyzv[i]] = globals->count[i]+5; } else { voxel[xyzv[i]] = 0.0; count_extended[xyzv[i]] = 1; } } if (globals->flags.debug) { print("in append_new_default_deformation_field:\n\tcount_extended= %d %d %d %d\n", count_extended[0],count_extended[1],count_extended[2],count_extended[3]); } set_volume_sizes(new_field, count_extended); for(i=0; i<VIO_MAX_DIMENSIONS; i++) count[i] = count_extended[i]; /* reset the first voxel position with the new origin */ convert_voxel_to_world(new_field, voxel, &(point[VIO_X]), &(point[VIO_Y]), &(point[VIO_Z])); for(i=0; i<VIO_MAX_DIMENSIONS; i++) voxel[i] = 0; set_volume_translation(new_field, voxel, point); if (globals->flags.debug) { print (" point: %8.3f %8.3f %8.3f \n", point[VIO_X], point[VIO_Y], point[VIO_Z]); get_volume_starts(new_field, st); print (" start: %8.3f %8.3f %8.3f \n", st[xyzv[VIO_X]], st[xyzv[VIO_Y]], st[xyzv[VIO_Z]]); voxel[0] = 0; voxel[1] = 0; voxel[2] = 0; get_volume_translation(new_field, voxel, wst); print (" wstrt: %8.3f %8.3f %8.3f \n", wst[VIO_X], wst[VIO_Y], wst[VIO_Z]); print (" voxel: %8.3f %8.3f %8.3f \n", voxel[xyzv[VIO_X]], voxel[xyzv[VIO_Y]], voxel[xyzv[VIO_Z]]); for(i=0; i<3; i++) { get_volume_direction_cosine(new_field,xyzv[i], wst); print (" dirs: %8.3f %8.3f %8.3f \n", wst[VIO_X], wst[VIO_Y], wst[VIO_Z]); } } /* allocate space for the deformation field data */ alloc_volume_data(new_field); /* Initilize the field to zero deformation */ /* zero = CONVERT_VALUE_TO_VOXEL(new_field, 0.0); not needed, defs are now doubles */ for(index[0]=0; index[0]<count[0]; index[0]++) for(index[1]=0; index[1]<count[1]; index[1]++) for(index[2]=0; index[2]<count[2]; index[2]++) for(index[3]=0; index[3]<count[3]; index[3]++) { SET_VOXEL(new_field, index[0],index[1],index[2],index[3],0, 0.0); /* was set to 'zero', but now as a double,can be set to 0.0 */ } /* build the new GRID_TRANSFORM */ ALLOC(grid_trans, 1); create_grid_transform(grid_trans, new_field, NULL); /* append the deforamation to the current transformation */ concat_general_transforms(globals->trans_info.transformation, grid_trans, globals->trans_info.transformation); delete_volume(new_field); delete_general_transform(grid_trans); }
void interpolate_deformation_slice(VIO_Volume volume, VIO_Real wx,Real wy,Real wz, VIO_Real def[]) { VIO_Real world[VIO_N_DIMENSIONS], v00,v01,v02,v03, v10,v11,v12,v13, v20,v21,v22,v23, v30,v31,v32,v33; long ind0, ind1, ind2; VIO_Real voxel[VIO_MAX_DIMENSIONS], frac[VIO_MAX_DIMENSIONS]; int i, xyzv[VIO_MAX_DIMENSIONS], sizes[VIO_MAX_DIMENSIONS]; double temp_result; def[VIO_X] = def[VIO_Y] = def[VIO_Z] = 0.0; world[VIO_X] = wx; world[VIO_Y] = wy; world[VIO_Z] = wz; convert_world_to_voxel(volume, wx, wy, wz, voxel); /* Check that the coordinate is inside the volume */ get_volume_sizes(volume, sizes); get_volume_XYZV_indices(volume, xyzv); if ((voxel[ xyzv[VIO_X] ] < 0) || (voxel[ xyzv[VIO_X] ] >=sizes[ xyzv[VIO_X]]) || (voxel[ xyzv[VIO_Y] ] < 0) || (voxel[ xyzv[VIO_Y] ] >=sizes[ xyzv[VIO_Y]]) || (voxel[ xyzv[VIO_Z] ] < 0) || (voxel[ xyzv[VIO_Z] ] >=sizes[ xyzv[VIO_Z]])) { return ; } if (/*(sizes[ xyzv[VIO_Z] ] == 1) &&*/ xyzv[VIO_Z]==1) { /* Get the whole and fractional part of the coordinate */ ind0 = FLOOR( voxel[ xyzv[VIO_Z] ] ); ind1 = FLOOR( voxel[ xyzv[VIO_Y] ] ); ind2 = FLOOR( voxel[ xyzv[VIO_X] ] ); frac[VIO_Y] = voxel[ xyzv[VIO_Y] ] - ind1; frac[VIO_X] = voxel[ xyzv[VIO_X] ] - ind2; if (sizes[xyzv[VIO_X]] < 4 || sizes[xyzv[VIO_Y]] < 4) { def[VIO_X] = get_volume_real_value(volume, 0, ind0, ind1, ind2, 0); def[VIO_Y] = get_volume_real_value(volume, 1, ind0, ind1, ind2, 0); def[VIO_Z] = get_volume_real_value(volume, 2, ind0, ind1, ind2, 0); return; } if (ind1==0) frac[VIO_Y] -= 1.0; else { ind1--; while ( ind1+3 >= sizes[xyzv[VIO_Y]] ) { ind1--; frac[VIO_Y] += 1.0; } } if (ind2==0) frac[VIO_X] -= 1.0; else { ind2--; while ( ind2+3 >= sizes[xyzv[VIO_X]] ) { ind2--; frac[VIO_X] += 1.0; } } for(i=0; i<3; i++) { GET_VOXEL_4D(v00, volume, i, ind0, ind1, ind2); GET_VOXEL_4D(v01, volume, i, ind0, ind1, ind2+1); GET_VOXEL_4D(v02, volume, i, ind0, ind1, ind2+2); GET_VOXEL_4D(v03, volume, i, ind0, ind1, ind2+3); GET_VOXEL_4D(v10, volume, i, ind0, ind1+1, ind2); GET_VOXEL_4D(v11, volume, i, ind0, ind1+1, ind2+1); GET_VOXEL_4D(v12, volume, i, ind0, ind1+1, ind2+2); GET_VOXEL_4D(v13, volume, i, ind0, ind1+1, ind2+3); GET_VOXEL_4D(v20, volume, i, ind0, ind1+2, ind2); GET_VOXEL_4D(v21, volume, i, ind0, ind1+2, ind2+1); GET_VOXEL_4D(v22, volume, i, ind0, ind1+2, ind2+2); GET_VOXEL_4D(v23, volume, i, ind0, ind1+2, ind2+3); GET_VOXEL_4D(v30, volume, i, ind0, ind1+3, ind2); GET_VOXEL_4D(v31, volume, i, ind0, ind1+3, ind2+1); GET_VOXEL_4D(v32, volume, i, ind0, ind1+3, ind2+2); GET_VOXEL_4D(v33, volume, i, ind0, ind1+3, ind2+3); CUBIC_BIVAR(v00,v01,v02,v03, \ v10,v11,v12,v13, \ v20,v21,v22,v23, \ v30,v31,v32,v33, \ frac[VIO_Y],frac[VIO_X], temp_result); def[i] = CONVERT_VOXEL_TO_VALUE(volume,temp_result); } } else { print ("\n\nxyzv[] = %d %d %d %d\n",xyzv[0],xyzv[1],xyzv[2],xyzv[3]); print ("\n\nsizes[]= %d %d %d %d\n",sizes[0],sizes[1],sizes[2],sizes[3]); print_error_and_line_num("error in slice_interpolate", __FILE__, __LINE__); } }
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; }