void normalize_data_to_match_target(VIO_Volume d1, VIO_Volume m1, VIO_Real thresh1, VIO_Volume d2, VIO_Volume m2, VIO_Real thresh2, Arg_Data *globals) { VectorR vector_step; PointR starting_position, slice, row, col, pos2, voxel; double tx,ty,tz; int i,j,k, r,c,s; VIO_Real min_range, max_range, data_vox, data_val, value1, value2; VIO_Real t1,t2, /* temporary threshold values */ s1,s2,s3; /* to store the sums for f1,f2,f3 */ float *ratios, result; /* the result */ int sizes[VIO_MAX_DIMENSIONS],ratios_size,count1,count2; VIO_Volume vol; VIO_progress_struct progress; VIO_Data_types data_type; set_feature_value_threshold(d1,d2, &thresh1, &thresh2, &t1, &t2); if (globals->flags.debug) { print ("In normalize_data_to_match_target, thresh = %10.3f %10.3f\n",t1,t2) ; } ratios_size = globals->count[ROW_IND] * globals->count[COL_IND] * globals->count[SLICE_IND]; ALLOC(ratios, ratios_size); fill_Point( starting_position, globals->start[VIO_X], globals->start[VIO_Y], globals->start[VIO_Z]); s1 = s2 = s3 = 0.0; count1 = count2 = 0; for(s=0; s<=globals->count[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, globals->directions[SLICE_IND], s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=globals->count[ROW_IND]; r++) { SCALE_VECTOR( vector_step, globals->directions[ROW_IND], r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=globals->count[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))) { value1 = get_value_of_point_in_volume( Point_x(col), Point_y(col), Point_z(col), d1); if ( value1 > t1 ) { count1++; DO_TRANSFORM(pos2, globals->trans_info.transformation, col); convert_3D_world_to_voxel(d2, Point_x(pos2), Point_y(pos2), Point_z(pos2), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m2, Point_x(pos2), Point_y(pos2), Point_z(pos2))) { value2 = get_value_of_point_in_volume( Point_x(pos2), Point_y(pos2), Point_z(pos2), d2); if ( (value2 > t2) && ((value2 < -1e-15) || (value2 > 1e-15)) ) { ratios[count2++] = value1 / value2 ; s1 += value1*value2; s2 += value1*value1; s3 += value2*value2; } /* if voxel in d2 */ } /* if point in mask volume two */ } /* if voxel in d1 */ } /* if point in mask volume one */ ADD_POINT_VECTOR( col, col, globals->directions[COL_IND] ); } /* for c */ } /* for r */ } /* for s */ if (count2 > 0) { if (globals->flags.debug) (void)print ("Starting qsort of ratios..."); qs_list (ratios,0,count2); if (globals->flags.debug) (void)print ("Done.\n"); result = ratios[ (int)(count2/2) ]; /* the median value */ if (globals->flags.debug) (void)print ("Normalization: %7d %7d -> %10.8f\n",count1,count2,result); if ( fabs(result) < 1e-15) { print_error_and_line_num("Error computing normalization ratio `%f'.",__FILE__, __LINE__, result); } else { data_type = get_volume_data_type(d1); switch( data_type ) { case SIGNED_BYTE: case UNSIGNED_BYTE: case SIGNED_SHORT: case UNSIGNED_SHORT: /* build temporary working volume */ vol = copy_volume_definition_no_alloc(d1, NC_UNSPECIFIED, FALSE, 0.0, 0.0); get_volume_minimum_maximum_real_value(d1, &min_range, &max_range); min_range /= result; max_range /= result; set_volume_real_range(vol, min_range, max_range); get_volume_sizes(d1, sizes); initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Normalizing source data" ); count1 = 0; /* reset values in the data volume */ for(i=0; i<sizes[0]; i++) for(j=0; j<sizes[1]; j++) { count1++; update_progress_report( &progress, count1); for(k=0; k<sizes[2]; k++) { GET_VOXEL_3D( data_vox, d1, i, j, k ); data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); data_val /= result; data_vox = CONVERT_VALUE_TO_VOXEL( vol, data_val); SET_VOXEL_3D( d1 , i, j, k, data_vox ); } } terminate_progress_report( &progress ); set_volume_real_range(d1, min_range, max_range); if (globals->flags.debug) (void)print ("After normalization min,max, thresh = %f %f %f\n", min_range, max_range, t1/result); delete_volume(vol); break; default: /* then volume should be either float or double */ get_volume_sizes(d1, sizes); initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Normalizing source data" ); count1 = 0; /* nomalize the values in the data volume */ for(i=0; i<sizes[0]; i++) for(j=0; j<sizes[1]; j++) { count1++; update_progress_report( &progress, count1); for(k=0; k<sizes[2]; k++) { /* it should be possible to directly stream through the voxels, without indexing... */ GET_VOXEL_3D( data_vox, d1, i, j, k ); data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); data_val /= result; data_vox = CONVERT_VALUE_TO_VOXEL( d1, data_val); SET_VOXEL_3D( d1 , i, j, k, data_vox ); } } terminate_progress_report( &progress ); } } } FREE(ratios); }
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); }
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 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__); } }