/* zscore - z-score differences */ double do_int_calcs(double f_px, double s_px, double mean_f_px, double mean_s_px, double sum_f_px, double sum_s_px, double nvox){ double sd_f, sd_s, zscore; /* mean */ mean_f_px = sum_f_px / nvox; mean_s_px = sum_s_px / nvox; /* variance and sd */ sd_f = sqrt(((nvox * SQR2(sum_f_px)) - SQR2(f_px)) / (nvox * (nvox - 1))); sd_s = sqrt(((nvox * SQR2(sum_s_px)) - SQR2(s_px)) / (nvox * (nvox - 1))); for (int i = 0; i < nvox; i ++) { zscore += fabs((f_px - mean_f_px)/sd_f - (s_px - mean_s_px)/sd_s)/nvox; } return zscore; }
/* 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]]; } }