Example #1
0
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[] = {

		OPT_FLOAT('l', &l1, "lambda", ""),
		OPT_INT('i', &iter, "iter", ""),
		OPT_SET('c', &rvc, ""),
		OPT_CLEAR('N', &normalize, ""),
		OPT_FLOAT('f', &restrict_fov, "FOV", ""),
		OPT_STRING('p', &psf, "PSF", ""),
		OPT_SET('g', &usegpu, "use gpu"),
	};

	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 = ((4 == argc) ? create_cfl : anon_cfl)((4 == argc) ? argv[3] : "", DIMS, ksp_dims);


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

	if (NULL != psf) {

		pattern = load_cfl(psf, DIMS, pat_dims);

		// FIXME: check compatibility
	} else {

		md_copy_dims(DIMS, pat_dims, img_dims);
		pattern = anon_cfl("", DIMS, pat_dims);
		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);
	}


	md_free(norm);
	md_free(mask);

	unmap_cfl(DIMS, ksp_dims, sens);
	unmap_cfl(DIMS, pat_dims, pattern);
	unmap_cfl(DIMS, img_dims, image);
	unmap_cfl(DIMS, ksp_dims, kspace_data);
	exit(0);
}
int main_homodyne(int argc, char* argv[])
{
	bool clear = false;
	const char* phase_ref = NULL;

	int com;
	while (-1 != (com = getopt(argc, argv, "hCP:"))) {

		switch (com) {

		case 'C':
			clear = true;
			break;

		case 'P':
			phase_ref = strdup(optarg);
			break;

		case 'h':
			help(argv[0], stdout);
			exit(0);

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

	if (argc - optind != 4) {
		usage(argv[0], stderr);
		exit(1);
	}

	const int N = DIMS;
	long dims[N];
	complex float* idata = load_cfl(argv[optind + 2], N, dims);
	complex float* data = create_cfl(argv[optind + 3], N, dims);

	int pfdim = atoi(argv[optind + 0]);
	float frac = atof(argv[optind + 1]);

	assert((0 <= pfdim) && (pfdim < N));
	assert(frac > 0.);


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

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

	complex float* cdata = NULL;
	complex float* idata2 = NULL;

	if (clear) {

		long cdims[N];
		md_select_dims(N, ~MD_BIT(pfdim), cdims, dims);
		cdims[pfdim] = (int)(dims[pfdim] * frac);

		cdata = md_alloc(N, cdims, CFL_SIZE);
		idata2 = anon_cfl(NULL, N, dims);

		md_resize(N, cdims, cdata, dims, idata, CFL_SIZE);
		md_resize(N, dims, idata2, cdims, cdata, CFL_SIZE);

		md_free(cdata);
		unmap_cfl(N, dims, idata);
		idata = idata2;

	}


	if ((1 == dims[PHS2_DIM]) || (PHS2_DIM == pfdim)) {

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

	} else {

		unsigned int pardim = PHS2_DIM;

		ifftuc(N, dims, MD_CLEAR(FFT_FLAGS, pfdim), data, idata);

		long rdims[N];
		md_select_dims(N, ~MD_BIT(pardim), rdims, dims);
		long rstrs[N];
		md_calc_strides(N, rstrs, rdims, CFL_SIZE);

#pragma 	omp parallel for
		for (unsigned int i = 0; i < dims[pardim]; i++) {

			complex float* tmp = md_alloc(N, rdims, CFL_SIZE);
			long pos[N];
			md_set_dims(N, pos, 0);
			pos[pardim] = i;

			md_copy_block(N, pos, rdims, tmp, dims, data, CFL_SIZE);
			homodyne(wdata, MD_BIT(pfdim), N, rdims, rstrs, tmp, tmp, pstrs, phase);
			md_copy_block(N, pos, dims, data, rdims, tmp, CFL_SIZE);
			md_free(tmp);
		}
	}

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