sinusoid_t
calculate_refined_sinusoid_parameters(track_t *t, track_point_t *tp) {
	sinusoid_t s;
	int n_bins = t->fft.n_bins;
	dp(29, "power[%d]=%g\n", tp->bin, power_t_to_double(tp->power[1]));
  	double frequency_delta = parabolic_frequency_interpolation(tp->power, 1);
	s.frequency = (tp->bin + frequency_delta)/(2.0*n_bins);
	dp(28, "frequency_delta=%g frequency %g -> %g\n", frequency_delta, tp->bin/(2.0*n_bins), s.frequency);
	double corrected_power = parabolic_amplitude_interpolation(tp->power, 1);
 	double amplitude_correction = w(2*n_bins,M_PI*frequency_delta/n_bins)/n_bins;
	s.amplitude = sqrt(1.49*corrected_power/n_bins); // FIXME -   1.49 is an experimentally determined kludge
	dp(28, "amplitude correction %g s.amplitude=%g\n", amplitude_correction, s.amplitude);
	s.phase = tp->phase[1] ? estimate_phase(1, frequency_delta, tp->phase) : 0;
	return s;
}
sinusoid_t
estimate_sinusoid_parameters(int bin, int n_bins, power_t power[n_bins], phase_t phase[n_bins], int approximate) {
	sinusoid_t s;
	if (approximate) {
		s.frequency = bin/(2.0*n_bins);
		s.amplitude = 1;
		s.phase = 0;
		return s;
	}
	dp(29, "power[%d]=%g\n", bin, power_t_to_double(power[bin]));
  	double frequency_delta = parabolic_frequency_interpolation(power, bin);
	s.frequency = (bin + frequency_delta)/(2.0*n_bins);
	dp(28, "frequency_delta=%g frequency %g -> %g\n", frequency_delta, bin/(2.0*n_bins), s.frequency);
	double corrected_power = parabolic_amplitude_interpolation(power, bin);
 	double amplitude_correction = w(2*n_bins,M_PI*frequency_delta/n_bins)/n_bins;
	s.amplitude = sqrt(1.49*corrected_power/n_bins); // FIXME -   1.49 is an experimentally determined kludge
	dp(28, "amplitude correction %g s.amplitude=%g\n", amplitude_correction, s.amplitude);
	s.phase = phase ? estimate_phase(bin, frequency_delta, phase) : 0;
	return s;
}
Пример #3
0
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);
}
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);
}