Example #1
0
static double bench_wavelet_thresh(int version, long scale)
{
	long dims[DIMS] = { 1, 256 * scale, 256 * scale, 1, 16, 1, 1, 1 };
	long minsize[DIMS] = { [0 ... DIMS - 1] = 1 };
	minsize[0] = MIN(dims[0], 16);
	minsize[1] = MIN(dims[1], 16);
	minsize[2] = MIN(dims[2], 16);

	const struct operator_p_s* p;

	switch (version) {
	case 2:
		p = prox_wavethresh_create(DIMS, dims, 7, minsize, 1.1, true, false);
		break;
	case 3:
		p = prox_wavelet3_thresh_create(DIMS, dims, 6, minsize, 1.1, true);
		break;
	default:
		assert(0);
	}

	complex float* x = md_alloc(DIMS, dims, CFL_SIZE);
	md_gaussian_rand(DIMS, dims, x);

	double tic = timestamp();

	operator_p_apply(p, 0.98, DIMS, dims, x, DIMS, dims, x);

	double toc = timestamp();

	md_free(x);
	operator_p_free(p);

	return toc - tic;
}
Example #2
0
void opt_reg_configure(unsigned int N, const long img_dims[N], struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS], unsigned int llr_blk, bool randshift, bool use_gpu)
{
	float lambda = ropts->lambda;

	if (-1. == lambda)
		lambda = 0.;

	// if no penalities specified but regularization
	// parameter is given, add a l2 penalty

	struct reg_s* regs = ropts->regs;

	if ((0 == ropts->r) && (lambda > 0.)) {

		regs[0].xform = L2IMG;
		regs[0].xflags = 0u;
		regs[0].jflags = 0u;
		regs[0].lambda = lambda;
		ropts->r = 1;
	}



	int nr_penalties = ropts->r;
	long blkdims[MAX_LEV][DIMS];
	int levels;


	for (int nr = 0; nr < nr_penalties; nr++) {

		// fix up regularization parameter
		if (-1. == regs[nr].lambda)
			regs[nr].lambda = lambda;

		switch (regs[nr].xform) {

			case L1WAV:
				debug_printf(DP_INFO, "l1-wavelet regularization: %f\n", regs[nr].lambda);

				if (0 != regs[nr].jflags)
					debug_printf(DP_WARN, "joint l1-wavelet thresholding not currently supported.\n");

				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);


				unsigned int wflags = 0;
				for (unsigned int i = 0; i < DIMS; i++) {

					if ((1 < img_dims[i]) && MD_IS_SET(regs[nr].xflags, i)) {

						wflags = MD_SET(wflags, i);
						minsize[i] = MIN(img_dims[i], 16);
					}
				}

				trafos[nr] = linop_identity_create(DIMS, img_dims);
				prox_ops[nr] = prox_wavelet3_thresh_create(DIMS, img_dims, wflags, minsize, regs[nr].lambda, randshift);
				break;

			case TV:
				debug_printf(DP_INFO, "TV regularization: %f\n", regs[nr].lambda);

				trafos[nr] = linop_grad_create(DIMS, img_dims, regs[nr].xflags);
				prox_ops[nr] = prox_thresh_create(DIMS + 1,
						linop_codomain(trafos[nr])->dims,
						regs[nr].lambda, regs[nr].jflags | MD_BIT(DIMS), use_gpu);
				break;

			case LLR:
				debug_printf(DP_INFO, "lowrank regularization: %f\n", regs[nr].lambda);

				// add locally lowrank penalty
				levels = llr_blkdims(blkdims, regs[nr].jflags, img_dims, llr_blk);

				assert(1 == levels);
				assert(levels == img_dims[LEVEL_DIM]);

				for(int l = 0; l < levels; l++)
#if 0
					blkdims[l][MAPS_DIM] = img_dims[MAPS_DIM];
#else
				blkdims[l][MAPS_DIM] = 1;
#endif

				int remove_mean = 0;

				trafos[nr] = linop_identity_create(DIMS, img_dims);
				prox_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, remove_mean, use_gpu);
				break;

			case MLR:
#if 0
				// FIXME: multiscale low rank changes the output image dimensions 
				// and requires the forward linear operator. This should be decoupled...
				debug_printf(DP_INFO, "multi-scale lowrank regularization: %f\n", regs[nr].lambda);

				levels = multilr_blkdims(blkdims, regs[nr].jflags, img_dims, 8, 1);

				img_dims[LEVEL_DIM] = levels;
				max_dims[LEVEL_DIM] = levels;

				for(int l = 0; l < levels; l++)
					blkdims[l][MAPS_DIM] = 1;

				trafos[nr] = linop_identity_create(DIMS, img_dims);
				prox_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, 0, use_gpu);

				const struct linop_s* decom_op = sum_create( img_dims, use_gpu );
				const struct linop_s* tmp_op = forward_op;
				forward_op = linop_chain(decom_op, forward_op);

				linop_free(decom_op);
				linop_free(tmp_op);
#else
				debug_printf(DP_WARN, "multi-scale lowrank regularization not yet supported: %f\n", regs[nr].lambda);
#endif

				break;

			case IMAGL1:
				debug_printf(DP_INFO, "l1 regularization of imaginary part: %f\n", regs[nr].lambda);

				trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i });
				prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags, use_gpu);
				break;

			case IMAGL2:
				debug_printf(DP_INFO, "l2 regularization of imaginary part: %f\n", regs[nr].lambda);

				trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i });
				prox_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL);
				break;

			case L1IMG:
				debug_printf(DP_INFO, "l1 regularization: %f\n", regs[nr].lambda);

				trafos[nr] = linop_identity_create(DIMS, img_dims);
				prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags, use_gpu);
				break;

			case L2IMG:
				debug_printf(DP_INFO, "l2 regularization: %f\n", regs[nr].lambda);

				trafos[nr] = linop_identity_create(DIMS, img_dims);
				prox_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL);
				break;

			case FTL1:
				debug_printf(DP_INFO, "l1 regularization of Fourier transform: %f\n", regs[nr].lambda);

				trafos[nr] = linop_fft_create(DIMS, img_dims, regs[nr].xflags);
				prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags, use_gpu);
				break;
		}
Example #3
0
void grecon(struct grecon_conf* param,  const long dims1[DIMS], complex float* out1, 
	const long cov1_dims[DIMS], complex float* cov1,
	const long w1_dims[DIMS], const complex float* weights,
	complex float* kspace1, bool usegpu)
{
	struct sense_conf* conf = param->sense_conf;

	long ksp1_dims[DIMS];
	md_select_dims(DIMS, ~MAPS_FLAG, ksp1_dims, dims1);

	long pat1_dims[DIMS];
	const complex float* pattern;

	if (NULL == weights) {

		md_select_dims(DIMS, ~(COIL_FLAG | MAPS_FLAG), pat1_dims, dims1);
		complex float* tpattern = md_alloc(DIMS, pat1_dims, CFL_SIZE);
		estimate_pattern(DIMS, ksp1_dims, COIL_DIM, tpattern, kspace1);
		pattern = tpattern;

	} else {

		md_copy_dims(DIMS, pat1_dims, w1_dims);
		pattern = weights;
	}

	complex float* sens1;

	if (NULL != param->calib) {

		long img1_dims[DIMS];
		md_select_dims(DIMS, ~COIL_FLAG, img1_dims, dims1);

		complex float* maps1 = md_alloc(DIMS, img1_dims, CFL_SIZE);

		sens1 = md_alloc(DIMS, dims1, CFL_SIZE);
	
		caltwo(param->calib, dims1, sens1, maps1, cov1_dims, cov1, NULL, NULL);

		crop_sens(dims1, sens1, param->calib->softcrop, param->calib->crop, maps1);

		fixphase(DIMS, dims1, COIL_DIM, sens1, sens1);

		md_free(maps1);

	} else {

		sens1 = cov1;
	}

	if (NOIR == param->algo) {

		assert(NULL == param->calib);
		assert(1 == dims1[MAPS_DIM]);

		sens1 = md_alloc(DIMS, dims1, CFL_SIZE);
		md_clear(DIMS, dims1, sens1, CFL_SIZE);
		fftmod(DIMS, ksp1_dims, FFT_FLAGS, kspace1, kspace1);
	}

	fftmod(DIMS, dims1, FFT_FLAGS, sens1, sens1);
	fftmod(DIMS, ksp1_dims, FFT_FLAGS, kspace1, kspace1);

	complex float* image1 = NULL;

	long img1_dims[DIMS];
	md_select_dims(DIMS, ~COIL_FLAG, img1_dims, dims1);

	if (param->ksp && (POCS != param->algo)) {

		image1 = md_alloc(DIMS, img1_dims, CFL_SIZE);
		md_clear(DIMS, img1_dims, image1, CFL_SIZE);

	} else {

		image1 = out1;
	}


#ifdef  USE_CUDA
	int gpun = 0;

	if (usegpu) {

		int nr_cuda_devices = MIN(cuda_devices(), MAX_CUDA_DEVICES);
		gpun = omp_get_thread_num() % nr_cuda_devices;
		cuda_init(gpun);
	}
#endif

	const struct operator_p_s* thresh_op = NULL;

	if (param->l1wav) {

		long minsize[DIMS] = { [0 ... DIMS - 1] = 1 };
		minsize[0] = MIN(img1_dims[0], 16);
		minsize[1] = MIN(img1_dims[1], 16);
		minsize[2] = MIN(img1_dims[2], 16);
#ifndef W3
		thresh_op = prox_wavethresh_create(DIMS, img1_dims, FFT_FLAGS, minsize, param->lambda, param->randshift, usegpu);
#else
		unsigned int wflags = 0;
		for (unsigned int i = 0; i < 3; i++)
			if (1 < img1_dims[i])
				wflags = MD_SET(wflags, i);

		thresh_op = prox_wavelet3_thresh_create(DIMS, img1_dims, wflags, minsize, param->lambda, param->randshift);
#endif
	}
Example #4
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;
	iconf.rho = 10; // more sensibile default
	conf.iconf = CAST_UP(&iconf);

	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', &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', &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_FLAG, 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 = linop_grad_create(DIMS, img_dims, FFT_FLAGS);
		l1prox = prox_thresh_create(DIMS + 1, linop_codomain(l1op)->dims, 1., 0u, usegpu);
		conf.l1op_obj = l1op;

	} else {

		long strs[N];
		md_calc_strides(N, strs, img_dims, CFL_SIZE);

		bool randshift = true;
		l1op = linop_identity_create(DIMS, img_dims);
		conf.l1op_obj = linop_wavelet3_create(DIMS, FFT_FLAGS, img_dims, strs, minsize);
		l1prox = prox_wavelet3_thresh_create(DIMS, img_dims, FFT_FLAGS, minsize, 1., randshift);
	}


	// -----------------------------------------------------------
	// 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