-
Notifications
You must be signed in to change notification settings - Fork 92
Added sonar model checkers for EK60, EK80, ER60, AZFP6, AZFP, AD2CP and tests #1399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
spacetimeengineer
wants to merge
38
commits into
echostack-org:main
Choose a base branch
from
spacetimeengineer:Parse-sonar-model-from-.raw-for-EK60,-EK80
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
94ec110
Added sonar model checkers for EK60, EK80
spacetimeengineer cae865e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 2cb2625
Update parse_ek60.py
spacetimeengineer 7bf89a1
Added test cases for EK60 and EK80 model validation
spacetimeengineer 1affd2d
Fixed the tests.
spacetimeengineer 2abe8be
Fixed an import error
spacetimeengineer fa7dc1c
Test fix + Update to documentation for Docker and sudo privileges
spacetimeengineer adb5111
Update parse_ek60.py
spacetimeengineer 8967c3e
Refactor error handling: Removed unnecessary 'e' variable
spacetimeengineer 907424d
Made tests better so that they run through all test files in the test…
spacetimeengineer 8a2517d
Added better tests for ek80 checker functions.
spacetimeengineer 01ceb52
Added the rest of the sonar checkers.
spacetimeengineer 0534589
Update test_convert_azfp6.py
spacetimeengineer 853d01b
Added more tests
spacetimeengineer d3467f5
Update test_convert_azfp.py
spacetimeengineer bf73faa
Corrected some tests.
spacetimeengineer a8cd12b
Merge branch 'Parse-sonar-model-from-.raw-for-EK60,-EK80' into parse-…
spacetimeengineer 4db7dd5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 9929523
Needed some fixes for the merge.
spacetimeengineer 1f8f44d
Merge branch 'Parse-sonar-model-from-.raw-for-EK60,-EK80' of https://…
spacetimeengineer d128ff7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 48d9d6b
More merge fixes.
spacetimeengineer 80b6656
Update __init__.py
spacetimeengineer 29ce582
Finishing 1399 requests from Dr. Wu-Jung
spacetimeengineer 20d0932
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] dea1f3c
Adding more PR requests.
spacetimeengineer 35f6e0f
Adding in more requests.
spacetimeengineer afd3bd2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 4574f81
More fixes for PR1399
spacetimeengineer 895b764
Update sonar_model_checker.py
spacetimeengineer 1049942
Update __init__.py
spacetimeengineer e39263b
Fixed test_convert_ek80.py
spacetimeengineer cdcb936
Made more updates to tests.
spacetimeengineer 8d9562d
Merge branch 'main' into Parse-sonar-model-from-.raw-for-EK60,-EK80
spacetimeengineer 3a89a9c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 5dfd4d4
Update test_convert_ad2cp.py
spacetimeengineer 0d63fd3
Update test_sonar_model_checker.py
spacetimeengineer c7c4f94
Merge remote-tracking branch 'upstream/main' into Parse-sonar-model-f…
spacetimeengineer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import os | ||
| import xml.etree.ElementTree as ET | ||
|
|
||
| import numpy as np | ||
|
|
||
| from .utils.ek_raw_io import RawSimradFile | ||
|
|
||
|
|
||
| def is_EK80(raw_file, storage_options): | ||
| """Check if a raw data file is from Simrad EK80 echosounder.""" | ||
| with RawSimradFile(raw_file, "r", storage_options=storage_options) as fid: | ||
| config_datagram = fid.read(1) | ||
| config_datagram["timestamp"] = np.datetime64( | ||
| config_datagram["timestamp"].replace(tzinfo=None), "[ns]" | ||
| ) | ||
|
|
||
| # Return True if "configuration" exists in config_datagram | ||
| return "configuration" in config_datagram | ||
|
|
||
|
|
||
| def is_EK60(raw_file, storage_options): | ||
| """Check if a raw data file is from Simrad EK60 echosounder.""" | ||
| with RawSimradFile(raw_file, "r", storage_options=storage_options) as fid: | ||
| config_datagram = fid.read(1) | ||
| config_datagram["timestamp"] = np.datetime64( | ||
| config_datagram["timestamp"].replace(tzinfo=None), "[ns]" | ||
| ) | ||
|
|
||
| try: | ||
| # Return True if the sounder name matches "EK60" | ||
| return config_datagram["sounder_name"] in {"ER60", "EK60"} | ||
| except KeyError: | ||
| return False | ||
|
|
||
|
|
||
| def is_AZFP6(raw_file): | ||
| """ | ||
| Check if the provided file has a .azfp extension. | ||
|
|
||
| Parameters: | ||
| raw_file (str): The name of the file to check. | ||
|
|
||
| Returns: | ||
| bool: True if the file has a .azfp extension, False otherwise. | ||
| """ | ||
|
|
||
| # Check if the input is a string | ||
| if not isinstance(raw_file, str): | ||
| return False # Return False if the input is not a string | ||
|
|
||
| # Use the str.lower() method to check for the .azfp extension | ||
| has_azfp_extension = raw_file.lower().endswith(".azfp") | ||
|
|
||
| # Return the result of the check | ||
| return has_azfp_extension | ||
|
|
||
|
|
||
| def is_AZFP(raw_file): | ||
| """ | ||
| Check if the specified XML file contains an <InstrumentType> with string="AZFP". | ||
|
|
||
| Parameters: | ||
| raw_file (str): The base name of the XML file (with or without extension). | ||
|
|
||
| Returns: | ||
| bool: True if <InstrumentType> with string="AZFP" is found, False otherwise. | ||
| """ | ||
|
|
||
| # Check if the filename ends with .xml or .XML, and strip the extension if it does | ||
| base_filename = raw_file.rstrip(".xml").rstrip(".XML") | ||
|
|
||
| # Create a list of possible filenames with both extensions | ||
| possible_files = [f"{base_filename}.xml", f"{base_filename}.XML"] | ||
|
|
||
| for full_filename in possible_files: | ||
| if os.path.isfile(full_filename): | ||
| try: | ||
| # Parse the XML file | ||
| tree = ET.parse(full_filename) | ||
| root = tree.getroot() | ||
|
|
||
| # Check for <InstrumentType> elements | ||
| for instrument in root.findall(".//InstrumentType"): | ||
| if instrument.get("string") == "AZFP": | ||
| return True | ||
| except ET.ParseError: | ||
| print(f"Error parsing the XML file: {full_filename}.") | ||
|
|
||
| return False | ||
|
|
||
|
|
||
| def is_AD2CP(raw_file): | ||
| """ | ||
| Check if the provided file has a .ad2cp extension. | ||
|
|
||
| Parameters: | ||
| raw_file (str): The name of the file to check. | ||
|
|
||
| Returns: | ||
| bool: True if the file has a .ad2cp extension, False otherwise. | ||
| """ | ||
|
|
||
| # Check if the input is a string | ||
| if not isinstance(raw_file, str): | ||
| return False # Return False if the input is not a string | ||
|
|
||
| # Use the str.lower() method to check for the .ad2cp extension | ||
| has_ad2cp_extension = raw_file.lower().endswith(".ad2cp") | ||
|
|
||
| # Return the result of the check | ||
| return has_ad2cp_extension | ||
|
|
||
|
|
||
| def is_ER60(raw_file, storage_options): | ||
| """Check if a raw data file is from Simrad EK60 echosounder.""" | ||
| with RawSimradFile(raw_file, "r", storage_options=storage_options) as fid: | ||
| config_datagram = fid.read(1) | ||
| config_datagram["timestamp"] = np.datetime64( | ||
| config_datagram["timestamp"].replace(tzinfo=None), "[ns]" | ||
| ) | ||
| # Return True if the sounder name matches "ER60" | ||
| try: | ||
| return config_datagram["sounder_name"] in {"ER60", "EK60"} | ||
| except KeyError: | ||
| return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| import shutil | ||
|
|
||
| import pytest | ||
| import numpy as np | ||
| import pandas as pd | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| import glob | ||
| from echopype.convert.sonar_model_checker import is_AD2CP, is_AZFP, is_AZFP6, is_EK60, is_EK80, is_ER60 | ||
| import pytest | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_EK80_ek80_files(): | ||
| """Test that EK80 files are identified as EK80.""" | ||
| # Collect all .raw files in the ek80 directory | ||
| ek80_files = glob.glob("echopype/test_data/ek80/*.raw") | ||
|
|
||
| # Check that each file in ek80 is identified as EK80 | ||
| for test_file_path in ek80_files: | ||
| assert is_EK80(test_file_path, storage_options={}) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_EK80_non_ek80_files(): | ||
| """Test that non-EK80 files are not identified as EK80.""" | ||
| # Collect all .raw files in the ek60 directory (non-EK80 files) | ||
| ek60_files = glob.glob("echopype/test_data/ek60/*.raw") | ||
|
|
||
| # Check that each file in ek60 is not identified as EK80 | ||
| for test_file_path in ek60_files: | ||
| assert is_EK80(test_file_path, storage_options={}) == False | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_EK60_ek60_files(): | ||
| """Check that EK60 files are identified as EK60""" | ||
| # Collect all .raw files in the ek60 directory | ||
| ek60_files = glob.glob("echopype/test_data/ek60/from_echopy/*.raw") | ||
|
|
||
| # Check that each file in ek60 is identified as EK60 | ||
| for test_file_path in ek60_files: | ||
| assert is_EK60(test_file_path, storage_options={}) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_EK60_non_ek60_files(): | ||
| """Check that non-EK60 files are not identified as EK60""" | ||
| # Collect all .raw files in the ek80 directory (non-EK60 files) | ||
| ek80_files = glob.glob("echopype/test_data/ek80/*.raw") | ||
|
|
||
| # Check that each file in ek80 is not identified as EK60 | ||
| for test_file_path in ek80_files: | ||
| assert is_EK60(test_file_path, storage_options={}) == False | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_ER60_er60_files(): | ||
| """Check that EK60 files are identified as EK60""" | ||
| # Collect all .raw files in the ek60 directory | ||
| ek60_files = glob.glob("echopype/test_data/ek60/from_echopy/*.raw") | ||
|
|
||
| # Check that each file in ek60 is identified as EK60 | ||
| for test_file_path in ek60_files: | ||
| assert is_ER60(test_file_path, storage_options={}) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_ER60_non_er60_files(): | ||
| """Check that non-EK60 files are not identified as EK60""" | ||
| # Collect all .raw files in the ek80 directory (non-EK60 files) | ||
| ek80_files = glob.glob("echopype/test_data/ek80/*.raw") | ||
|
|
||
| # Check that each file in ek80 is not identified as EK60 | ||
| for test_file_path in ek80_files: | ||
| assert is_ER60(test_file_path, storage_options={}) == False | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AZFP6_valid_files(): | ||
| """Test that .azfp files are identified as valid AZFP files.""" | ||
| # Collect all .azfp files in the test directory | ||
| azfp_files = glob.glob("echopype/test_data/azfp6/*.azfp") | ||
|
|
||
| # Check that each file in azfp is identified as valid AZFP | ||
| for test_file_path in azfp_files: | ||
| assert is_AZFP6(test_file_path) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AZFP6_invalid_files(): | ||
| """Test that non-.azfp files are not identified as valid AZFP files.""" | ||
| # Collect all non-.azfp files in the test directory | ||
| non_azfp_files = glob.glob("echopype/test_data/azfp/*") | ||
|
|
||
| # Check that each file in non_azfp is not identified as valid AZFP | ||
| for test_file_path in non_azfp_files: | ||
| assert is_AZFP6(test_file_path) == False | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AZFP_valid_files(): | ||
| """Test that XML files with <InstrumentType string="AZFP"> are identified as valid AZFP files.""" | ||
| # Collect all valid XML files in the test directory | ||
| valid_files = glob.glob("echopype/test_data/azfp/*.xml") + glob.glob("echopype/test_data/azfp/*.XML") | ||
|
|
||
| for test_file_path in valid_files: | ||
| assert is_AZFP(test_file_path) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AZFP_invalid_files(): | ||
| """Test that XML files without <InstrumentType string="AZFP"> are not identified as valid AZFP files.""" | ||
| # Collect all invalid XML files in the test directory | ||
| invalid_files = glob.glob("echopype/test_data/azfp6/*") | ||
|
|
||
| for test_file_path in invalid_files: | ||
| assert is_AZFP(test_file_path) == False | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AD2CP_valid_files(): | ||
| """Test that .ad2cp files are identified as valid AD2CP files.""" | ||
| # Collect all .ad2cp files in the test directory | ||
| ad2cp_files = glob.glob("echopype/test_data/ad2cp/normal/*.ad2cp") | ||
|
|
||
| # Check that each file in ad2cp is identified as valid AD2CP | ||
| for test_file_path in ad2cp_files: | ||
| assert is_AD2CP(test_file_path) == True | ||
|
|
||
| @pytest.fixture(scope="session") | ||
| def test_is_AD2CP_invalid_files(): | ||
| """Test that non-.ad2cp files are not identified as valid AD2CP files.""" | ||
| # Collect all non-.ad2cp files in the test directory | ||
| non_ad2cp_files = glob.glob("echopype/test_data/azfp6/*") | ||
|
|
||
| # Check that each file in non_ad2cp is not identified as valid AD2CP | ||
| for test_file_path in non_ad2cp_files: | ||
| assert is_AD2CP(test_file_path) == False |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this to a new PR since it's under a completely different topic? I think there we could update the contributing guide from you and others as you're fresh from setting up a dev environment and may want to add other details. Thanks!