Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0fab902
first draft ESACCI-PERMAFROST downloader
axel-lauer Feb 27, 2024
9e0be9d
snapshot 2024-02-28
axel-lauer Feb 28, 2024
680c617
working version of ESACCI-PERMAFROST downloader
axel-lauer Feb 28, 2024
127c924
some pylint fixes
axel-lauer Feb 28, 2024
ada5ae3
snapshot 2024-02-29
axel-lauer Feb 29, 2024
2230739
added cmor_config/ESACCI-PERMAFROST.yml
axel-lauer Mar 1, 2024
b7d412e
snapshot 2024-03-01
axel-lauer Mar 1, 2024
81b99c6
first working version
axel-lauer Mar 4, 2024
5487cb4
cleaned up code a bit
axel-lauer Mar 4, 2024
7682235
Merge branch 'main' into cmorize_esacci_permafrost
axel-lauer Jun 10, 2024
21708d6
snapshot 2024-06-21
axel-lauer Jun 21, 2024
f913206
merged with main
axel-lauer May 5, 2025
b0ebee8
snapshot 2025-05-07
axel-lauer May 7, 2025
ba1359e
updated recipe_check_obs.yml
axel-lauer Jul 23, 2025
ae463f4
Merge branch 'main' into cmorize_esacci_permafrost
axel-lauer Jul 23, 2025
b174566
updated input.rst
axel-lauer Jul 23, 2025
133cd2e
small formatting updates
axel-lauer Jul 23, 2025
52c7782
format updates
axel-lauer Jul 24, 2025
8fa7972
updated with latest main
axel-lauer Jan 9, 2026
e74218d
removed unneeded time zone
axel-lauer Jan 9, 2026
25668cf
changed path of regridding cache
axel-lauer Jan 12, 2026
a5811b5
add source of cdo grid definition file
axel-lauer Feb 18, 2026
98142ae
replaced glob with Path
axel-lauer Feb 18, 2026
1de23ac
removed automatic deletion of grid definition file
axel-lauer Feb 18, 2026
6f4a180
changed from ESACCI-PERMAFROST v3.0 to v5.0
axel-lauer Feb 19, 2026
0b7deee
update formatters/datasets/esacci_permafrost.py
axel-lauer Feb 19, 2026
6f09965
merged with main
axel-lauer Feb 19, 2026
c84fd37
fix codacy issues 1
axel-lauer Feb 20, 2026
69816c4
update cmor config file
axel-lauer Feb 20, 2026
105253e
fix codacy issues 2
axel-lauer Feb 20, 2026
b2c0e99
added doc sting to formatter
axel-lauer Feb 20, 2026
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
3 changes: 3 additions & 0 deletions doc/sphinx/source/input.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ A list of the datasets for which a CMORizers is available is provided in the fol

.. tabularcolumns:: |p{3cm}|p{6cm}|p{3cm}|p{3cm}|


+----------------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
| Dataset | Variables (MIP) | Tier | Script language |
+========================================+======================================================================================================+======+=================+
Expand Down Expand Up @@ -338,6 +339,8 @@ A list of the datasets for which a CMORizers is available is provided in the fol
+----------------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
| ESACCI-OZONE [#note5]_ | toz, o3 (AERmon) | 2 | Python |
+----------------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
| ESACCI-PERMAFROST | alt, gtd, pfr (Lyr, frequency: yr) | 2 | Python |
+----------------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
| ESACCI-SEAICE | siconc (SIday, SImon) | 2 | Python |
+----------------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
| ESACCI-SEA-SURFACE-SALINITY | sos (Omon) | 2 | Python |
Expand Down
29 changes: 29 additions & 0 deletions esmvaltool/cmorizers/data/cmor_config/ESACCI-PERMAFROST.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# Common global attributes for CMORizer output
attributes:
dataset_id: ESACCI-PERMAFROST
version: 'v5.0NH'
tier: 2
type: sat
project_id: OBS6
source: 'ftp://dap.ceda.ac.uk/neodc/esacci/permafrost'
reference: "esacci-permafrost"
comment: ""

# Variables to CMORize
variables:
alt:
mip: Lyr
raw: ALT
file: 'ESACCI-PERMAFROST-L4-ALT-*-AREA4_PP-{year}-fv05.0.nc'
weights_dir: './esacci-permafrost-weights'
gtd:
mip: Lyr
raw: [GST, T1m, T2m, T5m, T10m]
file: 'ESACCI-PERMAFROST-L4-GTD-*-AREA4_PP-{year}-fv05.0.nc'
weights_dir: './esacci-permafrost-weights'
pfr:
mip: Lyr
raw: PFR
file: 'ESACCI-PERMAFROST-L4-PFR-*-AREA4_PP-{year}-fv05.0.nc'
weights_dir: './esacci-permafrost-weights'
11 changes: 11 additions & 0 deletions esmvaltool/cmorizers/data/datasets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,17 @@ datasets:
Version = "v0008"
Put all files under a single directory (no subdirectories with years).

ESACCI-PERMAFROST:
tier: 2
source: ftp://dap.ceda.ac.uk/neodc/esacci/permafrost/data
last_access: 2026-02-18
info: |
Download the data from:
active_layer_thickness/L4/area4/pp/v05.0/northern_hemisphere/<yyyy>/
ground_temperature/L4/area4/pp/v05.0/northern_hemisphere/<yyyy>/
permafrost_extent/L4/area4/pp/v05.0/northern_hemisphere/<yyyy>/
Put all files in a single directory.

ESACCI-SEAICE:
tier: 2
source: ftp://anon-ftp.ceda.ac.uk/neodc/esacci/sea_ice/data/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""Script to download ESACCI-PERMAFROST."""

import datetime
import logging

from dateutil import relativedelta

from esmvaltool.cmorizers.data.downloaders.wget import WGetDownloader

logger = logging.getLogger(__name__)


def download_dataset(
original_data_dir,
dataset,
dataset_info,
start_date,
end_date,
overwrite,
) -> None:
"""Download dataset.

Parameters
----------
original_data_dir : Path
Directory where original data will be stored.
dataset : str
Name of the dataset
dataset_info : dict
Dataset information from the datasets.yml file
start_date : datetime
Start of the interval to download
end_date : datetime
End of the interval to download
overwrite : bool
Overwrite already downloaded files
"""
if start_date is None:
start_date = datetime.datetime(1997, 1, 1, tzinfo=datetime.UTC)
if end_date is None:
end_date = datetime.datetime(2023, 12, 31, tzinfo=datetime.UTC)

downloader = WGetDownloader(
original_data_dir=original_data_dir,
dataset=dataset,
dataset_info=dataset_info,
overwrite=overwrite,
)

version = "v05.0"

path = "https://dap.ceda.ac.uk/neodc/esacci/permafrost/data/"

ccivars = [
"active_layer_thickness",
"ground_temperature",
"permafrost_extent",
]

# download cci variables active layer thickness, ground temperature and
# permafrost extent
loop_date = start_date
while loop_date <= end_date:
for var in ccivars:
folder = (
path
+ f"{var}/L4/area4/pp/{version}/northern_hemisphere/{loop_date.year}/"
)
downloader.download_folder(
folder,
wget_options=["-e robots=off", "--no-parent", "--accept=nc"],
)
loop_date += relativedelta.relativedelta(years=1)
39 changes: 39 additions & 0 deletions esmvaltool/cmorizers/data/downloaders/ftp.py
Comment thread
jlenh marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import fnmatch
import ftplib
import logging
import os
Expand Down Expand Up @@ -260,6 +261,26 @@ def dataset_name(self):
"""
return self.dataset.lower().replace("-", "_")

def download_files(self, filename, path=None):
"""Download file(s).

Parameters
----------
filename : str
Name of file (w/o path) to download (wildcards are allowed)
path : str
Path of file(s) to download (optional)
"""
if path is not None:
self.set_cwd(path)
files = self._client.nlst()
matching_files = fnmatch.filter(files, filename)
if len(matching_files) != 0:
for file in matching_files:
super().download_file(file)
else:
logger.info("No files %s found.", filename)

def download_year(self, year):
"""Download a specific year.

Expand All @@ -269,3 +290,21 @@ def download_year(self, year):
Year to download
"""
self.download_folder(str(year))

def file_exists(self, filename, path=None):
"""Check if a file exists.

Parameters
----------
filename : str
Name of file (w/o path) to check (wildcards are allowed)
path : str
Path of file to check (optional)
"""
if path is not None:
self.set_cwd(path)
files = self._client.nlst()
matching_files = fnmatch.filter(files, filename)
if len(matching_files) != 0:
return True
return False
Loading