Skip to content

Commit

Permalink
Merge pull request #680 from PCMDI/multiple_write_bug
Browse files Browse the repository at this point in the history
Multiple write bug
  • Loading branch information
mauzey1 authored Nov 16, 2022
2 parents 2a101f4 + b8032eb commit dc868f8
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 7 deletions.
8 changes: 5 additions & 3 deletions Src/cmor.c
Original file line number Diff line number Diff line change
Expand Up @@ -6719,9 +6719,11 @@ int calculate_leadtime_coord(int var_id) {
/* activate define mode */
nc_redef(ncid);
/* add leadtime */
if (ierr = nc_def_var(ncid, "leadtime", NC_DOUBLE, 1, &time_dim, &leadtime)) {
snprintf(msg, CMOR_MAX_STRING, "cannot add 'leadtime' variable");
cmor_handle_error(msg, CMOR_CRITICAL);
if (ierr = nc_inq_varid(ncid, "leadtime", &leadtime)) {
if (ierr = nc_def_var(ncid, "leadtime", NC_DOUBLE, 1, &time_dim, &leadtime)) {
snprintf(msg, CMOR_MAX_STRING, "cannot add 'leadtime' variable");
cmor_handle_error(msg, CMOR_CRITICAL);
}
}

/* variable attributes */
Expand Down
99 changes: 95 additions & 4 deletions Test/test_python_forecast_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import numpy as np
import cmor
import unittest
import os

from netCDF4 import Dataset

Expand Down Expand Up @@ -31,7 +32,7 @@
"parent_activity_id": "no parent",
"physics_index": "1",
"realization_index": "1",
"source": "HadGEM3-GC31-LL",
"source": "HadGEM3-GC31-LL (2016): \naerosol: UKCA-GLOMAP-mode\natmos: MetUM-HadGEM3-GA7.1 (N96; 192 x 144 longitude/latitude; 85 levels; top level 85 km)\natmosChem: none\nland: JULES-HadGEM3-GL7.1\nlandIce: none\nocean: NEMO-HadGEM3-GO6.0 (eORCA1 tripolar primarily 1 deg with meridional refinement down to 1/3 degree in the tropics; 360 x 330 longitude/latitude; 75 levels; top grid cell 0-1 m)\nocnBgchem: none\nseaIce: CICE-HadGEM3-GSI8 (eORCA1 tripolar primarily 1 deg; 360 x 330 longitude/latitude)",
"source_id": "HadGEM3-GC31-LL",
"source_type": "AGCM",
"sub_experiment": "none",
Expand Down Expand Up @@ -59,6 +60,8 @@ def setUp(self):
if error_flag:
raise RuntimeError("CMOR dataset_json call failed")


def test_has_forcast_coordinates(self):
# load MIP table
mip_table = "CMIP6_Amon_leadtime.json"
table_id = cmor.load_table(mip_table)
Expand All @@ -82,13 +85,101 @@ def setUp(self):
reshaped_data = data.reshape((5, 5, 2, 1, 1))
# write data
cmor.write(tas_var_id, reshaped_data)
self.filename = cmor.close(tas_var_id, file_name=True)
filename = cmor.close(tas_var_id, file_name=True)

def test_has_forcast_coordinates(self):
ds = Dataset(self.filename)
ds = Dataset(filename)
np.testing.assert_array_equal(ds.variables['reftime'][:].data, [10.0])
np.testing.assert_array_equal(ds.variables['leadtime'][:].data, [20.0, 50.0])
ds.close()
os.remove(filename)


class TestWriteSlices(unittest.TestCase):

def setUp(self):
"""
Write out a simple file using CMOR
"""
# Set up CMOR
cmor.setup(inpath="TestTables", netcdf_file_action=cmor.CMOR_REPLACE,
logfile="cmor.log", create_subdirectories=0)

# Define dataset using DATASET_INFO
with open("Test/input_leadtime.json", "w") as input_file_handle:
json.dump(DATASET_INFO, input_file_handle, sort_keys=True, indent=4)

# read dataset info
error_flag = cmor.dataset_json("Test/input_leadtime.json")
if error_flag:
raise RuntimeError("CMOR dataset_json call failed")


def test_multiple_writes(self):
# load MIP table
mip_table = "CMIP6_Amon.json"
table_id = cmor.load_table(mip_table)

# construct axes
time = cmor.axis(table_entry="time", units="days since 2000-01-01")
height2m = cmor.axis(table_entry="height2m", units="m", coord_vals=np.array((2.0,)))
latitude = cmor.axis(table_entry="latitude", units="degrees_north",
coord_vals=np.array(range(5)),
cell_bounds=np.array(range(6)))
longitude = cmor.axis(table_entry="longitude", units="degrees_east",
coord_vals=np.array(range(5)),
cell_bounds=np.array(range(6)))
axis_ids = [longitude, latitude, time, height2m]
tas_var_id = cmor.variable(table_entry="tas", axis_ids=axis_ids, units="K")
# write data
for year in range(2):
data = np.random.random(25*12)
reshaped_data = data.reshape((5, 5, 12, 1))
time_vals = [pt*30 + 360.0 * year + 15.0 for pt in range(12)]
time_bnds = [360.0 * year ] + [pt*30 + 360.0 * year + 30.0 for pt in range(12)]
cmor.write(tas_var_id, reshaped_data, time_vals=time_vals, time_bnds=time_bnds)

filename = cmor.close(tas_var_id, file_name=True)
ds = Dataset(filename)
np.testing.assert_array_equal(ds.variables['time'][:].data, [15., 45., 75., 105., 135., 165., 195., 225., 255., 285., 315., 345., 375., 405., 435., 465., 495., 525., 555., 585., 615., 645., 675., 705.])
ds.close()
os.remove(filename)


def test_multiple_writes_with_leadtime(self):
# load MIP table
mip_table = "CMIP6_Amon_leadtime.json"
table_id = cmor.load_table(mip_table)

# construct axes
time = cmor.axis(table_entry="time", units="days since 2000-01-01")
height2m = cmor.axis(table_entry="height2m", units="m", coord_vals=np.array((2.0,)))
latitude = cmor.axis(table_entry="latitude", units="degrees_north",
coord_vals=np.array(range(5)),
cell_bounds=np.array(range(6)))
longitude = cmor.axis(table_entry="longitude", units="degrees_east",
coord_vals=np.array(range(5)),
cell_bounds=np.array(range(6)))
reftime = cmor.axis(table_entry="reftime1", units="days since 2000-01-01",
coord_vals=np.array([10.0]))
axis_ids = [longitude, latitude, time, reftime, height2m]

tas_var_id = cmor.variable(table_entry="tas", axis_ids=axis_ids, units="K")
# write data
for year in range(2):
data = np.random.random(25 * 12)
reshaped_data = data.reshape((5, 5, 12, 1, 1))
time_vals = [pt * 30 + 360.0 * year + 15.0 for pt in range(12)]
time_bnds = [360.0 * year] + [pt * 30 + 360.0 * year + 30.0 for pt in range(12)]
cmor.write(tas_var_id, reshaped_data, time_vals=time_vals, time_bnds=time_bnds)

filename = cmor.close(tas_var_id, file_name=True)
ds = Dataset(filename)
np.testing.assert_array_equal(ds.variables['time'][:].data,
[15., 45., 75., 105., 135., 165., 195., 225., 255., 285., 315., 345., 375., 405.,
435., 465., 495., 525., 555., 585., 615., 645., 675., 705.])
ds.close()
os.remove(filename)


if __name__ == '__main__':
unittest.main()
36 changes: 36 additions & 0 deletions TestTables/CMIP6_Amon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Header": {
"data_specs_version": "01.00.33",
"cmor_version": "3.5",
"table_id": "Table Amon",
"realm": "atmos atmosChem",
"table_date": "18 November 2020",
"missing_value": "1e20",
"int_missing_value": "-999",
"product": "model-output",
"approx_interval": "30.00000",
"generic_levels": "alevel alevhalf",
"mip_era": "CMIP6",
"Conventions": "CF-1.7 CMIP-6.2"
},
"variable_entry": {
"tas": {
"frequency": "mon",
"modeling_realm": "atmos",
"standard_name": "air_temperature",
"units": "K",
"cell_methods": "area: time: mean",
"cell_measures": "area: areacella",
"long_name": "Near-Surface Air Temperature",
"comment": "near-surface (usually, 2 meter) air temperature",
"dimensions": "longitude latitude time height2m",
"out_name": "tas",
"type": "real",
"positive": "",
"valid_min": "",
"valid_max": "",
"ok_min_mean_abs": "",
"ok_max_mean_abs": ""
}
}
}

0 comments on commit dc868f8

Please sign in to comment.