Skip to content

Commit 7550b3d

Browse files
committed
CDAT migration: Fix African easterly wave density plots in TC analysis and convert H20LNZ units to ppm/volume (#882)
1 parent 8031e2f commit 7550b3d

File tree

3 files changed

+43
-22
lines changed

3 files changed

+43
-22
lines changed

e3sm_diags/driver/tc_analysis_driver.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ def run_diag(parameter: TCAnalysisParameter) -> TCAnalysisParameter:
8181
test_data_path,
8282
"aew_hist_{}_{}_{}.nc".format(test_name, test_start_yr, test_end_yr),
8383
)
84-
test_aew_hist = xr.open_dataset(test_aew_file).sel(
85-
lat=slice(0, 35), lon=slice(180, 360)
86-
)["density"]
84+
test_aew_hist = xr.open_dataset(test_aew_file).sel()["density"]
8785

8886
test_data = collections.OrderedDict()
8987
ref_data = collections.OrderedDict()
@@ -120,9 +118,7 @@ def run_diag(parameter: TCAnalysisParameter) -> TCAnalysisParameter:
120118
"aew_hist_{}_{}_{}.nc".format(ref_name, ref_start_yr, ref_end_yr),
121119
)
122120
# Note the refactor included subset that was missed in original implementation
123-
ref_aew_hist = xr.open_dataset(ref_aew_file).sel(
124-
lat=slice(0, 35), lon=slice(180, 360)
125-
)["density"]
121+
ref_aew_hist = xr.open_dataset(ref_aew_file).sel()["density"]
126122
ref_data["metrics"] = generate_tc_metrics_from_te_stitch_file(ref_te_file)
127123
ref_data["cyclone_density"] = ref_cyclones_hist # type: ignore
128124
ref_data["aew_density"] = ref_aew_hist # type: ignore
@@ -181,19 +177,10 @@ def generate_tc_metrics_from_te_stitch_file(te_stitch_file: str) -> Dict[str, An
181177
if not lines_orig:
182178
raise ValueError(f"The file {te_stitch_file} is empty.")
183179

184-
line_ind = []
185180
data_start_year = int(te_stitch_file.split(".")[-2].split("_")[-2])
186181
data_end_year = int(te_stitch_file.split(".")[-2].split("_")[-1])
187-
for i in range(0, np.size(lines_orig)):
188-
if lines_orig[i][0] == "s":
189-
year = int(lines_orig[i].split("\t")[2])
190-
191-
if year <= data_end_year:
192-
line_ind.append(i)
193182

194-
# Remove excessive time points cross year bounds from 6 hourly data
195-
end_ind = line_ind[-1]
196-
lines = lines_orig[0:end_ind]
183+
lines = _filter_lines_within_year_bounds(lines_orig, data_end_year)
197184

198185
if not lines:
199186
raise ValueError(f"The file {te_stitch_file} is empty.")
@@ -243,6 +230,43 @@ def generate_tc_metrics_from_te_stitch_file(te_stitch_file: str) -> Dict[str, An
243230
return result_mod
244231

245232

233+
def _filter_lines_within_year_bounds(
234+
lines_orig: List[str], data_end_year: int
235+
) -> List[str]:
236+
"""Filters lines within the specified year bounds.
237+
238+
This function processes a list of strings, each representing a line of data.
239+
It filters out lines based on a year extracted from each line, ensuring that
240+
only lines with years less than or equal to `data_end_year` are retained.
241+
Additionally, it removes excessive time points crossing year bounds from
242+
6-hourly data.
243+
244+
Parameters
245+
----------
246+
lines_orig : List[str]
247+
A list of strings where each string represents a line of data.
248+
data_end_year : int
249+
The end year for filtering lines. Only lines with years less than or
250+
equal to this value will be retained.
251+
Returns
252+
-------
253+
List[str]
254+
A list of strings filtered based on the specified year bounds.
255+
"""
256+
line_ind = []
257+
for i in range(0, np.size(lines_orig)):
258+
if lines_orig[i][0] == "s":
259+
year = int(lines_orig[i].split("\t")[2])
260+
261+
if year <= data_end_year:
262+
line_ind.append(i)
263+
264+
end_ind = line_ind[-1]
265+
266+
new_lines = lines_orig[0:end_ind]
267+
return new_lines
268+
269+
246270
def _calc_num_storms_and_max_len(lines: List[str]) -> Tuple[int, int]:
247271
"""Calculate number of storms and max length using lines from a TE stitch file.
248272

e3sm_diags/driver/zonal_mean_2d_driver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def _convert_g_kg_to_ppm_units(
138138
139139
This is a special case to handle small values of stratosphere specific
140140
humidity. The general derived variable process converts specific humidity to
141-
units [g/kg]. This function converts from "g/kg" to "ppm".
141+
units [g/kg]. This function converts from "g/kg" to "ppm" by volume.
142142
143143
Parameters
144144
----------
@@ -161,8 +161,8 @@ def _convert_g_kg_to_ppm_units(
161161
parameter.current_set == "zonal_mean_2d_stratosphere"
162162
and parameter.var_id == "Q"
163163
):
164-
ds_new[var_key] = ds_new[var_key] * 1000.0
165-
ds_new[var_key].attrs["units"] = "ppm"
164+
ds_new[var_key] = ds_new[var_key] * 28.97 / 18.0 * 1000.0
165+
ds_new[var_key].attrs["units"] = "ppmv"
166166

167167
return ds_new
168168

tests/e3sm_diags/driver/test_tc_analysis_driver.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ def test_correct_output(self):
7777
"vsmc": np.array([[1.94, np.nan]]),
7878
"yearmc": np.array([[1, np.nan]]),
7979
"monthmc": np.array([[1, np.nan]]),
80-
"year_start": 90,
81-
"year_end": 90,
82-
"num_years": 1,
8380
}
8481
num_storms = 2 # noqa
8582
basin_info = BASIN_DICT["NA"] # noqa

0 commit comments

Comments
 (0)