int main_index(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); int N = atoi(argv[1]); int s = atoi(argv[2]); assert(N >= 0); assert(s >= 0); long dims[N + 1]; for (int i = 0; i < N; i++) dims[i] = 1; dims[N] = s; complex float* x = create_cfl(argv[3], N + 1, dims); for (int i = 0; i < s; i++) x[i] = i; unmap_cfl(N + 1, dims, x); exit(0); }
int main_conv(int argc, char* argv[]) { cmdline(&argc, argv, 4, 4, usage_str, help_str, 0, NULL); num_init(); unsigned int flags = atoi(argv[1]); unsigned int N = DIMS; long dims[N]; const complex float* in = load_cfl(argv[2], N, dims); long krn_dims[N]; const complex float* krn = load_cfl(argv[3], N, krn_dims); complex float* out = create_cfl(argv[4], N, dims); struct conv_plan* plan = conv_plan(N, flags, CONV_CYCLIC, CONV_SYMMETRIC, dims, dims, krn_dims, krn); conv_exec(plan, out, in); conv_free(plan); unmap_cfl(N, dims, out); unmap_cfl(N, krn_dims, krn); unmap_cfl(N, dims, in); exit(0); }
int main_transpose(int argc, char* argv[]) { mini_cmdline(argc, argv, 4, usage_str, help_str); int N = DIMS; long idims[N]; int dim1 = atoi(argv[1]); int dim2 = atoi(argv[2]); assert((0 <= dim1) && (dim1 < N)); assert((0 <= dim2) && (dim2 < N)); complex float* idata = load_cfl(argv[3], N, idims); long odims[N]; md_transpose_dims(N, dim1, dim2, odims, idims); complex float* odata = create_cfl(argv[4], N, odims); md_transpose(N, dim1, dim2, odims, odata, idims, idata, sizeof(complex float)); unmap_cfl(N, idims, idata); unmap_cfl(N, odims, odata); exit(0); }
int main_repmat(int argc, char* argv[]) { mini_cmdline(argc, argv, 4, usage_str, help_str); 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 rep = atoi(argv[2]); assert(dim < DIMS); assert(rep >= 0); assert(1 == in_dims[dim]); md_copy_dims(DIMS, out_dims, in_dims); out_dims[dim] = rep; complex float* out_data = create_cfl(argv[4], DIMS, out_dims); long in_strs[DIMS]; long out_strs[DIMS]; md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); md_calc_strides(DIMS, out_strs, out_dims, CFL_SIZE); md_copy2(DIMS, out_dims, out_strs, out_data, in_strs, in_data, CFL_SIZE); unmap_cfl(DIMS, out_dims, out_data); unmap_cfl(DIMS, in_dims, in_data); exit(0); }
int main_fft(int argc, char* argv[]) { bool unitary = false; bool inv = false; const struct opt_s opts[] = { OPT_SET('u', &unitary, "unitary"), OPT_SET('i', &inv, "inverse"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); long dims[DIMS]; complex float* idata = load_cfl(argv[2], DIMS, dims); complex float* data = create_cfl(argv[3], DIMS, dims); unsigned long flags = labs(atol(argv[1])); md_copy(DIMS, dims, data, idata, sizeof(complex float)); unmap_cfl(DIMS, dims, idata); if (unitary) fftscale(DIMS, dims, flags, data, data); (inv ? ifftc : fftc)(DIMS, dims, flags, data, data); unmap_cfl(DIMS, dims, data); exit(0); }
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; }
void dump_cfl(const char* name, int D, const long dimensions[D], const complex float* src) { complex float* out = create_cfl(name, D, dimensions); md_copy(D, dimensions, out, src, sizeof(complex float)); unmap_cfl(D, dimensions, out); }
int main_threshold(int argc, char* argv[]) { unsigned int flags = 0; enum th_type { NONE, WAV, LLR, DFW, MPDFW, HARD } th_type = NONE; int llrblk = 8; const struct opt_s opts[] = { OPT_SELECT('H', enum th_type, &th_type, HARD, "hard thresholding"), OPT_SELECT('W', enum th_type, &th_type, WAV, "daubechies wavelet soft-thresholding"), OPT_SELECT('L', enum th_type, &th_type, LLR, "locally low rank soft-thresholding"), OPT_SELECT('D', enum th_type, &th_type, DFW, "divergence-free wavelet soft-thresholding"), OPT_UINT('j', &flags, "bitmask", "joint soft-thresholding"), OPT_INT('b', &llrblk, "blocksize", "locally low rank block size"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); float lambda = atof(argv[1]); switch (th_type) { case WAV: wthresh(N, dims, lambda, flags, odata, idata); break; case LLR: lrthresh(N, dims, llrblk, lambda, flags, odata, idata); break; case DFW: dfthresh(N, dims, lambda, odata, idata); break; case HARD: hard_thresh(N, dims, lambda, odata, idata); break; default: md_zsoftthresh(N, dims, lambda, flags, odata, idata); } unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; }
int main_copy(int argc, char* argv[]) { const struct opt_s opts[] = { }; cmdline(&argc, argv, 2, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int N = DIMS; int count = argc - 3; assert((count >= 0) && (count % 2 == 0)); long in_dims[N]; long out_dims[N]; void* in_data = load_cfl(argv[argc - 2], N, in_dims); if (count > 0) { // get dimensions void* out_data = load_cfl(argv[argc - 1], N, out_dims); unmap_cfl(N, out_dims, out_data); } else { md_copy_dims(N, out_dims, in_dims); } void* out_data = create_cfl(argv[argc - 1], N, out_dims); long position[N]; for (unsigned int i = 0; i < N; i++) position[i] = 0; for (int i = 0; i < count; i += 2) { unsigned int dim = atoi(argv[i + 1]); long pos = atol(argv[i + 2]); assert(dim < N); assert((0 <= pos) && (pos < out_dims[dim])); position[dim] = pos; } md_copy_block(N, position, out_dims, out_data, in_dims, in_data, CFL_SIZE); unmap_cfl(N, in_dims, in_data); unmap_cfl(N, out_dims, out_data); return 0; }
int main_cdf97(int argc, char* argv[]) { int c; _Bool inv = false; while (-1 != (c = getopt(argc, argv, "ih"))) { switch (c) { case 'i': inv = true; break; case 'h': usage(argv[0], stdout); help(); exit(0); default: usage(argv[0], stderr); exit(1); } } if (argc - optind != 3) { usage(argv[0], stderr); exit(1); } unsigned int flags = atoi(argv[optind + 0]); long dims[DIMS]; complex float* idata = load_cfl(argv[optind + 1], DIMS, dims); complex float* odata = create_cfl(argv[optind + 2], DIMS, dims); md_copy(DIMS, dims, odata, idata, CFL_SIZE); unmap_cfl(DIMS, dims, idata); if (inv) { md_iresortz(DIMS, dims, flags, odata); md_icdf97z(DIMS, dims, flags, odata); } else { md_cdf97z(DIMS, dims, flags, odata); md_resortz(DIMS, dims, flags, odata); } unmap_cfl(DIMS, dims, odata); exit(0); }
int main_conj(int argc, char* argv[]) { mini_cmdline(argc, argv, 2, usage_str, help_str); const int N = 16; long dims[N]; complex float* idata = load_cfl(argv[1], N, dims); complex float* odata = create_cfl(argv[2], N, dims); md_zconj(N, dims, odata, idata); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); exit(0); }
int main_carg(int argc, char* argv[]) { mini_cmdline(argc, argv, 2, usage_str, help_str); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); complex float* out_data = create_cfl(argv[2], DIMS, dims); md_zarg(DIMS, dims, out_data, in_data); unmap_cfl(DIMS, dims, out_data); unmap_cfl(DIMS, dims, in_data); exit(0); }
int main_mip(int argc, char* argv[argc]) { bool mIP = false; const struct opt_s opts[] = { OPT_SET('m', &mIP, "minimum" ), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); unsigned int flags = atoi(argv[1]); long idims[DIMS]; complex float* in = load_cfl(argv[2], DIMS, idims); long odims[DIMS]; md_select_dims(DIMS, ~flags, odims, idims); complex float* out = create_cfl(argv[3], DIMS, odims); complex float* tmp = md_alloc(DIMS, idims, CFL_SIZE); md_zabs(DIMS, idims, tmp, in); long istr[DIMS]; long ostr[DIMS]; md_calc_strides(DIMS, istr, idims, CFL_SIZE); md_calc_strides(DIMS, ostr, odims, CFL_SIZE); md_clear(DIMS, odims, out, CFL_SIZE); md_max2(DIMS, idims, ostr, (float*)out, ostr, (const float*)out, istr, (const float*)tmp); if (mIP) { // need result of max in output md_min2(DIMS, idims, ostr, (float*)out, ostr, (const float*)out, istr, (const float*)tmp); } md_free(tmp); unmap_cfl(DIMS, idims, in); unmap_cfl(DIMS, odims, out); exit(0); }
int main_reshape(int argc, char* argv[]) { cmdline(&argc, argv, 3, 100, usage_str, help_str, 0, NULL); num_init(); unsigned int flags = atoi(argv[1]); unsigned int n = bitcount(flags); assert((int)n + 3 == argc - 1); long in_dims[DIMS]; long in_strs[DIMS]; long out_dims[DIMS]; long out_strs[DIMS]; complex float* in_data = load_cfl(argv[n + 2], DIMS, in_dims); md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); md_copy_dims(DIMS, out_dims, in_dims); unsigned int j = 0; for (unsigned int i = 0; i < DIMS; i++) if (MD_IS_SET(flags, i)) out_dims[i] = atoi(argv[j++ + 2]); assert(j == n); assert(md_calc_size(DIMS, in_dims) == md_calc_size(DIMS, out_dims)); md_calc_strides(DIMS, out_strs, out_dims, CFL_SIZE); for (unsigned int i = 0; i < DIMS; i++) if (!(MD_IS_SET(flags, i) || (in_strs[i] == out_strs[i]))) error("Dimensions are not consistent at index %d.\n"); complex float* out_data = create_cfl(argv[n + 3], DIMS, out_dims); md_copy(DIMS, in_dims, out_data, in_data, CFL_SIZE); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); exit(0); }
int main_resize(int argc, char* argv[]) { bool center = false; const struct opt_s opts[] = { OPT_SET('c', ¢er, "center"), }; cmdline(&argc, argv, 4, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int N = DIMS; int count = argc - 3; assert((count > 0) && (count % 2 == 0)); long in_dims[N]; long out_dims[N]; void* in_data = load_cfl(argv[argc - 2], N, in_dims); md_copy_dims(N, out_dims, in_dims); for (int i = 0; i < count; i += 2) { unsigned int dim = atoi(argv[i + 1]); unsigned int size = atoi(argv[i + 2]); assert(dim < N); assert(size >= 1); out_dims[dim] = size; } void* out_data = create_cfl(argv[argc - 1], N, out_dims); (center ? md_resize_center : md_resize)(N, out_dims, out_data, in_dims, in_data, CFL_SIZE); unmap_cfl(N, in_dims, in_data); unmap_cfl(N, out_dims, out_data); return 0; }
int main_flip(int argc, char* argv[]) { mini_cmdline(argc, argv, 3, usage_str, help_str); int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); unsigned long flags = atoi(argv[1]); md_flip(N, dims, flags, odata, idata, sizeof(complex float)); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); exit(0); }
int main_conv(int argc, char* argv[]) { int c; while (-1 != (c = getopt(argc, argv, "ah"))) { switch (c) { case 'h': usage(argv[0], stdout); help(); exit(0); default: usage(argv[0], stderr); exit(1); } } if (argc - optind != 4) { usage(argv[0], stderr); exit(1); } unsigned int flags = atoi(argv[optind + 0]); unsigned int N = DIMS; long dims[N]; const complex float* in = load_cfl(argv[optind + 1], N, dims); long krn_dims[N]; const complex float* krn = load_cfl(argv[optind + 2], N, krn_dims); complex float* out = create_cfl(argv[optind + 3], N, dims); struct conv_plan* plan = conv_plan(N, flags, CONV_CYCLIC, CONV_SYMMETRIC, dims, dims, krn_dims, krn); conv_exec(plan, out, in); conv_free(plan); unmap_cfl(N, dims, out); unmap_cfl(N, krn_dims, krn); unmap_cfl(N, dims, in); exit(0); }
int main_walsh(int argc, char* argv[]) { long bsize[3] = { 20, 20, 20 }; long calsize[3] = { 24, 24, 24 }; const struct opt_s opts[] = { { 'r', true, opt_vec3, &calsize, " cal_size\tLimits the size of the calibration region." }, { 'R', true, opt_vec3, &calsize, NULL }, { 'b', true, opt_vec3, &bsize, " block_size\tBlock size." }, { 'B', true, opt_vec3, &bsize, NULL }, }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); assert((dims[0] == 1) || (calsize[0] < dims[0])); assert((dims[1] == 1) || (calsize[1] < dims[1])); assert((dims[2] == 1) || (calsize[2] < dims[2])); assert(1 == dims[MAPS_DIM]); long caldims[DIMS]; complex float* cal_data = extract_calib(caldims, calsize, dims, in_data, false); unmap_cfl(DIMS, dims, in_data); debug_printf(DP_INFO, "Calibration region %ldx%ldx%ld\n", caldims[0], caldims[1], caldims[2]); dims[COIL_DIM] = dims[COIL_DIM] * (dims[COIL_DIM] + 1) / 2; complex float* out_data = create_cfl(argv[2], DIMS, dims); walsh(bsize, dims, out_data, caldims, cal_data); debug_printf(DP_INFO, "Done.\n"); md_free(cal_data); unmap_cfl(DIMS, dims, out_data); exit(0); }
int main_invert(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long dims[DIMS]; complex float* idata = load_cfl(argv[1], DIMS, dims); complex float* odata = create_cfl(argv[2], DIMS, dims); #pragma omp parallel for for (long i = 0; i < md_calc_size(DIMS, dims); i++) odata[i] = idata[i] == 0 ? 0. : 1. / idata[i]; unmap_cfl(DIMS, dims, idata); unmap_cfl(DIMS, dims, odata); return 0; }
int main_itsense(int argc, char* argv[]) { mini_cmdline(argc, argv, 5, usage_str, help_str); struct sense_data data; data.alpha = atof(argv[1]); complex float* kspace = load_cfl(argv[3], DIMS, data.data_dims); data.sens = load_cfl(argv[2], DIMS, data.sens_dims); data.pattern = load_cfl(argv[4], DIMS, data.mask_dims); // 1 2 4 8 md_select_dims(DIMS, ~COIL_FLAG, data.imgs_dims, data.sens_dims); assert(check_dimensions(&data)); complex float* image = create_cfl(argv[5], DIMS, data.imgs_dims); md_calc_strides(DIMS, data.sens_strs, data.sens_dims, CFL_SIZE); md_calc_strides(DIMS, data.imgs_strs, data.imgs_dims, CFL_SIZE); md_calc_strides(DIMS, data.data_strs, data.data_dims, CFL_SIZE); md_calc_strides(DIMS, data.mask_strs, data.mask_dims, CFL_SIZE); data.tmp = md_alloc(DIMS, data.data_dims, CFL_SIZE); num_init(); sense_reco(&data, image, kspace); unmap_cfl(DIMS, data.imgs_dims, image); unmap_cfl(DIMS, data.mask_dims, data.pattern); unmap_cfl(DIMS, data.sens_dims, data.sens); unmap_cfl(DIMS, data.data_dims, data.sens); md_free(data.tmp); exit(0); }
int main_zeros(int argc, char* argv[]) { mini_cmdline(argc, argv, -3, usage_str, help_str); int N = atoi(argv[1]); assert(N >= 0); assert(argc == 3 + N); long dims[N]; for (int i = 0; i < N; i++) { dims[i] = atoi(argv[2 + i]); assert(dims[i] >= 1); } complex float* x = create_cfl(argv[2 + N], N, dims); md_clear(N, dims, x, sizeof(complex float)); unmap_cfl(N, dims, x); exit(0); }
int main_normalize(int argc, char* argv[]) { bool l1 = false; l1 = mini_cmdline_bool(argc, argv, 'b', 3, usage_str, help_str); int N = DIMS; long dims[N]; complex float* data = load_cfl(argv[2], N, dims); int flags = atoi(argv[1]); assert(flags >= 0); complex float* out = create_cfl(argv[3], N, dims); md_copy(N, dims, out, data, CFL_SIZE); (l1 ? normalizel1 : normalize)(N, flags, dims, out); unmap_cfl(N, dims, out); exit(0); }
int main_spow(int argc, char* argv[argc]) { mini_cmdline(argc, argv, 3, usage_str, help_str); complex float expo; if (0 != parse_cfl(&expo, argv[1])) { fprintf(stderr, "ERROR: exponent %s is not a number.\n", argv[1]); exit(1); } const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); md_zspow(N, dims, odata, idata, expo); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); exit(0); }
int main_rss(int argc, char* argv[argc]) { mini_cmdline(argc, argv, 3, usage_str, help_str); long dims[DIMS]; complex float* data = load_cfl(argv[2], DIMS, dims); int flags = atoi(argv[1]); assert(0 <= flags); long odims[DIMS]; md_select_dims(DIMS, ~flags, odims, dims); complex float* out = create_cfl(argv[3], DIMS, odims); md_zrss(DIMS, dims, flags, out, data); unmap_cfl(DIMS, dims, data); unmap_cfl(DIMS, odims, out); exit(0); }
int main_wavg(int argc, char* argv[argc]) { cmdline(&argc, argv, 3, 3, usage_str, help_str, 0, NULL); int N = DIMS; unsigned int flags = atoi(argv[1]); long idims[N]; complex float* data = load_cfl(argv[2], N, idims); long odims[N]; md_select_dims(N, ~flags, odims, idims); complex float* out = create_cfl(argv[3], N, odims); md_zwavg(N, idims, flags, out, data); unmap_cfl(N, idims, data); unmap_cfl(N, odims, out); exit(0); }
int main_extract(int argc, char* argv[]) { mini_cmdline(argc, argv, 5, usage_str, help_str); num_init(); long in_dims[DIMS]; long out_dims[DIMS]; complex float* in_data = load_cfl(argv[4], DIMS, in_dims); int dim = atoi(argv[1]); int start = atoi(argv[2]); int end = atoi(argv[3]); assert((0 <= dim) && (dim < DIMS)); assert(start >= 0); assert(start <= end); assert(end < in_dims[dim]); for (int i = 0; i < DIMS; i++) out_dims[i] = in_dims[i]; out_dims[dim] = end - start + 1; complex float* out_data = create_cfl(argv[5], DIMS, out_dims); long pos2[DIMS] = { [0 ... DIMS - 1] = 0 }; pos2[dim] = start; md_copy_block(DIMS, pos2, out_dims, out_data, in_dims, in_data, sizeof(complex float)); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); exit(0); }
int main_bpsense(int argc, char* argv[]) { // ----------------------------------------------------------- // set up conf and option parser struct bpsense_conf conf = bpsense_defaults; struct iter_admm_conf iconf = iter_admm_defaults; conf.iconf = &iconf; conf.iconf->rho = 10; // more sensibile default bool usegpu = false; const char* psf = NULL; const char* image_truth_fname = NULL; bool im_truth = false; bool use_tvnorm = false; double start_time = timestamp(); const struct opt_s opts[] = { OPT_FLOAT('e', &conf.eps, "eps", "data consistency error"), OPT_FLOAT('r', &conf.lambda, "lambda", "l2 regularization parameter"), OPT_FLOAT('u', &conf.iconf->rho, "rho", "ADMM penalty parameter"), OPT_SET('c', &conf.rvc, "real-value constraint"), OPT_SET('t', &use_tvnorm, "use TV norm"), OPT_STRING('T', &image_truth_fname, "file", "compare to truth image"), OPT_UINT('i', &conf.iconf->maxiter, "iter", "max. iterations"), OPT_SET('g', &usegpu, "(use gpu)"), OPT_STRING('p', &psf, "file", "point-spread function"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (NULL != image_truth_fname) im_truth = true; // ----------------------------------------------------------- // load data and print some info about the recon int N = DIMS; long dims[N]; long dims1[N]; long img_dims[N]; long ksp_dims[N]; complex float* kspace_data = load_cfl(argv[1], N, ksp_dims); complex float* sens_maps = load_cfl(argv[2], N, dims); for (int i = 0; i < 4; i++) // sizes2[4] may be > 1 if (ksp_dims[i] != dims[i]) error("Dimensions of kspace and sensitivities do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); (usegpu ? num_init_gpu : num_init)(); if (dims[MAPS_DIM] > 1) debug_printf(DP_INFO, "%ld maps.\nESPIRiT reconstruction.\n", dims[4]); if (conf.lambda > 0.) debug_printf(DP_INFO, "l2 regularization: %f\n", conf.lambda); if (use_tvnorm) debug_printf(DP_INFO, "use Total Variation\n"); else debug_printf(DP_INFO, "use Wavelets\n"); if (im_truth) debug_printf(DP_INFO, "Compare to truth\n"); md_select_dims(N, ~(COIL_FLAG | MAPS_FLAG), dims1, dims); md_select_dims(N, ~COIL_FLAG, img_dims, dims); // ----------------------------------------------------------- // initialize sampling pattern complex float* pattern = NULL; long pat_dims[N]; if (NULL != psf) { pattern = load_cfl(psf, N, pat_dims); // FIXME: check compatibility } else { pattern = md_alloc(N, dims1, CFL_SIZE); estimate_pattern(N, ksp_dims, COIL_DIM, pattern, kspace_data); } // ----------------------------------------------------------- // print some statistics size_t T = md_calc_size(N, dims1); long samples = (long)pow(md_znorm(N, dims1, pattern), 2.); debug_printf(DP_INFO, "Size: %ld Samples: %ld Acc: %.2f\n", T, samples, (float)T/(float)samples); // ----------------------------------------------------------- // fftmod to un-center data fftmod(N, ksp_dims, FFT_FLAGS, kspace_data, kspace_data); fftmod(N, dims, FFT_FLAGS, sens_maps, sens_maps); // ----------------------------------------------------------- // apply scaling float scaling = estimate_scaling(ksp_dims, NULL, kspace_data); debug_printf(DP_INFO, "Scaling: %f\n", scaling); if (scaling != 0.) md_zsmul(N, ksp_dims, kspace_data, kspace_data, 1. / scaling); // ----------------------------------------------------------- // create l1 prox operator and transform long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(img_dims[0], 16); minsize[1] = MIN(img_dims[1], 16); minsize[2] = MIN(img_dims[2], 16); const struct linop_s* l1op = NULL; const struct operator_p_s* l1prox = NULL; if (use_tvnorm) { l1op = grad_init(DIMS, img_dims, FFT_FLAGS); l1prox = prox_thresh_create(DIMS + 1, linop_codomain(l1op)->dims, 1., 0u, usegpu); conf.l1op_obj = l1op; } else { bool randshift = true; l1op = linop_identity_create(DIMS, img_dims); conf.l1op_obj = wavelet_create(DIMS, img_dims, FFT_FLAGS, minsize, false, usegpu); l1prox = prox_wavethresh_create(DIMS, img_dims, FFT_FLAGS, minsize, 1., randshift, usegpu); } // ----------------------------------------------------------- // create image and load truth image complex float* image = create_cfl(argv[3], N, img_dims); md_clear(N, img_dims, image, CFL_SIZE); long img_truth_dims[DIMS]; complex float* image_truth = NULL; if (im_truth) image_truth = load_cfl(image_truth_fname, DIMS, img_truth_dims); // ----------------------------------------------------------- // call recon if (usegpu) #ifdef USE_CUDA bpsense_recon_gpu(&conf, dims, image, sens_maps, dims1, pattern, l1op, l1prox, ksp_dims, kspace_data, image_truth); #else assert(0); #endif else
int main_pocsense(int argc, char* argv[]) { float alpha = 0.; int maxiter = 50; bool l1wav = false; float lambda = -1.; bool use_gpu = false; bool use_admm = false; float admm_rho = -1.; int l1type = 2; const struct opt_s opts[] = { { 'i', true, opt_int, &maxiter, NULL }, { 'r', true, opt_float, &alpha, " alpha\tregularization parameter" }, { 'l', true, opt_int, &l1type, "1/-l2\t\ttoggle l1-wavelet or l2 regularization" }, { 'g', false, opt_set, &use_gpu, NULL }, { 'o', true, opt_float, &lambda, NULL }, { 'm', true, opt_float, &admm_rho, NULL }, }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (1 == l1type) l1wav = true; else if (2 == l1type) l1wav = false; else error("Unknown regularization type."); unsigned int N = DIMS; long dims[N]; long ksp_dims[N]; complex float* kspace_data = load_cfl(argv[1], N, ksp_dims); complex float* sens_maps = load_cfl(argv[2], N, dims); for (int i = 0; i < 4; i++) // sizes2[4] may be > 1 if (ksp_dims[i] != dims[i]) error("Dimensions of kspace and sensitivities do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); num_init(); long dims1[N]; md_select_dims(N, ~(COIL_FLAG|MAPS_FLAG), dims1, dims); // ----------------------------------------------------------- // memory allocation complex float* result = create_cfl(argv[3], N, ksp_dims); complex float* pattern = md_alloc(N, dims1, CFL_SIZE); // ----------------------------------------------------------- // pre-process data float scaling = estimate_scaling(ksp_dims, NULL, kspace_data); md_zsmul(N, ksp_dims, kspace_data, kspace_data, 1. / scaling); estimate_pattern(N, ksp_dims, COIL_DIM, pattern, kspace_data); // ----------------------------------------------------------- // l1-norm threshold operator const struct operator_p_s* thresh_op = NULL; const struct linop_s* wave_op = NULL; if (l1wav) { long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(ksp_dims[0], 16); minsize[1] = MIN(ksp_dims[1], 16); minsize[2] = MIN(ksp_dims[2], 16); wave_op = wavelet_create(DIMS, ksp_dims, FFT_FLAGS, minsize, true, use_gpu); thresh_op = prox_unithresh_create(DIMS, wave_op, alpha, COIL_FLAG, use_gpu); } #if 0 else {
int main_traj(int argc, char* argv[]) { int X = 128; int Y = 128; int accel = 1; bool radial = false; bool golden = false; bool dbl = false; int c; int turns = 1; while (-1 != (c = getopt(argc, argv, "x:y:a:t:rDGh"))) { switch (c) { case 'x': X = atoi(optarg); break; case 'y': Y = atoi(optarg); break; case 'a': accel = atoi(optarg); break; case 'G': golden = true; radial = true; break; case 'D': dbl = true; case 'r': radial = true; break; case 't': turns = atoi(optarg); break; case 'h': usage(argv[0], stdout); help(); exit(0); default: usage(argv[0], stderr); exit(1); } } if (argc - optind != 1) { usage(argv[0], stderr); exit(1); } int N = X * Y / accel; long dims[3] = { 3, X, Y / accel }; complex float* samples = create_cfl(argv[optind + 0], 3, dims); int p = 0; for (int j = 0; j < Y; j += accel) { for (int i = 0; i < X; i++) { if (radial) { /* golden-ratio sampling * * Winkelmann S, Schaeffter T, Koehler T, Eggers H, Doessel O. * An optimal radial profile order based on the Golden Ratio * for time-resolved MRI. IEEE TMI 26:68--76 (2007) */ double golden_angle = 3. - sqrtf(5.); double base = golden ? ((2. - golden_angle) / 2.) : (1. / (float)Y); double angle = M_PI * (float)remap(Y, turns, j) * (dbl ? 2. : 1.) * base; samples[p * 3 + 0] = ((float)i + 0.5 - (float)X / 2.) * sin(angle); samples[p * 3 + 1] = ((float)i + 0.5 - (float)X / 2.) * cos(angle); samples[p * 3 + 2] = 0.; } else { samples[p * 3 + 0] = (i - X / 2); samples[p * 3 + 1] = (j - Y / 2); samples[p * 3 + 2] = 0; } p++; } } assert(p == N - 0); unmap_cfl(3, dims, samples); exit(0); }
int main_poisson(int argc, char* argv[]) { int yy = 128; int zz = 128; bool cutcorners = false; float vardensity = 0.; bool vd_def = false; int T = 1; int rnd = 0; bool msk = true; int points = -1; float mindist = 1. / 1.275; float yscale = 1.; float zscale = 1.; unsigned int calreg = 0; const struct opt_s opts[] = { OPT_INT('Y', &yy, "size", "size dimension 1"), OPT_INT('Z', &zz, "size", "size dimension 2"), OPT_FLOAT('y', &yscale, "acc", "acceleration dim 1"), OPT_FLOAT('z', &zscale, "acc", "acceleration dim 2"), OPT_UINT('C', &calreg, "size", "size of calibration region"), OPT_SET('v', &vd_def, "variable density"), OPT_FLOAT('V', &vardensity, "", "(variable density)"), OPT_SET('e', &cutcorners, "elliptical scanning"), OPT_FLOAT('D', &mindist, "", "()"), OPT_INT('T', &T, "", "()"), OPT_CLEAR('m', &msk, "()"), OPT_INT('R', &points, "", "()"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); if (vd_def && (0. == vardensity)) vardensity = 20.; if (-1 != points) rnd = 1; assert((yscale >= 1.) && (zscale >= 1.)); // compute mindest and scaling float kspext = MAX(yy, zz); int Pest = T * (int)(1.2 * powf(kspext, 2.) / (yscale * zscale)); mindist /= kspext; yscale *= (float)kspext / (float)yy; zscale *= (float)kspext / (float)zz; if (vardensity != 0.) { // TODO } long dims[5] = { 1, yy, zz, T, 1 }; complex float* mask = NULL; if (msk) { mask = create_cfl(argv[1], 5, dims); md_clear(5, dims, mask, sizeof(complex float)); } int M = rnd ? (points + 1) : Pest; int P; while (true) { float (*points)[2] = xmalloc(M * sizeof(float[3])); int* kind = xmalloc(M * sizeof(int)); kind[0] = 0; if (!rnd) { points[0][0] = 0.5; points[0][1] = 0.5; if (1 == T) { P = poissondisc(2, M, 1, vardensity, mindist, points); } else { float (*delta)[T] = xmalloc(T * T * sizeof(complex float)); float dd[T]; for (int i = 0; i < T; i++) dd[i] = mindist; mc_poisson_rmatrix(2, T, delta, dd); P = poissondisc_mc(2, T, M, 1, vardensity, (const float (*)[T])delta, points, kind); } } else { // random pattern P = M - 1; for (int i = 0; i < P; i++) random_point(2, points[i]); } if (P < M) { for (int i = 0; i < P; i++) { points[i][0] = (points[i][0] - 0.5) * yscale + 0.5; points[i][1] = (points[i][1] - 0.5) * zscale + 0.5; } // throw away points outside float center[2] = { 0.5, 0.5 }; int j = 0; for (int i = 0; i < P; i++) { if ((cutcorners ? dist : maxn)(2, center, points[i]) <= 0.5) { points[j][0] = points[i][0]; points[j][1] = points[i][1]; j++; } } P = j; if (msk) { // rethink module here for (int i = 0; i < P; i++) { int yy = (int)floorf(points[i][0] * dims[1]); int zz = (int)floorf(points[i][1] * dims[2]); if ((yy < 0) || (yy >= dims[1]) || (zz < 0) || (zz >= dims[2])) continue; if (1 == T) mask[zz * dims[1] + yy] = 1.;//cexpf(2.i * M_PI * (float)kind[i] / (float)T); else mask[(kind[i] * dims[2] + zz) * dims[1] + yy] = 1.;//cexpf(2.i * M_PI * (float)kind[i] / (float)T); } } else { #if 1 long sdims[2] = { 3, P }; complex float* samples = create_cfl(argv[1], 2, sdims); for (int i = 0; i < P; i++) { samples[3 * i + 0] = 0.; samples[3 * i + 1] = (points[i][0] - 0.5) * dims[1]; samples[3 * i + 2] = (points[i][1] - 0.5) * dims[2]; // printf("%f %f\n", creal(samples[3 * i + 0]), creal(samples[3 * i + 1])); } unmap_cfl(2, sdims, (void*)samples); #endif } break; } // repeat with more points M *= 2; free(points); free(kind); } // calibration region assert((mask != NULL) || (0 == calreg)); assert((calreg <= dims[1]) && (calreg <= dims[2])); for (unsigned int i = 0; i < calreg; i++) { for (unsigned int j = 0; j < calreg; j++) { int y = (dims[1] - calreg) / 2 + i; int z = (dims[2] - calreg) / 2 + j; for (int k = 0; k < T; k++) { if (0. == mask[(k * dims[2] + z) * dims[1] + y]) { mask[(k * dims[2] + z) * dims[1] + y] = 1.; P++; } } } } printf("points: %d", P); if (1 != T) printf(", classes: %d", T); if (NULL != mask) { float f = cutcorners ? (M_PI / 4.) : 1.; printf(", grid size: %ldx%ld%s = %ld (R = %f)", dims[1], dims[2], cutcorners ? "x(pi/4)" : "", (long)(f * dims[1] * dims[2]), f * T * dims[1] * dims[2] / (float)P); unmap_cfl(5, dims, (void*)mask); } printf("\n"); exit(0); }