struct prox_4pt_dfwavelet_data* prepare_prox_4pt_dfwavelet_data(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { PTR_ALLOC(struct prox_4pt_dfwavelet_data, data); md_copy_dims(DIMS, data->im_dims, im_dims); md_select_dims(DIMS, FFT_FLAGS, data->tim_dims, im_dims); md_calc_strides(DIMS, data->im_strs, im_dims, CFL_SIZE); assert(4 == im_dims[flow_dim]); // initialize temp #ifdef USE_CUDA if (use_gpu) { data->vx = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->ph0 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc0 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc1 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc2 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc3 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); } else #endif { data->vx = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->ph0 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc0 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc1 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc2 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc3 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); } data->flow_dim = flow_dim; data->slice_flag = ~FFT_FLAGS; data->lambda = lambda; data->plan = prepare_dfwavelet_plan( 3, data->tim_dims, (long*) min_size, (complex float*) res, use_gpu ); data->w_op = wavelet_create(DIMS, data->tim_dims, FFT_FLAGS, min_size, true, use_gpu); data->wthresh_op = prox_unithresh_create(DIMS, data->w_op, lambda, MD_BIT(data->flow_dim), use_gpu); return data; }
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_pocsense(int argc, char* argv[]) { int c; float alpha = 0.; int maxiter = 50; bool l1wav = false; float lambda = -1.; bool use_gpu = false; bool use_admm = false; float admm_rho = 0.1; while (-1 != (c = getopt(argc, argv, "m:ghi:r:o:l:"))) { switch (c) { case 'i': maxiter = atoi(optarg); break; case 'r': alpha = atof(optarg); break; case 'l': if (1 == atoi(optarg)) l1wav = true; else if (2 == atoi(optarg)) l1wav = false; else { usage(argv[0], stderr); exit(1); } break; case 'g': use_gpu = true; break; case 'o': lambda = atof(optarg); break; case 'm': use_admm = true; admm_rho = atof(optarg); 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 N = DIMS; long dims[N]; long ksp_dims[N]; complex float* kspace_data = load_cfl(argv[optind + 0], N, ksp_dims); complex float* sens_maps = load_cfl(argv[optind + 1], N, dims); for (int i = 0; i < 4; i++) { // sizes2[4] may be > 1 if (ksp_dims[i] != dims[i]) { fprintf(stderr, "Dimensions of kspace and sensitivities do not match!\n"); exit(1); } } 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[optind + 2], 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 {