Skip to content

Commit e4fef6e

Browse files
committed
Merge remote-tracking branch 'samsrabin/standardize-time-metadata' into standardize-time-metadata
Getting my local copy of this branch in sync with the remote.
2 parents 0360129 + 9b71518 commit e4fef6e

File tree

10 files changed

+115
-23
lines changed

10 files changed

+115
-23
lines changed

cime_config/SystemTests/rxcropmaturity.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def __init__(self, case):
106106
# Which conda environment should we use?
107107
self._get_conda_env()
108108

109-
def _run_phase(self, skip_gen=False):
109+
def _run_phase(self, skip_gen=False, h1_inst=False):
110110
# Modeling this after the SSP test, we create a clone to be the case whose outputs we don't
111111
# want to be saved as baseline.
112112

@@ -129,7 +129,7 @@ def _run_phase(self, skip_gen=False):
129129
self._set_active_case(case_gddgen)
130130

131131
# Set up stuff that applies to both tests
132-
self._setup_all()
132+
self._setup_all(h1_inst)
133133

134134
# Add stuff specific to GDD-Generating run
135135
logger.info("RXCROPMATURITY log: modify user_nl files: generate GDDs")
@@ -196,7 +196,7 @@ def _run_phase(self, skip_gen=False):
196196
self._set_active_case(case_rxboth)
197197

198198
# Set up stuff that applies to both tests
199-
self._setup_all()
199+
self._setup_all(h1_inst)
200200

201201
# Add stuff specific to Prescribed Calendars run
202202
logger.info("RXCROPMATURITY log: modify user_nl files: Prescribed Calendars")
@@ -264,7 +264,7 @@ def _get_rx_dates(self):
264264
logger.error(error_message)
265265
raise RuntimeError(error_message)
266266

267-
def _setup_all(self):
267+
def _setup_all(self, h1_inst):
268268
logger.info("RXCROPMATURITY log: _setup_all start")
269269

270270
# Get some info
@@ -274,7 +274,7 @@ def _setup_all(self):
274274

275275
# Set sowing dates file (and other crop calendar settings) for all runs
276276
logger.info("RXCROPMATURITY log: modify user_nl files: all tests")
277-
self._modify_user_nl_allruns()
277+
self._modify_user_nl_allruns(h1_inst)
278278
logger.info("RXCROPMATURITY log: _setup_all done")
279279

280280
# Make a surface dataset that has every crop in every gridcell
@@ -399,7 +399,7 @@ def _run_check_rxboth_run(self, skip_gen):
399399
tool_path,
400400
)
401401

402-
def _modify_user_nl_allruns(self):
402+
def _modify_user_nl_allruns(self, h1_inst):
403403
nl_additions = [
404404
"cropcals_rx = .true.",
405405
"cropcals_rx_adapt = .false.",
@@ -417,6 +417,8 @@ def _modify_user_nl_allruns(self):
417417
"hist_type1d_pertape(2) = 'PFTS'",
418418
"hist_dov2xy(2) = .false.",
419419
]
420+
if h1_inst:
421+
nl_additions.append("hist_avgflag_pertape(2) = 'I'")
420422
self._append_to_user_nl_clm(nl_additions)
421423

422424
def _run_generate_gdds(self, case_gddgen):
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from rxcropmaturity import RXCROPMATURITYSHARED
2+
3+
4+
class RXCROPMATURITYINST(RXCROPMATURITYSHARED):
5+
def run_phase(self):
6+
self._run_phase(h1_inst=True)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from rxcropmaturity import RXCROPMATURITYSHARED
2+
3+
4+
class RXCROPMATURITYSKIPGENINST(RXCROPMATURITYSHARED):
5+
def run_phase(self):
6+
self._run_phase(skip_gen=True, h1_inst=True)

cime_config/config_tests.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ This defines various CTSM-specific system tests
145145
<HIST_N>$STOP_N</HIST_N>
146146
</test>
147147

148+
<test NAME="RXCROPMATURITYINST">
149+
<DESC>As RXCROPMATURITY but ensure instantaneous h1. Can be removed once instantaneous and other variables are on separate files.</DESC>
150+
<INFO_DBUG>1</INFO_DBUG>
151+
<DOUT_S>FALSE</DOUT_S>
152+
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
153+
<REST_OPTION>never</REST_OPTION>
154+
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
155+
<HIST_N>$STOP_N</HIST_N>
156+
</test>
157+
148158
<test NAME="RXCROPMATURITYSKIPGEN">
149159
<DESC>As RXCROPMATURITY but don't actually generate GDDs. Allows short testing with existing GDD inputs.</DESC>
150160
<INFO_DBUG>1</INFO_DBUG>
@@ -155,6 +165,16 @@ This defines various CTSM-specific system tests
155165
<HIST_N>$STOP_N</HIST_N>
156166
</test>
157167

168+
<test NAME="RXCROPMATURITYSKIPGENINST">
169+
<DESC>As RXCROPMATURITYSKIPGEN but ensure instantaneous h1. Can be removed once instantaneous and other variables are on separate files.</DESC>
170+
<INFO_DBUG>1</INFO_DBUG>
171+
<DOUT_S>FALSE</DOUT_S>
172+
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
173+
<REST_OPTION>never</REST_OPTION>
174+
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
175+
<HIST_N>$STOP_N</HIST_N>
176+
</test>
177+
158178
<!--
159179
SSP smoke CLM spinup test (only valid for CLM compsets with CLM45)
160180
do an initial spin test (setting CLM_ACCELERATED_SPINUP to on)

cime_config/testdefs/testlist_clm.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,6 +3603,17 @@
36033603
</options>
36043604
</test>
36053605

3606+
<test name="RXCROPMATURITYINST_Lm61" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
3607+
<machines>
3608+
<machine name="derecho" compiler="intel" category="rxcropmaturity"/>
3609+
<machine name="derecho" compiler="intel" category="crop_calendars"/>
3610+
</machines>
3611+
<options>
3612+
<option name="wallclock">6:00:00</option>
3613+
<option name="comment">As RXCROPMATURITY, but ensure that h1 file is instantaneous. Can be removed once instantaneous and other variables are separated onto separate files.</option>
3614+
</options>
3615+
</test>
3616+
36063617
<test name="RXCROPMATURITYSKIPGEN_Ld1097" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
36073618
<machines>
36083619
<machine name="derecho" compiler="intel" category="aux_clm"/>
@@ -3615,6 +3626,17 @@
36153626
</options>
36163627
</test>
36173628

3629+
<test name="RXCROPMATURITYSKIPGENINST_Ld1097" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
3630+
<machines>
3631+
<machine name="derecho" compiler="intel" category="rxcropmaturity"/>
3632+
<machine name="derecho" compiler="intel" category="crop_calendars"/>
3633+
</machines>
3634+
<options>
3635+
<option name="wallclock">00:45:00</option>
3636+
<option name="comment">As RXCROPMATURITYSKIPGEN, but ensure that h1 file is instantaneous. Can be removed once instantaneous and other variables are separated onto separate files.</option>
3637+
</options>
3638+
</test>
3639+
36183640
<test name="ERP_D_P64x2_Ld10" grid="f10_f10_mg37" compset="I2000Clm60Bgc" testmods="clm/Hillslope">
36193641
<machines>
36203642
<machine name="derecho" compiler="intel" category="aux_clm"/>

python/ctsm/crop_calendars/convert_axis_time2gs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import sys
66
import numpy as np
77
import xarray as xr
8+
from ctsm.crop_calendars.cropcal_utils import get_integer_years
89

910
try:
1011
import pandas as pd
@@ -85,7 +86,7 @@ def set_up_ds_with_gs_axis(ds_in):
8586
if not any(x in ["mxsowings", "mxharvests"] for x in ds_in[var].dims):
8687
data_vars[var] = ds_in[var]
8788
# Set up the new dataset
88-
gs_years = [t.year - 1 for t in ds_in.time.values[:-1]]
89+
gs_years = get_integer_years(ds_in)[:-1]
8990
coords = ds_in.coords
9091
coords["gs"] = gs_years
9192
ds_out = xr.Dataset(data_vars=data_vars, coords=coords, attrs=ds_in.attrs)

python/ctsm/crop_calendars/cropcal_figs_module.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from matplotlib import cm
1414
import matplotlib.collections as mplcol
1515

16+
# pylint: disable=abstract-class-instantiated
1617

1718
# Colormaps (maps)
1819
cropcal_colors = {

python/ctsm/crop_calendars/cropcal_module.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,16 @@ def check_and_trim_years(year_1, year_n, ds_in):
2020
"""
2121
After importing a file, restrict it to years of interest.
2222
"""
23-
### In annual outputs, file with name Y is actually results from year Y-1.
24-
### Note that time values refer to when it was SAVED. So 1981-01-01 is for year 1980.
25-
26-
def get_year_from_cftime(cftime_date):
27-
# Subtract 1 because the date for annual files is when it was SAVED
28-
return cftime_date.year - 1
2923

3024
# Check that all desired years are included
31-
if get_year_from_cftime(ds_in.time.values[0]) > year_1:
32-
raise RuntimeError(
33-
f"Requested year_1 is {year_1} but first year in outputs is "
34-
+ f"{get_year_from_cftime(ds_in.time.values[0])}"
35-
)
36-
if get_year_from_cftime(ds_in.time.values[-1]) < year_1:
25+
year = utils.get_timestep_year(ds_in, ds_in.time.values[0])
26+
if year > year_1:
3727
raise RuntimeError(
38-
f"Requested year_n is {year_n} but last year in outputs is "
39-
+ f"{get_year_from_cftime(ds_in.time.values[-1])}"
28+
f"Requested year_1 is {year_1} but first year in outputs is {year}"
4029
)
30+
year = utils.get_timestep_year(ds_in, ds_in.time.values[-1])
31+
if year < year_1:
32+
raise RuntimeError(f"Requested year_n is {year_n} but last year in outputs is {year}")
4133

4234
# Remove years outside range of interest
4335
### Include an extra year at the end to finish out final seasons.

python/ctsm/crop_calendars/cropcal_utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,45 @@ def make_lon_increasing(xr_obj):
430430
raise RuntimeError("Unable to rearrange longitude axis so it's monotonically increasing")
431431

432432
return xr_obj.roll(lon=shift, roll_coords=True)
433+
434+
435+
def is_inst_file(dsa):
436+
"""
437+
Check whether Dataset or DataArray has time data from an "instantaneous file"
438+
"""
439+
return "at end of" in dsa["time"].attrs["long_name"]
440+
441+
442+
def get_beg_inst_timestep_year(timestep):
443+
"""
444+
Get year associated with the BEGINNING of a timestep in an
445+
instantaneous file
446+
"""
447+
year = timestep.year
448+
449+
is_jan1 = timestep.dayofyr == 1
450+
is_midnight = timestep.hour == timestep.minute == timestep.second == 0
451+
if is_jan1 and is_midnight:
452+
year -= 1
453+
454+
return year
455+
456+
457+
def get_timestep_year(dsa, timestep):
458+
"""
459+
Get the year associated with a timestep, with different handling
460+
depending on whether the file is instantaneous
461+
"""
462+
if is_inst_file(dsa):
463+
year = get_beg_inst_timestep_year(timestep)
464+
else:
465+
year = timestep.year
466+
return year
467+
468+
469+
def get_integer_years(dsa):
470+
"""
471+
Convert time axis to numpy array of integer years
472+
"""
473+
out_array = [get_timestep_year(dsa, t) for t in dsa["time"].values]
474+
return out_array

python/ctsm/crop_calendars/generate_gdds_functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,8 @@ def import_and_process_1yr(
553553
clm_gdd_var = "GDDACCUM"
554554
my_vars = [clm_gdd_var, "GDDHARV"]
555555
patterns = [f"*h2.{this_year-1}-01*.nc", f"*h2.{this_year-1}-01*.nc.base"]
556-
for p in patterns:
557-
pattern = os.path.join(indir, p)
556+
for pat in patterns:
557+
pattern = os.path.join(indir, pat)
558558
h2_files = glob.glob(pattern)
559559
if h2_files:
560560
break

0 commit comments

Comments
 (0)