diff --git a/.travis.yml b/.travis.yml index 3df7e509..5b15ca73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,6 @@ install: - conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION coverage coveralls - source activate test-environment - conda env update -n test-environment -f environment.yml - - pip install pyradiosky - pip install git+https://github.com/HERA-Team/hera_sim.git - pip install . diff --git a/environment.yml b/environment.yml index 4b4cf633..16d0594d 100644 --- a/environment.yml +++ b/environment.yml @@ -11,4 +11,3 @@ dependencies: - pip - pip: - git+https://github.com/HERA-Team/hera_sim - - git+https://github.com/RadioAstronomySoftwareGroup/pyradiosky diff --git a/uvtools/dspec.py b/uvtools/dspec.py index 4899177e..f014375b 100644 --- a/uvtools/dspec.py +++ b/uvtools/dspec.py @@ -431,9 +431,14 @@ def fourier_filter(x, data, wgts, filter_centers, filter_half_widths, mode, _process_filter_kwargs(filter_kwargs, defaults) if 'dft' in mode: fp = np.asarray(filter_kwargs['fundamental_period']).flatten() - for m in range(len(fp)): - if np.isnan(fp[m]): - fp[m] = 2. * (x[m].max() - x[m].min()) + if filter2d: + for m in range(len(fp)): + if np.isnan(fp[m]): + fp[m] = 2. * (x[m].max() - x[m].min()) + else: + if np.isnan(fp[0]): + fp = [2. * (x.max() - x.min())] + if len(fp) == 1: filter_kwargs['fundamental_period'] = fp[0] else: diff --git a/uvtools/tests/test_dspec.py b/uvtools/tests/test_dspec.py index 27abd029..94a46cf0 100644 --- a/uvtools/tests/test_dspec.py +++ b/uvtools/tests/test_dspec.py @@ -204,6 +204,8 @@ def test_gen_window(self): nt.assert_true(np.all(np.isclose(win, win3*np.sqrt(np.mean(win**2.)),atol=1e-6))) nt.assert_raises(ValueError, dspec.gen_window, 'foo', 200) + # check Ncut ValueError + nt.assert_raises(ValueError, dspec.gen_window, 'bh', 200, edgecut_hi=101, edgecut_low=100) def test_dft_operator(): @@ -358,7 +360,10 @@ def test_dayenu_filter(): nt.assert_raises(ValueError, dspec.dayenu_filter, x=np.arange(-nf/2, nf/2)*df, data=data_1d, wgts=wghts_1d, filter_dimensions=[2], filter_centers=filter_centers, filter_half_widths=filter_half_widths, filter_factors=filter_factors) - + # check error if negative filter_factor provided + nt.assert_raises(ValueError, dspec.dayenu_filter, x=np.arange(-nf/2, nf/2)*df, data=data_1d, wgts=wghts_1d, filter_dimensions=[0], + filter_centers=filter_centers, filter_half_widths=filter_half_widths, + filter_factors=[-1e-9]) #now filter foregrounds and test that std of residuals are close to std of noise: filtered_noise, _ = dspec.dayenu_filter(np.arange(-nf/2, nf/2)*df, data_1d, wghts_1d, [1], filter_centers, filter_half_widths, filter_factors) @@ -381,6 +386,7 @@ def test_dayenu_filter(): nt.assert_true(np.all(filtered_noise[~(wghts_1d.astype(bool))] == 0.)) + #Next, we test performing a fringe-rate clean. Generate a 50-meter EW baseline with a single #source moving overhead perpindicular to baseline TEST_CACHE = {} @@ -402,6 +408,10 @@ def test_dayenu_filter(): nt.assert_raises(ValueError, dspec.dayenu_filter, x=['time is a construct', np.arange(-nf/2, nf/2)*df], data=data_2d, wgts=np.ones_like(data_2d), filter_dimensions=[1, 0], filter_centers=[[0.],[0.]], filter_half_widths=[[1e-3], [100e-9]], filter_factors=[[1e-9], [1e-9]]) + # check value error if length of one of the filter_centers is greater then 2 + nt.assert_raises(ValueError, dspec.dayenu_filter, x=[times, np.arange(-nf/2, nf/2)*df], data=data_2d, wgts=np.ones_like(data_2d), filter_dimensions=[1, 0], + filter_centers=[[0.], [0.]], filter_half_widths=[[1e-3], [100e-9]], + filter_factors=[[1e-9], [1e-9], [1e-9]]) #now, only filter fringe-rate domain. The fringe rate for a source #overhead should be roughly 0.0036 for this baseline. @@ -797,6 +807,24 @@ def get_snr(clean, fftax=1, avgax=0, modes=[2, 20]): #check that fringe rate filter model gives similar results to delay filter. nt.assert_true(np.all(np.isclose(mdl1[~f],mdl5[~f], rtol=1e-2))) + + #perform some sanity checks on handling of nans in dft_leastsq. If nans are present in fundamental period + #then the default behavior should be to set fundamental period to 2 * bandwidth. + mdl, res, info = dspec.fourier_filter(x=freqs, data=d[0], wgts=w[0], filter_centers=[0.], + filter_half_widths=[bl_len], suppression_factors=[1e-9], + mode='dft_leastsq') + # check that the filter_period is indeed equal to 1 / (2 * bandwidth) + nt.assert_true(np.isclose(info['filter_params']['axis_1']['basis_options']['fundamental_period'], + 2 * (freqs.max() - freqs.min()))) + + #check that user provided fundamental period agrees with whats in info. + mdl, res, info = dspec.fourier_filter(x=freqs, data=d[0], wgts=w[0], filter_centers=[0.], + filter_half_widths=[bl_len], suppression_factors=[1e-9], + mode='dft_leastsq', fundamental_period=4. * (freqs.max() - freqs.min())) + # check that the filter_period is indeed equal to 1 / (2 * bandwidth) + nt.assert_true(np.isclose(info['filter_params']['axis_1']['basis_options']['fundamental_period'], + 4. * (freqs.max() - freqs.min()))) + #check fringe rate filter with dft mode mdl6, res6, info6 = dspec.fourier_filter(x=times, data=d, wgts=w, filter_centers=[0.], filter_half_widths=[fr_len], suppression_factors=[0.], filter_dims=0, @@ -833,6 +861,7 @@ def get_snr(clean, fftax=1, avgax=0, modes=[2, 20]): #perform 2d dayenu filter with dpss and dft deconvolution. dpss_options1_2d = {'eigenval_cutoff': [[1e-12], [1e-12]]} dft_options1_2d = {'fundamental_period': [np.nan, np.nan]} + dft_options2_2d = {'fundamental_period': [4 * (times.max() - times.min()), 4 * (freqs.max() - freqs.min())]} mdl9, res9, info9 = dspec.fourier_filter(x=[times, freqs], data=d, wgts=w, filter_centers=[[0.],[0.]], filter_half_widths=[[fr_len],[bl_len]], suppression_factors=[[1e-8],[1e-8]], @@ -890,6 +919,17 @@ def get_snr(clean, fftax=1, avgax=0, modes=[2, 20]): nt.assert_raises(ValueError, dspec.fourier_filter,x=flog, data=d, wgts=w, filter_centers=[0.], filter_half_widths=[bl_len], mode='clean', filter_dims=[1], **{'tol':1e-5}) + + # check that fundamental period in 2d dft fit is correctly assigned. + mdl_dft, res_dft, info_dft = dspec.fourier_filter(x=[times, freqs], data=d, wgts=w, filter_centers=[[0.],[0.]], + filter_half_widths=[[fr_len],[bl_len]], suppression_factors=[[0.],[0.]], + mode='dft_leastsq', filter_dims=[1, 0], **dft_options2_2d) + + nt.assert_true(np.isclose(info_dft['filter_params']['axis_1']['basis_options']['fundamental_period'], + dft_options2_2d['fundamental_period'][1])) + nt.assert_true(np.isclose(info_dft['filter_params']['axis_0']['basis_options']['fundamental_period'], + dft_options2_2d['fundamental_period'][0])) + def test_vis_clean(): # validate that fourier_filter in various clean modes gives close values to vis_clean with equivalent parameters! uvd = UVData()