From a4d69b92792a27b758a2b3998385e90098e9b70b Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Mon, 2 Sep 2024 19:31:31 -0400 Subject: [PATCH 01/11] ADD: Auto Read Function --- tests/io/test_auto_read.py | 36 +++++++++ xradar/io/__init__.py | 1 + xradar/io/auto_read.py | 153 +++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 tests/io/test_auto_read.py create mode 100644 xradar/io/auto_read.py diff --git a/tests/io/test_auto_read.py b/tests/io/test_auto_read.py new file mode 100644 index 00000000..ba012eea --- /dev/null +++ b/tests/io/test_auto_read.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright (c) 2022-2024, openradar developers. +# Distributed under the MIT License. See LICENSE for more info. + +from pathlib import Path + +import pytest +from open_radar_data import DATASETS + +import xradar as xd +from xradar.io import read # noqa + + +@pytest.fixture +def test_file(): + """Fixture to provide a valid radar data file for testing.""" + return Path(DATASETS.fetch("KATX20130717_195021_V06")) + + +def test_read_failed_opening(monkeypatch, test_file): + """Test that the read function handles failed opening attempts.""" + + def mock_open_func(file): + raise OSError("Simulated failure") + + # Replace all open functions with the mock that raises an error + monkeypatch.setattr(xd.io, "open_cfradial1_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_datamet_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_furuno_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_gamic_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_hpl_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_iris_datatree", mock_open_func) + monkeypatch.setattr(xd.io, "open_nexradlevel2_datatree", mock_open_func) + + with pytest.raises(ValueError, match="File could not be opened"): + read(test_file, verbose=True) diff --git a/xradar/io/__init__.py b/xradar/io/__init__.py index 560175ef..0935d0af 100644 --- a/xradar/io/__init__.py +++ b/xradar/io/__init__.py @@ -15,5 +15,6 @@ """ from .backends import * # noqa from .export import * # noqa +from .auto_read import * # noqa __all__ = [s for s in dir() if not s.startswith("_")] diff --git a/xradar/io/auto_read.py b/xradar/io/auto_read.py new file mode 100644 index 00000000..d4f0335d --- /dev/null +++ b/xradar/io/auto_read.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# Copyright (c) 2022-2024, openradar developers. +# Distributed under the MIT License. See LICENSE for more info. + +""" +XRadar Auto Reader +================== + +.. autosummary:: + :nosignatures: + :toctree: generated/ + + {} +""" + +__all__ = [ + "read", +] + +__doc__ = __doc__.format("\n ".join(__all__)) + +from .. import io # noqa +import signal + + +# Custom exception for handling timeouts +class TimeoutException(Exception): + pass + + +# Timeout handler +def timeout_handler(signum, frame): + raise TimeoutException("Radar file reading timed out.") + + +# Decorator for handling timeouts +def with_timeout(timeout): + def decorator(func): + def wrapper(*args, **kwargs): + # Set the signal handler and a timeout + signal.signal(signal.SIGALRM, timeout_handler) + signal.alarm(timeout) + try: + return func(*args, **kwargs) + finally: + # Disable the alarm + signal.alarm(0) + + return wrapper + + return decorator + + +def read(file, georeference=True, verbose=False, timeout=None): + """ + Attempt to read a radar file using all available formats in xradar.io. + + This function iterates over all the available file-opening functions in the + xradar.io module and attempts to open the provided radar file. If successful, + it can optionally georeference the data (adding x, y, z coordinates). + + Parameters + ---------- + file : str or Path + The path to the radar file to be read. + georeference : bool, optional + If True, georeference the radar data by adding x, y, z coordinates (default is True). + verbose : bool, optional + If True, prints out detailed processing information (default is False). + timeout : int or None, optional + Timeout in seconds for reading the radar file. If None, no timeout is applied (default is None). + + Returns + ------- + dtree : DataTree + A DataTree object containing the radar data. + + Raises + ------ + ValueError + If the file could not be opened by any supported format in xradar.io. + TimeoutException + If reading the file takes longer than the specified timeout. + + Examples + -------- + >>> file = DATASETS.fetch('KATX20130717_195021_V06') + >>> dtree = xd.io.read(file, verbose=True, timeout=10) + Georeferencing radar data... + File opened successfully using open_nexrad_archive. + + Notes + ----- + This function relies on the `xradar` library to support various radar file formats. + It tries to open the file using all available `open_` functions in the `xradar.io` module. + """ + dtree = None + + # Wrap the read process with a timeout if specified + if timeout: + + @with_timeout(timeout) + def attempt_read(file): + nonlocal dtree + for key in io.__all__: + if "open_" in key: + open_func = getattr(io, key) + try: + dtree = open_func(file) + if georeference: + if verbose: + print("Georeferencing radar data...") + dtree = dtree.xradar.georeference() + if verbose: + print(f"File opened successfully using {key}.") + break + except Exception as e: + if verbose: + print(f"Failed to open with {key}: {e}") + continue + + if dtree is None: + raise ValueError( + "File could not be opened by any supported format in xradar.io." + ) + return dtree + + return attempt_read(file) + + # Normal read process without timeout + for key in io.__all__: + if "open_" in key: + open_func = getattr(io, key) + try: + dtree = open_func(file) + if georeference: + if verbose: + print("Georeferencing radar data...") + dtree = dtree.xradar.georeference() + if verbose: + print(f"File opened successfully using {key}.") + break + except Exception as e: + if verbose: + print(f"Failed to open with {key}: {e}") + continue + + if dtree is None: + raise ValueError( + "File could not be opened by any supported format in xradar.io." + ) + + return dtree From 2a779671f4228bc822635d83c1ff498f109720fc Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Mon, 2 Sep 2024 22:27:04 -0400 Subject: [PATCH 02/11] FIX: Linting issues --- xradar/io/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xradar/io/__init__.py b/xradar/io/__init__.py index 0935d0af..6f37640d 100644 --- a/xradar/io/__init__.py +++ b/xradar/io/__init__.py @@ -15,6 +15,6 @@ """ from .backends import * # noqa from .export import * # noqa -from .auto_read import * # noqa +from .auto_read import * # noqa __all__ = [s for s in dir() if not s.startswith("_")] From 0599ec7e688887de483d46b00c7c76a49d566dfe Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Mon, 2 Sep 2024 23:08:08 -0400 Subject: [PATCH 03/11] FIX: auto_read tests --- tests/io/test_auto_read.py | 106 ++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 24 deletions(-) diff --git a/tests/io/test_auto_read.py b/tests/io/test_auto_read.py index ba012eea..7133a9ab 100644 --- a/tests/io/test_auto_read.py +++ b/tests/io/test_auto_read.py @@ -1,36 +1,94 @@ -#!/usr/bin/env python -# Copyright (c) 2022-2024, openradar developers. -# Distributed under the MIT License. See LICENSE for more info. - -from pathlib import Path +import signal +from unittest.mock import MagicMock, patch import pytest from open_radar_data import DATASETS -import xradar as xd -from xradar.io import read # noqa +from xradar.io import auto_read + + +# Mocked functions for testing +def mock_open_success(file): + mock_dtree = MagicMock(name="DataTree") + return mock_dtree + + +def mock_open_failure(file): + raise ValueError("Failed to open the file.") + + +def mock_georeference(dtree): + return dtree + + +def mock_timeout_handler(signum, frame): + raise auto_read.TimeoutException("Radar file reading timed out.") @pytest.fixture -def test_file(): - """Fixture to provide a valid radar data file for testing.""" - return Path(DATASETS.fetch("KATX20130717_195021_V06")) +def sample_file(): + # Fetch a sample radar file for testing + return DATASETS.fetch("KATX20130717_195021_V06") + + +def test_read_success(sample_file): + # Test successful reading without timeout and with georeferencing + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), + ): + dtree = auto_read.read(sample_file, georeference=True, verbose=True) + assert dtree is not None + +def test_read_failure(sample_file): + # Test that it raises ValueError when no format can open the file + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_failure, + ), + ): + with pytest.raises( + ValueError, + match="File could not be opened by any supported format in xradar.io.", + ): + auto_read.read(sample_file) -def test_read_failed_opening(monkeypatch, test_file): - """Test that the read function handles failed opening attempts.""" - def mock_open_func(file): - raise OSError("Simulated failure") +def test_read_with_timeout(sample_file): + # Mock the signal handling and ensure it raises the timeout as expected. + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + patch("signal.signal"), + patch( + "signal.alarm", + side_effect=lambda _: mock_timeout_handler(signal.SIGALRM, None), + ), + ): + with pytest.raises( + auto_read.TimeoutException, match="Radar file reading timed out." + ): + auto_read.read(sample_file, timeout=1) - # Replace all open functions with the mock that raises an error - monkeypatch.setattr(xd.io, "open_cfradial1_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_datamet_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_furuno_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_gamic_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_hpl_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_iris_datatree", mock_open_func) - monkeypatch.setattr(xd.io, "open_nexradlevel2_datatree", mock_open_func) - with pytest.raises(ValueError, match="File could not be opened"): - read(test_file, verbose=True) +def test_read_success_without_georeference(sample_file): + # Test successful reading without georeferencing + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + ): + dtree = auto_read.read(sample_file, georeference=False) + assert dtree is not None From 6ba967c258a914d0913ce0ea797e77fab8c8e10e Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Tue, 3 Sep 2024 23:04:08 -0400 Subject: [PATCH 04/11] FIX: Test Coverage --- tests/io/test_auto_read.py | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/io/test_auto_read.py b/tests/io/test_auto_read.py index 7133a9ab..bd689a53 100644 --- a/tests/io/test_auto_read.py +++ b/tests/io/test_auto_read.py @@ -31,6 +31,77 @@ def sample_file(): return DATASETS.fetch("KATX20130717_195021_V06") +# Test case for the timeout handler +def test_timeout_handler(): + # Mock the signal handling and ensure it raises the timeout exception as expected. + with ( + patch("signal.signal"), + pytest.raises( + auto_read.TimeoutException, match="Radar file reading timed out." + ), + ): + auto_read.timeout_handler(signal.SIGALRM, None) + + +# Test that the alarm is disabled after reading the radar file with timeout +def test_timeout_alarm_disabled(sample_file): + # Mock the alarm function and check if it gets called with 0 to disable it. + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + patch("signal.signal"), + patch("signal.alarm") as mock_alarm, + ): + auto_read.read(sample_file, timeout=1) + # Ensure that alarm was called with 0 to disable it after the read. + mock_alarm.assert_called_with(0) + + +# Test the nonlocal dtree block +def test_read_nonlocal_dtree(sample_file): + # Test that it attempts multiple open_ functions and finally succeeds. + with ( + patch( + "xradar.io.auto_read.io.__all__", + ["open_nexradlevel2_datatree", "open_odim_datatree"], + ), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_failure, + ), + patch( + "xradar.io.auto_read.io.open_odim_datatree", side_effect=mock_open_success + ), + patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), + ): + dtree = auto_read.read(sample_file, georeference=True, verbose=True) + assert dtree is not None + + +def test_verbose_failure_output(sample_file, capsys): + # Test that the failure message is printed when verbose is True. + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_failure, + ), + ): + with pytest.raises(ValueError, match="File could not be opened"): + auto_read.read(sample_file, georeference=True, verbose=True) + + # Capture the printed output + captured = capsys.readouterr() + assert ( + "Failed to open with open_nexradlevel2_datatree: Failed to open the file." + in captured.out + ) + + +# Test read success with georeferencing def test_read_success(sample_file): # Test successful reading without timeout and with georeferencing with ( @@ -45,6 +116,7 @@ def test_read_success(sample_file): assert dtree is not None +# Test read failure when no format can open the file def test_read_failure(sample_file): # Test that it raises ValueError when no format can open the file with ( @@ -61,6 +133,7 @@ def test_read_failure(sample_file): auto_read.read(sample_file) +# Test read with timeout raising a TimeoutException def test_read_with_timeout(sample_file): # Mock the signal handling and ensure it raises the timeout as expected. with ( @@ -81,6 +154,7 @@ def test_read_with_timeout(sample_file): auto_read.read(sample_file, timeout=1) +# Test read success without georeferencing def test_read_success_without_georeference(sample_file): # Test successful reading without georeferencing with ( From 1e136aca0ab654114d870ad858f450ed68d532dd Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Tue, 3 Sep 2024 23:14:21 -0400 Subject: [PATCH 05/11] FIX: Test 2 with cov --- tests/io/test_auto_read.py | 89 +++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/tests/io/test_auto_read.py b/tests/io/test_auto_read.py index bd689a53..63e1b401 100644 --- a/tests/io/test_auto_read.py +++ b/tests/io/test_auto_read.py @@ -81,50 +81,64 @@ def test_read_nonlocal_dtree(sample_file): assert dtree is not None -def test_verbose_failure_output(sample_file, capsys): - # Test that the failure message is printed when verbose is True. +# Test for georeferencing and verbose output +def test_read_with_georeferencing_and_verbose(sample_file, capsys): + # Test successful reading with georeferencing and verbose mode. with ( patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), patch( "xradar.io.auto_read.io.open_nexradlevel2_datatree", - side_effect=mock_open_failure, + side_effect=mock_open_success, ), + patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), ): - with pytest.raises(ValueError, match="File could not be opened"): - auto_read.read(sample_file, georeference=True, verbose=True) + dtree = auto_read.read(sample_file, georeference=True, verbose=True) + assert dtree is not None # Capture the printed output captured = capsys.readouterr() + assert "Georeferencing radar data..." in captured.out assert ( - "Failed to open with open_nexradlevel2_datatree: Failed to open the file." - in captured.out + "File opened successfully using open_nexradlevel2_datatree." in captured.out ) -# Test read success with georeferencing -def test_read_success(sample_file): - # Test successful reading without timeout and with georeferencing +# Test for exception handling and verbose output during failure +def test_read_failure_with_verbose_output(sample_file, capsys): + # Test that it handles exceptions and prints the verbose failure message. with ( patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), patch( "xradar.io.auto_read.io.open_nexradlevel2_datatree", - side_effect=mock_open_success, + side_effect=mock_open_failure, ), - patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), ): - dtree = auto_read.read(sample_file, georeference=True, verbose=True) - assert dtree is not None + with pytest.raises( + ValueError, + match="File could not be opened by any supported format in xradar.io.", + ): + auto_read.read(sample_file, georeference=True, verbose=True) + + # Capture the printed output + captured = capsys.readouterr() + assert "Failed to open with open_nexradlevel2_datatree" in captured.out -# Test read failure when no format can open the file -def test_read_failure(sample_file): - # Test that it raises ValueError when no format can open the file +# Test for raising ValueError when no format can open the file +def test_read_failure_raises_value_error(sample_file): + # Test that it raises ValueError when no format can open the file. with ( - patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.__all__", + ["open_nexradlevel2_datatree", "open_odim_datatree"], + ), patch( "xradar.io.auto_read.io.open_nexradlevel2_datatree", side_effect=mock_open_failure, ), + patch( + "xradar.io.auto_read.io.open_odim_datatree", side_effect=mock_open_failure + ), ): with pytest.raises( ValueError, @@ -133,25 +147,19 @@ def test_read_failure(sample_file): auto_read.read(sample_file) -# Test read with timeout raising a TimeoutException -def test_read_with_timeout(sample_file): - # Mock the signal handling and ensure it raises the timeout as expected. +# Test read success with georeferencing +def test_read_success(sample_file): + # Test successful reading without timeout and with georeferencing with ( patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), patch( "xradar.io.auto_read.io.open_nexradlevel2_datatree", side_effect=mock_open_success, ), - patch("signal.signal"), - patch( - "signal.alarm", - side_effect=lambda _: mock_timeout_handler(signal.SIGALRM, None), - ), + patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), ): - with pytest.raises( - auto_read.TimeoutException, match="Radar file reading timed out." - ): - auto_read.read(sample_file, timeout=1) + dtree = auto_read.read(sample_file, georeference=True, verbose=True) + assert dtree is not None # Test read success without georeferencing @@ -166,3 +174,24 @@ def test_read_success_without_georeference(sample_file): ): dtree = auto_read.read(sample_file, georeference=False) assert dtree is not None + + +# Test read with timeout raising a TimeoutException +def test_read_with_timeout(sample_file): + # Mock the signal handling and ensure it raises the timeout as expected. + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + patch("signal.signal"), + patch( + "signal.alarm", + side_effect=lambda _: mock_timeout_handler(signal.SIGALRM, None), + ), + ): + with pytest.raises( + auto_read.TimeoutException, match="Radar file reading timed out." + ): + auto_read.read(sample_file, timeout=1) From 2de6ac702dc0042c163c4e3a3ad5dbdb40338dac Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Wed, 4 Sep 2024 01:25:15 -0400 Subject: [PATCH 06/11] FIX: Coverge Test 3 --- tests/io/test_auto_read.py | 71 ++++++++++++++------ xradar/io/auto_read.py | 131 ++++++++++++++++++++++++++++++------- 2 files changed, 160 insertions(+), 42 deletions(-) diff --git a/tests/io/test_auto_read.py b/tests/io/test_auto_read.py index 63e1b401..c4f98307 100644 --- a/tests/io/test_auto_read.py +++ b/tests/io/test_auto_read.py @@ -1,3 +1,4 @@ +import logging import signal from unittest.mock import MagicMock, patch @@ -10,6 +11,8 @@ # Mocked functions for testing def mock_open_success(file): mock_dtree = MagicMock(name="DataTree") + # Mock the behavior of georeference to return the same object without changing attrs + mock_dtree.xradar.georeference.return_value = mock_dtree return mock_dtree @@ -82,8 +85,8 @@ def test_read_nonlocal_dtree(sample_file): # Test for georeferencing and verbose output -def test_read_with_georeferencing_and_verbose(sample_file, capsys): - # Test successful reading with georeferencing and verbose mode. +def test_read_with_georeferencing_and_logging(sample_file, caplog): + # Test successful reading with georeferencing and log output. with ( patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), patch( @@ -92,20 +95,21 @@ def test_read_with_georeferencing_and_verbose(sample_file, capsys): ), patch("xarray.core.dataset.Dataset.pipe", side_effect=mock_georeference), ): - dtree = auto_read.read(sample_file, georeference=True, verbose=True) - assert dtree is not None + with caplog.at_level(logging.DEBUG): + dtree = auto_read.read(sample_file, georeference=True, verbose=True) + assert dtree is not None - # Capture the printed output - captured = capsys.readouterr() - assert "Georeferencing radar data..." in captured.out - assert ( - "File opened successfully using open_nexradlevel2_datatree." in captured.out - ) + # Check that the log messages contain the correct information + assert "Georeferencing radar data..." in caplog.text + assert ( + "File opened successfully using open_nexradlevel2_datatree." + in caplog.text + ) # Test for exception handling and verbose output during failure -def test_read_failure_with_verbose_output(sample_file, capsys): - # Test that it handles exceptions and prints the verbose failure message. +def test_read_failure_with_verbose_output(sample_file, caplog): + # Test that it handles exceptions and logs the verbose failure message. with ( patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), patch( @@ -113,15 +117,17 @@ def test_read_failure_with_verbose_output(sample_file, capsys): side_effect=mock_open_failure, ), ): - with pytest.raises( - ValueError, - match="File could not be opened by any supported format in xradar.io.", - ): - auto_read.read(sample_file, georeference=True, verbose=True) + with caplog.at_level(logging.DEBUG): + with pytest.raises( + ValueError, + match="File could not be opened by any supported format in xradar.io.", + ): + auto_read.read(sample_file, georeference=True, verbose=True) - # Capture the printed output - captured = capsys.readouterr() - assert "Failed to open with open_nexradlevel2_datatree" in captured.out + # Check that the failure log messages contain the correct information + assert ( + "Failed to open with open_nexradlevel2_datatree" in caplog.text + ) # Capturing log instead of print # Test for raising ValueError when no format can open the file @@ -195,3 +201,28 @@ def test_read_with_timeout(sample_file): auto_read.TimeoutException, match="Radar file reading timed out." ): auto_read.read(sample_file, timeout=1) + + +def test_read_comment_update(sample_file): + with ( + patch("xradar.io.auto_read.io.__all__", ["open_nexradlevel2_datatree"]), + patch( + "xradar.io.auto_read.io.open_nexradlevel2_datatree", + side_effect=mock_open_success, + ), + ): + dtree = auto_read.read(sample_file) + assert dtree is not None + + # Print the actual value of the 'comment' attribute for debugging + print(f"Actual comment: {dtree.attrs['comment']}") + + # The initial comment is "im/exported using xradar" (lowercase 'i') + expected_comment_start = "im/exported using xradar" + + # Ensure the comment starts with the correct initial value + assert dtree.attrs["comment"].startswith(expected_comment_start) + + # Ensure the comment has the correct format with 'nexradlevel2' + expected_comment_end = ",\n'nexradlevel2'" + assert dtree.attrs["comment"].endswith(expected_comment_end) diff --git a/xradar/io/auto_read.py b/xradar/io/auto_read.py index d4f0335d..9f27b258 100644 --- a/xradar/io/auto_read.py +++ b/xradar/io/auto_read.py @@ -6,11 +6,15 @@ XRadar Auto Reader ================== +This module provides the ability to automatically read radar files using all +available formats in the `xradar.io` module. It supports handling various file +types, georeferencing, and logging, as well as a timeout mechanism for file reading. + .. autosummary:: :nosignatures: :toctree: generated/ - {} + read """ __all__ = [ @@ -19,22 +23,69 @@ __doc__ = __doc__.format("\n ".join(__all__)) -from .. import io # noqa +import logging import signal +from .. import io # noqa + +# Setup a logger for this module +logger = logging.getLogger(__name__) +logging.basicConfig( + level=logging.WARNING +) # Default log level to suppress debug logs unless verbose is set + -# Custom exception for handling timeouts class TimeoutException(Exception): + """ + Custom exception to handle file read timeouts. + + This exception is raised when the radar file reading process exceeds the + specified timeout duration. + """ + pass -# Timeout handler def timeout_handler(signum, frame): + """ + Timeout handler to raise a TimeoutException. + + This function is triggered by the alarm signal when the radar file reading + exceeds the allowed timeout duration. + + Parameters + ---------- + signum : int + The signal number (in this case, SIGALRM). + frame : frame object + The current stack frame at the point where the signal was received. + + Raises + ------ + TimeoutException + If the reading operation takes too long and exceeds the timeout. + """ raise TimeoutException("Radar file reading timed out.") -# Decorator for handling timeouts def with_timeout(timeout): + """ + Decorator to enforce a timeout on the file reading process. + + This decorator wraps the file reading function to ensure that if it takes longer than the + specified `timeout` duration, it raises a `TimeoutException`. + + Parameters + ---------- + timeout : int + The maximum number of seconds allowed for the file reading process. + + Returns + ------- + function + A wrapped function that raises `TimeoutException` if it exceeds the timeout. + """ + def decorator(func): def wrapper(*args, **kwargs): # Set the signal handler and a timeout @@ -56,8 +107,9 @@ def read(file, georeference=True, verbose=False, timeout=None): Attempt to read a radar file using all available formats in xradar.io. This function iterates over all the available file-opening functions in the - xradar.io module and attempts to open the provided radar file. If successful, - it can optionally georeference the data (adding x, y, z coordinates). + `xradar.io` module and attempts to open the provided radar file. If successful, + it can optionally georeference the data (adding x, y, z coordinates) and log + detailed processing information. Parameters ---------- @@ -66,19 +118,20 @@ def read(file, georeference=True, verbose=False, timeout=None): georeference : bool, optional If True, georeference the radar data by adding x, y, z coordinates (default is True). verbose : bool, optional - If True, prints out detailed processing information (default is False). + If True, prints out detailed processing information (default is False). When set to True, + debug-level logs are enabled. When False, only warnings and errors are logged. timeout : int or None, optional Timeout in seconds for reading the radar file. If None, no timeout is applied (default is None). Returns ------- dtree : DataTree - A DataTree object containing the radar data. + A `DataTree` object containing the radar data. Raises ------ ValueError - If the file could not be opened by any supported format in xradar.io. + If the file could not be opened by any supported format in `xradar.io`. TimeoutException If reading the file takes longer than the specified timeout. @@ -93,7 +146,18 @@ def read(file, georeference=True, verbose=False, timeout=None): ----- This function relies on the `xradar` library to support various radar file formats. It tries to open the file using all available `open_` functions in the `xradar.io` module. + If a `comment` attribute exists in the radar file's metadata, this function appends the + radar type to the comment. The default comment is set to "im/exported using xradar". """ + # Configure logger level based on 'verbose' + if verbose: + logger.setLevel(logging.DEBUG) # Enable debug messages when verbose is True + logger.debug("Verbose mode activated.") + else: + logger.setLevel( + logging.WARNING + ) # Suppress debug messages when verbose is False + dtree = None # Wrap the read process with a timeout if specified @@ -107,16 +171,30 @@ def attempt_read(file): open_func = getattr(io, key) try: dtree = open_func(file) + + # Ensure the 'comment' key exists; if not, create it + if "comment" not in dtree.attrs: + logger.debug("Creating new 'comment' key.") + dtree.attrs["comment"] = "im/exported using xradar" + else: + logger.debug( + f"Existing 'comment': {dtree.attrs['comment']}" + ) + + # Append the key information to the comment without quotes + dtree.attrs["comment"] += f",\n{key.split('_')[1]}" + + # Log the updated comment + logger.debug(f"After update: {dtree.attrs['comment']}") + if georeference: - if verbose: - print("Georeferencing radar data...") + logger.debug("Georeferencing radar data...") dtree = dtree.xradar.georeference() - if verbose: - print(f"File opened successfully using {key}.") + + logger.debug(f"File opened successfully using {key}.") break except Exception as e: - if verbose: - print(f"Failed to open with {key}: {e}") + logger.debug(f"Failed to open with {key}: {e}") continue if dtree is None: @@ -133,16 +211,25 @@ def attempt_read(file): open_func = getattr(io, key) try: dtree = open_func(file) + + if "comment" not in dtree.attrs: + logger.debug("Creating new 'comment' key.") + dtree.attrs["comment"] = "im/exported using xradar" + else: + logger.debug( + f"Existing 'comment' before update: {dtree.attrs['comment']}" + ) + + dtree.attrs["comment"] += f",\n{key.split('_')[1]}" + if georeference: - if verbose: - print("Georeferencing radar data...") + logger.debug("Georeferencing radar data...") dtree = dtree.xradar.georeference() - if verbose: - print(f"File opened successfully using {key}.") + + logger.debug(f"File opened successfully using {key}.") break except Exception as e: - if verbose: - print(f"Failed to open with {key}: {e}") + logger.debug(f"Failed to open with {key}: {e}") continue if dtree is None: From 01b270b2f3d0e64f0646934adbab4032fa1b3859 Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Wed, 4 Sep 2024 02:14:32 -0400 Subject: [PATCH 07/11] ADD: Example notebook for auto read --- examples/notebooks/Auto_Read.ipynb | 39952 +++++++++++++++++++++++++++ 1 file changed, 39952 insertions(+) create mode 100644 examples/notebooks/Auto_Read.ipynb diff --git a/examples/notebooks/Auto_Read.ipynb b/examples/notebooks/Auto_Read.ipynb new file mode 100644 index 00000000..b86ddfdd --- /dev/null +++ b/examples/notebooks/Auto_Read.ipynb @@ -0,0 +1,39952 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "40d35907", + "metadata": {}, + "source": [ + "# Auto read with Xradar" + ] + }, + { + "cell_type": "markdown", + "id": "cc48004a", + "metadata": {}, + "source": [ + "### Description" + ] + }, + { + "cell_type": "markdown", + "id": "20e5bbe7", + "metadata": {}, + "source": [ + "This notebook demonstrates how to automatically read various radar data formats using the xradar library. The examples cover multiple radar file formats, showing how xradar handles and organizes the data into DataTree structures. Each dataset showcases a specific radar format, presenting detailed metadata, dimensions, coordinates, and data variables for each radar type.\n", + "\n", + "Available Features:\n", + "\n", + "- **Georeferencing (default: True)**: Automatically adds cartesian coordinates (x, y, z) to the radar data for easier analysis. This feature can be disabled by setting `georeference=False`.\n", + "\n", + "- **Verbose Mode (default: False)**: Enables detailed logging when `verbose=True`, including debug-level information about the file reading process, format attempts, and georeferencing steps.\n", + "\n", + "- **Timeout**: The `timeout` parameter allows you to set a time limit for reading radar files. If the reading process gets stuck or runs indefinitely, a `TimeoutException` is raised, preventing the process from hanging and ensuring smooth operation." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "df20a9ea", + "metadata": {}, + "outputs": [], + "source": [ + "import xradar as xd\n", + "from open_radar_data import DATASETS" + ] + }, + { + "cell_type": "markdown", + "id": "8ebf62d0", + "metadata": {}, + "source": [ + "## CF/Radial" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5a2372e7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 477B\n",
+       "Dimensions:              (sweep: 9)\n",
+       "Dimensions without coordinates: sweep\n",
+       "Data variables:\n",
+       "    volume_number        int32 4B ...\n",
+       "    platform_type        |S32 32B ...\n",
+       "    primary_axis         |S32 32B ...\n",
+       "    status_str           |S1 1B ...\n",
+       "    instrument_type      |S32 32B ...\n",
+       "    time_coverage_start  |S32 32B ...\n",
+       "    time_coverage_end    |S32 32B ...\n",
+       "    latitude             float64 8B ...\n",
+       "    longitude            float64 8B ...\n",
+       "    altitude             float64 8B ...\n",
+       "    sweep_group_name     (sweep) <U7 252B 'sweep_0' 'sweep_1' ... 'sweep_8'\n",
+       "    sweep_fixed_angle    (sweep) float32 36B ...\n",
+       "Attributes: (12/13)\n",
+       "    Conventions:         CF/Radial instrument_parameters radar_parameters rad...\n",
+       "    version:             1.2\n",
+       "    title:               TIMREX\n",
+       "    institution:         \n",
+       "    references:          \n",
+       "    source:              \n",
+       "    ...                  ...\n",
+       "    comment:             ,\\ncfradial1\n",
+       "    instrument_name:     SPOLRVP8\n",
+       "    site_name:           \n",
+       "    scan_name:           \n",
+       "    scan_id:             0\n",
+       "    platform_is_mobile:  false
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: (sweep: 9)\n", + "│ Dimensions without coordinates: sweep\n", + "│ Data variables:\n", + "│ volume_number int32 4B ...\n", + "│ platform_type |S32 32B ...\n", + "│ primary_axis |S32 32B ...\n", + "│ status_str |S1 1B ...\n", + "│ instrument_type |S32 32B ...\n", + "│ time_coverage_start |S32 32B ...\n", + "│ time_coverage_end |S32 32B ...\n", + "│ latitude float64 8B ...\n", + "│ longitude float64 8B ...\n", + "│ altitude float64 8B ...\n", + "│ sweep_group_name (sweep) \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2018-12-20T06:06:28Z'\n",
+       "    time_coverage_end    <U20 80B '2018-12-20T06:10:42Z'\n",
+       "    longitude            float64 8B 151.2\n",
+       "    altitude             float64 8B 195.0\n",
+       "    latitude             float64 8B -33.7\n",
+       "Attributes:\n",
+       "    Conventions:      ODIM_H5/V2_2\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\nodim
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2018-06-01T05:40:47Z'\n",
+       "    time_coverage_end    <U20 80B '2018-06-01T05:44:16Z'\n",
+       "    longitude            float64 8B 6.457\n",
+       "    altitude             float64 8B 310.0\n",
+       "    latitude             float64 8B 50.93\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\ngamic
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2021-07-30T16:00:00Z'\n",
+       "    time_coverage_end    <U20 80B '2021-07-30T16:00:14Z'\n",
+       "    longitude            float64 8B 15.45\n",
+       "    altitude             float64 8B 407.9\n",
+       "    latitude             float64 8B 47.08\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\nfuruno
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2013-05-10T00:00:06Z'\n",
+       "    time_coverage_end    <U20 80B '2013-05-10T00:03:14Z'\n",
+       "    longitude            float64 8B 6.38\n",
+       "    altitude             float64 8B 116.7\n",
+       "    latitude             float64 8B 50.86\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\nrainbow
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    longitude            float64 8B 25.52\n",
+       "    latitude             float64 8B 58.48\n",
+       "    altitude             float64 8B 157.0\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2021-08-19T00:02:28Z'\n",
+       "    time_coverage_end    <U20 80B '2021-08-19T00:02:49Z'\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\niris
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ longitude float64 8B 25.52\n", + "│ latitude float64 8B 58.48\n", + "│ altitude float64 8B 157.0\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    longitude            float64 8B -75.28\n",
+       "    latitude             float64 8B 9.331\n",
+       "    altitude             float64 8B 143.0\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2013-11-25T10:55:04Z'\n",
+       "    time_coverage_end    <U20 80B '2013-11-25T10:59:24Z'\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  None\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\niris
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ longitude float64 8B -75.28\n", + "│ latitude float64 8B 9.331\n", + "│ altitude float64 8B 143.0\n", + "│ volume_number int64 8B 0\n", + "│ platform_type \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DatasetView> Size: 232B\n",
+       "Dimensions:              ()\n",
+       "Data variables:\n",
+       "    volume_number        int64 8B 0\n",
+       "    platform_type        <U5 20B 'fixed'\n",
+       "    instrument_type      <U5 20B 'radar'\n",
+       "    time_coverage_start  <U20 80B '2013-07-17T19:50:21Z'\n",
+       "    time_coverage_end    <U20 80B '2013-07-17T19:55:11Z'\n",
+       "    longitude            float64 8B -122.5\n",
+       "    altitude             int64 8B 195\n",
+       "    latitude             float64 8B 48.19\n",
+       "Attributes:\n",
+       "    Conventions:      None\n",
+       "    instrument_name:  KATX\n",
+       "    version:          None\n",
+       "    title:            None\n",
+       "    institution:      None\n",
+       "    references:       None\n",
+       "    source:           None\n",
+       "    history:          None\n",
+       "    comment:          im/exported using xradar,\\nnexradlevel2
" + ], + "text/plain": [ + "DataTree('root', parent=None)\n", + "│ Dimensions: ()\n", + "│ Data variables:\n", + "│ volume_number int64 8B 0\n", + "│ platform_type >> file = DATASETS.fetch('KATX20130717_195021_V06')\n", + " >>> dtree = xd.io.read(file, verbose=True, timeout=10)\n", + " Georeferencing radar data...\n", + " File opened successfully using open_nexrad_archive.\n", + "\n", + " Notes\n", + " -----\n", + " This function relies on the `xradar` library to support various radar file formats.\n", + " It tries to open the file using all available `open_` functions in the `xradar.io` module.\n", + " If a `comment` attribute exists in the radar file's metadata, this function appends the\n", + " radar type to the comment. The default comment is set to \"im/exported using xradar\".\n", + "\n" + ] + } + ], + "source": [ + "help(xd.io.read)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "c2ba511f", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEBUG:xradar.io.auto_read:Verbose mode activated.\n", + "DEBUG:xradar.io.auto_read:Existing 'comment' before update: \n", + "DEBUG:xradar.io.auto_read:Georeferencing radar data...\n", + "DEBUG:xradar.io.auto_read:File opened successfully using open_cfradial1_datatree.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + ",\n", + "cfradial1\n" + ] + } + ], + "source": [ + "filename = DATASETS.fetch(\"cfrad.20080604_002217_000_SPOL_v36_SUR.nc\")\n", + "radar = xd.io.read(filename, verbose=True)\n", + "print(radar.attrs['comment'])" + ] + }, + { + "cell_type": "markdown", + "id": "6dfaebb8", + "metadata": {}, + "source": [ + "---" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From fdcb75ef43475f86082992e1158f65a78c760ad0 Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Wed, 4 Sep 2024 02:18:03 -0400 Subject: [PATCH 08/11] ADD: Example notebook for auto read + Linting --- examples/notebooks/Auto_Read.ipynb | 39751 +-------------------------- 1 file changed, 54 insertions(+), 39697 deletions(-) diff --git a/examples/notebooks/Auto_Read.ipynb b/examples/notebooks/Auto_Read.ipynb index b86ddfdd..986f9340 100644 --- a/examples/notebooks/Auto_Read.ipynb +++ b/examples/notebooks/Auto_Read.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "40d35907", + "id": "0", "metadata": {}, "source": [ "# Auto read with Xradar" @@ -10,7 +10,7 @@ }, { "cell_type": "markdown", - "id": "cc48004a", + "id": "1", "metadata": {}, "source": [ "### Description" @@ -18,7 +18,7 @@ }, { "cell_type": "markdown", - "id": "20e5bbe7", + "id": "2", "metadata": {}, "source": [ "This notebook demonstrates how to automatically read various radar data formats using the xradar library. The examples cover multiple radar file formats, showing how xradar handles and organizes the data into DataTree structures. Each dataset showcases a specific radar format, presenting detailed metadata, dimensions, coordinates, and data variables for each radar type.\n", @@ -34,8 +34,8 @@ }, { "cell_type": "code", - "execution_count": 1, - "id": "df20a9ea", + "execution_count": null, + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -45,7 +45,7 @@ }, { "cell_type": "markdown", - "id": "8ebf62d0", + "id": "4", "metadata": {}, "source": [ "## CF/Radial" @@ -53,5749 +53,10 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "5a2372e7", + "execution_count": null, + "id": "5", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 477B\n",
-       "Dimensions:              (sweep: 9)\n",
-       "Dimensions without coordinates: sweep\n",
-       "Data variables:\n",
-       "    volume_number        int32 4B ...\n",
-       "    platform_type        |S32 32B ...\n",
-       "    primary_axis         |S32 32B ...\n",
-       "    status_str           |S1 1B ...\n",
-       "    instrument_type      |S32 32B ...\n",
-       "    time_coverage_start  |S32 32B ...\n",
-       "    time_coverage_end    |S32 32B ...\n",
-       "    latitude             float64 8B ...\n",
-       "    longitude            float64 8B ...\n",
-       "    altitude             float64 8B ...\n",
-       "    sweep_group_name     (sweep) <U7 252B 'sweep_0' 'sweep_1' ... 'sweep_8'\n",
-       "    sweep_fixed_angle    (sweep) float32 36B ...\n",
-       "Attributes: (12/13)\n",
-       "    Conventions:         CF/Radial instrument_parameters radar_parameters rad...\n",
-       "    version:             1.2\n",
-       "    title:               TIMREX\n",
-       "    institution:         \n",
-       "    references:          \n",
-       "    source:              \n",
-       "    ...                  ...\n",
-       "    comment:             ,\\ncfradial1\n",
-       "    instrument_name:     SPOLRVP8\n",
-       "    site_name:           \n",
-       "    scan_name:           \n",
-       "    scan_id:             0\n",
-       "    platform_is_mobile:  false
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: (sweep: 9)\n", - "│ Dimensions without coordinates: sweep\n", - "│ Data variables:\n", - "│ volume_number int32 4B ...\n", - "│ platform_type |S32 32B ...\n", - "│ primary_axis |S32 32B ...\n", - "│ status_str |S1 1B ...\n", - "│ instrument_type |S32 32B ...\n", - "│ time_coverage_start |S32 32B ...\n", - "│ time_coverage_end |S32 32B ...\n", - "│ latitude float64 8B ...\n", - "│ longitude float64 8B ...\n", - "│ altitude float64 8B ...\n", - "│ sweep_group_name (sweep) \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2018-12-20T06:06:28Z'\n",
-       "    time_coverage_end    <U20 80B '2018-12-20T06:10:42Z'\n",
-       "    longitude            float64 8B 151.2\n",
-       "    altitude             float64 8B 195.0\n",
-       "    latitude             float64 8B -33.7\n",
-       "Attributes:\n",
-       "    Conventions:      ODIM_H5/V2_2\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\nodim
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2018-06-01T05:40:47Z'\n",
-       "    time_coverage_end    <U20 80B '2018-06-01T05:44:16Z'\n",
-       "    longitude            float64 8B 6.457\n",
-       "    altitude             float64 8B 310.0\n",
-       "    latitude             float64 8B 50.93\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\ngamic
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2021-07-30T16:00:00Z'\n",
-       "    time_coverage_end    <U20 80B '2021-07-30T16:00:14Z'\n",
-       "    longitude            float64 8B 15.45\n",
-       "    altitude             float64 8B 407.9\n",
-       "    latitude             float64 8B 47.08\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\nfuruno
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2013-05-10T00:00:06Z'\n",
-       "    time_coverage_end    <U20 80B '2013-05-10T00:03:14Z'\n",
-       "    longitude            float64 8B 6.38\n",
-       "    altitude             float64 8B 116.7\n",
-       "    latitude             float64 8B 50.86\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\nrainbow
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    longitude            float64 8B 25.52\n",
-       "    latitude             float64 8B 58.48\n",
-       "    altitude             float64 8B 157.0\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2021-08-19T00:02:28Z'\n",
-       "    time_coverage_end    <U20 80B '2021-08-19T00:02:49Z'\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\niris
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ longitude float64 8B 25.52\n", - "│ latitude float64 8B 58.48\n", - "│ altitude float64 8B 157.0\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    longitude            float64 8B -75.28\n",
-       "    latitude             float64 8B 9.331\n",
-       "    altitude             float64 8B 143.0\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2013-11-25T10:55:04Z'\n",
-       "    time_coverage_end    <U20 80B '2013-11-25T10:59:24Z'\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  None\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\niris
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ longitude float64 8B -75.28\n", - "│ latitude float64 8B 9.331\n", - "│ altitude float64 8B 143.0\n", - "│ volume_number int64 8B 0\n", - "│ platform_type \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DatasetView> Size: 232B\n",
-       "Dimensions:              ()\n",
-       "Data variables:\n",
-       "    volume_number        int64 8B 0\n",
-       "    platform_type        <U5 20B 'fixed'\n",
-       "    instrument_type      <U5 20B 'radar'\n",
-       "    time_coverage_start  <U20 80B '2013-07-17T19:50:21Z'\n",
-       "    time_coverage_end    <U20 80B '2013-07-17T19:55:11Z'\n",
-       "    longitude            float64 8B -122.5\n",
-       "    altitude             int64 8B 195\n",
-       "    latitude             float64 8B 48.19\n",
-       "Attributes:\n",
-       "    Conventions:      None\n",
-       "    instrument_name:  KATX\n",
-       "    version:          None\n",
-       "    title:            None\n",
-       "    institution:      None\n",
-       "    references:       None\n",
-       "    source:           None\n",
-       "    history:          None\n",
-       "    comment:          im/exported using xradar,\\nnexradlevel2
" - ], - "text/plain": [ - "DataTree('root', parent=None)\n", - "│ Dimensions: ()\n", - "│ Data variables:\n", - "│ volume_number int64 8B 0\n", - "│ platform_type >> file = DATASETS.fetch('KATX20130717_195021_V06')\n", - " >>> dtree = xd.io.read(file, verbose=True, timeout=10)\n", - " Georeferencing radar data...\n", - " File opened successfully using open_nexrad_archive.\n", - "\n", - " Notes\n", - " -----\n", - " This function relies on the `xradar` library to support various radar file formats.\n", - " It tries to open the file using all available `open_` functions in the `xradar.io` module.\n", - " If a `comment` attribute exists in the radar file's metadata, this function appends the\n", - " radar type to the comment. The default comment is set to \"im/exported using xradar\".\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "help(xd.io.read)" ] }, { "cell_type": "code", - "execution_count": 11, - "id": "c2ba511f", + "execution_count": null, + "id": "28", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEBUG:xradar.io.auto_read:Verbose mode activated.\n", - "DEBUG:xradar.io.auto_read:Existing 'comment' before update: \n", - "DEBUG:xradar.io.auto_read:Georeferencing radar data...\n", - "DEBUG:xradar.io.auto_read:File opened successfully using open_cfradial1_datatree.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - ",\n", - "cfradial1\n" - ] - } - ], + "outputs": [], "source": [ "filename = DATASETS.fetch(\"cfrad.20080604_002217_000_SPOL_v36_SUR.nc\")\n", "radar = xd.io.read(filename, verbose=True)\n", - "print(radar.attrs['comment'])" + "print(radar.attrs[\"comment\"])" ] }, { "cell_type": "markdown", - "id": "6dfaebb8", + "id": "29", "metadata": {}, "source": [ "---" @@ -39929,11 +291,6 @@ } ], "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, "language_info": { "codemirror_mode": { "name": "ipython", From b7412b48a60774e08934bbc8495cd40eb5512698 Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Wed, 4 Sep 2024 03:04:16 -0400 Subject: [PATCH 09/11] FIX: Linting issue with notebook --- examples/notebooks/Auto_Read.ipynb | 99 ++++++------------------------ 1 file changed, 18 insertions(+), 81 deletions(-) diff --git a/examples/notebooks/Auto_Read.ipynb b/examples/notebooks/Auto_Read.ipynb index 986f9340..a54bbd03 100644 --- a/examples/notebooks/Auto_Read.ipynb +++ b/examples/notebooks/Auto_Read.ipynb @@ -39,8 +39,9 @@ "metadata": {}, "outputs": [], "source": [ - "import xradar as xd\n", - "from open_radar_data import DATASETS" + "from open_radar_data import DATASETS\n", + "\n", + "import xradar as xd" ] }, { @@ -67,14 +68,6 @@ "cell_type": "markdown", "id": "6", "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "7", - "metadata": {}, "source": [ "## ODIM_H5" ] @@ -82,7 +75,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8", + "id": "7", "metadata": {}, "outputs": [], "source": [ @@ -93,15 +86,7 @@ }, { "cell_type": "markdown", - "id": "9", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "10", + "id": "8", "metadata": {}, "source": [ "## GAMIC" @@ -110,7 +95,7 @@ { "cell_type": "code", "execution_count": null, - "id": "11", + "id": "9", "metadata": {}, "outputs": [], "source": [ @@ -121,15 +106,7 @@ }, { "cell_type": "markdown", - "id": "12", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "13", + "id": "10", "metadata": {}, "source": [ "## Furuno" @@ -138,7 +115,7 @@ { "cell_type": "code", "execution_count": null, - "id": "14", + "id": "11", "metadata": {}, "outputs": [], "source": [ @@ -149,15 +126,7 @@ }, { "cell_type": "markdown", - "id": "15", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "16", + "id": "12", "metadata": {}, "source": [ "## Rainbow" @@ -166,7 +135,7 @@ { "cell_type": "code", "execution_count": null, - "id": "17", + "id": "13", "metadata": {}, "outputs": [], "source": [ @@ -177,15 +146,7 @@ }, { "cell_type": "markdown", - "id": "18", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "19", + "id": "14", "metadata": {}, "source": [ "## Iris/Sigmet - Reader" @@ -194,7 +155,7 @@ { "cell_type": "code", "execution_count": null, - "id": "20", + "id": "15", "metadata": {}, "outputs": [], "source": [ @@ -206,7 +167,7 @@ { "cell_type": "code", "execution_count": null, - "id": "21", + "id": "16", "metadata": {}, "outputs": [], "source": [ @@ -217,15 +178,7 @@ }, { "cell_type": "markdown", - "id": "22", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "23", + "id": "17", "metadata": {}, "source": [ "## NEXRAD Level 2" @@ -234,7 +187,7 @@ { "cell_type": "code", "execution_count": null, - "id": "24", + "id": "18", "metadata": {}, "outputs": [], "source": [ @@ -245,15 +198,7 @@ }, { "cell_type": "markdown", - "id": "25", - "metadata": {}, - "source": [ - "---" - ] - }, - { - "cell_type": "markdown", - "id": "26", + "id": "19", "metadata": {}, "source": [ "## Other available options" @@ -262,7 +207,7 @@ { "cell_type": "code", "execution_count": null, - "id": "27", + "id": "20", "metadata": {}, "outputs": [], "source": [ @@ -272,7 +217,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28", + "id": "21", "metadata": {}, "outputs": [], "source": [ @@ -280,14 +225,6 @@ "radar = xd.io.read(filename, verbose=True)\n", "print(radar.attrs[\"comment\"])" ] - }, - { - "cell_type": "markdown", - "id": "29", - "metadata": {}, - "source": [ - "---" - ] } ], "metadata": { From fdca6abc5f840cb2d1a05de37d3ec5d0626d30ec Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Wed, 4 Sep 2024 03:14:11 -0400 Subject: [PATCH 10/11] FIX: Fix doc of auto_read --- xradar/io/auto_read.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xradar/io/auto_read.py b/xradar/io/auto_read.py index 9f27b258..cd6fdb9e 100644 --- a/xradar/io/auto_read.py +++ b/xradar/io/auto_read.py @@ -14,7 +14,7 @@ :nosignatures: :toctree: generated/ - read + {} """ __all__ = [ From e9a10c6e7b8bf4e1d65e67f23c6898ecea65428e Mon Sep 17 00:00:00 2001 From: syedhamidali Date: Sun, 8 Sep 2024 17:51:21 -0400 Subject: [PATCH 11/11] ADD: Added Notebook to docs/usage.md --- docs/usage.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/usage.md b/docs/usage.md index 540ad1ff..8387da7e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -24,6 +24,7 @@ notebooks/Accessors :maxdepth: 2 :caption: Examples +notebooks/Auto_Read notebooks/CfRadial1_Model_Transformation notebooks/CfRadial1 notebooks/CfRadial1_Export