Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize time metadata (we will mark this as the release tag for ctsm5.3) #2052

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
bdf6b32
Changes to remove 0th timestep
olyson Jun 1, 2023
7278900
Standardize time_bounds long_name.
samsrabin Jul 10, 2023
0ae9dcf
Add units to time_bounds.
samsrabin Jul 10, 2023
21fae29
Add calendar to time_bounds.
samsrabin Jul 10, 2023
1eb46c4
Renamed dimension hist_interval to nbnd.
samsrabin Jul 10, 2023
bbb8080
Use my RTM/MOSART forks' standardize-time-metadata branches.
samsrabin Jul 11, 2023
f255b06
Add calendar attribute to mcdate, mcsec, mdcur, and mscur.
samsrabin Jul 11, 2023
a9eb1e7
Changes for lilac
olyson Jul 25, 2023
b8be204
Remove do while loop and dosend variable.
olyson Jul 25, 2023
7f38c07
Fix unit tests for nstep starting at 1 instead of 0
billsacks Jul 25, 2023
55184f4
Merge pull request #1 from billsacks/zerothtstep
olyson Jul 26, 2023
750ed1d
Cleanup.
olyson Jul 27, 2023
198ac31
Merge branch 'zerothtstep' of https://github.com/olyson/ctsm into zer…
olyson Jul 27, 2023
caa384b
Remove comment.
olyson Aug 1, 2023
0dfd901
Remove BACKWARD COMPATIBILITY comment.
olyson Aug 3, 2023
881fd07
Merge tag 'ctsm5.1.dev131' into standardize-time-metadata
samsrabin Aug 4, 2023
d5b007f
Merge tag 'ctsm5.1.dev147' into zerothtstep
olyson Nov 1, 2023
c9c89a8
Correct a comment.
samsrabin Nov 1, 2023
d059220
Print error()s to console, not just log file.
samsrabin Nov 1, 2023
b311d1d
Rearrange search for h2 files in import_and_process_1yr().
samsrabin Nov 1, 2023
fa843e5
Fix h2 file patterns in import_and_process_1yr().
samsrabin Nov 1, 2023
11b6042
Merge pull request #2 from samsrabin/zerothtstep-fix-RXCROPMATURITY
olyson Nov 2, 2023
258792e
If avgflag /= 'I', time_bounds is present and time = mid of time_bounds
slevis-lmwg Mar 28, 2024
020db62
Merge commit '258792e9c2ecf34d5e7dd58b556b34330edd0884' into hist_tim…
slevis-lmwg Oct 17, 2024
1e81456
Remove a comment unrelated to these modifications
slevis-lmwg Oct 17, 2024
268ad5a
Merge tag 'ctsm5.3.010' into zerothtstep
slevis-lmwg Nov 12, 2024
d07fd9d
Removed comments with prefix !KO
slevis-lmwg Nov 12, 2024
0f54bc2
Merge tag 'ctsm5.3.011' into zerothtstep
slevis-lmwg Nov 12, 2024
a4b9dcf
Update docstring of is_first_step function
slevis-lmwg Nov 12, 2024
4d0ac48
New update of function's docstring
slevis-lmwg Nov 12, 2024
e578ae7
Fix typo in comment
slevis-lmwg Nov 12, 2024
bd51b8c
Correct a variable name that came in with a merge conflict
slevis-lmwg Nov 12, 2024
e87b119
Correct another error that came in with a merge conflict
slevis-lmwg Nov 13, 2024
18acd55
Merge remote-tracking branch 'escomp/master' into hist_time_mid_of_ti…
slevis-lmwg Nov 13, 2024
c42cd12
Update .gitmodules to the mosart/rtm tags corresponding to this ctsm
slevis-lmwg Nov 13, 2024
71fbe09
cropcal_module.py import_output(): Handle "instantaneous files."
samsrabin Nov 14, 2024
a51816e
Reformat with black.
samsrabin Nov 15, 2024
3220dbb
Add previous commit to .git-blame-ignore-revs.
samsrabin Nov 15, 2024
760eb96
Merge pull request #16 from samsrabin/ctsm_hist_time_mid_of_time_boun…
slevis-lmwg Nov 15, 2024
ea91981
Draft ChangeLog/ChangeSum
slevis-lmwg Nov 15, 2024
c7e1366
Revert change I brought in with the conflicts
slevis-lmwg Nov 15, 2024
f85104b
Merge branch 'hist_time_mid_of_time_bounds' into zerothtstep
slevis-lmwg Nov 15, 2024
5148dbc
Update .gitmodules to the mosart/rtm tags corresponding to this ctsm
slevis-lmwg Nov 15, 2024
dc295f7
Correct variable name that came in with the conflicts
slevis-lmwg Nov 15, 2024
d49f74d
Merge branch 'zerothtstep' into standardize-time-metadata
slevis-lmwg Nov 19, 2024
1c3ae10
Move line inside if-statement
slevis-lmwg Nov 20, 2024
69bd98c
crop_calendars scripts: Handle center-of-period timesteps.
samsrabin Nov 22, 2024
bd7ecaa
Add SystemTests for RXCROPMATURITY with instantaneous h1.
samsrabin Nov 23, 2024
20ab4c9
RXCROPMATURITY: Fix _setup_all() call.
samsrabin Nov 25, 2024
13cbf65
Merge branch 'fix-rxcropmaturity-20241122' into standardize-time-meta…
samsrabin Dec 2, 2024
9b71518
Satisfy black and pylint.
samsrabin Dec 2, 2024
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 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ d866510188d26d51bcd6d37239283db690af7e82
e096358c832ab292ddfd22dd5878826c7c788968
475831f0fb0e31e97f630eac4e078c886558b61c
fd5f177131d63d39e79a13918390bdfb642d781e
a51816e0de380300b69db9fc3e2c7fa83b267b64
# Ran SystemTests and python/ctsm through black python formatter
5364ad66eaceb55dde2d3d598fe4ce37ac83a93c
8056ae649c1b37f5e10aaaac79005d6e3a8b2380
Expand Down
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CISM-wrapper
[submodule "rtm"]
path = components/rtm
url = https://github.com/ESCOMP/RTM
fxtag = rtm1_0_80
fxtag = rtm1_0_83
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/RTM

[submodule "mosart"]
path = components/mosart
url = https://github.com/ESCOMP/MOSART
fxtag = mosart1.1.02
fxtag = mosart1.1.05
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/MOSART
Expand Down
14 changes: 8 additions & 6 deletions cime_config/SystemTests/rxcropmaturity.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def __init__(self, case):
# Which conda environment should we use?
self._get_conda_env()

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

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

# Set up stuff that applies to both tests
self._setup_all()
self._setup_all(h1_inst)

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

# Set up stuff that applies to both tests
self._setup_all()
self._setup_all(h1_inst)

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

def _setup_all(self):
def _setup_all(self, h1_inst):
logger.info("RXCROPMATURITY log: _setup_all start")

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

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

# Make a surface dataset that has every crop in every gridcell
Expand Down Expand Up @@ -399,7 +399,7 @@ def _run_check_rxboth_run(self, skip_gen):
tool_path,
)

def _modify_user_nl_allruns(self):
def _modify_user_nl_allruns(self, h1_inst):
nl_additions = [
"cropcals_rx = .true.",
"cropcals_rx_adapt = .false.",
Expand All @@ -417,6 +417,8 @@ def _modify_user_nl_allruns(self):
"hist_type1d_pertape(2) = 'PFTS'",
"hist_dov2xy(2) = .false.",
]
if h1_inst:
nl_additions.append("hist_avgflag_pertape(2) = 'I'")
self._append_to_user_nl_clm(nl_additions)

def _run_generate_gdds(self, case_gddgen):
Expand Down
6 changes: 6 additions & 0 deletions cime_config/SystemTests/rxcropmaturityinst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rxcropmaturity import RXCROPMATURITYSHARED


class RXCROPMATURITYINST(RXCROPMATURITYSHARED):
def run_phase(self):
self._run_phase(h1_inst=True)
6 changes: 6 additions & 0 deletions cime_config/SystemTests/rxcropmaturityskipgeninst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rxcropmaturity import RXCROPMATURITYSHARED


class RXCROPMATURITYSKIPGENINST(RXCROPMATURITYSHARED):
def run_phase(self):
self._run_phase(skip_gen=True, h1_inst=True)
20 changes: 20 additions & 0 deletions cime_config/config_tests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ This defines various CTSM-specific system tests
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="RXCROPMATURITYINST">
<DESC>As RXCROPMATURITY but ensure instantaneous h1. Can be removed once instantaneous and other variables are on separate files.</DESC>
<INFO_DBUG>1</INFO_DBUG>
<DOUT_S>FALSE</DOUT_S>
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
<REST_OPTION>never</REST_OPTION>
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="RXCROPMATURITYSKIPGEN">
<DESC>As RXCROPMATURITY but don't actually generate GDDs. Allows short testing with existing GDD inputs.</DESC>
<INFO_DBUG>1</INFO_DBUG>
Expand All @@ -155,6 +165,16 @@ This defines various CTSM-specific system tests
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="RXCROPMATURITYSKIPGENINST">
<DESC>As RXCROPMATURITYSKIPGEN but ensure instantaneous h1. Can be removed once instantaneous and other variables are on separate files.</DESC>
<INFO_DBUG>1</INFO_DBUG>
<DOUT_S>FALSE</DOUT_S>
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
<REST_OPTION>never</REST_OPTION>
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
<HIST_N>$STOP_N</HIST_N>
</test>

<!--
SSP smoke CLM spinup test (only valid for CLM compsets with CLM45)
do an initial spin test (setting CLM_ACCELERATED_SPINUP to on)
Expand Down
22 changes: 22 additions & 0 deletions cime_config/testdefs/testlist_clm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3540,6 +3540,17 @@
</options>
</test>

<test name="RXCROPMATURITYINST_Lm61" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
<machines>
<machine name="derecho" compiler="intel" category="rxcropmaturity"/>
<machine name="derecho" compiler="intel" category="crop_calendars"/>
</machines>
<options>
<option name="wallclock">6:00:00</option>
<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>
</options>
</test>

<test name="RXCROPMATURITYSKIPGEN_Ld1097" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
<machines>
<machine name="derecho" compiler="intel" category="aux_clm"/>
Expand All @@ -3552,6 +3563,17 @@
</options>
</test>

<test name="RXCROPMATURITYSKIPGENINST_Ld1097" grid="f10_f10_mg37" compset="IHistClm60BgcCrop" testmods="clm/cropMonthOutput">
<machines>
<machine name="derecho" compiler="intel" category="rxcropmaturity"/>
<machine name="derecho" compiler="intel" category="crop_calendars"/>
</machines>
<options>
<option name="wallclock">00:45:00</option>
<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>
</options>
</test>

<test name="ERP_D_P64x2_Ld10" grid="f10_f10_mg37" compset="I2000Clm60Bgc" testmods="clm/Hillslope">
<machines>
<machine name="derecho" compiler="intel" category="aux_clm"/>
Expand Down
104 changes: 104 additions & 0 deletions doc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,108 @@
===============================================================
Tag name: ctsm5.3.014
Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310)
Date: Fri 15 Nov 2024 01:24:45 PM MST
One-line Summary: Change history time to be the middle of the time bounds

Purpose and description of changes
----------------------------------

Making the change in order to be consistent with CAM and to make history output more intuitive.


Significant changes to scientifically-supported configurations
--------------------------------------------------------------

Does this tag change answers significantly for any of the following physics configurations?
(Details of any changes will be given in the "Answer changes" section below.)

[Put an [X] in the box for any configuration with significant answer changes.]

[ ] clm6_0

[ ] clm5_1

[ ] clm5_0

[ ] ctsm5_0-nwp

[ ] clm4_5


Bugs fixed
----------
List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
Partly addresses issue #1059

Notes of particular relevance for users
---------------------------------------
Caveats for users (e.g., need to interpolate initial conditions):
The history time variable now equals the middle of the time bounds.
Instantaneous history tapes now do not include time bounds.
Mixed history tapes do not change the treatment of instantaneous fields or move them to separate tapes, yet.


Notes of particular relevance for developers:
---------------------------------------------
Caveats for developers (e.g., code that is duplicated that requires double maintenance):

Changes to tests or testing:
This tag introduces changes to the mosart/rtm testlists.

Testing summary:
----------------

[PASS means all tests PASS; OK means tests PASS other than expected fails.]

python testing (if python code has changed; see instructions in python/README.md; document testing done):

derecho -

regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):

derecho ----- OK
izumi ------- OK

mosart
derecho ----- OK
izumi ------- OK

rtm
derecho ----- OK

any other testing (give details below):

ctsm_sci
derecho ----

If the tag used for baseline comparisons was NOT the previous tag, note that here:


Answer changes
--------------

Changes answers relative to baseline: Only time variable

Summarize any changes to answers, i.e.,
- what code configurations: all
- what platforms/compilers: all
- nature of change: only the time variable


Other details
-------------
List any git submodules updated (cime, rtm, mosart, cism, fates, etc.):
rtm, mosart

Pull Requests that document the changes (include PR ids):
https://github.com/ESCOMP/ctsm/pull/2838
https://github.com/ESCOMP/MOSART/pull/70
https://github.com/ESCOMP/RTM/issues/54
https://github.com/ESCOMP/MOSART/pull/106
https://github.com/ESCOMP/RTM/pull/39

===============================================================
===============================================================
Tag name: ctsm5.3.012
Originator(s): afoster (Adrianna Foster,UCAR/TSS,303-497-1728)
Date: Wed 13 Nov 2024 09:53:51 AM MST
Expand Down
1 change: 1 addition & 0 deletions doc/ChangeSum
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Tag Who Date Summary
============================================================================================================================
ctsm5.3.014 slevis 11/18/2024 Change history time to be the middle of the time bounds
ctsm5.3.012 afoster 11/13/2024 update fates tag
ctsm5.3.011 samrabin 11/11/2024 Improve handling of cold-start finidat
ctsm5.3.010 afoster 11/09/2024 Merge b4b-dev
Expand Down
3 changes: 2 additions & 1 deletion python/ctsm/crop_calendars/convert_axis_time2gs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import sys
import numpy as np
import xarray as xr
from ctsm.crop_calendars.cropcal_utils import get_integer_years

try:
import pandas as pd
Expand Down Expand Up @@ -85,7 +86,7 @@ def set_up_ds_with_gs_axis(ds_in):
if not any(x in ["mxsowings", "mxharvests"] for x in ds_in[var].dims):
data_vars[var] = ds_in[var]
# Set up the new dataset
gs_years = [t.year - 1 for t in ds_in.time.values[:-1]]
gs_years = get_integer_years(ds_in)[:-1]
coords = ds_in.coords
coords["gs"] = gs_years
ds_out = xr.Dataset(data_vars=data_vars, coords=coords, attrs=ds_in.attrs)
Expand Down
1 change: 1 addition & 0 deletions python/ctsm/crop_calendars/cropcal_figs_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from matplotlib import cm
import matplotlib.collections as mplcol

# pylint: disable=abstract-class-instantiated

# Colormaps (maps)
cropcal_colors = {
Expand Down
54 changes: 36 additions & 18 deletions python/ctsm/crop_calendars/cropcal_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,16 @@ def check_and_trim_years(year_1, year_n, ds_in):
"""
After importing a file, restrict it to years of interest.
"""
### In annual outputs, file with name Y is actually results from year Y-1.
### Note that time values refer to when it was SAVED. So 1981-01-01 is for year 1980.

def get_year_from_cftime(cftime_date):
# Subtract 1 because the date for annual files is when it was SAVED
return cftime_date.year - 1

# Check that all desired years are included
if get_year_from_cftime(ds_in.time.values[0]) > year_1:
raise RuntimeError(
f"Requested year_1 is {year_1} but first year in outputs is "
+ f"{get_year_from_cftime(ds_in.time.values[0])}"
)
if get_year_from_cftime(ds_in.time.values[-1]) < year_1:
year = utils.get_timestep_year(ds_in, ds_in.time.values[0])
if year > year_1:
raise RuntimeError(
f"Requested year_n is {year_n} but last year in outputs is "
+ f"{get_year_from_cftime(ds_in.time.values[-1])}"
f"Requested year_1 is {year_1} but first year in outputs is {year}"
)
year = utils.get_timestep_year(ds_in, ds_in.time.values[-1])
if year < year_1:
raise RuntimeError(f"Requested year_n is {year_n} but last year in outputs is {year}")

# Remove years outside range of interest
### Include an extra year at the end to finish out final seasons.
Expand Down Expand Up @@ -443,10 +435,7 @@ def import_output(
)

# Convert time axis to integer year, saving original as 'cftime'
this_ds_gs = this_ds_gs.assign_coords(
{"cftime": this_ds["time_bounds"].isel({"hist_interval": 0})}
)
this_ds_gs = this_ds_gs.assign_coords({"time": [t.year for t in this_ds_gs["cftime"].values]})
this_ds_gs = convert_time_to_int_year(filename, this_ds, this_ds_gs)

# Get number of harvests
this_ds_gs["NHARVESTS"] = (this_ds_gs["GDDHARV_PERHARV"] > 0).sum(dim="mxharvests")
Expand All @@ -458,6 +447,35 @@ def import_output(
return this_ds_gs, any_bad


def convert_time_to_int_year(filename, this_ds, this_ds_gs):
"""
Convert time axis to integer year, saving original as 'cftime'
"""
if "time_bounds" in this_ds:
# Always true before PR #2838, when even files with all instantaneous variables got
# time_bounds saved. After that PR (and before the segregation of instantaneous and other
# variables onto separate files), files with an instantaneous variable first in their list
# do not get time_bounds saved.
this_ds_gs = this_ds_gs.assign_coords(
{"cftime": this_ds["time_bounds"].isel({"hist_interval": 0})}
)
this_ds_gs = this_ds_gs.assign_coords(
{"time": [t.year for t in this_ds_gs["cftime"].values]}
)
elif this_ds["time"].attrs["long_name"] == "time at end of time step":
# This is an "instantaneous file."
this_ds_gs = this_ds_gs.assign_coords({"cftime": this_ds["time"]})
this_ds_gs = this_ds_gs.assign_coords(
{"time": [t.year - 1 for t in this_ds_gs["cftime"].values]}
)
else:
raise RuntimeError(
f"{filename} is neither an instantaneous nor a combined/non-instantaneous file."
)

return this_ds_gs


def handle_zombie_crops(this_ds):
"""
When doing transient runs, it's somehow possible for crops in newly-active patches to be
Expand Down
Loading