From ef36bb000b02cf816a55ab5d8e58333b27aec01f Mon Sep 17 00:00:00 2001 From: texadactyl Date: Wed, 20 Jul 2022 16:35:36 -0500 Subject: [PATCH 1/3] Fix issue #264 --- tests/test_waterfall2.py | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/test_waterfall2.py diff --git a/tests/test_waterfall2.py b/tests/test_waterfall2.py new file mode 100644 index 0000000..c968d86 --- /dev/null +++ b/tests/test_waterfall2.py @@ -0,0 +1,48 @@ +import numpy as np +from astropy import units as u +from astropy.coordinates import Angle +import blimpy as bl +from tests.data import voyager_h5 + +def test_waterfall_stream_1(): + + print("\n===== test_waterfall_stream_1") + + source_name = "Not_Voyager_1" + src_raj = Angle("17:10:03.984 hours") + src_dej = Angle("12:10:58.8 degrees") + tstart = 57650.78209490741 + tsamp = 18.253611008 + f_start = 8418.457032646984 + f_stop = 8421.386717353016 + n_fine_chans = 20 + n_tints = 8 + + foff = (f_stop - f_start) / float(n_fine_chans) + + header = {"az_start": 0.0, "data_type": 1, + "fch1": f_start, "foff": foff, + "ibeam": 1, "machine_id": 42, "nbeams": 1, "nbits": 32, + "nchans": n_fine_chans, "nifs": 1, "rawdatafile": "nil", + "source_name": source_name, "src_raj": src_raj, "src_dej": src_dej, + "telescope_id": 42, + "tstart": tstart, "tsamp": tsamp, "zs_tart": 0.0} + + data_matrix = np.zeros((n_tints, 1, n_fine_chans), dtype=np.float32) + + wf = bl.Waterfall(header_dict=header, data_array=data_matrix) + print("\nwf:", wf) + wf.info() + + +def test_waterfall_stream_2(): + + print("\n===== test_waterfall_stream_2") + wf_voya1 = bl.Waterfall(voyager_h5) + wf_voya2 = bl.Waterfall(header_dict=wf_voya1.header, data_array=wf_voya1.data) + wf_voya2.info() + + +if __name__ == "__main__": + test_waterfall_stream_1() + test_waterfall_stream_2() From 3492343c100964d3801056ee2c69f01613d28c81 Mon Sep 17 00:00:00 2001 From: texadactyl Date: Wed, 20 Jul 2022 16:37:53 -0500 Subject: [PATCH 2/3] Fix issue #264 --- VERSION-HISTORY.md | 1 + blimpy/waterfall.py | 75 ++++++++++++++++++++++++++++++++++++++--- setup.py | 2 +- tests/test_waterfall.py | 12 ------- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/VERSION-HISTORY.md b/VERSION-HISTORY.md index d56f44e..7f6305c 100644 --- a/VERSION-HISTORY.md +++ b/VERSION-HISTORY.md @@ -3,6 +3,7 @@ This file is a version history of blimpy amendments, beginning with version 2.0.
| Date | Version | Contents | | :--: | :--: | :-- | +| 2022-07-20 | 2.1.1 | New WaterfallStream class, an alternative to file loading (issue #264). | | 2022-07-08 | 2.1.0 | New utility: dsamp (issue #267). | | 2022-04-19 | 2.0.40 | Fixed blimpy to show plots when the display supports it (issue #263). | | 2022-03-30 | 2.0.39 | examine_h5 in hdf_reader.py is loading too much data (issue #261). | diff --git a/blimpy/waterfall.py b/blimpy/waterfall.py index c622299..88bd593 100755 --- a/blimpy/waterfall.py +++ b/blimpy/waterfall.py @@ -60,9 +60,73 @@ class Waterfall(): """ Class for loading and writing blimpy data (.fil, .h5) """ + def __repr__(self): return "Waterfall data: %s" % self.filename + + def _init_alternate(self, header_dict, data, filename=None): + + # Validate parameters. + assert filename is None + assert isinstance(header_dict, dict) + assert "nchans" in header_dict + assert "fch1" in header_dict + assert data.ndim == 3 + assert data.shape[1] == 1 + + # Set dummy-file Waterfall object properties. + self.filename = None + self.ext = self.filename + self.file_shape = self.filename + self.file_size_bytes = 0 + + # The Waterfall "container": + class Container(): + n_beams_in_file = 1 + n_pols_in_file = 1 + _d_type = np.float32 + t_begin = 0 + freq_axis = 2 + time_axis = 0 + beam_axis = 1 + self.container = Container() + self.container.n_channels_in_file = header_dict["nchans"] + self.container._n_bytes = int(header_dict["nbits"] / 8) # number of bytes per digit. + if header_dict['foff'] < 0: + self.container.f_end = header_dict['fch1'] + self.container.f_begin = self.container.f_end + self.container.n_channels_in_file * header_dict['foff'] + else: + self.container.f_begin = header_dict['fch1'] + self.container.f_end = self.container.f_begin + self.container.n_channels_in_file * header_dict['foff'] + self.container.f_start = self.container.f_begin + self.container.f_stop = self.container.f_end + self.container.t_end = data.shape[0] + + # Set Waterfall object properties. + self.header = header_dict + self.file_header = header_dict + self.n_ints_in_file = data.shape[0] + self.selection_shape = data.shape + self.n_channels_in_file = header_dict["nchans"] + self.freq_axis = 2 + self.time_axis = 0 + self.beam_axis = 1 + self.stokes_axis = 4 + self.logger = logger + + # Attach data matrix. + self.data = data + + # Attach plotting methods. + self.plot_spectrum = six.create_bound_method(plot_spectrum, self) + self.plot_waterfall = six.create_bound_method(plot_waterfall, self) + self.plot_kurtosis = six.create_bound_method(plot_kurtosis, self) + self.plot_time_series = six.create_bound_method(plot_time_series, self) + self.plot_all = six.create_bound_method(plot_all, self) + self.plot_spectrum_min_max = six.create_bound_method(plot_spectrum_min_max, self) + + def __init__(self, filename=None, f_start=None, f_stop=None, t_start=None, t_stop=None, load_data=True, max_load=None, header_dict=None, data_array=None): """ Class for loading and plotting blimpy data. @@ -86,7 +150,8 @@ def __init__(self, filename=None, f_start=None, f_stop=None, t_start=None, t_sto """ if (header_dict is not None) or (data_array is not None): - raise ValueError("Neither header_dict nor data_array is currently supported.") + self._init_alternate(header_dict, data_array, filename=filename) + return if filename is None: raise ValueError("Currently, a value for filename must be supplied.") @@ -192,10 +257,10 @@ def info(self): print("%16s : %32s" % ("File shape", self.file_shape)) print("--- Selection Info ---") print("%16s : %32s" % ("Data selection shape", self.selection_shape)) - if self.header['foff'] < 0: + if self.header['foff'] < 0: # descending frequency values minfreq = self.container.f_start - self.header['foff'] maxfreq = self.container.f_stop - else: + else: # ascending frequency values minfreq = self.container.f_start maxfreq = self.container.f_stop - self.header['foff'] print("%16s : %32s" % ("Minimum freq (MHz)", minfreq)) @@ -336,11 +401,11 @@ def blank_dc(self, n_coarse_chan): if n_coarse_chan < 1: logger.warning('Coarse channel number < 1, unable to blank DC bin.') - return None + return if not n_coarse_chan % int(n_coarse_chan) == 0: logger.warning('Selection does not contain an integer number of coarse channels, unable to blank DC bin.') - return None + return n_coarse_chan = int(n_coarse_chan) diff --git a/setup.py b/setup.py index 322d03e..1851322 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ """ from setuptools import setup, find_packages -__version__ = '2.1.0' +__version__ = '2.1.1' with open("README.md", "r") as fh: long_description = fh.read() diff --git a/tests/test_waterfall.py b/tests/test_waterfall.py index a0f6e6c..347eeb4 100644 --- a/tests/test_waterfall.py +++ b/tests/test_waterfall.py @@ -147,15 +147,3 @@ def test_bug_no_filename(): with pytest.raises(ValueError): bl.Waterfall() -def test_bug_header_dict(): - print("\n===== test_bug_header") - header_dict = { "banana": "is a fruit" } - with pytest.raises(ValueError): - bl.Waterfall(voyager_h5, header_dict=header_dict) - -def test_bug_data_array(): - print("\n===== test_bug_data_array") - data_array = np.arange(1, 11) - with pytest.raises(ValueError): - bl.Waterfall(voyager_h5, data_array=data_array) - From 8f47cfaaa33c6496e7511ab5ab851d9c8b571e93 Mon Sep 17 00:00:00 2001 From: Richard Elkins Date: Wed, 20 Jul 2022 16:40:36 -0500 Subject: [PATCH 3/3] Fix the one-line description for version 2.1.1 --- VERSION-HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION-HISTORY.md b/VERSION-HISTORY.md index 7f6305c..341512b 100644 --- a/VERSION-HISTORY.md +++ b/VERSION-HISTORY.md @@ -3,7 +3,7 @@ This file is a version history of blimpy amendments, beginning with version 2.0.
| Date | Version | Contents | | :--: | :--: | :-- | -| 2022-07-20 | 2.1.1 | New WaterfallStream class, an alternative to file loading (issue #264). | +| 2022-07-20 | 2.1.1 | Mods to Waterfall class, an alternative to file loading (issue #264). | | 2022-07-08 | 2.1.0 | New utility: dsamp (issue #267). | | 2022-04-19 | 2.0.40 | Fixed blimpy to show plots when the display supports it (issue #263). | | 2022-03-30 | 2.0.39 | examine_h5 in hdf_reader.py is loading too much data (issue #261). |