From 9e565d83312366e2e89e10e286ce38413f983374 Mon Sep 17 00:00:00 2001 From: Aaron Ewall-Wice Date: Tue, 4 Aug 2020 21:49:06 -0700 Subject: [PATCH] handle unsupported fit_2d modes and update docstrings. --- uvtools/dspec.py | 19 ++++++++++++++----- uvtools/tests/test_dspec.py | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/uvtools/dspec.py b/uvtools/dspec.py index d18d50e5..0d6d50d6 100644 --- a/uvtools/dspec.py +++ b/uvtools/dspec.py @@ -281,6 +281,13 @@ def fourier_filter(x, data, wgts, filter_centers, filter_half_widths, mode, max_contiguous_edge_flags : int, optional if the number of contiguous samples at the edge is greater then this at either side, skip. + filt2d_mode, string optional + can be in {"rect", "outer"}. If "rect" treat each filter center and filter width in time as defining the bounds + of a separate rectangle that is independently fitted and subtracted from the data in Fourier space. If "outer" + then remove all combinations of rectangular regions that arise from the provided list of time and frequency + regions. Default is "outer". + cache : dict, optional + dictionary for caching fitting matrices. * dayenu : cache : dict, optional dictionary for caching fitting matrices. @@ -303,6 +310,11 @@ def fourier_filter(x, data, wgts, filter_centers, filter_half_widths, mode, max_contiguous_edge_flags : int, optional if the number of contiguous samples at the edge is greater then this at either side, skip. + filt2d_mode, string optional + can be in {"rect", "outer"}. If "rect" treat each filter center and filter width in time as defining the bounds + of a separate rectangle that is independently fitted and subtracted from the data in Fourier space. If "outer" + then remove all combinations of rectangular regions that arise from the provided list of time and frequency + regions. Default is "outer". cache : dict, optional dictionary for caching fitting matrices. * clean : @@ -1816,21 +1828,17 @@ def _fit_basis_2d(x, data, wgts, filter_centers, filter_half_widths, using scipy.optimize.leastsq *'matrix' derive model by directly calculate the fitting matrix [A^T W A]^{-1} A^T W and applying it to the y vector. - filter_dim, int optional specify dimension to filter. default 1, and if 2d filter, will use both dimensions. - filt2d_mode, string optional can be in {"rect", "outer"}. If "rect" treat each filter center and filter width in time as defining the bounds of a separate rectangle that is independently fitted and subtracted from the data in Fourier space. If "outer" then remove all combinations of rectangular regions that arise from the provided list of time and frequency regions. Default is "outer". - skip_wgt: skips filtering rows with very low total weight (unflagged fraction ~< skip_wgt). Model is left as 0s, residual is left as data, and info is {'skipped': True} for that time. Only works properly when all weights are all between 0 and 1. - max_contiguous_edge_flags : int, optional if the number of contiguous samples at the edge is greater then this at either side, skip . @@ -1982,7 +1990,8 @@ def _fit_basis_2d(x, data, wgts, filter_centers, filter_half_widths, # and add the model to the overall model. model += model_temp # repeate this for all the rectangle bounds provided. - + else: + raise ValueError("%s not a supported filt2d_mode ('rect', 'outer')"%filt2d_mode) residual = (data - model) * (np.abs(wgts) > 0).astype(float) #this will only happen if filter_dims is only zero! if filter_dims[0] == 0: diff --git a/uvtools/tests/test_dspec.py b/uvtools/tests/test_dspec.py index 0d0c2e80..8c69787e 100644 --- a/uvtools/tests/test_dspec.py +++ b/uvtools/tests/test_dspec.py @@ -894,6 +894,7 @@ def get_snr(clean, fftax=1, avgax=0, modes=[2, 20]): # check that 2d clean with single rectangular region is the same for outer and rect filter2d modes. dpss_options1_2d = {'eigenval_cutoff': [[1e-12], [1e-12]], 'filt2d_mode': 'rect'} dpss_options2_2d = {'eigenval_cutoff': [[1e-12], [1e-12]], 'filt2d_mode': 'outer'} + dpss_options3_2d = {'eigenval_cutoff': [[1e-12], [1e-12]], 'filt2d_mode': 'plus'} mdl1, res1, info1 = 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]], mode='dayenu_dpss_leastsq', filter_dims=[1, 0], **dpss_options1_2d) @@ -902,6 +903,10 @@ def get_snr(clean, fftax=1, avgax=0, modes=[2, 20]): mode='dayenu_dpss_leastsq', filter_dims=[1, 0], **dpss_options2_2d) nt.assert_true(np.all(np.isclose(mdl1, mdl2))) nt.assert_true(np.all(np.isclose(res1, res2))) + # assert ValueError for unsupported filt2d_mode + nt.assert_raises(ValueError, 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]], + mode='dayenu_dpss_leastsq', filter_dims=[1, 0], **dpss_options3_2d) def test_vis_clean(): # validate that fourier_filter in various clean modes gives close values to vis_clean with equivalent parameters!