示例#1
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);
}
static void sense_reco(struct sense_data* data, complex float* imgs, const complex float* kspace)
{
	complex float* adj = md_alloc(DIMS, data->imgs_dims, CFL_SIZE);

	md_clear(DIMS, data->imgs_dims, imgs, CFL_SIZE);

	sense_adjoint(data, adj, kspace);

	long size = md_calc_size(DIMS, data->imgs_dims);

	conjgrad(100, data->alpha, 1.E-3, 2 * size, data, &cpu_iter_ops, sense_normal,
	(float*)imgs, (const float*)adj, NULL, NULL, NULL);

	md_free(adj);
}
示例#3
0
文件: mip.c 项目: morpheus-med/bart
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);
}
示例#4
0
文件: rand.c 项目: Markusjsommer/bart
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();
}
static void nufft_apply_normal(const void* _data, complex float* dst, const complex float* src)
{
	const struct nufft_data* data = _data;

	if (data->conf.toeplitz) {

		toeplitz_mult(data, dst, src);

	} else {

		complex float* tmp_ksp = md_alloc(data->N + 3, data->ksp_dims, CFL_SIZE);
		nufft_apply((const void*)data, tmp_ksp, src);
		nufft_apply_adjoint((const void*)data, dst, tmp_ksp);
		md_free(tmp_ksp);
	}
}
static complex float* compute_linphases(unsigned int N, long lph_dims[N + 3], const long img_dims[N + 3])
{
	float shifts[8][3];

	int s = 0;
	for(int i = 0; i < 8; i++) {

		bool skip = false;

		for(int j = 0; j < 3; j++) {

			shifts[s][j] = 0.;

			if (MD_IS_SET(i, j)) {

				skip = skip || (1 == img_dims[j]);
				shifts[s][j] = -0.5;
			}
		}

		if (!skip)
			s++;
	}

	unsigned int ND = N + 3;
	md_select_dims(ND, FFT_FLAGS, lph_dims, img_dims);
	lph_dims[N + 0] = s;

	complex float* linphase = md_alloc(ND, lph_dims, CFL_SIZE);

	for(int i = 0; i < s; i++) {

		float shifts2[ND];
		for (unsigned int j = 0; j < ND; j++)
			shifts2[j] = 0.;

		shifts2[0] = shifts[i][0];
		shifts2[1] = shifts[i][1];
		shifts2[2] = shifts[i][2];

		linear_phase(ND, img_dims, shifts2, 
				linphase + i * md_calc_size(ND, img_dims));
	}

	return linphase;
}
示例#7
0
文件: sum.c 项目: grlee77/bart
void sum_apply_normal(const void* _data, complex float* dst, const complex float* src)
{
	struct sum_data* data = (struct sum_data*)_data;

	if (NULL == data->tmp) {

#ifdef USE_CUDA
		data->tmp = (data->use_gpu ? md_alloc_gpu : md_alloc)(DIMS, data->img_dims, CFL_SIZE);
#else
		data->tmp = md_alloc(DIMS, data->img_dims, CFL_SIZE);
#endif
	}


	sum_apply(_data, data->tmp, src);
	sum_apply_adjoint( _data, dst, data->tmp);
}
示例#8
0
static bool test_md_zavg_flags(unsigned int D, const long idims[D], unsigned int flags, const complex float* in, const complex float* out_ref, bool wavg)
{
	long odims[D];
	md_select_dims(D, ~flags, odims, idims);

	complex float* out = md_alloc(D, odims, CFL_SIZE);

	(wavg ? md_zwavg : md_zavg)(D, idims, flags, out, in);

	float err = md_znrmse(D, odims, out_ref, out);

	md_free(out);

	UT_ASSERT(err < UT_TOL);

	return true;
}
示例#9
0
void overlapandadd(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2)
{
	long ndims[2 * N];
	long L[2 * N];
	long ndim2[2 * N];
	long ndim3[2 * N];

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

		assert(0 == dims[i] % blk[i]);
		assert(dim2[i] <= blk[i]);

		ndims[i * 2 + 1] = dims[i] / blk[i];
		ndims[i * 2 + 0] = blk[i];

		L[i * 2 + 1] = dims[i] / blk[i];
		L[i * 2 + 0] = blk[i] + dim2[i] - 1;

		ndim2[i * 2 + 1] = 1;
		ndim2[i * 2 + 0] = dim2[i];

		ndim3[i * 2 + 1] = dims[i] / blk[i] + 1;
		ndim3[i * 2 + 0] = blk[i];
	}

	complex float* tmp = md_alloc(2 * N, L, CFL_SIZE);

//	conv_causal_extend(2 * N, L, tmp, ndims, src1, ndim2, src2);
	conv(2 * N, ~0, CONV_EXTENDED, CONV_CAUSAL, L, tmp, ndims, src1, ndim2, src2);
	// [------++++||||||||

	//long str1[2 * N];
	long str2[2 * N];
	long str3[2 * N];

	//md_calc_strides(2 * N, str1, ndims, 8);
	md_calc_strides(2 * N, str2, L, 8);
	md_calc_strides(2 * N, str3, ndim3, 8);

	md_clear(2 * N, ndim3, dst, CFL_SIZE);
	md_zadd2(2 * N, L, str3, dst, str3, dst, str2, tmp);
	
	md_free(tmp);
}
示例#10
0
void overlapandsave(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2)
{
	// [------++++
	// [------

	long ndims[2 * N];
	long L[2 * N];
	long ndim2[2 * N];
	long ndim3[2 * N];

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

		assert(0 == dims[i] % blk[i]);
		assert(dim2[i] <= blk[i]);

		ndims[i * 2 + 1] = dims[i] / blk[i];
		ndims[i * 2 + 0] = blk[i];

		L[i * 2 + 1] = dims[i] / blk[i];
		L[i * 2 + 0] = blk[i] + dim2[i] - 1;

		ndim2[i * 2 + 1] = 1;
		ndim2[i * 2 + 0] = dim2[i];

		ndim3[i * 2 + 1] = dims[i] / blk[i] - 0;
		ndim3[i * 2 + 0] = blk[i];
	}

	complex float* tmp = md_alloc(2 * N, L, CFL_SIZE);

	long str1[2 * N];
	long str2[2 * N];
	long str3[2 * N];

	md_calc_strides(2 * N, str1, ndims, 8);
	md_calc_strides(2 * N, str2, L, 8);
	md_calc_strides(2 * N, str3, ndim3, 8);

	md_clear(2 * N, L, tmp, 8);
	md_copy2(2 * N, ndim3, str2, tmp, str1, src1, 8);
	conv(2 * N, ~0, CONV_VALID, CONV_CAUSAL, ndims, dst, L, tmp, ndim2, src2);

	md_free(tmp);
}
示例#11
0
文件: calib.c 项目: thisiscam/bart
void caltwo(const struct ecalib_conf* conf, const long out_dims[DIMS], complex float* out_data, complex float* emaps, const long in_dims[4], complex float* in_data, const long msk_dims[3], const bool* msk)
{

	long xx = out_dims[0];
	long yy = out_dims[1];
	long zz = out_dims[2];

	long xh = in_dims[0];
	long yh = in_dims[1];
	long zh = in_dims[2];

	long channels = out_dims[3];
	long cosize = channels * (channels + 1) / 2;
	
	assert(DIMS >= 5);
	assert(1 == md_calc_size(DIMS - 5, out_dims + 5));
	assert(in_dims[3] == cosize);

	long cov_dims[4] = { xh, yh, zh, cosize };
	long covbig_dims[4] = { xx, yy, zz, cosize };

	assert(((xx == 1) && (xh == 1)) || (xx >= xh));
	assert(((yy == 1) && (yh == 1)) || (yy >= yh));
	assert(((zz == 1) && (zh == 1)) || (zz >= zh));

	assert((1 == xh) || (0 == xh % 2));
	assert((1 == yh) || (0 == yh % 2));
	assert((1 == zh) || (0 == zh % 2));

	complex float* imgcov2 = md_alloc(4, covbig_dims, CFL_SIZE);

	debug_printf(DP_DEBUG1, "Resize...\n");

	sinc_zeropad(4, covbig_dims, imgcov2, cov_dims, in_data);

	debug_printf(DP_DEBUG1, "Point-wise eigen-decomposition...\n");

	eigenmaps(out_dims, out_data, emaps, imgcov2, msk_dims, msk, conf->orthiter, conf->usegpu);

	md_free(imgcov2);
}
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);
}
示例#13
0
文件: calib.c 项目: thisiscam/bart
static void perturb(const long dims[2], complex float* vecs, float amt)
{
	complex float* noise = md_alloc(2, dims, CFL_SIZE);

	md_gaussian_rand(2, dims, noise);

	for (long j = 0; j < dims[1]; j++) {

		float nrm = md_znorm(1, dims, noise + j * dims[0]);
		complex float val = amt / nrm;
		md_zsmul(1, dims, noise + j * dims[0], noise + j * dims[0], val);
	}

	md_zadd(2, dims, vecs, vecs, noise);

	for (long j = 0; j < dims[1]; j++) {

		float nrm = md_znorm(1, dims, vecs + j * dims[0]);
		complex float val = 1 / nrm;
		md_zsmul(1, dims, vecs + j * dims[0], vecs + j * dims[0], val);
	}

	md_free(noise);
}
示例#14
0
文件: ufft.c 项目: Markusjsommer/bart
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);

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

	return data;
}
示例#15
0
文件: test_multind.c 项目: hcmh/bart
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));
示例#16
0
void walsh(const long bsize[3], const long dims[DIMS], complex float* sens, const long caldims[DIMS], const complex float* data)
{
	assert(1 == caldims[MAPS_DIM]);
	assert(1 == dims[MAPS_DIM]);

	int channels = caldims[COIL_DIM];
	int cosize = channels * (channels + 1) / 2;
	assert(dims[COIL_DIM] == cosize);

	long dims1[DIMS];
	md_copy_dims(DIMS, dims1, dims);
	dims1[COIL_DIM] = channels;
	
	long kdims[4];
	kdims[0] = MIN(bsize[0], dims[0]);
	kdims[1] = MIN(bsize[1], dims[1]);
	kdims[2] = MIN(bsize[2], dims[2]);

	md_resize_center(DIMS, dims1, sens, caldims, data, CFL_SIZE);
	ifftc(DIMS, dims1, FFT_FLAGS, sens, sens);

	long odims[DIMS];
	md_copy_dims(DIMS, odims, dims1);

	for (int i = 0; i < 3; i++)
		odims[i] = dims[i] + kdims[i] - 1;

	complex float* tmp = md_alloc(DIMS, odims, CFL_SIZE);
#if 0
	md_resizec(DIMS, odims, tmp, dims1, sens, CFL_SIZE);
#else
	long cen[DIMS] = { 0 };

	for (int i = 0; i < 3; i++)
		cen[i] = (odims[i] - dims[i] + 1) / 2;

	complex float* tmp1 = md_alloc(DIMS, odims, CFL_SIZE);
	md_circ_ext(DIMS, odims, tmp1, dims1, sens, CFL_SIZE);
//	md_resize(DIMS, odims, tmp1, dims1, sens, CFL_SIZE);
	md_circ_shift(DIMS, odims, cen, tmp, tmp1, CFL_SIZE);
	md_free(tmp1);
#endif

	long calmat_dims[2];
	complex float* cm = calibration_matrix(calmat_dims, kdims, odims, tmp);
	md_free(tmp);

	int xh = dims[0];
	int yh = dims[1];
	int zh = dims[2];

	int pixels = calmat_dims[1] / channels;

#pragma omp parallel for
	for (int k = 0; k < zh; k++) {

		complex float in[channels][pixels];
		complex float cov[cosize];

		for (int j = 0; j < yh; j++) {
			for (int i = 0; i < xh; i++) {

				for (int c = 0; c < channels; c++)
					for (int p = 0; p < pixels; p++)
						in[c][p] = cm[((((c * pixels + p) * zh) + k) * yh + j) * xh + i];

				gram_matrix2(channels, cov, pixels, in);

				for (int l = 0; l < cosize; l++)
					sens[(((l * zh) + k) * yh + j) * xh + i] = cov[l];
			}
		}
	}
}
示例#17
0
文件: nlinv.c 项目: 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);
}
示例#18
0
文件: ecalib.c 项目: hcmh/bart
int main_ecalib(int argc, char* argv[])
{
	long calsize[3] = { 24, 24, 24 }; 
	int maps = 2;
	bool one = false;
	bool calcen = false;
	bool print_svals = false;

	struct ecalib_conf conf = ecalib_defaults;

	const struct opt_s opts[] = {

		OPT_FLOAT('t', &conf.threshold, "threshold", "This determined the size of the null-space."),
		OPT_FLOAT('c', &conf.crop, "crop_value", "Crop the sensitivities if the eigenvalue is smaller than {crop_value}."),
		OPT_VEC3('k', &conf.kdims, "ksize", "kernel size"),
		OPT_VEC3('K', &conf.kdims, "", "()"),
		OPT_VEC3('r', &calsize, "cal_size", "Limits the size of the calibration region."),
		OPT_VEC3('R', &calsize, "", "()"),
		OPT_INT('m', &maps, "maps", "Number of maps to compute."),
		OPT_SET('S', &conf.softcrop, "create maps with smooth transitions (Soft-SENSE)."),
		OPT_SET('W', &conf.weighting, "soft-weighting of the singular vectors."),
		OPT_SET('I', &conf.intensity, "intensity correction"),
		OPT_SET('1', &one, "perform only first part of the calibration"),
		OPT_CLEAR('P', &conf.rotphase, "Do not rotate the phase with respect to the first principal component"),
		OPT_CLEAR('O', &conf.orthiter, "()"),
		OPT_FLOAT('b', &conf.perturb, "", "()"),
		OPT_SET('V', &print_svals, "()"),
		OPT_SET('C', &calcen, "()"),
		OPT_SET('g', &conf.usegpu, "()"),
		OPT_FLOAT('p', &conf.percentsv, "", "()"),
		OPT_INT('n', &conf.numsv, "", "()"),
		OPT_FLOAT('v', &conf.var, "variance", "Variance of noise in data."),
		OPT_SET('a', &conf.automate, "Automatically pick thresholds."),
		OPT_INT('d', &debug_level, "level", "Debug level"),
	};

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

	if (-1. != conf.percentsv)
		conf.threshold = -1.;

	if (-1 != conf.numsv)
		conf.threshold = -1.;

	if (conf.automate) {

		conf.crop      = -1.;
		conf.weighting = true;
	}

	if (conf.weighting) {

		conf.numsv      = -1.;
		conf.threshold  =   0;
		conf.percentsv  = -1.;
		conf.orthiter   = false;
	}

	int N = DIMS;
	long ksp_dims[N];

	complex float* in_data = load_cfl(argv[1], N, ksp_dims);

	
	// assert((kdims[0] < calsize_ro) && (kdims[1] < calsize_ro) && (kdims[2] < calsize_ro));
	// assert((ksp_dims[0] == 1) || (calsize_ro < ksp_dims[0]));
	if (1 != ksp_dims[MAPS_DIM])
		error("MAPS dimension is not of size one.\n");


	long cal_dims[N];
	complex float* cal_data = NULL;

	 if (!calcen) {

#ifdef USE_CC_EXTRACT_CALIB
		cal_data = cc_extract_calib(cal_dims, calsize, ksp_dims, in_data);
#else
		cal_data = extract_calib(cal_dims, calsize, ksp_dims, in_data, false);
#endif

	} else {
	
		for (int i = 0; i < 3; i++)
			cal_dims[i] = (calsize[i] < ksp_dims[i]) ? calsize[i] : ksp_dims[i];

		for (int i = 3; i < N; i++)
			cal_dims[i] = ksp_dims[i];

		cal_data = md_alloc(5, cal_dims, CFL_SIZE);
		md_resize_center(5, cal_dims, cal_data, ksp_dims, in_data, CFL_SIZE);
	 }



	 for (int i = 0; i < 3; i++)
		 if (1 == ksp_dims[i])
			 conf.kdims[i] = 1;


	 long channels = cal_dims[3];
	 unsigned int K = conf.kdims[0] * conf.kdims[1] * conf.kdims[2] * channels;
	 float svals[K];


	 for (unsigned int i = 0; i < 3; i++)
		if ((1 == cal_dims[i]) && (1 != ksp_dims[i]))
			error("Calibration region not found!\n");


	// To reproduce old results turn off rotation of phase.
	// conf.rotphase = false;


	// FIXME: we should scale the data

	(conf.usegpu ? num_init_gpu : num_init)();

        if ((conf.var < 0) && (conf.weighting || (conf.crop < 0)))
		conf.var = estvar_calreg(conf.kdims, cal_dims, cal_data);

	if (one) {

#if 0
		long maps = out_dims[4];

		assert(caldims[3] == out_dims[3]);
		assert(maps <= channels);
#endif
		long cov_dims[4];

		calone_dims(&conf, cov_dims, channels);
		complex float* imgcov = md_alloc(4, cov_dims, CFL_SIZE);


		calone(&conf, cov_dims, imgcov, K, svals, cal_dims, cal_data);

		complex float* out = create_cfl(argv[2], 4, cov_dims);
		md_copy(4, cov_dims, out, imgcov, CFL_SIZE);
		unmap_cfl(4, cov_dims, out);

//		caltwo(crthr, out_dims, out_data, emaps, cov_dims, imgcov, NULL, NULL);

		md_free(imgcov);

	} else {

		long out_dims[N];
		long map_dims[N];

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

			out_dims[i] = 1;
			map_dims[i] = 1;

			if ((i < 3) && (1 < conf.kdims[i])) {

				out_dims[i] = ksp_dims[i];
				map_dims[i] = ksp_dims[i];
			}
		}


		assert(maps <= ksp_dims[COIL_DIM]);


		out_dims[COIL_DIM] = ksp_dims[COIL_DIM];
		out_dims[MAPS_DIM] = maps;	
		map_dims[COIL_DIM] = 1;
		map_dims[MAPS_DIM] = maps;

		const char* emaps_file = NULL;

		if (4 == argc)
			emaps_file = argv[3];

		complex float* out_data = create_cfl(argv[2], N, out_dims);
		complex float* emaps = (emaps_file ? create_cfl : anon_cfl)(emaps_file, N, map_dims);

		calib(&conf, out_dims, out_data, emaps, K, svals, cal_dims, cal_data); 

		unmap_cfl(N, out_dims, out_data);
		unmap_cfl(N, map_dims, emaps);
	}


	if (print_svals) {

		for (unsigned int i = 0; i < K; i++)
			printf("SVALS %d %f\n", i, svals[i]);
	}

	printf("Done.\n");

	unmap_cfl(N, ksp_dims, in_data);
	md_free(cal_data);

	return 0;
}
示例#19
0
文件: nufft.c 项目: andruw17/bart
int main_nufft(int argc, char* argv[])
{
	int c;
	bool adjoint = false;
	bool inverse = false;
	bool toeplitz = false;
	bool precond = false;
	bool use_gpu = false;
	bool two = false;
	bool calib = false;
	bool sizeinit = false;
	bool stoch = false;

	long coilim_dims[DIMS];
	md_singleton_dims(DIMS, coilim_dims);

	int maxiter = 50;
	float lambda = 0.00;

	const char* pat_str = NULL;

	while (-1 != (c = getopt(argc, argv, "d:m:l:p:aihCto:w:2:c:S"))) {

		switch (c) {

		case '2':
			two = true;
			break;

		case 'i':
			inverse = true;
			break;

		case 'a':
			adjoint = true;
			break;

		case 'C':
			precond = true;
			break;

		case 'S':
			stoch = true;
			break;

		case 'c':
			calib = true;
			inverse = true;
		case 'd':
			sscanf(optarg, "%ld:%ld:%ld", &coilim_dims[0], &coilim_dims[1], &coilim_dims[2]);
			sizeinit = true;
			break;

		case 'm':
			maxiter = atoi(optarg);
			break;

		case 'p':
			pat_str = strdup(optarg);
			break;

		case 'l':
			lambda = atof(optarg);
			break;

		case 't':
			toeplitz = 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);
	}

	// Read trajectory
	long traj_dims[2];
	complex float* traj = load_cfl(argv[optind + 0], 2, traj_dims);

	assert(3 == traj_dims[0]);

	if (!sizeinit)
		estimate_im_dims(coilim_dims, traj_dims, traj);

	num_init();

	// Load pattern / density compensation (if any)
	complex float* pat = NULL;
	long pat_dims[2];

	if (pat_str) {

		pat = load_cfl(pat_str, 2, pat_dims);
		assert(pat_dims[0] == 1);
		assert(pat_dims[1] == traj_dims[1]);
	}

	if (inverse || adjoint) {

		long ksp_dims[DIMS];
		const complex float* ksp = load_cfl(argv[optind + 1], DIMS, ksp_dims);

		coilim_dims[COIL_DIM] = ksp_dims[COIL_DIM];

		long out_dims[DIMS];

		if (calib) {

			md_singleton_dims(DIMS, out_dims);
			estimate_im_dims(out_dims, traj_dims, traj);
			out_dims[COIL_DIM] = ksp_dims[COIL_DIM];

		} else {

			md_copy_dims(DIMS, out_dims, coilim_dims);
		}

		complex float* out = create_cfl(argv[optind + 2], DIMS, out_dims);
		complex float* img = out;

		if (calib)
			img = md_alloc(DIMS, coilim_dims, CFL_SIZE);

		md_clear(DIMS, coilim_dims, img, CFL_SIZE);

		struct iter_conjgrad_conf cgconf = iter_conjgrad_defaults;
		cgconf.maxiter = maxiter;
		cgconf.l2lambda = 0.;
		cgconf.tol = 0;

		const struct linop_s* nufft_op;

		// Get nufft_op
		if (two)
#ifdef BERKELEY_SVN
			nufft_op = nufft2_create(ksp_dims, coilim_dims, traj, pat, toeplitz, precond, &cgconf, use_gpu);
#else
			assert(!two);
#endif
		else
示例#20
0
int
g_process_math_string(__g_handle hdl, char *string, pmda mdm, pmda chain,
    int *ret, void **p_ret, uint32_t flags, uint32_t int_flags)
{
  g_setjmp(0, "g_process_math_string", NULL, NULL);
  char *ptr = string, *left, oper = 0x0;
  size_t i;

  size_t sin_len = strlen(string);

  if (sin_len == 0)
    {
      return 0;
    }

  //g_del_char(string, string_p, 0x20);

  int f_ret = 0;

  while (ptr[0])
    {
      if (ptr[0] == 0x0 || ptr[0] == 0x23 || ptr[0] == 0x7D || ptr[0] == 0x29
          || ptr[0] == 0x3A)
        {
          if (ptr[0] == 0x29)
            {
              if (!(int_flags & F_PROC_MATH_STR_INB))
                {
                  f_ret = 0;
                  goto f_end;
                }
              else
                {
                  *p_ret = ptr;
                }
            }
          else
            {
              /*if ((int_flags & F_PROC_MATH_STR_INB))
               {
               return 12;
               }*/
            }
          break;
        }

      while (ptr[0] == 0x20)
        {
          ptr++;
        }

      if (ptr[0] == 0x28)
        {
          if (ptr[1] == 0x29)
            {
              break;
            }
          pmda object = (pmda) md_alloc(chain, sizeof(mda));

          if (NULL == object)
            {
              f_ret = -1;
              goto f_end;
            }

          md_init(object, 8);
          char *pms_ret = "";

          ptr++;

          int r = g_process_math_string(hdl, ptr, object, chain, ret,
              (void*) &pms_ret, flags, int_flags | F_PROC_MATH_STR_INB);
          if (0 != r)
            {
              ERROR(
                  "g_process_math_string (F_PROC_MATH_STR_INB): FAILED: [%d]: %s\n",
                  r, pms_ret);
              md_free(object);
              f_ret = r;
              goto f_end;
            }
          else
            {
              __g_math math_c = (__g_math ) m_find_last_dtype(chain,
                  chain->pos);
              __g_math math = (__g_math ) md_alloc(mdm, sizeof(_g_math));

              if (NULL == math)
                {
                  f_ret = 16;
                  goto f_end;
                }

              if (NULL == math_c)
                {
                  f_ret = 17;
                  goto f_end;
                }

              math->next = object;
              math->flags |= F_MATH_NITEM;

              pms_ret++;
              ptr = pms_ret;

              math->flags |= (math_c->flags & F_MATH_TYPES);

              __g_math math_p = (__g_math ) m_find_prev_dtype(mdm,
                  (p_md_obj) mdm->pos);

              math->_m_p = g_get_math_m_p(math, math_p);

              if (!(is_ascii_arith_bin_oper(ptr[0])))
                {
                  if (NULL == math_c->_m_p)
                    {
                      f_ret = 21;
                      goto f_end;
                    }

                  math->op_t = m_get_op_proc(ptr[0], math_c);

                  if ( NULL == math->op_t)
                    {
                      f_ret = 22;
                      goto f_end;
                    }

                  //math->_m_p = math_c->_m_p;
                }

              math->vb = math_c->vb;
              math->l_off = math_c->l_off;

              if (ptr[0] == 0x0 || ptr[0] == 0x23 || ptr[0] == 0x7D
                  || ptr[0] == 0x3A || ptr[0] == 0x29)
                {
                  continue;
                }

              ptr++;

              continue;
            }

        }

      i = 0;

      left = ptr;

      uint32_t add_flags = 0;

      char in_dummy[8192];

      if (ptr[0] == 0x5B)
        {
          void *l_next_ref;

          char *s_ptr = l_mppd_shell_ex(ptr, in_dummy, sizeof(in_dummy),
              &l_next_ref,
              0x5B,
              0x5D, F_MPPD_SHX_TZERO);

          if (NULL == s_ptr)
            {
              f_ret = 130;
              goto f_end;
            }

          if (NULL == l_next_ref || ((char*) l_next_ref)[0] == 0x0)
            {
              f_ret = 131;
              goto f_end;
            }

          left = s_ptr;
          ptr = l_next_ref;
          add_flags |= F_MATH_STRCONV;
        }
      else
        {

          if (ptr[0] == 0x2B || ptr[0] == 0x2D)
            {
              ptr++;
            }

          while (is_ascii_arith_bin_oper(ptr[0]) && ptr[0] && ptr[0] != 0x23
              && ptr[0] != 0x7D && ptr[0] != 0x29 && ptr[0] != 0x3A
              && ptr[0] != 0x29 && ptr[0] != 0x20)
            {
              i++;
              ptr++;
            }

          if (!i)
            {
              f_ret = 1;
              goto f_end;
            }
        }

      if (ptr[0] && ptr[0] != 0x23 && ptr[0] != 0x7D && ptr[0] != 0x29
          && ptr[0] != 0x3A && ptr[0] != 0x29)
        {
          if (is_ascii_arith_bin_oper(ptr[0]))
            {
              f_ret = 23;
              goto f_end;
            }

          if (ptr[0] == 0x3C || ptr[0] == 0x3E)
            {
              if (ptr[0] != ptr[1])
                {
                  f_ret = 2;
                  goto f_end;
                }
              ptr++;
            }
          oper = ptr[0];
          ptr++;
        }
      else
        {
          oper = 0x0;
        }

      __g_math mm;
      *ret = g_build_math_packet(hdl, left, oper, mdm, &mm, flags | add_flags);

      if (*ret)
        {
          f_ret = 6;
          goto f_end;
        }

      if (oper == 0x7E && (ptr[0] == 0x7D || ptr[0] == 0x29))
        {
          *ret = g_build_math_packet(hdl, left, oper, mdm, NULL,
              flags | add_flags);
          if (*ret)
            {
              f_ret = 7;
              goto f_end;
            }
        }

    }

  f_end: ;

  //free(string_p);

  return f_ret;
}
示例#21
0
void overlapandsave2NE(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], complex float* src1, const long dims2[N], complex float* src2, const long mdims[N], complex float* msk)
{
	long dims1B[N];

	long tdims[2 * N];
	long nodims[2 * N];
	long ndims1[2 * N];
	long ndims2[2 * N];

	long shift[2 * N];

	unsigned int nflags = 0;

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

		if (MD_IS_SET(flags, i)) {

			nflags = MD_SET(nflags, 2 * i);

			assert(1 == dims2[i] % 2);
			assert(0 == blk[i] % 2);
			assert(0 == dims1[i] % 2);
			assert(0 == odims[i] % blk[i]);
			assert(0 == dims1[i] % blk[i]);
			assert(dims1[i] == odims[i]);
			assert(dims2[i] <= blk[i]);
			assert(dims1[i] >= dims2[i]);

			// blocked output

			nodims[i * 2 + 1] = odims[i] / blk[i];
			nodims[i * 2 + 0] = blk[i];

			// expanded temporary storage

			tdims[i * 2 + 1] = dims1[i] / blk[i];
			tdims[i * 2 + 0] = blk[i] + dims2[i] - 1;

			// blocked input

			// ---|---,---,---|---
			//   + +++ +
			//       + +++ +

			// resized input

			dims1B[i] = dims1[i] + 2 * blk[i];

			ndims1[i * 2 + 1] = dims1[i] / blk[i] + 2; // do we need two full blocks?
			ndims1[i * 2 + 0] = blk[i];

			shift[i * 2 + 1] = 0;
			shift[i * 2 + 0] = blk[i] - (dims2[i] - 1) / 2;

			// kernel

			ndims2[i * 2 + 1] = 1;
			ndims2[i * 2 + 0] = dims2[i];

		} else {

			nodims[i * 2 + 1] = 1;
			nodims[i * 2 + 0] = odims[i];

			tdims[i * 2 + 1] = 1;
			tdims[i * 2 + 0] = dims1[i];

			ndims1[i * 2 + 1] = 1;
			ndims1[i * 2 + 0] = dims1[i];

			shift[i * 2 + 1] = 0;
			shift[i * 2 + 0] = 0;


			dims1B[i] = dims1[i];

			ndims2[i * 2 + 1] = 1;
			ndims2[i * 2 + 0] = dims2[i];
		}
	}

	complex float* src1B = md_alloc(N, dims1B, CFL_SIZE);
	complex float* tmp = md_alloc(2 * N, tdims, CFL_SIZE);
	complex float* tmpX = md_alloc(N, odims, CFL_SIZE);

	long str1[2 * N];
	long str2[2 * N];

	md_calc_strides(2 * N, str1, ndims1, sizeof(complex float));
	md_calc_strides(2 * N, str2, tdims, sizeof(complex float));

	long off = md_calc_offset(2 * N, str1, shift);

	md_resize_center(N, dims1B, src1B, dims1, src1, sizeof(complex float));

	// we can loop here

	md_copy2(2 * N, tdims, str2, tmp, str1, ((void*)src1B) + off, sizeof(complex float));

	conv(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, nodims, tmpX, tdims, tmp, ndims2, src2);

	long ostr[N];
	long mstr[N];

	md_calc_strides(N, ostr, odims, sizeof(complex float));
	md_calc_strides(N, mstr, mdims, sizeof(complex float));

	md_zmul2(N, odims, ostr, tmpX, ostr, tmpX, mstr, msk);

	convH(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, tdims, tmp, nodims, tmpX, ndims2, src2);

	md_clear(N, dims1B, src1B, sizeof(complex float));
	md_zadd2(2 * N, tdims, str1, ((void*)src1B) + off, str1, ((void*)src1B) + off, str2, tmp);

	//

	md_resize_center(N, dims1, dst, dims1B, src1B, sizeof(complex float));

	md_free(src1B);
	md_free(tmpX);
	md_free(tmp);
}
示例#22
0
int
g_build_math_packet(__g_handle hdl, char *field, char oper, pmda mdm,
    __g_math *ret, uint32_t flags)
{
  g_setjmp(0, "g_build_math_packet", NULL, NULL);
  int rt = 0;
  md_init(mdm, 16);

  __g_math p_math = (__g_math ) mdm->pos->ptr;
  __g_math math = (__g_math ) md_alloc(mdm, sizeof(_g_math));

  if (!math)
    {
      rt = 1;
      goto end;
    }

  math->flags |= flags;

  if ((rt = g_get_math_g_t_ptr(hdl, field, math, 0, p_math)))
    {
      goto end;
    }

  if (!(math->flags & F_MATH_TYPES))
    {
      rt = 6;
      goto end;
    }

  if (math->_m_p)
    {
      math->op_t = m_get_op_proc(oper, math);

      if ( NULL == math->op_t)
        {
          rt = 7;
          goto end;
        }

      /*if (oper == 0x7E)
       {
       math->flags |= F_MATH_IS_SQRT;

       }*/
    }

  if (ret)
    {
      *ret = math;
    }

  end:

  if (rt)
    {
      md_unlink(mdm, mdm->pos);
    }

  return rt;
}
示例#23
0
文件: pics.c 项目: grlee77/bart
int main_pics(int argc, char* argv[])
{
	// Initialize default parameters

	struct sense_conf conf = sense_defaults;



	bool use_gpu = false;

	bool randshift = true;
	unsigned int maxiter = 30;
	float step = -1.;

	// Start time count

	double start_time = timestamp();

	// Read input options
	struct nufft_conf_s nuconf = nufft_conf_defaults;
	nuconf.toeplitz = false;

	float restrict_fov = -1.;
	const char* pat_file = NULL;
	const char* traj_file = NULL;
	bool scale_im = false;
	bool eigen = false;
	float scaling = 0.;

	unsigned int llr_blk = 8;

	const char* image_truth_file = NULL;
	bool im_truth = false;

	const char* image_start_file = NULL;
	bool warm_start = false;

	bool hogwild = false;
	bool fast = false;
	float admm_rho = iter_admm_defaults.rho;
	unsigned int admm_maxitercg = iter_admm_defaults.maxitercg;

	struct opt_reg_s ropts;
	ropts.r = 0;
	ropts.algo = CG;
	ropts.lambda = -1.;


	const struct opt_s opts[] = {

		{ 'l', true, opt_reg, &ropts, "1/-l2\t\ttoggle l1-wavelet or l2 regularization." },
		OPT_FLOAT('r', &ropts.lambda, "lambda", "regularization parameter"),
		{ 'R', true, opt_reg, &ropts, " <T>:A:B:C\tgeneralized regularization options (-Rh for help)" },
		OPT_SET('c', &conf.rvc, "real-value constraint"),
		OPT_FLOAT('s', &step, "step", "iteration stepsize"),
		OPT_UINT('i', &maxiter, "iter", "max. number of iterations"),
		OPT_STRING('t', &traj_file, "file", "k-space trajectory"),
		OPT_CLEAR('n', &randshift, "disable random wavelet cycle spinning"),
		OPT_SET('g', &use_gpu, "use GPU"),
		OPT_STRING('p', &pat_file, "file", "pattern or weights"),
		OPT_SELECT('I', enum algo_t, &ropts.algo, IST, "(select IST)"),
		OPT_UINT('b', &llr_blk, "blk", "Lowrank block size"),
		OPT_SET('e', &eigen, "Scale stepsize based on max. eigenvalue"),
		OPT_SET('H', &hogwild, "(hogwild)"),
		OPT_SET('F', &fast, "(fast)"),
		OPT_STRING('T', &image_truth_file, "file", "(truth file)"),
		OPT_STRING('W', &image_start_file, "<img>", "Warm start with <img>"),
		OPT_INT('d', &debug_level, "level", "Debug level"),
		OPT_INT('O', &conf.rwiter, "rwiter", "(reweighting)"),
		OPT_FLOAT('o', &conf.gamma, "gamma", "(reweighting)"),
		OPT_FLOAT('u', &admm_rho, "rho", "ADMM rho"),
		OPT_UINT('C', &admm_maxitercg, "iter", "ADMM max. CG iterations"),
		OPT_FLOAT('q', &conf.cclambda, "cclambda", "(cclambda)"),
		OPT_FLOAT('f', &restrict_fov, "rfov", "restrict FOV"),
		OPT_SELECT('m', enum algo_t, &ropts.algo, ADMM, "Select ADMM"),
		OPT_FLOAT('w', &scaling, "val", "scaling"),
		OPT_SET('S', &scale_im, "Re-scale the image after reconstruction"),
	};

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

	if (NULL != image_truth_file)
		im_truth = true;

	if (NULL != image_start_file)
		warm_start = true;


	long max_dims[DIMS];
	long map_dims[DIMS];
	long pat_dims[DIMS];
	long img_dims[DIMS];
	long coilim_dims[DIMS];
	long ksp_dims[DIMS];
	long traj_dims[DIMS];



	// load kspace and maps and get dimensions

	complex float* kspace = load_cfl(argv[1], DIMS, ksp_dims);
	complex float* maps = load_cfl(argv[2], DIMS, map_dims);


	complex float* traj = NULL;

	if (NULL != traj_file)
		traj = load_cfl(traj_file, DIMS, traj_dims);


	md_copy_dims(DIMS, max_dims, ksp_dims);
	md_copy_dims(5, max_dims, map_dims);

	md_select_dims(DIMS, ~COIL_FLAG, img_dims, max_dims);
	md_select_dims(DIMS, ~MAPS_FLAG, coilim_dims, max_dims);

	if (!md_check_compat(DIMS, ~(MD_BIT(MAPS_DIM)|FFT_FLAGS), img_dims, map_dims))
		error("Dimensions of image and sensitivities do not match!\n");

	assert(1 == ksp_dims[MAPS_DIM]);


	(use_gpu ? num_init_gpu : num_init)();

	// print options

	if (use_gpu)
		debug_printf(DP_INFO, "GPU reconstruction\n");

	if (map_dims[MAPS_DIM] > 1) 
		debug_printf(DP_INFO, "%ld maps.\nESPIRiT reconstruction.\n", map_dims[MAPS_DIM]);

	if (hogwild)
		debug_printf(DP_INFO, "Hogwild stepsize\n");

	if (im_truth)
		debug_printf(DP_INFO, "Compare to truth\n");



	// initialize sampling pattern

	complex float* pattern = NULL;

	if (NULL != pat_file) {

		pattern = load_cfl(pat_file, DIMS, pat_dims);

		assert(md_check_compat(DIMS, COIL_FLAG, ksp_dims, pat_dims));

	} else {

		md_select_dims(DIMS, ~COIL_FLAG, pat_dims, ksp_dims);
		pattern = md_alloc(DIMS, pat_dims, CFL_SIZE);
		estimate_pattern(DIMS, ksp_dims, COIL_DIM, pattern, kspace);
	}


	if ((NULL != traj_file) && (NULL == pat_file)) {

		md_free(pattern);
		pattern = NULL;
		nuconf.toeplitz = true;

	} else {

		// print some statistics

		long T = md_calc_size(DIMS, pat_dims);
		long samples = (long)pow(md_znorm(DIMS, pat_dims, pattern), 2.);

		debug_printf(DP_INFO, "Size: %ld Samples: %ld Acc: %.2f\n", T, samples, (float)T / (float)samples);
	}

	if (NULL == traj_file) {

		fftmod(DIMS, ksp_dims, FFT_FLAGS, kspace, kspace);
		fftmod(DIMS, map_dims, FFT_FLAGS, maps, maps);
	}

	// apply fov mask to sensitivities

	if (-1. != restrict_fov) {

		float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. };
		restrict_dims[0] = restrict_fov;
		restrict_dims[1] = restrict_fov;
		restrict_dims[2] = restrict_fov;

		apply_mask(DIMS, map_dims, maps, restrict_dims);
	}
示例#24
0
/**
 *
 * NUFFT operator initialization
 *
 * @param N		-	number of dimensions
 * @param ksp_dims      -	kspace dimension
 * @param cim_dims	-	coil images dimension
 * @param traj		-	trajectory
 * @param conf          -	configuration options
 * @param use_gpu       -	use gpu boolean
 *
 */
struct linop_s* nufft_create(unsigned int N, const long ksp_dims[N], const long cim_dims[N], const long traj_dims[N], const complex float* traj, const complex float* weights, struct nufft_conf_s conf, bool use_gpu)

{
	struct nufft_data* data = (struct nufft_data*)xmalloc(sizeof(struct nufft_data));

	data->N = N;
	data->use_gpu = use_gpu;
	data->traj = traj;
	data->conf = conf;

	data->width = 3.;
	data->beta = calc_beta(2., data->width);

	// get dims

	assert(md_check_compat(N - 3, 0, ksp_dims + 3, cim_dims + 3));

	unsigned int ND = N + 3;

	data->ksp_dims = xmalloc(ND * sizeof(long));
	data->cim_dims = xmalloc(ND * sizeof(long));
	data->cml_dims = xmalloc(ND * sizeof(long));
	data->img_dims = xmalloc(ND * sizeof(long));
	data->trj_dims = xmalloc(ND * sizeof(long));
	data->lph_dims = xmalloc(ND * sizeof(long));
	data->psf_dims = xmalloc(ND * sizeof(long));
	data->wgh_dims = xmalloc(ND * sizeof(long));

	data->ksp_strs = xmalloc(ND * sizeof(long));
	data->cim_strs = xmalloc(ND * sizeof(long));
	data->cml_strs = xmalloc(ND * sizeof(long));
	data->img_strs = xmalloc(ND * sizeof(long));
	data->trj_strs = xmalloc(ND * sizeof(long));
	data->lph_strs = xmalloc(ND * sizeof(long));
	data->psf_strs = xmalloc(ND * sizeof(long));
	data->wgh_strs = xmalloc(ND * sizeof(long));

	md_singleton_dims(ND, data->cim_dims);
	md_singleton_dims(ND, data->ksp_dims);

	md_copy_dims(N, data->cim_dims, cim_dims);
	md_copy_dims(N, data->ksp_dims, ksp_dims);


	md_select_dims(ND, FFT_FLAGS, data->img_dims, data->cim_dims);

	assert(3 == traj_dims[0]);
	assert(traj_dims[1] == ksp_dims[1]);
	assert(traj_dims[2] == ksp_dims[2]);
	assert(md_check_compat(N - 3, ~0, traj_dims + 3, ksp_dims + 3));
	assert(md_check_bounds(N - 3, ~0, traj_dims + 3, ksp_dims + 3));

	md_singleton_dims(ND, data->trj_dims);
	md_copy_dims(N, data->trj_dims, traj_dims);


	// get strides

	md_calc_strides(ND, data->cim_strs, data->cim_dims, CFL_SIZE);
	md_calc_strides(ND, data->img_strs, data->img_dims, CFL_SIZE);
	md_calc_strides(ND, data->trj_strs, data->trj_dims, CFL_SIZE);
	md_calc_strides(ND, data->ksp_strs, data->ksp_dims, CFL_SIZE);


	data->weights = NULL;

	if (NULL != weights) {

		md_singleton_dims(ND, data->wgh_dims);
		md_select_dims(N, ~MD_BIT(0), data->wgh_dims, data->trj_dims);
		md_calc_strides(ND, data->wgh_strs, data->wgh_dims, CFL_SIZE);

		complex float* tmp = md_alloc(ND, data->wgh_dims, CFL_SIZE);
		md_copy(ND, data->wgh_dims, tmp, weights, CFL_SIZE);
		data->weights = tmp;
	}


	complex float* roll = md_alloc(ND, data->img_dims, CFL_SIZE);
	rolloff_correction(2., data->width, data->beta, data->img_dims, roll);
	data->roll = roll;


	complex float* linphase = compute_linphases(N, data->lph_dims, data->img_dims);

	md_calc_strides(ND, data->lph_strs, data->lph_dims, CFL_SIZE);

	if (!conf.toeplitz)
		md_zmul2(ND, data->lph_dims, data->lph_strs, linphase, data->lph_strs, linphase, data->img_strs, data->roll);


	fftmod(ND, data->lph_dims, FFT_FLAGS, linphase, linphase);
	fftscale(ND, data->lph_dims, FFT_FLAGS, linphase, linphase);
//	md_zsmul(ND, data->lph_dims, linphase, linphase, 1. / (float)(data->trj_dims[1] * data->trj_dims[2]));

	complex float* fftm = md_alloc(ND, data->img_dims, CFL_SIZE);
	md_zfill(ND, data->img_dims, fftm, 1.);
	fftmod(ND, data->img_dims, FFT_FLAGS, fftm, fftm);
	data->fftmod = fftm;



	data->linphase = linphase;
	data->psf = NULL;

	if (conf.toeplitz) {

#if 0
		md_copy_dims(ND, data->psf_dims, data->lph_dims);
#else
		md_copy_dims(3, data->psf_dims, data->lph_dims);
		md_copy_dims(ND - 3, data->psf_dims + 3, data->trj_dims + 3);
		data->psf_dims[N] = data->lph_dims[N];
#endif
		md_calc_strides(ND, data->psf_strs, data->psf_dims, CFL_SIZE);
		data->psf = compute_psf2(N, data->psf_dims, data->trj_dims, data->traj, data->weights);
	}


	md_copy_dims(ND, data->cml_dims, data->cim_dims);
	data->cml_dims[N + 0] = data->lph_dims[N + 0];

	md_calc_strides(ND, data->cml_strs, data->cml_dims, CFL_SIZE);


	data->cm2_dims = xmalloc(ND * sizeof(long));
	// !
	md_copy_dims(ND, data->cm2_dims, data->cim_dims);
	for (int i = 0; i < 3; i++)
		data->cm2_dims[i] = (1 == cim_dims[i]) ? 1 : (2 * cim_dims[i]);



	data->grid = md_alloc(ND, data->cml_dims, CFL_SIZE);

	data->fft_op = linop_fft_create(ND, data->cml_dims, FFT_FLAGS, use_gpu);



	return linop_create(N, ksp_dims, N, cim_dims,
		data, nufft_apply, nufft_apply_adjoint, nufft_apply_normal, NULL, nufft_free_data);
}
示例#25
0
文件: estdelay.c 项目: mrirecon/bart
// [RING] Caclucate intersection points
static void calc_intersections(unsigned int Nint, unsigned int N, unsigned int no_intersec_sp, float dist[2][Nint], long idx[2][Nint], const float angles[N], const long kc_dims[DIMS], const complex float* kc, const int ROI)
{
	long spoke_dims[DIMS];
	md_copy_dims(DIMS, spoke_dims, kc_dims);
	spoke_dims[PHS2_DIM] = 1;

	complex float* spoke_i = md_alloc(DIMS, spoke_dims, CFL_SIZE);
	complex float* spoke_j = md_alloc(DIMS, spoke_dims, CFL_SIZE);

	long pos_i[DIMS] = { 0 };
	long pos_j[DIMS] = { 0 };

	long coilPixel_dims[DIMS];
	md_copy_dims(DIMS, coilPixel_dims, spoke_dims);
	coilPixel_dims[PHS1_DIM] = 1;

	complex float* coilPixel_l = md_alloc(DIMS, coilPixel_dims, CFL_SIZE);
	complex float* coilPixel_m = md_alloc(DIMS, coilPixel_dims, CFL_SIZE);
	complex float* diff = md_alloc(DIMS, coilPixel_dims, CFL_SIZE);

	long diff_rss_dims[DIMS];
	md_copy_dims(DIMS, diff_rss_dims, coilPixel_dims);
	diff_rss_dims[COIL_DIM] = 1;
	diff_rss_dims[PHS1_DIM] = 1;

	complex float* diff_rss = md_alloc(DIMS, diff_rss_dims, CFL_SIZE);

	long pos_l[DIMS] = { 0 };
	long pos_m[DIMS] = { 0 };

	// Array to store indices of spokes that build an angle close to pi/2 with the current spoke
	long intersec_sp[no_intersec_sp];

	for (unsigned int i = 0; i < no_intersec_sp; i++)
		intersec_sp[i] = -1;

	// Boundaries for spoke comparison
	int myROI = ROI;

	myROI += (ROI % 2 == 0) ? 1 : 0; // make odd

	int low = 0;
	int high = myROI - 1;

	int count = 0;

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

		pos_i[PHS2_DIM] = i;

		md_slice(DIMS, PHS2_FLAG, pos_i, kc_dims, spoke_i, kc, CFL_SIZE);

		find_intersec_sp(no_intersec_sp, intersec_sp, i, N, angles);

		for (unsigned int j = 0; j < no_intersec_sp; j++) {

			pos_j[PHS2_DIM] = intersec_sp[j];

			md_slice(DIMS, PHS2_FLAG, pos_j, kc_dims, spoke_j, kc, CFL_SIZE);

			idx[0][i * no_intersec_sp + j] = i;
			idx[1][i * no_intersec_sp + j] = intersec_sp[j];

			// Elementwise rss comparisson
			float rss = FLT_MAX;

			for (int l = low; l <= high; l++) {

				pos_l[PHS1_DIM] = l;
				md_copy_block(DIMS, pos_l, coilPixel_dims, coilPixel_l, spoke_dims, spoke_i, CFL_SIZE);

				for (int m = low; m <= high; m++) {

					pos_m[PHS1_DIM] = m;

					md_copy_block(DIMS, pos_m, coilPixel_dims, coilPixel_m, spoke_dims, spoke_j, CFL_SIZE);
					md_zsub(DIMS, coilPixel_dims, diff, coilPixel_l, coilPixel_m);

					md_zrss(DIMS, coilPixel_dims, PHS1_FLAG|COIL_FLAG, diff_rss, diff);

					if (cabsf(diff_rss[0]) < rss) { // New minimum found

						rss = cabsf(diff_rss[0]);
						dist[0][i * no_intersec_sp + j] = (l + 1/2 - ROI/2);
						dist[1][i * no_intersec_sp + j] = (m + 1/2 - ROI/2);
					}
				}
			}

			count++;
		}
	}

#ifdef RING_PAPER
	// Print projection angles and corresponding offsets to files

	const char* idx_out = "projangle.txt";
	FILE* fp = fopen(idx_out, "w");

	const char* d_out = "offset.txt";
	FILE* fp1 = fopen(d_out, "w");

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

		for (unsigned int j = 0; j < no_intersec_sp; j++) {

			fprintf(fp, "%f \t %f\n", angles[idx[0][i * no_intersec_sp + j]], angles[idx[1][i * no_intersec_sp + j]]);
			fprintf(fp1, "%f \t %f\n", dist[0][i * no_intersec_sp + j], dist[1][i * no_intersec_sp + j]);
		}
	}

	fclose(fp);
	fclose(fp1);
#endif

	md_free(spoke_i);
	md_free(spoke_j);
	md_free(coilPixel_l);
	md_free(coilPixel_m);
	md_free(diff);
	md_free(diff_rss);
}
示例#26
0
文件: pocsense.c 项目: cbasasif/bart
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 {
示例#27
0
文件: homodyne.c 项目: cbasasif/bart
int main_homodyne(int argc, char* argv[])
{
	bool clear = false;
	bool image = false;
	const char* phase_ref = NULL;

	float alpha = 0.;

	num_init();

	const struct opt_s opts[] = {

		{ 'r', true, opt_float, &alpha, " <alpha>\tOffset of ramp filter, between 0 and 1. alpha=0 is a full ramp, alpha=1 is a horizontal line" },
		{ 'I', false, opt_set, &image, "\tInput is in image domain" },
		{ 'C', false, opt_set, &clear, "\tClear unacquired portion of kspace" },
		{ 'P', true, opt_string, &phase_ref, " <phase_ref>\tUse <phase_ref> as phase reference" },
	};

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


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

	if (image) {
		complex float* ksp_in = md_alloc(N, dims, CFL_SIZE);
		fftuc(N, dims, FFT_FLAGS, ksp_in, idata);
		md_copy(N, dims, idata, ksp_in, CFL_SIZE);
		md_free(ksp_in);
	}


	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);
	wdata.alpha = alpha;
	wdata.clear = clear;

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

	homodyne(wdata, FFT_FLAGS, N, dims, strs, data, idata, pstrs, phase);

	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);
}
示例#28
0
文件: model.c 项目: cbasasif/bart
struct noir_data* noir_init(const long dims[DIMS], const complex float* mask, const complex float* psf, bool rvc, bool use_gpu)
{
#ifdef USE_CUDA
	md_alloc_fun_t my_alloc = use_gpu ? md_alloc_gpu : md_alloc;
#else
	assert(!use_gpu);
	md_alloc_fun_t my_alloc = md_alloc;
#endif

	PTR_ALLOC(struct noir_data, data);


	data->rvc = rvc;

	md_copy_dims(DIMS, data->dims, dims);

	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG|CSHIFT_FLAG, data->sign_dims, dims);
	md_calc_strides(DIMS, data->sign_strs, data->sign_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, data->coil_dims, dims);
	md_calc_strides(DIMS, data->coil_strs, data->coil_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|CSHIFT_FLAG, data->imgs_dims, dims);
	md_calc_strides(DIMS, data->imgs_strs, data->imgs_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG, data->data_dims, dims);
	md_calc_strides(DIMS, data->data_strs, data->data_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS, data->mask_dims, dims);
	md_calc_strides(DIMS, data->mask_strs, data->mask_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS, data->wght_dims, dims);
	md_calc_strides(DIMS, data->wght_strs, data->wght_dims, CFL_SIZE);

	md_select_dims(DIMS, FFT_FLAGS|CSHIFT_FLAG, data->ptrn_dims, dims);
	md_calc_strides(DIMS, data->ptrn_strs, data->ptrn_dims, CFL_SIZE);


	complex float* weights = md_alloc(DIMS, data->wght_dims, CFL_SIZE);

	noir_calc_weights(dims, weights);
	fftmod(DIMS, data->wght_dims, FFT_FLAGS, weights, weights);
	fftscale(DIMS, data->wght_dims, FFT_FLAGS, weights, weights);

	data->weights = weights;

#ifdef USE_CUDA
	if (use_gpu) {

		data->weights = md_gpu_move(DIMS, data->wght_dims, weights, CFL_SIZE);
	}
#endif


	complex float* ptr = my_alloc(DIMS, data->ptrn_dims, CFL_SIZE);

	md_copy(DIMS, data->ptrn_dims, ptr, psf, CFL_SIZE);
	fftmod(DIMS, data->ptrn_dims, FFT_FLAGS, ptr, ptr);

	data->pattern = ptr;

	complex float* msk = my_alloc(DIMS, data->mask_dims, CFL_SIZE);

	if (NULL == mask) {

		assert(!use_gpu);
		md_zfill(DIMS, data->mask_dims, msk, 1.);

	} else {

		md_copy(DIMS, data->mask_dims, msk, mask, CFL_SIZE);
	}

//	fftmod(DIMS, data->mask_dims, 7, msk, msk);
	fftscale(DIMS, data->mask_dims, FFT_FLAGS, msk, msk);

	data->mask = msk;

	data->sens = my_alloc(DIMS, data->coil_dims, CFL_SIZE);
	data->xn = my_alloc(DIMS, data->imgs_dims, CFL_SIZE);
	data->tmp = my_alloc(DIMS, data->sign_dims, CFL_SIZE);

	return data;
}
示例#29
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_ecaltwo(int argc, char* argv[])
{
	long maps = 2; // channels;
	struct ecalib_conf conf = ecalib_defaults;

	int c;
	while (-1 != (c = getopt(argc, argv, "OSc:m:gh"))) {

		switch (c) {

		case 'S':
			conf.softcrop = true;
			break;

		case 'O':
			conf.orthiter = false;
			break;

		case 'c':
			conf.crop = atof(optarg);
			break;

		case 'm':
			maps = atoi(optarg);
			break;

		case 'g':
			conf.usegpu = true;
			break;
			
		case 'h':
			usage(argv[0], stdout);
			help();
			exit(0);

		default:
			usage(argv[0], stderr);
			exit(1);
		}
	}

	if ((argc - optind != 5) && (argc - optind != 6)) {

		usage(argv[0], stderr);
		exit(1);
	}

	long in_dims[DIMS];

	complex float* in_data = load_cfl(argv[optind + 3], DIMS, in_dims);

	int channels = 0;

	while (in_dims[3] != (channels * (channels + 1) / 2))
		channels++;

	printf("Channels: %d\n", channels);

	assert(maps <= channels);


	long out_dims[DIMS] = { [0 ... DIMS - 1] = 1 };
	long map_dims[DIMS] = { [0 ... DIMS - 1] = 1 };
	
	out_dims[0] = atoi(argv[optind + 0]);
	out_dims[1] = atoi(argv[optind + 1]);
	out_dims[2] = atoi(argv[optind + 2]);
	out_dims[3] = channels;
	out_dims[4] = maps;

	assert((out_dims[0] >= in_dims[0]));
	assert((out_dims[1] >= in_dims[1]));
	assert((out_dims[2] >= in_dims[2]));


	for (int i = 0; i < 3; i++)
		map_dims[i] = out_dims[i];

	map_dims[3] = 1;
	map_dims[4] = maps;


	complex float* out_data = create_cfl(argv[optind + 4], DIMS, out_dims);
	complex float* emaps;

	if (6 == argc - optind)
		emaps = create_cfl(argv[optind + 5], DIMS, map_dims);
	else
		emaps = md_alloc(DIMS, map_dims, CFL_SIZE);

	caltwo(&conf, out_dims, out_data, emaps, in_dims, in_data, NULL, NULL);

	if (conf.intensity) {

		debug_printf(DP_DEBUG1, "Normalize...\n");

		normalizel1(DIMS, COIL_FLAG, out_dims, out_data);
	}

	debug_printf(DP_DEBUG1, "Crop maps... (%.2f)\n", conf.crop);

	crop_sens(out_dims, out_data, conf.softcrop, conf.crop, emaps);

	debug_printf(DP_DEBUG1, "Fix phase...\n");

	fixphase(DIMS, out_dims, COIL_DIM, out_data, out_data);

	printf("Done.\n");

	unmap_cfl(DIMS, in_dims, in_data);
	unmap_cfl(DIMS, out_dims, out_data);

	if (6 == argc - optind)
		unmap_cfl(DIMS, map_dims, emaps);
	else
		md_free(emaps);

	exit(0);
}