void fftshift2(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src) { long pos[N]; md_set_dims(N, pos, 0); for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) pos[i] = dims[i] / 2; md_circ_shift2(N, dims, pos, ostrs, dst, istrs, src, CFL_SIZE); }
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; } }
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; } }
int main_homodyne(int argc, char* argv[]) { bool clear = false; const char* phase_ref = NULL; int com; while (-1 != (com = getopt(argc, argv, "hCP:"))) { switch (com) { case 'C': clear = true; break; case 'P': phase_ref = strdup(optarg); break; case 'h': help(argv[0], stdout); exit(0); default: help(argv[0], stderr); exit(1); } } if (argc - optind != 4) { usage(argv[0], stderr); exit(1); } const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[optind + 2], N, dims); complex float* data = create_cfl(argv[optind + 3], N, dims); int pfdim = atoi(argv[optind + 0]); float frac = atof(argv[optind + 1]); assert((0 <= pfdim) && (pfdim < N)); assert(frac > 0.); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); struct wdata wdata; wdata.frac = frac; wdata.pfdim = pfdim; md_select_dims(N, MD_BIT(pfdim), wdata.wdims, dims); md_calc_strides(N, wdata.wstrs, wdata.wdims, CFL_SIZE); wdata.weights = md_alloc(N, wdata.wdims, CFL_SIZE); md_loop(N, wdata.wdims, &wdata, comp_weights); long pstrs[N]; long pdims[N]; complex float* phase = NULL; if (NULL == phase_ref) { phase = estimate_phase(wdata, FFT_FLAGS, N, dims, idata); md_copy_dims(N, pdims, dims); } else phase = load_cfl(phase_ref, N, pdims); md_calc_strides(N, pstrs, pdims, CFL_SIZE); complex float* cdata = NULL; complex float* idata2 = NULL; if (clear) { long cdims[N]; md_select_dims(N, ~MD_BIT(pfdim), cdims, dims); cdims[pfdim] = (int)(dims[pfdim] * frac); cdata = md_alloc(N, cdims, CFL_SIZE); idata2 = anon_cfl(NULL, N, dims); md_resize(N, cdims, cdata, dims, idata, CFL_SIZE); md_resize(N, dims, idata2, cdims, cdata, CFL_SIZE); md_free(cdata); unmap_cfl(N, dims, idata); idata = idata2; } if ((1 == dims[PHS2_DIM]) || (PHS2_DIM == pfdim)) { homodyne(wdata, FFT_FLAGS, N, dims, strs, data, idata, pstrs, phase); } else { unsigned int pardim = PHS2_DIM; ifftuc(N, dims, MD_CLEAR(FFT_FLAGS, pfdim), data, idata); long rdims[N]; md_select_dims(N, ~MD_BIT(pardim), rdims, dims); long rstrs[N]; md_calc_strides(N, rstrs, rdims, CFL_SIZE); #pragma omp parallel for for (unsigned int i = 0; i < dims[pardim]; i++) { complex float* tmp = md_alloc(N, rdims, CFL_SIZE); long pos[N]; md_set_dims(N, pos, 0); pos[pardim] = i; md_copy_block(N, pos, rdims, tmp, dims, data, CFL_SIZE); homodyne(wdata, MD_BIT(pfdim), N, rdims, rstrs, tmp, tmp, pstrs, phase); md_copy_block(N, pos, dims, data, rdims, tmp, CFL_SIZE); md_free(tmp); } } md_free(wdata.weights); if (NULL == phase_ref) md_free(phase); else { unmap_cfl(N, pdims, phase); free((void*)phase_ref); } unmap_cfl(N, dims, idata); unmap_cfl(N, dims, data); exit(0); }
int main_homodyne(int argc, char* argv[]) { mini_cmdline(argc, argv, 4, usage_str, help_str); const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[3], N, dims); complex float* data = create_cfl(argv[4], N, dims); int pfdim = atoi(argv[1]); float frac = atof(argv[2]); assert((0 <= pfdim) && (pfdim < N)); assert(frac > 0.); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); struct wdata wdata; wdata.frac = frac; wdata.pfdim = pfdim; md_select_dims(N, MD_BIT(pfdim), wdata.wdims, dims); md_calc_strides(N, wdata.wstrs, wdata.wdims, CFL_SIZE); wdata.weights = md_alloc(N, wdata.wdims, CFL_SIZE); md_loop(N, wdata.wdims, &wdata, comp_weights); if ((1 == dims[PHS2_DIM]) || (PHS2_DIM == pfdim)) { homodyne(wdata, FFT_FLAGS, N, dims, strs, data, idata); } else { unsigned int pardim = PHS2_DIM; ifftuc(N, dims, MD_CLEAR(FFT_FLAGS, pfdim), data, idata); long rdims[N]; md_select_dims(N, ~MD_BIT(pardim), rdims, dims); long rstrs[N]; md_calc_strides(N, rstrs, rdims, CFL_SIZE); #pragma omp parallel for for (unsigned int i = 0; i < dims[pardim]; i++) { complex float* tmp = md_alloc(N, rdims, CFL_SIZE); long pos[N]; md_set_dims(N, pos, 0); pos[pardim] = i; md_copy_block(N, pos, rdims, tmp, dims, data, CFL_SIZE); homodyne(wdata, MD_BIT(pfdim), N, rdims, rstrs, tmp, tmp); md_copy_block(N, pos, dims, data, rdims, tmp, CFL_SIZE); md_free(tmp); } } md_free(wdata.weights); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, data); exit(0); }