Example #1
0
File: prox.c Project: mjacob75/bart
/**
 * Proximal function for f(z) = 0.5 || y - A z ||_2^2.
 * Solution is (A^H A + (1/mu) I)z = A^H y + (1/mu)(x_plus_u)
 *
 * @param prox_data should be of type prox_normaleq_data
 * @param mu proximal penalty
 * @param z output
 * @param x_plus_u input
 */
static void prox_normaleq_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u)
{
	struct prox_normaleq_data* pdata = CAST_DOWN(prox_normaleq_data, prox_data);

	if (0 == mu) {

		md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE);

	} else {

		float rho = 1. / mu;
		float* b = md_alloc_sameplace(1, MD_DIMS(pdata->size), FL_SIZE, x_plus_u);
		md_copy(1, MD_DIMS(pdata->size), b, pdata->adj, FL_SIZE);
		md_axpy(1, MD_DIMS(pdata->size), b, rho, x_plus_u);

		if (NULL == pdata->op->norm_inv) {

			struct iter_conjgrad_conf* cg_conf = pdata->cgconf;
			cg_conf->l2lambda = rho;

			iter_conjgrad(CAST_UP(cg_conf), pdata->op->normal, NULL, pdata->size, z, (float*)b, NULL);

		} else {

			linop_norm_inv_iter((struct linop_s*)pdata->op, rho, z, b);
		}

		md_free(b);
	}
}
Example #2
0
void noir_recon(const struct noir_conf_s* conf, const long dims[DIMS], complex float* outbuf, complex float* sensout, const complex float* psf, const complex float* mask, const complex float* kspace)
{
	long imgs_dims[DIMS];
	long coil_dims[DIMS];
	long data_dims[DIMS];
	long img1_dims[DIMS];

	md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|CSHIFT_FLAG, imgs_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, coil_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG, data_dims, dims);
	md_select_dims(DIMS, FFT_FLAGS, img1_dims, dims);

	long skip = md_calc_size(DIMS, imgs_dims);
	long size = skip + md_calc_size(DIMS, coil_dims);
	long data_size = md_calc_size(DIMS, data_dims);

	long d1[1] = { size };
	complex float* img = md_alloc_sameplace(1, d1, CFL_SIZE, kspace);
	complex float* imgH = md_alloc_sameplace(1, d1, CFL_SIZE, kspace);


	md_clear(DIMS, imgs_dims, img, CFL_SIZE);

	md_zfill(DIMS, img1_dims, outbuf, 1.);	// initial only first image
	md_copy(DIMS, img1_dims, img, outbuf, CFL_SIZE);

	md_clear(DIMS, coil_dims, img + skip, CFL_SIZE);

	md_clear(DIMS, imgs_dims, imgH, CFL_SIZE);
	md_clear(DIMS, coil_dims, imgH + skip, CFL_SIZE);

	struct noir_data* ndata = noir_init(dims, mask, psf, conf->rvc, conf->usegpu);
	struct data data = { ndata };

	struct iter3_irgnm_conf irgnm_conf = { .iter = conf->iter, .alpha = conf->alpha, .redu = conf->redu };
	iter3_irgnm(&irgnm_conf.base, frw, der, adj, &data, size * 2, (float*)img, data_size * 2, (const float*)kspace);


	md_copy(DIMS, imgs_dims, outbuf, img, CFL_SIZE);

	if (NULL != sensout) {

		assert(!conf->usegpu);
		noir_forw_coils(ndata, sensout, img + skip);
	}

	noir_free(ndata);

	md_free(img);
	md_free(imgH);
}
Example #3
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);
}
Example #4
0
File: prox.c Project: mjacob75/bart
/**
 * Proximal function for f(z) = 0
 * Solution is z = x_plus_u
 * 
 * @param prox_data should be of type prox_zero_data
 * @param mu proximal penalty
 * @param z output
 * @param x_plus_u input
 */
static void prox_zero_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u)
{
	UNUSED(mu);
	struct prox_zero_data* pdata = CAST_DOWN(prox_zero_data, prox_data);

	md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE);
}
Example #5
0
static struct ufft_data* ufft_create_data(const long ksp_dims[DIMS], const long pat_dims[DIMS], const complex float* pat, unsigned int flags, bool use_gpu)
{
	PTR_ALLOC(struct ufft_data, data);
	SET_TYPEID(ufft_data, data);

	data->flags = flags;
	data->use_gpu = use_gpu;

	md_copy_dims(DIMS, data->pat_dims, pat_dims);
	md_copy_dims(DIMS, data->ksp_dims, ksp_dims);

	md_calc_strides(DIMS, data->pat_strs, pat_dims, CFL_SIZE);
	md_calc_strides(DIMS, data->ksp_strs, ksp_dims, CFL_SIZE);

#ifdef USE_CUDA
	data->pat = (use_gpu ? md_alloc_gpu : md_alloc)(DIMS, data->pat_dims, CFL_SIZE);
#else
	data->pat = md_alloc(DIMS, data->pat_dims, CFL_SIZE);
#endif
	md_copy(DIMS, data->pat_dims, data->pat, pat, CFL_SIZE);

	data->fft_op = linop_fftc_create(DIMS, ksp_dims, flags);

	return PTR_PASS(data);
}
Example #6
0
static struct maps_data* maps_create_data(const long max_dims[DIMS], 
			unsigned int sens_flags, const complex float* sens, bool gpu)
{
	struct maps_data* data = xmalloc(sizeof(struct maps_data));

	// maximal dimensions
	md_copy_dims(DIMS, data->max_dims, max_dims);

	// sensitivity dimensions
	md_select_dims(DIMS, sens_flags, data->mps_dims, max_dims);
	md_calc_strides(DIMS, data->strs_mps, data->mps_dims, CFL_SIZE);

	md_select_dims(DIMS, ~MAPS_FLAG, data->ksp_dims, max_dims);
	md_calc_strides(DIMS, data->strs_ksp, data->ksp_dims, CFL_SIZE);

	md_select_dims(DIMS, ~COIL_FLAG, data->img_dims, max_dims);
	md_calc_strides(DIMS, data->strs_img, data->img_dims, CFL_SIZE);

	
#ifdef USE_CUDA
	complex float* nsens = (gpu ? md_alloc_gpu : md_alloc)(DIMS, data->mps_dims, CFL_SIZE);
#else
	assert(!gpu);
	complex float* nsens = md_alloc(DIMS, data->mps_dims, CFL_SIZE);
#endif
	md_copy(DIMS, data->mps_dims, nsens, sens, CFL_SIZE);
	data->sens = nsens;

	data->norm = NULL;

	return data;
}
Example #7
0
static void linop_cdf97_adjoint(const linop_data_t* _data, complex float* out, const complex float* in)
{
	const struct linop_cdf97_s* data = CAST_DOWN(linop_cdf97_s, _data);

	md_copy(data->N, data->dims, out, in, CFL_SIZE);
	md_icdf97z(data->N, data->dims, data->flags, out);
}
Example #8
0
static void unisoftthresh_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src)
{
	const auto data = CAST_DOWN(thresh_s, _data);

	if (0. == mu) {

		md_copy(data->D, data->dim, dst, src, CFL_SIZE);

	} else {

		const long* transform_dims = linop_codomain(data->unitary_op)->dims;
		const long* transform_strs = linop_codomain(data->unitary_op)->strs;

		complex float* tmp = md_alloc_sameplace(data->D, transform_dims, CFL_SIZE, dst);

		linop_forward(data->unitary_op, data->D, transform_dims, tmp, data->D, data->dim, src);

		complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, dst);
		md_zsoftthresh_core2(data->D, transform_dims, data->lambda * mu, data->flags, tmp_norm, transform_strs, tmp, transform_strs, tmp);
		md_free(tmp_norm);

		linop_adjoint(data->unitary_op, data->D, data->dim, dst, data->D, transform_dims, tmp);

		md_free(tmp);
	}
}
Example #9
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);
}
Example #10
0
static void fft_linop_normal(const linop_data_t* _data, complex float* out, const complex float* in)
{
	const struct fft_linop_s* data = CAST_DOWN(fft_linop_s, _data);

	if (data->center)
		md_copy(data->N, data->dims, out, in, CFL_SIZE);
	else
		md_zsmul(data->N, data->dims, out, in, data->nscale);
}
Example #11
0
/*
 * Nuclear norm calculation for arbitrary block sizes
 */
float lrnucnorm(const struct operator_p_s* op, const complex float* src)
{
	struct lrthresh_data_s* data = (struct lrthresh_data_s*)operator_p_get_data(op);

	long strs1[DIMS];
	md_calc_strides(DIMS, strs1, data->dims_decom, 1);
	float nnorm = 0.;


	for (int l = 0; l < data->levels; l++) {

		const complex float* srcl = src + l * strs1[LEVEL_DIM];

		// Initialize
		long blkdims[DIMS];
		long blksize = 1;

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

			blkdims[i] = data->blkdims[l][i];
			blksize *= blkdims[i];
		}

		// Special case if blocksize is 1
		if (blksize == 1) {

			for (long j = 0; j < md_calc_size(DIMS, data->dims); j++)
				nnorm += 2 * cabsf(srcl[j]);
				
			continue;
		}

		// Initialize data
		struct svthresh_blockproc_data* svdata = svthresh_blockproc_create(data->mflags, 0., 0);

		// Initialize tmp
		complex float* tmp;
#ifdef USE_CUDA
		tmp = (data->use_gpu ? md_alloc_gpu : md_alloc)(DIMS, data->dims, CFL_SIZE);
#else
		tmp = md_alloc(DIMS, data->dims, CFL_SIZE);
#endif

		// Copy to tmp
		//debug_print_dims(DP_DEBUG1, DIMS, data->dims);
		md_copy(DIMS, data->dims, tmp, srcl, CFL_SIZE);

		// Block SVD Threshold
		nnorm = blockproc(DIMS, data->dims, blkdims, (void*)svdata, nucnorm_blockproc, tmp, tmp);

		// Free tmp
		free(svdata);
		md_free(tmp);
	}

	return nnorm;
}
Example #12
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);
}
Example #13
0
static bool test_md_swap(void)
{
	enum { N = 4 };
	long dims[N] = { 10, 10, 10, 10 };

	complex float* a = md_alloc(N, dims, sizeof(complex float));
	complex float* b = md_alloc(N, dims, sizeof(complex float));
	complex float* c = md_alloc(N, dims, sizeof(complex float));

	md_gaussian_rand(N, dims, a);
	md_gaussian_rand(N, dims, b);
	md_gaussian_rand(N, dims, c);

	complex float* d = md_alloc(N, dims, sizeof(complex float));
	complex float* e = md_alloc(N, dims, sizeof(complex float));
	complex float* f = md_alloc(N, dims, sizeof(complex float));

	md_copy(N, dims, d, a, sizeof(complex float));
	md_copy(N, dims, e, b, sizeof(complex float));
	md_copy(N, dims, f, c, sizeof(complex float));

	md_circular_swap(3, N, dims, (void*[]){ a, b, c }, sizeof(complex float));
Example #14
0
File: prox.c Project: mjacob75/bart
/**
 * Proximal function for f(z) = lambda / 2 || y - z ||_2^2.
 * Solution is z =  (mu * lambda * y + x_plus_u) / (mu * lambda + 1)
 *
 * @param prox_data should be of type prox_leastsquares_data
 * @param mu proximal penalty
 * @param z output
 * @param x_plus_u input
 */
static void prox_leastsquares_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u)
{
	struct prox_leastsquares_data* pdata = CAST_DOWN(prox_leastsquares_data, prox_data);

	md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE);

	if (0 != mu) {

		if (NULL != pdata->y)
			md_axpy(1, MD_DIMS(pdata->size), z, pdata->lambda * mu, pdata->y);

		md_smul(1, MD_DIMS(pdata->size), z, z, 1. / (mu * pdata->lambda + 1));
	}
}
Example #15
0
static void softthresh_apply(const operator_data_t* _data, float mu, complex float* optr, const complex float* iptr)
{
	const auto data = CAST_DOWN(thresh_s, _data);

	if (0. == mu) {

		md_copy(data->D, data->dim, optr, iptr, CFL_SIZE);

	} else {

		complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, optr);
		md_zsoftthresh_core2(data->D, data->dim, data->lambda * mu, data->flags, tmp_norm, data->str, optr, data->str, iptr);

		md_free(tmp_norm);
	}
}
Example #16
0
void md_gaussian_rand(unsigned int D, const long dims[D], complex float* dst)
{
#ifdef  USE_CUDA
	if (cuda_ondevice(dst)) {
	
		complex float* tmp = md_alloc(D, dims, sizeof(complex float));
		md_gaussian_rand(D, dims, tmp);
		md_copy(D, dims, dst, tmp, sizeof(complex float));
		md_free(tmp);
		return;
	}
#endif
//#pragma omp parallel for
	for (long i = 0; i < md_calc_size(D, dims); i++)
		dst[i] = (float)gaussian_rand();
}
Example #17
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);
}
Example #18
0
void circshift(struct wavelet_plan_s* plan, data_t* data) 
{
	bool shift = false;
	int N = plan->numdims_tr;

	for (int i = 0; i < N; i++)
		shift |= (0 != plan->randShift_tr[i]);

	if (shift) {

		void* data_copy = md_alloc_sameplace(N, plan->imSize_tr, sizeof(data_t), data);
		md_copy(N, plan->imSize_tr, data_copy, data, sizeof(data_t));
		md_circ_shift(N, plan->imSize_tr, plan->randShift_tr, data, data_copy, sizeof(data_t));
		md_free(data_copy);

	}
}
Example #19
0
File: lrthresh.c Project: hcmh/bart
/*
 * Nuclear norm calculation for arbitrary block sizes
 */
float lrnucnorm(const struct operator_p_s* op, const complex float* src)
{
	struct lrthresh_data_s* data = (struct lrthresh_data_s*)operator_p_get_data(op);

	long strs1[DIMS];
	md_calc_strides(DIMS, strs1, data->dims_decom, 1);
	float nnorm = 0.;


	for (int l = 0; l < data->levels; l++) {

		const complex float* srcl = src + l * strs1[LEVEL_DIM];

		long blkdims[DIMS];
		long blksize = 1;

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

			blkdims[i] = data->blkdims[l][i];
			blksize *= blkdims[i];
		}

		if (1 == blksize) {

			for (long j = 0; j < md_calc_size(DIMS, data->dims); j++)
				nnorm += 2 * cabsf(srcl[j]);
				
			continue;
		}

		struct svthresh_blockproc_data* svdata = svthresh_blockproc_create(data->mflags, 0., 0);

		complex float* tmp = md_alloc_sameplace(DIMS, data->dims, CFL_SIZE, src);

		//debug_print_dims(DP_DEBUG1, DIMS, data->dims);
		md_copy(DIMS, data->dims, tmp, srcl, CFL_SIZE);

		// Block SVD Threshold
		nnorm = blockproc(DIMS, data->dims, blkdims, (void*)svdata, nucnorm_blockproc, tmp, tmp);

		xfree(svdata);
		md_free(tmp);
	}

	return nnorm;
}
Example #20
0
void noir_fun(struct noir_data* data, complex float* dst, const complex float* src)
{	
	long split = md_calc_size(DIMS, data->imgs_dims);

	md_copy(DIMS, data->imgs_dims, data->xn, src, CFL_SIZE);
	noir_forw_coils(data, data->sens, src + split);

	md_clear(DIMS, data->sign_dims, data->tmp, CFL_SIZE);
	md_zfmac2(DIMS, data->sign_dims, data->sign_strs, data->tmp, data->imgs_strs, src, data->coil_strs, data->sens);

	// could be moved to the benning, but see comment below
	md_zmul2(DIMS, data->sign_dims, data->sign_strs, data->tmp, data->sign_strs, data->tmp, data->mask_strs, data->mask);

	fft(DIMS, data->sign_dims, FFT_FLAGS, data->tmp, data->tmp);

	md_clear(DIMS, data->data_dims, dst, CFL_SIZE);
	md_zfmac2(DIMS, data->sign_dims, data->data_strs, dst, data->sign_strs, data->tmp, data->ptrn_strs, data->pattern);
}
Example #21
0
File: prox.c Project: mjacob75/bart
/**
 * Proximal function for f(z) = Ind{ || y - z ||_2 < eps }
 * 
 * @param prox_data should be of type prox_l2ball_data
 * @param mu proximal penalty
 * @param z output
 * @param x_plus_u input
 */
static void prox_l2ball_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u)
{
	UNUSED(mu);
	struct prox_l2ball_data* pdata = CAST_DOWN(prox_l2ball_data, prox_data);

	if (NULL != pdata->center)
		md_sub(1, MD_DIMS(pdata->size), z, x_plus_u, pdata->center);
	else
		md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE);

	float q1 = md_norm(1, MD_DIMS(pdata->size), z);

	if (q1 > pdata->eps)
		md_smul(1, MD_DIMS(pdata->size), z, z, pdata->eps / q1);

	if (NULL != pdata->center)
		md_add(1, MD_DIMS(pdata->size), z, z, pdata->center);
}
Example #22
0
void data_consistency(const long dims[DIMS], complex float* dst, const complex float* pattern, const complex float* kspace1, const complex float* kspace2)
{
	assert(1 == dims[MAPS_DIM]);

	long strs[DIMS];
	long dims1[DIMS];
	long strs1[DIMS];

	md_select_dims(DIMS, ~COIL_FLAG, dims1, dims);
	md_calc_strides(DIMS, strs1, dims1, CFL_SIZE);
	md_calc_strides(DIMS, strs, dims, CFL_SIZE);

	complex float* tmp = md_alloc_sameplace(DIMS, dims, CFL_SIZE, dst);
	md_zmul2(DIMS, dims, strs, tmp, strs, kspace2, strs1, pattern);
	md_zsub(DIMS, dims, tmp, kspace2, tmp);
	md_zfmac2(DIMS, dims, strs, tmp, strs, kspace1, strs1, pattern);
	md_copy(DIMS, dims, dst, tmp, CFL_SIZE);
	md_free(tmp);
}
Example #23
0
static bool test_md_copy(void)
{
	enum { N = 4 };
	long dims[N] = { 10, 10, 10, 10 };

	complex float* a = md_alloc(N, dims, sizeof(complex float));

	md_gaussian_rand(N, dims, a);

	complex float* b = md_alloc(N, dims, sizeof(complex float));

	md_copy(N, dims, b, a, sizeof(complex float));

	bool eq = md_compare(N, dims, a, b, sizeof(complex float));

	md_free(a);
	md_free(b);

	return eq;
}
Example #24
0
void iter3_irgnm(iter_conf* _conf,
		void (*frw)(void* _data, float* dst, const float* src),
		void (*der)(void* _data, float* dst, const float* src),
		void (*adj)(void* _data, float* dst, const float* src),
		void* data2,
		long N, float* dst, long M, const float* src)
{
	struct iter3_irgnm_conf* conf = CONTAINER_OF(_conf, struct iter3_irgnm_conf, base);

	float* tmp = md_alloc_sameplace(1, MD_DIMS(M), FL_SIZE, src);
	struct irgnm_s data = { frw, der, adj, data2, tmp, N };

	float* x0 = md_alloc_sameplace(1, MD_DIMS(N), FL_SIZE, src);
	md_copy(1, MD_DIMS(N), x0, dst, FL_SIZE);

	irgnm(conf->iter, conf->alpha, conf->redu, &data, N, M, select_vecops(src),
		forward, adjoint, inverse, dst, x0, src);

	md_free(x0);
	md_free(tmp);
}
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);
}
Example #26
0
void direct_calib(const long dims[5], complex float* sens, const long caldims[5], const complex float* data)
{
	complex float* tmp = md_alloc(5, caldims, CFL_SIZE);

	assert(1 == caldims[4]);
	assert(1 == dims[4]);

	md_copy(5, caldims, tmp, data, CFL_SIZE);

	// apply Kaiser-Bessel Window beta=4
	for (int z = 0; z < caldims[2]; z++)
		for (int y = 0; y < caldims[1]; y++)
			for (int x = 0; x < caldims[0]; x++)
				for (int c = 0; c < caldims[3]; c++)
					tmp[((c * caldims[2] + z) * caldims[1] + y) * caldims[0] + x]
						*= kaiser(4., caldims[2], z)
						* kaiser(4., caldims[1], y)
						* kaiser(4., caldims[0], x);

	md_resize_center(5, dims, sens, caldims, tmp, CFL_SIZE);

	ifftc(5, dims, 7, sens, sens);

	long dims1[5];
	md_select_dims(5, ~MD_BIT(COIL_DIM), dims1, dims);

	complex float* img = md_alloc(5, dims1, CFL_SIZE);

	md_zrss(5, dims, COIL_FLAG, img, sens);
#if 1
	long T = md_calc_size(5, dims1);
	for (int i = 0; i < T; i++)
		for (int j = 0; j < dims[COIL_DIM]; j++)
			sens[j * T + i] *= (cabs(img[i]) == 0.) ? 0. : (1. / cabs(img[i]));
#endif
	md_free(img);
}
Example #27
0
void iwt(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen])
{
	if (0 == flags) {

		if (out != in)
			md_copy2(N, dims, ostr, out, ostr, in, CFL_SIZE);

		return;
	}

	unsigned long coeffs = wavelet_coeffs(N, flags, dims, minsize, flen);

	long wdims[2 * N];
	wavelet_dims(N, flags, wdims, dims, flen);

	long istr[2 * N];
	md_calc_strides(2 * N, istr, wdims, CFL_SIZE);

	long offset = coeffs - md_calc_size(2 * N, wdims);

	debug_printf(DP_DEBUG4, "%d %ld %ld\n", flags, coeffs, offset);

	complex float* tmp = md_alloc_sameplace(2 * N, wdims, CFL_SIZE, out);

	md_copy(2 * N, wdims, tmp, in + offset, CFL_SIZE);

	long shifts0[N];
	for (unsigned int i = 0; i < N; i++)
		shifts0[i] = 0;

	// fix me we need temp storage
	iwt(N, wavelet_filter_flags(N, flags, wdims, minsize), shifts0, wdims, istr, tmp, in, minsize, flen, filter);
	iwtN(N, flags, shifts, dims, ostr, out, istr, tmp, flen, filter);

	md_free(tmp);
}
Example #28
0
/**
 * Operator interface for a true matrix:
 * out = mat * in
 * in:	[x x x x 1 x x K x x]
 * mat:	[x x x x T x x K x x]
 * out:	[x x x x T x x 1 x x]
 * where the x's are arbitrary dimensions and T and K may be transposed
 *
 * use this interface if K == 1 or T == 1
 *
 * @param N number of dimensions
 * @param out_dims output dimensions after applying the matrix (codomain)
 * @param in_dims input dimensions to apply the matrix (domain)
 * @param T_dim dimension corresponding to the rows of A
 * @param K_dim dimension corresponding to the columns of A
 * @param matrix matrix data
 */
struct linop_s* linop_matrix_altcreate(unsigned int N, const long out_dims[N], const long in_dims[N], const unsigned int T_dim, const unsigned int K_dim, const complex float* matrix)
{
	long matrix_dims[N];
	md_singleton_dims(N, matrix_dims);

	matrix_dims[K_dim] = in_dims[K_dim];
	matrix_dims[T_dim] = out_dims[T_dim];

	unsigned int T = out_dims[T_dim];
	unsigned int K = in_dims[K_dim];

	PTR_ALLOC(long[N], max_dims);

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

		if ((in_dims[i] > 1) && (out_dims[i] == 1)) {

			(*max_dims)[i] = in_dims[i];
		}
		else if ((in_dims[i] == 1) && (out_dims[i] > 1)) {

			(*max_dims)[i] = out_dims[i];
		}
		else {

			assert(in_dims[i] == out_dims[i]);

			(*max_dims)[i] = in_dims[i];
		}
	}

	complex float* mat = md_alloc_sameplace(N, matrix_dims, CFL_SIZE, matrix);
	complex float* matc = md_alloc_sameplace(N, matrix_dims, CFL_SIZE, matrix);

	md_copy(N, matrix_dims, mat, matrix, CFL_SIZE);
	md_zconj(N, matrix_dims, matc, mat);

	complex float* gram = NULL;
	const struct iovec_s* gram_iovec = compute_gram_matrix(N, T_dim, T, K_dim, K, &gram, matrix_dims, matrix);

	PTR_ALLOC(struct operator_matrix_s, data);
	SET_TYPEID(operator_matrix_s, data);

	data->mat_iovec = iovec_create(N, matrix_dims, CFL_SIZE);
	data->mat_gram_iovec = gram_iovec;

	data->max_dims = *max_dims;

	data->mat = mat;
	data->mat_conj = matc;
	data->mat_gram = gram;

	data->K_dim = K_dim;
	data->T_dim = T_dim;
	data->K = K;
	data->T = T;

	data->domain_iovec = iovec_create(N, in_dims, CFL_SIZE);
	data->codomain_iovec = iovec_create(N, out_dims, CFL_SIZE);

	return linop_create(N, out_dims, N, in_dims, CAST_UP(PTR_PASS(data)), linop_matrix_apply, linop_matrix_apply_adjoint, linop_matrix_apply_normal, NULL, linop_matrix_del);
}
Example #29
0
/**
 * Compute the Gram matrix, A^H A.
 * Stores the result in @param gram, which is allocated by the function
 * Returns: iovec_s corresponding to the gram matrix dimensions
 *
 * @param N number of dimensions
 * @param T_dim dimension corresponding to the rows of A
 * @param T number of rows of A (codomain)
 * @param K_dim dimension corresponding to the columns of A
 * @param K number of columns of A (domain)
 * @param gram store the result (allocated by this function)
 * @param matrix_dims dimensions of A
 * @param matrix matrix data
 */
const struct iovec_s* compute_gram_matrix(unsigned int N, unsigned int T_dim, unsigned int T, unsigned int K_dim, unsigned int K, complex float** gram, const long matrix_dims[N], const complex float* matrix)
{
	// FIXME this can certainly be simplfied...
	// Just be careful to consider the case where the data passed to the operator is a subset of a bigger array
	

	// B_dims = [T K 1]  or  [K T 1]
	// C_dims = [T 1 K]  or  [1 T K]
	// A_dims = [1 K K]  or  [K 1 K]
	// after: gram_dims = [1 K1 K2] --> [K2 K1 1]  or  [K1 1 K2] --> [K1 K2 1]

	long A_dims[N + 1];
	long B_dims[N + 1];
	long C_dims[N + 1];
	long fake_gram_dims[N + 1];

	long A_str[N + 1];
	long B_str[N + 1];
	long C_str[N + 1];
	long max_dims[N + 1];

	md_singleton_dims(N + 1, A_dims);
	md_singleton_dims(N + 1, B_dims);
	md_singleton_dims(N + 1, C_dims);
	md_singleton_dims(N + 1, fake_gram_dims);
	md_singleton_dims(N + 1, max_dims);

	A_dims[K_dim] = K;
	A_dims[N] = K;

	B_dims[T_dim] = T;
	B_dims[K_dim] = K;

	C_dims[T_dim] = T;
	C_dims[N] = K;

	max_dims[T_dim] = T;
	max_dims[K_dim] = K;
	max_dims[N] = K;

	fake_gram_dims[T_dim] = K;
	fake_gram_dims[K_dim] = K;

	md_calc_strides(N + 1, A_str, A_dims, CFL_SIZE);
	md_calc_strides(N + 1, B_str, B_dims, CFL_SIZE);
	md_calc_strides(N + 1, C_str, C_dims, CFL_SIZE);

	complex float* tmpA = md_alloc_sameplace(N + 1 , A_dims, CFL_SIZE, matrix);
	complex float* tmpB = md_alloc_sameplace(N + 1, B_dims, CFL_SIZE, matrix);
	complex float* tmpC = md_alloc_sameplace(N + 1, C_dims, CFL_SIZE, matrix);

	md_copy(N, matrix_dims, tmpB, matrix, CFL_SIZE);
	//md_copy(N, matrix_dims, tmpC, matrix, CFL_SIZE);

	md_transpose(N + 1, K_dim, N, C_dims, tmpC, B_dims, tmpB, CFL_SIZE);
	md_clear(N + 1, A_dims, tmpA, CFL_SIZE);
	md_zfmacc2(N + 1, max_dims, A_str, tmpA, B_str, tmpB, C_str, tmpC);

	*gram = md_alloc_sameplace(N, fake_gram_dims, CFL_SIZE, matrix);
	md_transpose(N + 1, T_dim, N, fake_gram_dims, *gram, A_dims, tmpA, CFL_SIZE); 


	const struct iovec_s* s =  iovec_create(N, fake_gram_dims, CFL_SIZE);

	md_free(tmpA);
	md_free(tmpB);
	md_free(tmpC);

	return s;
}
Example #30
0
File: nlinv.c Project: nckz/bart
int main_nlinv(int argc, char* argv[])
{
    int iter = 8;
    float l1 = -1.;
    bool waterfat = false;
    bool rvc = false;
    bool normalize = true;
    float restrict_fov = -1.;
    float csh[3] = { 0., 0., 0. };
    bool usegpu = false;
    const char* psf = NULL;

    const struct opt_s opts[] = {

        { 'l', true, opt_float, &l1, NULL },
        { 'i', true, opt_int, &iter, NULL },
        { 'c', false, opt_set, &rvc, NULL },
        { 'N', false, opt_clear, &normalize, NULL },
        { 'f', true, opt_float, &restrict_fov, NULL },
        { 'p', true, opt_string, &psf, NULL },
        { 'g', false, opt_set, &usegpu, NULL },
    };

    cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts);

    num_init();

    assert(iter > 0);


    long ksp_dims[DIMS];
    complex float* kspace_data = load_cfl(argv[1], DIMS, ksp_dims);

    long dims[DIMS];
    md_copy_dims(DIMS, dims, ksp_dims);

    if (waterfat)
        dims[CSHIFT_DIM] = 2;

    long img_dims[DIMS];
    md_select_dims(DIMS, FFT_FLAGS|CSHIFT_FLAG, img_dims, dims);

    long img_strs[DIMS];
    md_calc_strides(DIMS, img_strs, img_dims, CFL_SIZE);


    complex float* image = create_cfl(argv[2], DIMS, img_dims);

    long msk_dims[DIMS];
    md_select_dims(DIMS, FFT_FLAGS, msk_dims, dims);

    long msk_strs[DIMS];
    md_calc_strides(DIMS, msk_strs, msk_dims, CFL_SIZE);

    complex float* mask;
    complex float* norm = md_alloc(DIMS, msk_dims, CFL_SIZE);
    complex float* sens;

    if (4 == argc) {

        sens = create_cfl(argv[3], DIMS, ksp_dims);

    } else {

        sens = md_alloc(DIMS, ksp_dims, CFL_SIZE);
    }


    complex float* pattern = NULL;
    long pat_dims[DIMS];

    if (NULL != psf) {

        pattern = load_cfl(psf, DIMS, pat_dims);

        // FIXME: check compatibility
    } else {

        pattern = md_alloc(DIMS, img_dims, CFL_SIZE);
        estimate_pattern(DIMS, ksp_dims, COIL_DIM, pattern, kspace_data);
    }


    if (waterfat) {

        size_t size = md_calc_size(DIMS, msk_dims);
        md_copy(DIMS, msk_dims, pattern + size, pattern, CFL_SIZE);

        long shift_dims[DIMS];
        md_select_dims(DIMS, FFT_FLAGS, shift_dims, msk_dims);

        long shift_strs[DIMS];
        md_calc_strides(DIMS, shift_strs, shift_dims, CFL_SIZE);

        complex float* shift = md_alloc(DIMS, shift_dims, CFL_SIZE);

        unsigned int X = shift_dims[READ_DIM];
        unsigned int Y = shift_dims[PHS1_DIM];
        unsigned int Z = shift_dims[PHS2_DIM];

        for (unsigned int x = 0; x < X; x++)
            for (unsigned int y = 0; y < Y; y++)
                for (unsigned int z = 0; z < Z; z++)
                    shift[(z * Z + y) * Y + x] = cexp(2.i * M_PI * ((csh[0] * x) / X + (csh[1] * y) / Y + (csh[2] * z) / Z));

        md_zmul2(DIMS, msk_dims, msk_strs, pattern + size, msk_strs, pattern + size, shift_strs, shift);
        md_free(shift);
    }

#if 0
    float scaling = 1. / estimate_scaling(ksp_dims, NULL, kspace_data);
#else
    float scaling = 100. / md_znorm(DIMS, ksp_dims, kspace_data);
#endif
    debug_printf(DP_INFO, "Scaling: %f\n", scaling);
    md_zsmul(DIMS, ksp_dims, kspace_data, kspace_data, scaling);

    if (-1. == restrict_fov) {

        mask = md_alloc(DIMS, msk_dims, CFL_SIZE);
        md_zfill(DIMS, msk_dims, mask, 1.);

    } else {

        float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. };
        restrict_dims[0] = restrict_fov;
        restrict_dims[1] = restrict_fov;
        restrict_dims[2] = restrict_fov;
        mask = compute_mask(DIMS, msk_dims, restrict_dims);
    }

#ifdef  USE_CUDA
    if (usegpu) {

        complex float* kspace_gpu = md_alloc_gpu(DIMS, ksp_dims, CFL_SIZE);
        md_copy(DIMS, ksp_dims, kspace_gpu, kspace_data, CFL_SIZE);
        noir_recon(dims, iter, l1, image, NULL, pattern, mask, kspace_gpu, rvc, usegpu);
        md_free(kspace_gpu);

        md_zfill(DIMS, ksp_dims, sens, 1.);

    } else
#endif
        noir_recon(dims, iter, l1, image, sens, pattern, mask, kspace_data, rvc, usegpu);

    if (normalize) {

        md_zrss(DIMS, ksp_dims, COIL_FLAG, norm, sens);
        md_zmul2(DIMS, img_dims, img_strs, image, img_strs, image, msk_strs, norm);
    }

    if (4 == argc) {

        long strs[DIMS];

        md_calc_strides(DIMS, strs, ksp_dims, CFL_SIZE);

        if (norm)
            md_zdiv2(DIMS, ksp_dims, strs, sens, strs, sens, img_strs, norm);

        fftmod(DIMS, ksp_dims, FFT_FLAGS, sens, sens);

        unmap_cfl(DIMS, ksp_dims, sens);

    } else {

        md_free(sens);
    }

    md_free(norm);
    md_free(mask);

    if (NULL != psf)
        unmap_cfl(DIMS, pat_dims, pattern);
    else
        md_free(pattern);


    unmap_cfl(DIMS, img_dims, image);
    unmap_cfl(DIMS, ksp_dims, kspace_data);
    exit(0);
}