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
1,297 changes: 649 additions & 648 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies = [
"cmocean (>=4.0.3,<5.0.0)",
"pyyaml (>=6.0.3,<7.0.0)",
"bitsea @ git+https://github.com/inogs/bit.sea.git",
"tabulate (>=0.10.0,<1.0.0)",
]

[tool.poetry.group.dev.dependencies]
Expand Down
134 changes: 134 additions & 0 deletions src/medunda/__main__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import argparse
import logging
from pathlib import Path
from shutil import get_terminal_size
from sys import exit as sys_exit

import tabulate

from medunda.components.frequencies import Frequency
from medunda.components.variables import VariableDataset
from medunda.downloader import configure_parser as downloader_config_parser
from medunda.downloader import downloader
from medunda.plotter import configure_parser as plotter_config_parser
from medunda.plotter import plotter
from medunda.providers import PROVIDERS
from medunda.providers import get_provider
from medunda.reducer import build_action_args
from medunda.reducer import configure_parser as reducer_config_parser
from medunda.reducer import reducer
Expand Down Expand Up @@ -41,6 +49,81 @@ def parse_args() -> argparse.Namespace:
help="Plot data from a Medunda dataset",
)

show_subparser = subparsers.add_parser(
"show",
help="Show the variables or the providers available in this version of Medunda",
)

show_subsubparsers = show_subparser.add_subparsers(
title="what", required=True, dest="what", help="Choose what to show"
)

show_variables_subparser = show_subsubparsers.add_parser(
"variables",
help="Show the variables available in this version of Medunda",
)

show_variables_subparser.add_argument(
"--format",
type=str,
required=False,
default="fancy_grid",
help="The format to use when showing the variables. "
"It can be any format supported by the tabulate library. "
"The default is 'fancy_grid'; other common options are "
"'plain', 'simple', 'grid', 'rst', 'latex', and 'html'. "
"Others can be found in the tabulate documentation.",
)

show_variables_subparser.add_argument(
"--provider",
type=str,
required=False,
choices=sorted(list(PROVIDERS.keys())),
default=None,
help="The provider to filter the variables by. If not "
"specified, all variables will be shown.",
)

show_variables_subparser.add_argument(
"--provider-config",
type=Path,
required=False,
default=None,
help="If the provider requires a configuration file, this "
"argument can be used to specify the path to that file. If no "
"provider is specified, this argument will be ignored.",
)

show_variables_subparser.add_argument(
"--frequency",
type=Frequency,
choices=list(Frequency),
required=False,
default=None,
help="If a provider is specified, this argument can be used to filter the "
"variables by frequency; in other words, only the variables that the "
"provider supports at the specified frequency will be shown. "
"If no provider is specified, this argument will be ignored.",
)

show_providers_subparser = show_subsubparsers.add_parser(
"providers",
help="Show the providers available in this version of Medunda",
)

show_providers_subparser.add_argument(
"--format",
type=str,
required=False,
default="fancy_grid",
help="The format to use when showing the providers. "
"It can be any format supported by the tabulate library. "
"The default is 'fancy_grid'; other common options are "
"'plain', 'simple', 'grid', 'rst', 'latex', and 'html'. "
"Others can be found in the tabulate documentation.",
)

downloader_config_parser(subparsers.choices["downloader"])
reducer_config_parser(subparsers.choices["reducer"])
plotter_config_parser(subparsers.choices["plotter"])
Expand Down Expand Up @@ -71,6 +154,57 @@ def main():
mode=args.mode,
args=args,
)
elif args.tool == "show":
if args.what == "variables":
if args.provider is None:
variables = VariableDataset.all_variables()
else:
provider = get_provider(args.provider).create(
config_file=args.provider_config
)
if args.frequency is not None:
variables = provider.available_variables(
frequency=args.frequency
)
else:
variables = VariableDataset()
for f in Frequency:
f_variables = provider.available_variables(frequency=f)
for v in f_variables:
variables.add_variable(v)

table = [[var.name, var.get_label()] for var in variables]
table.sort(key=lambda x: x[0])
table_str = tabulate.tabulate(
table,
headers=["Variable", "Description"],
tablefmt=args.format,
)
print(table_str)
elif args.what == "providers":
table = []
for provider_name, provider_class in PROVIDERS.items():
description = provider_class.get_description()
table.append([provider_name, description])
table.sort(key=lambda x: x[0])

column_width = get_terminal_size(fallback=(70, 20)).columns
first_column_width = max(len(row[0]) for row in table) + 5
second_column_width = max(
20, column_width - first_column_width - 5
)

table_str = tabulate.tabulate(
table,
headers=["Provider", "Description"],
tablefmt=args.format,
maxcolwidths=[None, second_column_width],
)

print(table_str)
else:
LOGGER.error(f"Unknown tool: {args.tool}")
return 1


if __name__ == "__main__":
Expand Down
19 changes: 19 additions & 0 deletions src/medunda/providers/cmems.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,29 @@ class CMEMSProviderMed(CMEMSProvider):
def get_name(cls) -> str:
return "cmems_mediterranean"

@classmethod
def get_description(cls) -> str:
return (
"Provider that provides physical and biogeochemical data for "
"the Mediterranean Sea from the Copernicus Marine Data Store. "
"The physical data is available from the "
"MEDSEA_MULTIYEAR_PHY_006_004 product, while the biogeochemical "
"data is available from the MEDSEA_MULTIYEAR_BGC_006_008 product."
)


class CMEMSProviderGlobal(CMEMSProvider):
PRODUCTS = GLOBAL_PRODUCTS

@classmethod
def get_name(cls) -> str:
return "cmems_global"

@classmethod
def get_description(cls) -> str:
return (
"Provider that provides physical data for the overall global ocean "
"from the Copernicus Marine Data Store. "
"The physical data is downloaded from the "
"GLOBAL_MULTIYEAR_PHY_001_030 product."
)
9 changes: 9 additions & 0 deletions src/medunda/providers/local_reanalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,12 @@ def create(cls, config_file: Path | None = None) -> "Provider":
start_time=config_content.get("start_time", None),
end_time=config_content.get("end_time", None),
)

@classmethod
def get_description(cls) -> str:
return (
"Local reanalysis provider that retrieves data from a local "
"directory structure. The directory structure is defined in a "
"YAML configuration file that specifies the available variables, "
"their units, and the paths to the data files for each frequency."
)
11 changes: 11 additions & 0 deletions src/medunda/providers/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,14 @@ def available_variables(self, frequency: Frequency) -> VariableDataset:
A `VariableDataset` containing all available variables
"""
return VariableDataset.all_variables()

@classmethod
@abstractmethod
def get_description(cls) -> str:
"""
Returns a description of this provider

Returns:
A string describing this provider
"""
raise NotImplementedError
10 changes: 10 additions & 0 deletions src/medunda/providers/tar_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,3 +855,13 @@ def create(cls, config_file: Path | None = None) -> "Provider":
start_time=config_content.get("start_time", None),
end_time=config_content.get("end_time", None),
)

@classmethod
def get_description(cls) -> str:
return (
"Tar archive provider that retrieves data from tar archives. "
"The tar archives are expected to contain netCDF files with a "
"specific naming convention. The provider uses a YAML configuration "
"file to define the available variables, their units, and the paths "
"to the tar archives for each frequency."
)