static void prox_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in) { struct prox_dfwavelet_data* data = CONTAINER_OF(_data, struct prox_dfwavelet_data, base); bool done = false; long pos[DIMS]; md_set_dims(DIMS, pos, 0); while (!done) { // copy vx, vy, vz md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vx, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vy, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vz, in, CFL_SIZE); pos[data->flow_dim]=0; // threshold dfwavelet_thresh(data->plan, thresh * data->lambda, thresh* data->lambda, data->vx, data->vy, data->vz, data->vx, data->vy, data->vz); // copy vx, vy, vz md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vx, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vy, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vz, CFL_SIZE); pos[data->flow_dim]=0; // increment pos long carryon = 1; for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(data->slice_flag & ~MD_BIT(data->flow_dim), i)) { pos[i] += carryon; if (pos[i] < data->im_dims[i]) { carryon = 0; break; } else { carryon = 1; pos[i] = 0; } } } done = carryon; } }
int main_slice(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); long in_dims[DIMS]; long out_dims[DIMS]; complex float* in_data = load_cfl(argv[3], DIMS, in_dims); int dim = atoi(argv[1]); int pos = atoi(argv[2]); assert(dim < DIMS); assert(pos >= 0); assert(pos < in_dims[dim]); for (int i = 0; i < DIMS; i++) out_dims[i] = in_dims[i]; out_dims[dim] = 1; complex float* out_data = create_cfl(argv[4], DIMS, out_dims); long pos2[DIMS] = { [0 ... DIMS - 1] = 0 }; pos2[dim] = pos; md_slice(DIMS, MD_BIT(dim), pos2, in_dims, out_data, in_data, CFL_SIZE); unmap_cfl(DIMS, out_dims, out_data); unmap_cfl(DIMS, in_dims, in_data); return 0; }
// [RING] Caclucate intersection points static void calc_intersections(unsigned int Nint, unsigned int N, unsigned int no_intersec_sp, float dist[2][Nint], long idx[2][Nint], const float angles[N], const long kc_dims[DIMS], const complex float* kc, const int ROI) { long spoke_dims[DIMS]; md_copy_dims(DIMS, spoke_dims, kc_dims); spoke_dims[PHS2_DIM] = 1; complex float* spoke_i = md_alloc(DIMS, spoke_dims, CFL_SIZE); complex float* spoke_j = md_alloc(DIMS, spoke_dims, CFL_SIZE); long pos_i[DIMS] = { 0 }; long pos_j[DIMS] = { 0 }; long coilPixel_dims[DIMS]; md_copy_dims(DIMS, coilPixel_dims, spoke_dims); coilPixel_dims[PHS1_DIM] = 1; complex float* coilPixel_l = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); complex float* coilPixel_m = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); complex float* diff = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); long diff_rss_dims[DIMS]; md_copy_dims(DIMS, diff_rss_dims, coilPixel_dims); diff_rss_dims[COIL_DIM] = 1; diff_rss_dims[PHS1_DIM] = 1; complex float* diff_rss = md_alloc(DIMS, diff_rss_dims, CFL_SIZE); long pos_l[DIMS] = { 0 }; long pos_m[DIMS] = { 0 }; // Array to store indices of spokes that build an angle close to pi/2 with the current spoke long intersec_sp[no_intersec_sp]; for (unsigned int i = 0; i < no_intersec_sp; i++) intersec_sp[i] = -1; // Boundaries for spoke comparison int myROI = ROI; myROI += (ROI % 2 == 0) ? 1 : 0; // make odd int low = 0; int high = myROI - 1; int count = 0; // Intersection determination for (unsigned int i = 0; i < N; i++) { pos_i[PHS2_DIM] = i; md_slice(DIMS, PHS2_FLAG, pos_i, kc_dims, spoke_i, kc, CFL_SIZE); find_intersec_sp(no_intersec_sp, intersec_sp, i, N, angles); for (unsigned int j = 0; j < no_intersec_sp; j++) { pos_j[PHS2_DIM] = intersec_sp[j]; md_slice(DIMS, PHS2_FLAG, pos_j, kc_dims, spoke_j, kc, CFL_SIZE); idx[0][i * no_intersec_sp + j] = i; idx[1][i * no_intersec_sp + j] = intersec_sp[j]; // Elementwise rss comparisson float rss = FLT_MAX; for (int l = low; l <= high; l++) { pos_l[PHS1_DIM] = l; md_copy_block(DIMS, pos_l, coilPixel_dims, coilPixel_l, spoke_dims, spoke_i, CFL_SIZE); for (int m = low; m <= high; m++) { pos_m[PHS1_DIM] = m; md_copy_block(DIMS, pos_m, coilPixel_dims, coilPixel_m, spoke_dims, spoke_j, CFL_SIZE); md_zsub(DIMS, coilPixel_dims, diff, coilPixel_l, coilPixel_m); md_zrss(DIMS, coilPixel_dims, PHS1_FLAG|COIL_FLAG, diff_rss, diff); if (cabsf(diff_rss[0]) < rss) { // New minimum found rss = cabsf(diff_rss[0]); dist[0][i * no_intersec_sp + j] = (l + 1/2 - ROI/2); dist[1][i * no_intersec_sp + j] = (m + 1/2 - ROI/2); } } } count++; } } #ifdef RING_PAPER // Print projection angles and corresponding offsets to files const char* idx_out = "projangle.txt"; FILE* fp = fopen(idx_out, "w"); const char* d_out = "offset.txt"; FILE* fp1 = fopen(d_out, "w"); for (unsigned int i = 0; i < N; i++) { for (unsigned int j = 0; j < no_intersec_sp; j++) { fprintf(fp, "%f \t %f\n", angles[idx[0][i * no_intersec_sp + j]], angles[idx[1][i * no_intersec_sp + j]]); fprintf(fp1, "%f \t %f\n", dist[0][i * no_intersec_sp + j], dist[1][i * no_intersec_sp + j]); } } fclose(fp); fclose(fp1); #endif md_free(spoke_i); md_free(spoke_j); md_free(coilPixel_l); md_free(coilPixel_m); md_free(diff); md_free(diff_rss); }
static void prox_4pt_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in) { struct prox_4pt_dfwavelet_data* data = CONTAINER_OF(_data, struct prox_4pt_dfwavelet_data, base); bool done = false; long pos[DIMS]; md_set_dims(DIMS, pos, 0); while (!done) { // copy pc md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc0, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc1, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc2, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc3, in, CFL_SIZE); pos[data->flow_dim] = 0; // pc to velocity // TODO: Make gpu for (int i = 0; i < md_calc_size(DIMS, data->tim_dims); i++) { data->vx[i] = (data->pc1[i] - data->pc0[i]) / 2; data->vy[i] = (data->pc2[i] - data->pc1[i]) / 2; data->vz[i] = (data->pc3[i] - data->pc2[i]) / 2; data->ph0[i] = (data->pc0[i] + data->pc3[i]) / 2; } // threshold dfwavelet_thresh(data->plan, thresh * data->lambda, thresh* data->lambda, data->vx, data->vy, data->vz, data->vx, data->vy, data->vz); operator_p_apply(data->wthresh_op, thresh, DIMS, data->tim_dims, data->ph0, DIMS, data->tim_dims, data->ph0); // velocity to pc for (int i = 0; i < md_calc_size(DIMS, data->tim_dims ); i++) { data->pc0[i] = (- data->vx[i] - data->vy[i] - data->vz[i] + data->ph0[i]); data->pc1[i] = (+ data->vx[i] - data->vy[i] - data->vz[i] + data->ph0[i]); data->pc2[i] = (+ data->vx[i] + data->vy[i] - data->vz[i] + data->ph0[i]); data->pc3[i] = (+ data->vx[i] + data->vy[i] + data->vz[i] + data->ph0[i]); } // copy pc md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->pc0, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->pc1, CFL_SIZE); pos[data->flow_dim]++; md_copy_block( DIMS, pos, data->im_dims, out, data->tim_dims, data->pc2, CFL_SIZE ); pos[data->flow_dim]++; md_copy_block( DIMS, pos, data->im_dims, out, data->tim_dims, data->pc3, CFL_SIZE ); pos[data->flow_dim] = 0; // increment pos long carryon = 1; for(unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(data->slice_flag & ~MD_BIT(data->flow_dim), i)) { pos[i] += carryon; if (pos[i] < data->im_dims[i]) { carryon = 0; break; } else { carryon = 1; pos[i] = 0; } } } done = carryon; } }