BICAPI void safe_compute_transform_from_tags( int npoints, Real **tag_list1, Real **tag_list2, Trans_type trans_type, General_transform *transform ) { #if !HAVE_FORK compute_transform_from_tags( npoints, tag_list1, tag_list2, trans_type, transform ); #else int fildes[2]; FILE *fpin, *fpout; Status status; int statptr; General_transform computed_transform; /* Create a pipe */ if (pipe(fildes)) { create_linear_transform(transform, NULL); return; } /* Fork */ if (fork()) { /* Parent */ (void) close(fildes[1]); fpin = fdopen(fildes[0], "r"); status = input_transform(fpin, NULL, transform); (void) fclose(fpin); do { (void) wait(&statptr); } while (WIFSTOPPED(statptr)); if (WEXITSTATUS(statptr) || status != OK) { if( status == OK ) delete_general_transform( transform ); create_linear_transform(transform, NULL); return; } } else { /* Child */ (void) close(fildes[0]); fpout = fdopen(fildes[1], "w"); compute_transform_from_tags(npoints, tag_list1, tag_list2, trans_type, &computed_transform); status = output_transform(fpout, NULL, NULL, NULL, &computed_transform); delete_general_transform( &computed_transform ); (void) fclose(fpout); if (status != OK) { exit(EXIT_FAILURE); } else { exit(EXIT_SUCCESS); } } return; #endif }
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); }
int main( int ac, char* av[] ) { VIO_General_transform xfm; FILE *in; int line=1; if ( ac != 4 ) { fprintf( stderr, "usage: %s transform.xfm control_table.txt tolerance\n", av[0] ); return 1; } if ( input_transform_file( av[1], &xfm ) != VIO_OK ) { fprintf( stderr, "Failed to load transform '%s'\n", av[1] ); return 2; } tolerance = atof( av[3] ); if(!(in=fopen(av[2],"r"))) { fprintf( stderr, "Failed to load table '%s'\n", av[2] ); return 2; } /*Set the same seed number*/ while (!feof(in)) { VIO_Real x,y,z; VIO_Real tx,ty,tz; VIO_Real ttx,tty,ttz; VIO_Real a,b,c; VIO_Real ta,tb,tc; int check=1; char line_c[1024]; check=fscanf(in,"%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",&x,&y,&z,&a,&b,&c,&ta,&tb,&tc); if(check<=0) break; if(check!=3 && check!=9) { fprintf( stderr,"Unexpected input file format at line %d , read %d values!\n",line,check); return 3; } if(general_transform_point( &xfm, x,y,z, &tx,&ty,&tz ) != VIO_OK) { fprintf( stderr, "Failed to transform point %f,%f,%f \n", x,y,z ); return 3; } if(general_inverse_transform_point( &xfm, x,y,z, &ttx,&tty,&ttz ) != VIO_OK) { fprintf( stderr, "Failed to invert transform point %f,%f,%f \n", tx,ty,tz ); return 3; } if(check==3) { fprintf( stdout,"%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg,%.20lg\n",x,y,z,tx,ty,tz,ttx,tty,ttz); } else { sprintf(line_c,"Line:%d Fwd ",line); assert_equal_point( tx,ty,tz, a,b,c, line_c ); sprintf(line_c,"Line:%d Inv ",line); assert_equal_point( ttx,tty,ttz, ta,tb,tc, line_c ); } line++; fgetc(in); } fclose(in); delete_general_transform(&xfm); return 0; }
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); }