From 8bf11dcde044cfe6a3157e68fae9458da5e1296e Mon Sep 17 00:00:00 2001 From: Jessy Barrette Date: Tue, 26 Jul 2022 15:48:14 -0400 Subject: [PATCH 01/10] fix minidot po2 --- ocean_data_parser/read/pme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocean_data_parser/read/pme.py b/ocean_data_parser/read/pme.py index a97fc55d..54575ce6 100644 --- a/ocean_data_parser/read/pme.py +++ b/ocean_data_parser/read/pme.py @@ -93,7 +93,7 @@ def minidot_txt(path, read_csv_kwargs=None): ds.attrs[ "history" ] += f"\n{datetime.now().isoformat()} Retrieve Oxygen Saturation Percentage values from 'DO (mg/l)' and 'T (deg C)' by assuming 0 salinity and at surface (pressure=0)" - ds["po2"] = retrieve_oxygen_saturation_percent( + ds["po2"] = retrieve_po2( ds["DO (mg/l)"], ds["T (deg C)"], salinity=0, pressure=0, units="mg/l" ) ds.attrs[ From 7190febc28da9ef4d3245238b724b858b11d0d1d Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Tue, 4 Oct 2022 15:47:38 -0700 Subject: [PATCH 02/10] add logging debug to pme parser --- ocean_data_parser/read/pme.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ocean_data_parser/read/pme.py b/ocean_data_parser/read/pme.py index 54575ce6..ea0bc3b2 100644 --- a/ocean_data_parser/read/pme.py +++ b/ocean_data_parser/read/pme.py @@ -52,6 +52,7 @@ def minidot_txt(path, read_csv_kwargs=None): ) as f: # Read the headre serial_number = f.readline().replace("\n", "") + logger.debug("Parse file from serial number: %s", serial_number) metadata = re.search( r"OS REV: (?P\d+\.\d+) Sensor Cal: (?P\d*)", f.readline(), From 4fab328269dfd06dbafffcfb63d136de6615f116 Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Wed, 2 Nov 2022 16:07:18 -0400 Subject: [PATCH 03/10] fix imports for parser detection and automated file parser --- ocean_data_parser/read/__init__.py | 2 +- tests/parser_detection_test.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ocean_data_parser/read/__init__.py b/ocean_data_parser/read/__init__.py index 1bd89f76..f150d15b 100644 --- a/ocean_data_parser/read/__init__.py +++ b/ocean_data_parser/read/__init__.py @@ -1 +1 @@ -from ocean_data_parser.read.auto import file +from ocean_data_parser.read.auto import file, detect_file_format diff --git a/tests/parser_detection_test.py b/tests/parser_detection_test.py index fcf4f6bb..5d1c5cef 100644 --- a/tests/parser_detection_test.py +++ b/tests/parser_detection_test.py @@ -4,7 +4,7 @@ import re import os -from ocean_data_parser.read import auto +from ocean_data_parser.read import file, detect_file_format logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger() @@ -16,7 +16,7 @@ def test_all_test_files(self): for file in test_files: if "nmea" in file or file.endswith("nc"): continue - parser = auto.detect_file_format(file) + parser = detect_file_format(file) assert parser, f"Test file {file} doesn't match any parser" def test_amundsen(self): @@ -24,7 +24,7 @@ def test_amundsen(self): for file in test_files: if file.endswith("nc"): continue - parser = auto.detect_file_format(file) + parser = detect_file_format(file) assert ( parser == "amundsen.int_format" ), f"Test file {file} doesn't match amundsen.int_format" @@ -34,16 +34,16 @@ def test_bio_odf(self): for file in test_files: if file.endswith("nc"): continue - parser = auto.detect_file_format(file) + parser = detect_file_format(file) assert ( parser == "dfo.odf.bio_format" ), f"Test file {file} doesn't match dfo.odf.bio_format" class AutomatedParserTests(unittest.TestCase): - def test_autodetect_and_parse(self): + def test_etect_and_parse(self): test_files = glob("tests/parsers_test_files/**/*", recursive=True) for test_file in test_files: if re.search("geojson", test_file) or not os.path.isfile(test_file): continue - output = auto.file(test_file) + output = file(test_file) From d787a749f386e3ba5de7c5bcdedb6feb80c434d3 Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Thu, 10 Nov 2022 10:36:31 -0500 Subject: [PATCH 04/10] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index fec48fcd..973f4d45 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ # Ocean Data Parser + +The `ocean data parser` has for primary objectif to streamline the data parsing the different oceanographic data format to a standard xarray object. This object can then easily be used for: +- Data Analysis +- NetCDF conversion +- Data Pipeline Ingestion + ## Installation With miniconda, create a new environement: ```console From 05ff48005dfe3075e586d5fc9866f79ae96b1fb6 Mon Sep 17 00:00:00 2001 From: Jessy Barrette Date: Fri, 9 Jun 2023 10:55:44 -0700 Subject: [PATCH 05/10] Update readme --- README.md | 82 +++++++++++++++++++++++----- docs/images/logo_EN_FR-1024x208.png | Bin 0 -> 63368 bytes 2 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 docs/images/logo_EN_FR-1024x208.png diff --git a/README.md b/README.md index 973f4d45..304b51f4 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,66 @@ -# Ocean Data Parser + -The `ocean data parser` has for primary objectif to streamline the data parsing the different oceanographic data format to a standard xarray object. This object can then easily be used for: -- Data Analysis -- NetCDF conversion -- Data Pipeline Ingestion +![Logo](docs/images/logo_EN_FR-1024x208.png) -## Installation -With miniconda, create a new environement: -```console -conda create --name ocean_parser -```` + + +# ocean-data-parser + + + +[![Update gh-pages Docs](https://github.com/HakaiInstitute/ocean-data-parser/actions/workflows/generate-documentation.yaml/badge.svg)](https://github.com/HakaiInstitute/ocean-data-parser/actions/workflows/generate-documentation.yaml) + +## What is it? + +The `ocean-data-parser` is a set of tools capable of parsing oceanographic proprietary data formats to a xarray CIOOS Compliant object. This xarray object can then be use in a number of application and/or easily saved to a NetCDF format. + +A more detailed documentation is available [here](https://hakaiinstitute.github.io/ocean-data-parser). Get in the environment: ```console conda activate ocean_parser ``` -Install the present package: -```console +## Table of Contents + +
+ +Table of Contents + +- [ocean-data-parser](#ocean-data-parser) + - [What is it?](#what-is-it) + - [Table of Contents](#table-of-contents) + - [How to](#how-to) + - [Development](#development) + - [Installation](#installation) + - [Documentation](#documentation) + - [Testing](#testing) + - [Parsers Tests](#parsers-tests) + - [Contributing](#contributing) + +
+ +--- + +## How to + +Install the package with the following command, ideally within a virtual environment: + +```env pip install git+https://github.com/HakaiInstitute/ocean-data-parser.git ``` +The `ocean-data-parser` can then be used within either a python package, script or jupyter notebook. See [documentation Notebook section](https://hakaiinstitute.github.io/ocean-data-parser) for examples on how to use the package within a jupyter notebook. +## Development +### Installation +Clone the project locally -For development, clone locally the package : -```console -git clone git+https://github.com/HakaiInstitute/ocean-data-parser.git +```shell + git clone git+https://github.com/HakaiInstitute/ocean-data-parser.git ``` and install the package: ```console @@ -44,3 +80,19 @@ from ocean_data_parser.read import searbird PATH_TO_SEABIRD_CNV = "PATH_TO_SEABIRD_CNV" ds = seabird.cnv(PATH_TO_SEABIRD_CNV) ``` + +Any documentation changes to the main and development branches will automatically update respectively the main and dev document pages. + +### Testing +The package use pytest to run a series of tests in order to help the development of the different aspect of the package. Within a developping environment, to run the different tests, run the pytest commmand through your terminal within the base directory of the repository. Pytest can also be integrated with different IDE and is run on any pushes and PR to the `main` and `development` branches. + +#### Parsers Tests +The package contains a number of different parsers compatible with different standard file formats. Each parser is tested on a series of test files made available within the [test file directory](tests/parsers_test_files) The different tests executed on each individual parsers can be subdivided in 3 main categories: +1. Parse test file to an xarray dataset +2. Parse test file to an xarray dataset and save to a NetCDF4 file. +3. Parse test file to an xarray dataset and compare to a reference file ('*_reference.nc) if made available. Any differences are flagged +4. *(in development)* Assess parsed xarray object compliance with the different convention by using the ioos-compliance checker, resulting objects should be to a minimum compliante to ACDD 1.3 and CF 1.6. Other conventions can be added by adding them to the xarray object global attribute `Convention`. + +## Contributing + +All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome. \ No newline at end of file diff --git a/docs/images/logo_EN_FR-1024x208.png b/docs/images/logo_EN_FR-1024x208.png new file mode 100644 index 0000000000000000000000000000000000000000..d52413baa5cc20b22d8cbfbc429edd4da2358710 GIT binary patch literal 63368 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 Date: Fri, 9 Jun 2023 11:03:41 -0700 Subject: [PATCH 06/10] drop old how to in readme --- README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/README.md b/README.md index 304b51f4..185b718a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ conda activate ocean_parser - [How to](#how-to) - [Development](#development) - [Installation](#installation) - - [Documentation](#documentation) - [Testing](#testing) - [Parsers Tests](#parsers-tests) - [Contributing](#contributing) @@ -71,18 +70,6 @@ For development purposes, it is recommended to install the development requireme ```console pip install -e ".[dev]" ``` - -## How to -To parse seabird file: -```python -from ocean_data_parser.read import searbird - -PATH_TO_SEABIRD_CNV = "PATH_TO_SEABIRD_CNV" -ds = seabird.cnv(PATH_TO_SEABIRD_CNV) -``` - -Any documentation changes to the main and development branches will automatically update respectively the main and dev document pages. - ### Testing The package use pytest to run a series of tests in order to help the development of the different aspect of the package. Within a developping environment, to run the different tests, run the pytest commmand through your terminal within the base directory of the repository. Pytest can also be integrated with different IDE and is run on any pushes and PR to the `main` and `development` branches. From f157615a7e5d727e6cd5d528076aaaf56bb02fea Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:29:43 -0700 Subject: [PATCH 07/10] update readme with an example --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 185b718a..b604eebd 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,32 @@ Install the package with the following command, ideally within a virtual environ ```env pip install git+https://github.com/HakaiInstitute/ocean-data-parser.git ``` + +As an example, to load a compatible file you can use the automated parser detection method: + +```python +import ocean_data_parser.read + +# Load a file to an xarray object +ds = ocean_data_parser.read.file('Path to file') + +# Save to netcdf +ds.to_netcdf('save-path.nc') +``` +** The parser detection method relies on the file extension and the first few lines present within the given file. + +Or specify the specific parser to use for this file format: +``` python +from ocean_data_parser.read import seabird + +# Load a seabird cnv file as an xarray dataset +ds = seabird.cnv('Path to seabird cnv file') + +# Save to netcdf +ds.to_netcdf('save-path.nc') +``` The `ocean-data-parser` can then be used within either a python package, script or jupyter notebook. See [documentation Notebook section](https://hakaiinstitute.github.io/ocean-data-parser) for examples on how to use the package within a jupyter notebook. + ## Development ### Installation From 59bf8f65ddbde3f689c41a313274ef683b4281f0 Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:37:59 -0700 Subject: [PATCH 08/10] add comment regarding parser detection --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b604eebd..9b95c6de 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ ds = ocean_data_parser.read.file('Path to file') # Save to netcdf ds.to_netcdf('save-path.nc') ``` -** The parser detection method relies on the file extension and the first few lines present within the given file. +> :warning: The parser detection method relies on the file extension and the first few lines present within the given file. Or specify the specific parser to use for this file format: ``` python From 2dba11e23911a352579d1362c8a1b36deb2881fa Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:40:29 -0700 Subject: [PATCH 09/10] cleanup main readme --- README.md | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9b95c6de..1f6b89c8 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,7 @@ The `ocean-data-parser` is a set of tools capable of parsing oceanographic propr A more detailed documentation is available [here](https://hakaiinstitute.github.io/ocean-data-parser). -Get in the environment: -```console -conda activate ocean_parser -``` +--- ## Table of Contents @@ -37,6 +34,7 @@ conda activate ocean_parser - [How to](#how-to) - [Development](#development) - [Installation](#installation) + - [Documentation](#documentation) - [Testing](#testing) - [Parsers Tests](#parsers-tests) - [Contributing](#contributing) @@ -86,15 +84,28 @@ Clone the project locally ```shell git clone git+https://github.com/HakaiInstitute/ocean-data-parser.git ``` -and install the package: -```console -cd ocean-data-parser -pip install -e . + +Go to the project directory + +```shell + cd ocean-data-parser +``` + +Install dependencies + +```shell + pip install -e ".[dev]" ``` -For development purposes, it is recommended to install the development requirements: -```console -pip install -e ".[dev]" + +### Documentation +To run a local instance of the documentation webpage, run the command: + +```shell +mike serve ``` + +Any documentation changes to the main and development branches will automatically update respectively the main and dev document pages. + ### Testing The package use pytest to run a series of tests in order to help the development of the different aspect of the package. Within a developping environment, to run the different tests, run the pytest commmand through your terminal within the base directory of the repository. Pytest can also be integrated with different IDE and is run on any pushes and PR to the `main` and `development` branches. From b61ff1ae53084d6b4eb8cd598b1f4626beeb9f1b Mon Sep 17 00:00:00 2001 From: Jessy Barrette <30420025+JessyBarrette@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:49:29 -0700 Subject: [PATCH 10/10] isort . black . --- ocean_data_parser/geo.py | 5 ++-- ocean_data_parser/metadata/pdc.py | 1 + ocean_data_parser/read/__init__.py | 2 +- ocean_data_parser/read/amundsen.py | 7 +++--- ocean_data_parser/read/auto.py | 7 +++--- ocean_data_parser/read/dfo/odf.py | 1 + .../read/dfo/odf_source/attributes.py | 1 + .../read/dfo/odf_source/process.py | 2 +- ocean_data_parser/read/electricblue.py | 6 ++--- ocean_data_parser/read/nmea.py | 1 - ocean_data_parser/read/onset.py | 2 -- ocean_data_parser/read/rbr.py | 1 + ocean_data_parser/read/seabird.py | 2 -- ocean_data_parser/read/star_oddi.py | 4 ++-- .../read/van_essen_instruments.py | 2 +- ocean_data_parser/tools/postgresql.py | 2 +- scripts/pdc_amundsen_conversion.py | 7 +++--- setup.py | 3 +-- tests/parser_detection_test.py | 6 ++--- tests/parsers_test.py | 24 +++++++++---------- 20 files changed, 42 insertions(+), 44 deletions(-) diff --git a/ocean_data_parser/geo.py b/ocean_data_parser/geo.py index 075d7304..de0c57d9 100644 --- a/ocean_data_parser/geo.py +++ b/ocean_data_parser/geo.py @@ -1,15 +1,14 @@ import json import os -from geographiclib.geodesic import Geodesic -from shapely.geometry import shape, Point, Polygon +from geographiclib.geodesic import Geodesic +from shapely.geometry import Point, Polygon, shape def read_geojson( path: str, encoding: str = "UTF-8", ) -> dict: - """Parse geojson files and return it as a dictionary. If features are available, generate a shapely feature object. diff --git a/ocean_data_parser/metadata/pdc.py b/ocean_data_parser/metadata/pdc.py index f906451e..3143b294 100644 --- a/ocean_data_parser/metadata/pdc.py +++ b/ocean_data_parser/metadata/pdc.py @@ -7,6 +7,7 @@ logger = logging.getLogger(__name__) + # def fgdc_to_acdd(xml) def fgdc_to_acdd(url=None, xml=None): """Convert PDC FGDC XML format to an ACDD 1.3 standard dictionary format.""" diff --git a/ocean_data_parser/read/__init__.py b/ocean_data_parser/read/__init__.py index f150d15b..9718f53a 100644 --- a/ocean_data_parser/read/__init__.py +++ b/ocean_data_parser/read/__init__.py @@ -1 +1 @@ -from ocean_data_parser.read.auto import file, detect_file_format +from ocean_data_parser.read.auto import detect_file_format, file diff --git a/ocean_data_parser/read/amundsen.py b/ocean_data_parser/read/amundsen.py index 35d14fed..1adf0035 100644 --- a/ocean_data_parser/read/amundsen.py +++ b/ocean_data_parser/read/amundsen.py @@ -1,14 +1,15 @@ """Module use to handle int file format generated historically ArcticNet and the Amundsen inc.""" __version__ = "0.1.0" -import re +import json import logging import os -import json +import re import pandas as pd from gsw import z_from_p -from .utils import standardize_dataset, get_history_handler + +from .utils import get_history_handler, standardize_dataset logger = logging.getLogger(__name__) string_attributes = ["Cruise_Number", "Cruise_Name", "Station"] diff --git a/ocean_data_parser/read/auto.py b/ocean_data_parser/read/auto.py index dc6ae518..a9426e14 100644 --- a/ocean_data_parser/read/auto.py +++ b/ocean_data_parser/read/auto.py @@ -1,7 +1,7 @@ -from importlib import import_module -import re -import os import logging +import os +import re +from importlib import import_module logger = logging.getLogger(__name__) @@ -84,7 +84,6 @@ def detect_file_format(file: str, encoding: str = "UTF-8") -> str: def file(path, parser=None, **kwargs): - # Review the file format if no parser is specified if parser is None: parser = detect_file_format(path) diff --git a/ocean_data_parser/read/dfo/odf.py b/ocean_data_parser/read/dfo/odf.py index cd8b4795..7f7e81c8 100644 --- a/ocean_data_parser/read/dfo/odf.py +++ b/ocean_data_parser/read/dfo/odf.py @@ -4,6 +4,7 @@ the different data formats developped by the different Canadian DFO offices. """ from typing import Union + from ocean_data_parser.read.dfo.odf_source.process import ( parse_odf, read_config, diff --git a/ocean_data_parser/read/dfo/odf_source/attributes.py b/ocean_data_parser/read/dfo/odf_source/attributes.py index f7357f2b..7cfe6971 100644 --- a/ocean_data_parser/read/dfo/odf_source/attributes.py +++ b/ocean_data_parser/read/dfo/odf_source/attributes.py @@ -10,6 +10,7 @@ from difflib import get_close_matches import pandas as pd + from ocean_data_parser.read.seabird import ( get_seabird_instrument_from_header, get_seabird_processing_history, diff --git a/ocean_data_parser/read/dfo/odf_source/process.py b/ocean_data_parser/read/dfo/odf_source/process.py index 393c41dc..b1d4e024 100644 --- a/ocean_data_parser/read/dfo/odf_source/process.py +++ b/ocean_data_parser/read/dfo/odf_source/process.py @@ -19,9 +19,9 @@ # ) import ocean_data_parser.read.dfo.odf_source.attributes as attributes import ocean_data_parser.read.dfo.odf_source.parser as odf_parser +from ocean_data_parser.geo import get_geo_code, get_nearest_station, read_geojson from ocean_data_parser.read import seabird from ocean_data_parser.read.utils import standardize_dataset -from ocean_data_parser.geo import get_nearest_station, read_geojson, get_geo_code tqdm.pandas() diff --git a/ocean_data_parser/read/electricblue.py b/ocean_data_parser/read/electricblue.py index 4d1e17d1..1089def9 100644 --- a/ocean_data_parser/read/electricblue.py +++ b/ocean_data_parser/read/electricblue.py @@ -1,10 +1,11 @@ import logging +import re import pandas as pd -import re + from ocean_data_parser.read.utils import ( - standardize_dataset, rename_variables_to_valid_netcdf, + standardize_dataset, ) logger = logging.getLogger(__name__) @@ -114,7 +115,6 @@ def csv( def log_csv(path, encoding="UTF-8", rename_variables=True): - df = pd.read_csv(path, encoding=encoding, parse_dates=True, index_col=["time"]) ds = df.to_xarray() # add default attributes diff --git a/ocean_data_parser/read/nmea.py b/ocean_data_parser/read/nmea.py index f77ce5a1..9a35f028 100644 --- a/ocean_data_parser/read/nmea.py +++ b/ocean_data_parser/read/nmea.py @@ -214,7 +214,6 @@ def rename_variable(name): nmea = [] long_names = {} with open(path, encoding=encoding) as f: - for row, line in enumerate(f): if not line: continue diff --git a/ocean_data_parser/read/onset.py b/ocean_data_parser/read/onset.py index e4cd97a7..6d9801ea 100644 --- a/ocean_data_parser/read/onset.py +++ b/ocean_data_parser/read/onset.py @@ -88,7 +88,6 @@ def _parse_onset_time(time, timezone="UTC"): def _parse_onset_csv_header(header_lines): - full_header = "\n".join(header_lines) header = { "instrument_manufacturer": "Onset", @@ -157,7 +156,6 @@ def csv( read_csv_kwargs: dict = None, standardize_variable_names: bool = True, ): - """tidbit_csv parses the Onset Tidbit CSV format into a pandas dataframe Returns: diff --git a/ocean_data_parser/read/rbr.py b/ocean_data_parser/read/rbr.py index e64c8e42..579b728a 100644 --- a/ocean_data_parser/read/rbr.py +++ b/ocean_data_parser/read/rbr.py @@ -5,6 +5,7 @@ import re import pandas as pd + from ocean_data_parser.read.utils import test_parsed_dataset diff --git a/ocean_data_parser/read/seabird.py b/ocean_data_parser/read/seabird.py index 257ec422..6c194102 100644 --- a/ocean_data_parser/read/seabird.py +++ b/ocean_data_parser/read/seabird.py @@ -237,7 +237,6 @@ def read_number_line(line): header["history"] = [] read_next_line = True while "*END*" not in line and line.startswith(("*", "#")): - if read_next_line: line = f.readline() else: @@ -490,7 +489,6 @@ def generate_binned_attributes(ds, seabird_header): ds.attrs["time_coverage_resolution"] = pd.Timedelta(bin_str).isoformat() for var in ds: if (len(ds.dims) == 1 and len(ds[var].dims) == 1) or binvar in ds[var].dims: - ds[var].attrs["cell_method"] = f"{binvar}: mean (interval: {bin_str})" return ds diff --git a/ocean_data_parser/read/star_oddi.py b/ocean_data_parser/read/star_oddi.py index 0e5ddc51..164cb4c4 100644 --- a/ocean_data_parser/read/star_oddi.py +++ b/ocean_data_parser/read/star_oddi.py @@ -1,7 +1,7 @@ -import pandas as pd +import logging import re -import logging +import pandas as pd logger = logging.getLogger(__name__) diff --git a/ocean_data_parser/read/van_essen_instruments.py b/ocean_data_parser/read/van_essen_instruments.py index 73a7767c..b1f49a1c 100644 --- a/ocean_data_parser/read/van_essen_instruments.py +++ b/ocean_data_parser/read/van_essen_instruments.py @@ -5,7 +5,7 @@ import pandas as pd -from .utils import test_parsed_dataset, standardize_dataset +from .utils import standardize_dataset, test_parsed_dataset logger = logging.getLogger(__name__) diff --git a/ocean_data_parser/tools/postgresql.py b/ocean_data_parser/tools/postgresql.py index 6d628ecb..ef923eba 100644 --- a/ocean_data_parser/tools/postgresql.py +++ b/ocean_data_parser/tools/postgresql.py @@ -1,6 +1,6 @@ -from io import StringIO import csv import logging +from io import StringIO logger = logging.getLogger(__name__) diff --git a/scripts/pdc_amundsen_conversion.py b/scripts/pdc_amundsen_conversion.py index 1ff8a414..8e952e71 100644 --- a/scripts/pdc_amundsen_conversion.py +++ b/scripts/pdc_amundsen_conversion.py @@ -4,13 +4,14 @@ Those NetCDFs are then served by the PDC Hyrax and CIOOS ERDAP servers """ -from glob import glob import logging +from glob import glob -from ocean_data_parser.read import amundsen -from ocean_data_parser.metadata import pdc from tqdm import tqdm +from ocean_data_parser.metadata import pdc +from ocean_data_parser.read import amundsen + FORMAT = "%(asctime)s [%(levelname)s] %(message)s" logging.basicConfig( filename="pdc-amundsen-conversion.log", level=logging.WARNING, format=FORMAT diff --git a/setup.py b/setup.py index 1a12747e..189bbe55 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ -from setuptools import setup, find_packages - +from setuptools import find_packages, setup setup( name="ocean_data_parser", diff --git a/tests/parser_detection_test.py b/tests/parser_detection_test.py index 5d1c5cef..9b2468a3 100644 --- a/tests/parser_detection_test.py +++ b/tests/parser_detection_test.py @@ -1,10 +1,10 @@ import logging +import os +import re import unittest from glob import glob -import re -import os -from ocean_data_parser.read import file, detect_file_format +from ocean_data_parser.read import detect_file_format, file logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger() diff --git a/tests/parsers_test.py b/tests/parsers_test.py index 995f8c8e..3080903b 100644 --- a/tests/parsers_test.py +++ b/tests/parsers_test.py @@ -1,26 +1,27 @@ import logging +import os import re import unittest from glob import glob -import os -import xarray as xr -import pandas as pd import numpy as np +import pandas as pd +import xarray as xr + from ocean_data_parser.read import ( - seabird, - van_essen_instruments, - onset, amundsen, - electricblue, - star_oddi, - rbr, - sunburst, dfo, + electricblue, + file, nmea, + onset, pme, + rbr, + seabird, + star_oddi, + sunburst, + van_essen_instruments, ) -from ocean_data_parser.read import file logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger() @@ -80,7 +81,6 @@ def ignore_from_attr(attr, expression, placeholder): test = standardize_dataset(test) if not ref.identical(test): - # Global attributes for key in ref.attrs.keys(): if not_identical(ref.attrs[key], test.attrs.get(key)):