-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #429 from euroargodev/float-store
For a given float WMO, a new class to easily open netcdf dataset for local and remote GDAC
- Loading branch information
Showing
55 changed files
with
1,964 additions
and
56 deletions.
There are no files selected for viewing
This file contains 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,83 @@ | ||
name: Debug windows | ||
|
||
on: | ||
workflow_dispatch: # allows you to trigger the workflow run manually | ||
pull_request: | ||
types: [synchronize] | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
permissions: | ||
id-token: write | ||
contents: read | ||
|
||
jobs: | ||
core-pinned: | ||
|
||
name: Core - Pinned - Py${{matrix.python-version}} | ||
runs-on: ${{ matrix.os }} | ||
defaults: | ||
run: | ||
shell: bash -l {0} | ||
continue-on-error: ${{ matrix.experimental }} | ||
# timeout-minutes: 45 | ||
strategy: | ||
max-parallel: 12 | ||
fail-fast: false | ||
matrix: | ||
python-version: ["3.10", "3.11"] | ||
os: ["windows-latest"] | ||
experimental: [false] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Configure AWS Credentials | ||
uses: aws-actions/configure-aws-credentials@v4.0.2 | ||
with: | ||
aws-region: us-west-1 | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/ga-ci-tests-argopy-01 | ||
|
||
- name: Set environment variables | ||
run: | | ||
echo "CONDA_ENV_FILE=ci/requirements/py${{matrix.python-version}}-core-pinned.yml" >> $GITHUB_ENV | ||
echo "PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV | ||
echo "LOG_FILE=argopy-tests-Core-Pinned-Py${{matrix.python-version}}-${{matrix.os}}.log" >> $GITHUB_ENV | ||
- name: Setup Micromamba ${{ matrix.python-version }} | ||
uses: mamba-org/setup-micromamba@v2 | ||
with: | ||
micromamba-version: '1.5.10-0' | ||
environment-name: argopy-tests | ||
environment-file: ${{ env.CONDA_ENV_FILE }} | ||
init-shell: bash | ||
cache-environment: true | ||
cache-environment-key: "${{runner.os}}-${{runner.arch}}-py${{matrix.python-version}}-${{env.TODAY}}-${{hashFiles(env.CONDA_ENV_FILE)}}" | ||
create-args: >- | ||
python=${{matrix.python-version}} | ||
- name: Install argopy | ||
run: | | ||
python -m pip install --no-deps -e . | ||
- name: Version info | ||
run: | | ||
micromamba info | ||
micromamba list | ||
- name: Test 1 | ||
continue-on-error: true | ||
run: | | ||
python -c "import argopy; print(argopy.utils.format.argo_split_path('/dac/coriolis/3902131/profiles/BD3902131_001.nc'))" | ||
- name: Test 2 | ||
continue-on-error: true | ||
run: | | ||
python -c "import argopy; print(argopy.utils.format.argo_split_path('C:/Users/runneradmin/.argopy_tutorial_data/ftp/dac/aoml/13857/profiles/R13857_001.nc'))" | ||
- name: Test 3 | ||
continue-on-error: true | ||
run: | | ||
python -c "import argopy; print(argopy.utils.format.argo_split_path('s3://argo-gdac-sandbox/pub/dac/aoml/13857/profiles/R13857_001.nc'))" |
This file contains 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 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 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 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 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
Empty file.
This file contains 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,73 @@ | ||
""" | ||
If client is online (connected to the web) we work with the 'online' implementation | ||
otherwise we fall back on an offline implementation. | ||
The choice is really meaningfull when the client is using a local host. In this case | ||
we don't know if client intends to be online or offline, so we check and implement. | ||
""" | ||
|
||
import logging | ||
|
||
from ...utils import isconnected | ||
|
||
|
||
log = logging.getLogger("argopy.stores.ArgoFloat") | ||
|
||
|
||
if isconnected(): | ||
from .implementations.argo_float_online import ArgoFloatOnline as FloatStore | ||
|
||
log.info("Using ONLINE Argo Float implementation") | ||
else: | ||
from .implementations.argo_float_offline import ArgoFloatOffline as FloatStore | ||
|
||
log.info("Using OFFLINE Argo Float implementation") | ||
|
||
|
||
class ArgoFloat(FloatStore): | ||
"""Argo GDAC float store | ||
This store makes it easy to load/read data for a given float from any GDAC location and netcdf files | ||
Examples | ||
-------- | ||
.. code-block:: python | ||
:caption: A float store is instantiated with float WMO number and a host (any access path: local, http, ftp or s3) where float files are to be found. | ||
>>> from argopy import ArgoFloat | ||
>>> af = ArgoFloat(WMO) # Use argopy 'gdac' option by default | ||
>>> af = ArgoFloat(WMO, host='/home/ref-argo/gdac') # Use your local GDAC copy | ||
>>> af = ArgoFloat(WMO, host='http') # Shortcut for https://data-argo.ifremer.fr | ||
>>> af = ArgoFloat(WMO, host='ftp') # shortcut for ftp://ftp.ifremer.fr/ifremer/argo | ||
>>> af = ArgoFloat(WMO, host='s3') # Shortcut for s3://argo-gdac-sandbox/pub | ||
.. code-block:: python | ||
:caption: Load/read GDAC netcdf files as a :class:`xarray.Dataset` | ||
>>> af.list_dataset() # Return a dictionary with all available datasets for this float | ||
>>> ds = af.open_dataset('prof') # Use keys from the available datasets dictionary | ||
>>> ds = af.open_dataset('meta') | ||
>>> ds = af.open_dataset('tech') | ||
>>> ds = af.open_dataset('Rtraj') | ||
>>> ds = af.open_dataset('Sprof') | ||
.. code-block:: python | ||
:caption: Other attributes and methods | ||
>>> af.N_CYCLES # Number of cycles (estimated) | ||
>>> af.path # root path for all float datasets | ||
>>> af.dac # name of the DAC this float belongs to | ||
>>> af.metadata # a dictionary with all available metadata for this file (from netcdf or fleetmonitoring API) | ||
>>> af.ls() # list af.path folder content | ||
.. code-block:: python | ||
:caption: Working with float profiles | ||
>>> af.lsprofiles() # list float "profiles" folder content | ||
>>> af.describe_profiles() # Pandas DataFrame describing all available float profile files | ||
""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) |
This file contains 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,11 @@ | ||
#!/bin/env python | ||
# -*coding: UTF-8 -*- | ||
# | ||
# HELP | ||
# | ||
# Created by gmaze on 09/01/2025 | ||
__author__ = 'gmaze@ifremer.fr' | ||
|
||
import os | ||
import sys | ||
import xarray as xr |
This file contains 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,91 @@ | ||
import pandas as pd | ||
import numpy as np | ||
from pathlib import Path | ||
import logging | ||
|
||
from ....errors import InvalidOption | ||
from ..spec import ArgoFloatProto | ||
|
||
|
||
log = logging.getLogger("argopy.stores.ArgoFloat") | ||
|
||
|
||
class ArgoFloatOffline(ArgoFloatProto): | ||
"""Offline :class:`ArgoFloat` implementation""" | ||
_online = False | ||
|
||
def __init__( | ||
self, | ||
*args, | ||
**kwargs, | ||
): | ||
super().__init__(*args, **kwargs) | ||
|
||
if self.host_protocol != "file": | ||
raise InvalidOption( | ||
"Trying to work with the offline store using a remote host !" | ||
) | ||
|
||
# Load some data (in a perfect world, this should be done asynchronously): | ||
self.load_dac() | ||
self.load_metadata() # must come after dac because metadata are read from netcdf files requiring dac folder name | ||
|
||
def load_metadata(self): | ||
"""Method to load float meta-data""" | ||
data = {} | ||
|
||
ds = self.open_dataset("meta") | ||
data.update( | ||
{ | ||
"deployment": { | ||
"launchDate": pd.to_datetime(ds["LAUNCH_DATE"].values, utc=True) | ||
} | ||
} | ||
) | ||
data.update( | ||
{"platform": {"type": ds["PLATFORM_TYPE"].values[np.newaxis][0].strip()}} | ||
) | ||
data.update({"maker": ds["PLATFORM_MAKER"].values[np.newaxis][0].strip()}) | ||
|
||
def infer_network(this_ds): | ||
if this_ds["PLATFORM_FAMILY"].values[np.newaxis][0].strip() == "FLOAT_DEEP": | ||
network = ["DEEP"] | ||
if len(this_ds["SENSOR"].values) > 4: | ||
network.append("BGC") | ||
|
||
elif this_ds["PLATFORM_FAMILY"].values[np.newaxis][0].strip() == "FLOAT": | ||
if len(this_ds["SENSOR"].values) > 4: | ||
network = ["BGC"] | ||
else: | ||
network = ["CORE"] | ||
|
||
else: | ||
network = ["?"] | ||
|
||
return network | ||
|
||
data.update({"networks": infer_network(ds)}) | ||
|
||
data.update({"cycles": np.unique(self.open_dataset("prof")["CYCLE_NUMBER"])}) | ||
|
||
self._metadata = data | ||
|
||
def load_dac(self): | ||
"""Load the DAC short name for this float""" | ||
try: | ||
dac = [ | ||
p.parts[-2] | ||
for p in Path(self.host).glob( | ||
self.host_sep.join(["dac", "*", "%i" % self.WMO]) | ||
) | ||
] | ||
if len(dac) > 0: | ||
self._dac = dac[0] | ||
|
||
except: | ||
raise ValueError( | ||
f"DAC name for Float {self.WMO} cannot be found from {self.host}" | ||
) | ||
|
||
# For the record, another method to get the DAC name, based on the profile index: | ||
# self._dac = self.idx.search_wmo(self.WMO).read_dac_wmo()[0][0] # Get DAC from Argo index |
Oops, something went wrong.