Skip to content

Commit 6fc781e

Browse files
rbeuchervaleriupredoiflicj191
authored
Add TropFlux CMORiser (#3863)
Co-authored-by: Valeriu Predoi <[email protected]> Co-authored-by: Felicity Chun <[email protected]>
1 parent 8faa403 commit 6fc781e

File tree

6 files changed

+279
-0
lines changed

6 files changed

+279
-0
lines changed

doc/sphinx/source/input.rst

+4
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ A list of the datasets for which a CMORizers is available is provided in the fol
463463
+------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
464464
| TCOM-N2O | n2o (Amon [#note3]_) | 2 | Python |
465465
+------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
466+
| TROPFLUX | ts, rlut, rsds, tauu, tauv, hfds (Amon) | 2 | Python |
467+
| | tos (Omon) | | |
468+
| | hfls (Lmon, Amon) | | |
469+
+------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
466470
| UWisc* [#t3]_ | clwvi, lwpStderr (Amon) | 3 | NCL |
467471
+------------------------------+------------------------------------------------------------------------------------------------------+------+-----------------+
468472
| WFDE5 | tas, pr (Amon, day) | 2 | Python |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
# Global attributes of NetCDF file
3+
attributes:
4+
dataset_id: TROPFLUX
5+
project_id: OBS6
6+
tier: 2
7+
version: "v1"
8+
modeling_realm: reanaly
9+
source: 'https://incois.gov.in/tropflux/'
10+
reference: 'tropflux'
11+
comment: |
12+
''
13+
14+
# Variables to CMORise
15+
variables:
16+
# monthly frequency
17+
ts_month:
18+
short_name: ts
19+
mip: Amon
20+
raw: t2m
21+
file: '/t2m_tropflux_1m_\d{4}\.nc$'
22+
23+
tos_month:
24+
short_name: tos
25+
mip: Omon
26+
raw: sst
27+
file: '/sst_tropflux_1m_\d{4}\.nc$'
28+
29+
hfls_month_Lmon:
30+
short_name: hfls
31+
mip: Lmon
32+
raw: lhf
33+
file: '/lhf_tropflux_1m_\d{4}\.nc$'
34+
35+
hfls_month_Amon:
36+
short_name: hfls
37+
mip: Amon
38+
raw: lhf
39+
file: '/lhf_tropflux_1m_\d{4}\.nc$'
40+
hfds_month:
41+
short_name: hfds
42+
mip: Omon
43+
raw: netflux
44+
file: '/netflux_tropflux_1m_\d{4}\.nc$'
45+
46+
rlus_month:
47+
short_name: rlus
48+
mip: Amon
49+
raw: lwr
50+
file: '/lwr_tropflux_1m_\d{4}\.nc$'
51+
52+
tauv_month:
53+
short_name: tauv
54+
mip: Amon
55+
raw: tauy
56+
file: '/tauy_tropflux_1m_\d{4}\.nc$'
57+
tauu_month:
58+
short_name: tauu
59+
mip: Amon
60+
raw: taux
61+
file: '/taux_tropflux_1m_\d{4}\.nc$'
62+
63+
rsds_month:
64+
short_name: rsds
65+
mip: Amon
66+
raw: swr
67+
file: '/swr_tropflux_1m_\d{4}\.nc$'

esmvaltool/cmorizers/data/datasets.yml

+8
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,14 @@ datasets:
12541254
last_access: 2023-01-17
12551255
info: |
12561256
Download the file zmn2o_TCOM_plev_T2Dz_1991_2021.nc.
1257+
1258+
TROPFLUX:
1259+
tier: 2
1260+
source: "https://incois.gov.in/tropflux"
1261+
last_access: 2025-01-15
1262+
info: |
1263+
The TropFlux project aims at providing daily, timely, accurate air-sea heat and momentum
1264+
flux data for the entire 30°N-30°S region.
12571265
12581266
UWisc:
12591267
tier: 3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# pylint: disable=unused-argument
2+
# pylint: disable=too-many-arguments
3+
# pylint: disable=too-many-function-args
4+
# pylint: disable=R0917
5+
# pylint: disable=E1121
6+
# flake8: noqa
7+
"""ESMValTool CMORizer for TROPFLUX data.
8+
9+
Tier
10+
Tier 2: other freely-available dataset.
11+
12+
Source
13+
https://incois.gov.in/tropflux
14+
15+
Last access
16+
20250115
17+
18+
Download and processing instructions
19+
Register and sign-in here:
20+
21+
https://incois.gov.in/tropflux/DataHome.jsp
22+
23+
Data is available per year from 1979 to 2018
24+
at daily and monthly frequency.
25+
26+
Products availables are:
27+
28+
- Air Temperature at 2m
29+
- Latent Heat Flux
30+
- Long Wave Radiation
31+
- Meridional Wind Stress
32+
- Net Surface Heat Flux
33+
- Sea Surface Temperature
34+
- Sensible Heat Flux
35+
- Shortwave Radiation
36+
- Specific Humidity at 2m
37+
- Wind Speed at 10m
38+
- Wind Stress magnitude
39+
- Zonal Wind Stress
40+
41+
Caveats
42+
"""
43+
44+
import logging
45+
import re
46+
from copy import deepcopy
47+
from pathlib import Path
48+
49+
import cf_units
50+
import iris
51+
from esmvalcore.cmor.table import CMOR_TABLES
52+
from iris import NameConstraint
53+
from iris.util import equalise_attributes
54+
55+
from esmvaltool.cmorizers.data import utilities as utils
56+
57+
logger = logging.getLogger(__name__)
58+
59+
# scitools-iris.readthedocs.io/en/stable/generated/api/iris.html#iris.Future
60+
try:
61+
iris.FUTURE.date_microseconds = True
62+
iris.FUTURE.save_split_attrs = True
63+
except AttributeError as e:
64+
# Handle cases where FUTURE or the attributes don't exist
65+
logger.warning("AttributeError: %s", e)
66+
except (TypeError, ValueError) as e:
67+
# Handle specific errors if these might occur
68+
logger.warning("TypeError or ValueError: %s", e)
69+
except BaseException as e:
70+
# Fallback for rare or unknown issues, but avoid catching Exception
71+
logger.warning("An unexpected error occurred: %s", e)
72+
73+
74+
def _fix_coordinates(cube, definition):
75+
cube = utils.fix_coords(cube)
76+
77+
for coord_def in definition.coordinates.values():
78+
axis = coord_def.axis
79+
coord = cube.coord(axis=axis)
80+
if axis == 'Z':
81+
coord.convert_units(coord_def.units)
82+
coord.standard_name = coord_def.standard_name
83+
coord.var_name = coord_def.out_name
84+
coord.long_name = coord_def.long_name
85+
coord.points = coord.core_points().astype('float64')
86+
if coord.var_name == 'plev':
87+
coord.attributes['positive'] = 'down'
88+
89+
return cube
90+
91+
92+
def _extract_variable(short_name, var, cfg, raw_filepaths, out_dir):
93+
attributes = deepcopy(cfg['attributes'])
94+
attributes['mip'] = var['mip']
95+
cmor_table = CMOR_TABLES[attributes['project_id']]
96+
definition = cmor_table.get_variable(var['mip'], short_name)
97+
cmor_info = cfg['cmor_table'].get_variable(var['mip'], short_name)
98+
99+
if cmor_info.positive != '':
100+
attributes['positive'] = cmor_info.positive
101+
102+
# load data
103+
raw_var = var.get('raw', short_name)
104+
cubes = iris.load(raw_filepaths, NameConstraint(var_name=raw_var))
105+
equalise_attributes(cubes)
106+
for cube in cubes:
107+
cube.rename(cubes[0].name())
108+
cube = cubes.concatenate_cube()
109+
utils.set_global_atts(cube, attributes)
110+
111+
# Set correct names
112+
cube.var_name = definition.short_name
113+
if definition.standard_name:
114+
cube.standard_name = definition.standard_name
115+
cube.long_name = definition.long_name
116+
117+
utils.fix_var_metadata(cube, cmor_info)
118+
119+
# fix time units
120+
cube.coord('time').convert_units(
121+
cf_units.Unit('days since 1950-1-1 00:00:00', calendar='gregorian'))
122+
123+
cube = _fix_coordinates(cube, definition)
124+
125+
if raw_var == 'taux':
126+
cube.data = -1 * cube.data
127+
128+
utils.save_variable(
129+
cube,
130+
short_name,
131+
out_dir,
132+
attributes,
133+
unlimited_dimensions=['time'],
134+
)
135+
136+
def cmorization(in_dir, out_dir, cfg, cfg_user, start_date, end_date):
137+
"""Run CMORizer for TROPFLUX."""
138+
for (short_name, var) in cfg['variables'].items():
139+
logger.info("CMORizing variable '%s'", short_name)
140+
short_name = var['short_name']
141+
raw_filenames = Path(in_dir).rglob("*.nc")
142+
filenames = []
143+
for raw_filename in raw_filenames:
144+
if re.search(var["file"], str(raw_filename)):
145+
filenames.append(raw_filename)
146+
147+
_extract_variable(short_name, var, cfg, filenames, out_dir)

esmvaltool/recipes/examples/recipe_check_obs.yml

+24
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,30 @@ diagnostics:
20242024
type: reanaly, version: 4, start_year: 1979, end_year: 2022}
20252025
scripts: null
20262026

2027+
TROPFLUX:
2028+
description: TROPFLUX
2029+
variables:
2030+
ts:
2031+
mip: Amon
2032+
tos:
2033+
mip: Omon
2034+
hfls:
2035+
mip: Lmon
2036+
hfls:
2037+
mip: Amon
2038+
rlut:
2039+
mip: Amon
2040+
tauu:
2041+
mip: Amon
2042+
tauv:
2043+
mip: Amon
2044+
rsds:
2045+
mip: Amon
2046+
additional_datasets:
2047+
- {dataset: TROPFLUX, project: OBS6, tier: 2,
2048+
type: reanaly, version: v1, start_year: 1979, end_year: 2018}
2049+
scripts: null
2050+
20272051
UWisc:
20282052
description: UWisc check
20292053
variables:

esmvaltool/references/tropflux.bibtex

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@article{PraveenKumar2012,
2+
author = {Praveen Kumar, B. and Vialard, J. and Lengaigne, M. and Murty, V. S. N. and McPhaden, M. J.},
3+
title = {TropFlux: air-sea fluxes for the global tropical oceans—description and evaluation},
4+
journal = {Climate Dynamics},
5+
year = {2012},
6+
volume = {38},
7+
number = {7},
8+
pages = {1521--1543},
9+
month = {Apr},
10+
abstract = {In this paper, we evaluate several timely, daily air-sea heat flux products (NCEP, NCEP2, ERA-Interim and OAFlux/ISCCP) against observations and present the newly developed TropFlux product. This new product uses bias-corrected ERA-interim and ISCCP data as input parameters to compute air-sea fluxes from the COARE v3.0 algorithm. Wind speed is corrected for mesoscale gustiness. Surface net shortwave radiation is based on corrected ISCCP data. We extend the shortwave radiation time series by using “near real-time” SWR estimated from outgoing longwave radiation. All products reproduce consistent intraseasonal surface net heat flux variations associated with the Madden-Julian Oscillation in the Indian Ocean, but display more disparate interannual heat flux variations associated with El Niño in the eastern Pacific. They also exhibit marked differences in mean values and seasonal cycle. Comparison with global tropical moored buoy array data, I-COADS and fully independent mooring data sets shows that the two NCEP products display lowest correlation to mooring turbulent fluxes and significant biases. ERA-interim data captures well temporal variability, but with significant biases. OAFlux and TropFlux perform best. All products have issues in reproducing observed longwave radiation. Shortwave flux is much better captured by ISCCP data than by any of the re-analyses. Our “near real-time” shortwave radiation performs better than most re-analyses, but tends to underestimate variability over the cold tongues of the Atlantic and Pacific. Compared to independent mooring data, NCEP and NCEP2 net heat fluxes display ~0.78 correlation and >65 W m−2 rms-difference, ERA-I performs better (~0.86 correlation and ~48 W m−2) while OAFlux and TropFlux perform best (~0.9 correlation and ~43 W m−2). TropFlux hence provides a useful option for studying flux variability associated with ocean–atmosphere interactions, oceanic heat budgets and climate fluctuations in the tropics.},
11+
issn = {1432-0894},
12+
url = {https://doi.org/10.1007/s00382-011-1115-0},
13+
doi = {10.1007/s00382-011-1115-0}
14+
}
15+
16+
@article{PraveenKumar2013,
17+
author = {Praveen Kumar, B. and Vialard, J. and Lengaigne, M. and Murty, V. S. N. and McPhaden, M. J. and Cronin, M. F. and Pinsard, F. and Gopala Reddy, K.},
18+
title = {TropFlux wind stresses over the tropical oceans: evaluation and comparison with other products},
19+
journal = {Climate Dynamics},
20+
year = {2013},
21+
volume = {40},
22+
number = {7},
23+
pages = {2049--2071},
24+
month = {Apr},
25+
abstract = {In this paper, we present TropFlux wind stresses and evaluate them against observations along with other widely used daily air-sea momentum flux products (NCEP, NCEP2, ERA-I and QuikSCAT). TropFlux wind stresses are computed from the COARE v3.0 algorithm, using bias and amplitude corrected ERA-I input data and an additional climatological gustiness correction. The wind stress products are evaluated against dependent data from the TAO/TRITON, PIRATA and RAMA arrays and independent data from the OceanSITES mooring networks. Wind stress products are more consistent amongst each other than surface heat fluxes, suggesting that 10 m-winds are better constrained than near-surface thermodynamical parameters (2 m-humidity and temperature) and surface downward radiative fluxes. QuikSCAT overestimates wind stresses away from the equator, while NCEP and NCEP2 underestimate wind stresses, especially in the equatorial Pacific. QuikSCAT wind stress quality is strongly affected by rain under the Inter Tropical Convergence Zones. ERA-I and TropFlux display the best agreement with in situ data, with correlations >0.93 and rms-differences <0.012 Nm−2. TropFlux wind stresses exhibit a small, but consistent improvement (at all timescales and most locations) over ERA-I, with an overall 17% reduction in root mean square error. ERA-I and TropFlux agree best with long-term mean zonal wind stress observations at equatorial latitudes. All products tend to underestimate the zonal wind stress seasonal cycle by ~20% in the western and central equatorial Pacific. TropFlux and ERA-I equatorial zonal wind stresses have clearly the best phase agreement with mooring data at intraseasonal and interannual timescales (correlation of ~0.9 versus ~0.8 at best for any other product), with TropFlux correcting the ~13% underestimation of ERA-I variance at both timescales. For example, TropFlux was the best at reproducing westerly wind bursts that played a key role in the 1997–1998 El Niño onset. Hence, we recommend the use of TropFlux for studies of equatorial ocean dynamics.},
26+
issn = {1432-0894},
27+
url = {https://doi.org/10.1007/s00382-012-1455-4},
28+
doi = {10.1007/s00382-012-1455-4}
29+
}

0 commit comments

Comments
 (0)