Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ coverage.xml
*.cover
.hypothesis/
.pytest_cache/
.ruff_cache/
.mypy_cache/

# Translations
*.mo
Expand All @@ -80,7 +82,7 @@ instance/

# Sphinx documentation
docs/_build/
docs/
docs/generated/

# PyBuilder
target/
Expand Down
5 changes: 5 additions & 0 deletions docs/_templates/autosummary/base.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{ objname | escape | underline }}

.. currentmodule:: {{ module }}

.. auto{{ objtype }}:: {{ objname }}
7 changes: 7 additions & 0 deletions docs/_templates/autosummary/class.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{ objname | escape | underline }}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
:members:
:show-inheritance:
77 changes: 77 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
API reference
=============

This page is generated from the docstrings.

Matchup
-------

.. currentmodule:: floatmatcher.floatmatcher

.. autosummary::
:toctree: generated/

FloatMatcher

Points and results
------------------

.. currentmodule:: floatmatcher.pointset

.. autosummary::
:toctree: generated/

PointSet

.. currentmodule:: floatmatcher.matchup_results

.. autosummary::
:toctree: generated/

MatchupResult

Errors
------

.. currentmodule:: floatmatcher.exceptions

.. autosummary::
:toctree: generated/

FloatMatcherError
ProfileFormatError

Extending FloatMatcher
----------------------

Products, sources and methods are classes registered by name, so that ``set_product`` and
``set_method`` can find them.

.. currentmodule:: floatmatcher.product

.. autosummary::
:toctree: generated/

Product
ERA5Product
LUTProduct
to_standard
available_products

.. currentmodule:: floatmatcher.sources

.. autosummary::
:toctree: generated/

Source
LocalSource
available_sources

.. currentmodule:: floatmatcher.methods

.. autosummary::
:toctree: generated/

Method
NearestNeighbor
available_methods
45 changes: 45 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Configuration file for the Sphinx documentation builder.
# Build: uv run --group docs sphinx-build -W -b html docs docs/_build/html

import floatmatcher

project = "FloatMatcher"
author = "Clement Weber, Guillaume Maze, Kevin Ballem, Alban Sizun, Virginie Racapé"
copyright = "EUPL v1.2"
release = floatmatcher.__version__
version = release

extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
"numpydoc",
"sphinx_copybutton",
]

templates_path = ["_templates"]
exclude_patterns = ["_build"]

# API pages are generated from the docstrings (numpydoc style, like argopy)
autosummary_generate = True
numpydoc_show_class_members = False

# readable names: "FloatMatcher" rather than "floatmatcher.floatmatcher.FloatMatcher"
add_module_names = False # signatures
toc_object_entries_show_parents = "hide" # "On this page": set_points, not FloatMatcher.set_points
autodoc_member_order = "bysource" # methods in the order of the code (the user workflow)

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"numpy": ("https://numpy.org/doc/stable", None),
"pandas": ("https://pandas.pydata.org/docs", None),
"xarray": ("https://docs.xarray.dev/en/stable", None),
}

html_theme = "sphinx_book_theme"
html_title = "FloatMatcher"
html_theme_options = {
"repository_url": "https://github.com/euroargodev/FloatMatcher",
"use_repository_button": True,
}
25 changes: 25 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FloatMatcher
============

FloatMatcher matches positions, such as Argo profiles, with a gridded product such as the
ERA5 reanalysis: each position gets the values of the nearest node of the grid, within a
distance and a time gap.

.. code-block:: python

import numpy as np
from floatmatcher.floatmatcher import FloatMatcher

fm = FloatMatcher()
fm.set_points(lon, lat, time) # or a DataFrame, or an xarray Dataset
fm.set_product("era5", "local", "/data/era5", ["sst"],
pattern="{year}/{month:02d}/era5_{year}{month:02d}{day:02d}.nc")
fm.set_method("nearest", radius=50, time_gap=np.timedelta64(3, "h"))
fm.match()
fm.result # matched values, distances and time gaps
fm.reinject() # the input DataFrame or Dataset, with <name>_coloc added

.. toctree::
:maxdepth: 2

api
4 changes: 2 additions & 2 deletions examples/tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
"# TODO : set_points_from dataframe/dataset\n",
"\n",
"# 1.1 example\n",
"my_fm.set_points_from_arrays(lon, lat, time)\n",
"my_fm.set_points(lon, lat, time)\n",
"my_fm"
]
},
Expand Down Expand Up @@ -327,7 +327,7 @@
"lon, lat, time = mocking.random_positions(50)\n",
"\n",
"my_fm = fm.FloatMatcher()\n",
"my_fm.set_points_from_arrays(lon, lat, time)\n",
"my_fm.set_points(lon, lat, time)\n",
"\n",
"# set_local_product not implemented yet: product and variables set directly\n",
"my_fm.product = ERA5Product.from_local(path=\"/runtime/data/era5_daily/2018/01\")\n",
Expand Down
5 changes: 3 additions & 2 deletions examples/tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# TODO : set_points_from dataframe/dataset

# 1.1 example
my_fm.set_points_from_arrays(lon, lat, time)
my_fm.set_points(lon, lat, time)



Expand Down Expand Up @@ -73,10 +73,11 @@

# my_fm.status() # TODO

result = my_fm.match() # or resultats = my_fm.match()
my_fm.match()

# Compte rendu / visualisation etc..
my_fm.result

# my_fm.result_summary()
# my_fm.result_viz(header=Npoints)

Expand Down
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ dev = [
"mypy",
"ruff",
]
docs = [
"numpydoc>=1.11.0",
"sphinx>=9.0.4",
"sphinx-book-theme>=1.4.0",
"sphinx-copybutton>=0.5.2",
]

[tool.hatch.build.targets.wheel]
packages = ["src/floatmatcher"]
Expand Down
9 changes: 8 additions & 1 deletion src/floatmatcher/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
__version__ = "0.1.0"
from importlib.metadata import PackageNotFoundError, version

try:
# single source of truth: the version of pyproject.toml, read from the installed package
__version__ = version("floatmatcher")
except PackageNotFoundError:
# local copy, not installed (same fallback as argopy)
__version__ = "999"
12 changes: 7 additions & 5 deletions src/floatmatcher/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

# --- geography ---
EARTH_RADIUS_KM: float = 6371.0
"""Mean Earth radius (km), used to project lon/lat onto a sphere in geo.py."""
"""float: Mean Earth radius (km), used to project lon/lat onto a sphere in geo.py"""

# --- time ---
TIME_UNIT: str = "ns"
"""Canonical datetime64 resolution enforced across the library (points and grids)."""
"""str: Canonical datetime64 resolution enforced across the library (points and grids)"""

REF_TIME: np.datetime64 = np.datetime64("1970-01-01", "ns")
"""Reference epoch: datetime64 values are turned into floating-point days from
here for the 1D temporal KDTree. Any fixed epoch works; what matters is that
points and grid use the SAME one, so their difference is correct."""
"""numpy.datetime64: Reference epoch of the time lookup

Datetimes are turned into floating-point seconds from here for the 1D temporal KDTree. Any
fixed epoch works; what matters is that points and grid use the SAME one, so their
difference is correct"""
11 changes: 8 additions & 3 deletions src/floatmatcher/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@


class FloatMatcherError(Exception):
"""Base class for all FloatMatcher errors."""
"""Base class for all FloatMatcher errors

Catch it to handle every error raised by the library.
"""


class ProfileFormatError(FloatMatcherError):
"""Raised when point data cannot be extracted from the given source
(missing coordinate, unrecognized structure)."""
"""Raise when the points cannot be extracted from the given data

A coordinate or variable is missing, or the structure is not recognized.
"""

Loading
Loading