Skip to content

Commit 3333010

Browse files
committed
Fixed unittes
1 parent 931ff1a commit 3333010

File tree

2 files changed

+158
-159
lines changed

2 files changed

+158
-159
lines changed

.ipynb_checkpoints/ECMWF_convert_to_ROMS-checkpoint.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def write_to_ROMS_netcdf_file(self, config_ecmwf: ECMWF_query, data_array, var_u
116116
longitude = ds.variables['longitude'][:]
117117
latitude = ds.variables['latitude'][:]
118118
time, time_units, time_calendar = self.change_reference_date(ds, config_ecmwf)
119-
119+
120120
netcdf_roms_filename = f"{out_filename[0:-3]}_roms.nc"
121121
if os.path.exists(netcdf_roms_filename):
122122
os.remove(netcdf_roms_filename)

ECMWF_convert_to_ROMS.py

+157-158
Original file line numberDiff line numberDiff line change
@@ -10,166 +10,165 @@
1010

1111
class ECMWF_convert_to_ROMS:
1212

13-
def __init__(self):
14-
self.plotter = ECMWF_plot.ECMWF_plot()
15-
16-
def convert_to_ROMS_units_standards(self, out_filename: str, metadata, parameter: str, config_ecmwf: ECMWF_query):
17-
dset = netCDF4.Dataset(out_filename, 'r+')
18-
19-
da = dset.variables[metadata['short_name']][:]
20-
masked_array = np.ma.masked_where(da == dset.variables[metadata['short_name']].missing_value, da)
21-
logging.debug("[ECMWF_convert_to_ROMS] Will convert for parameter: {}".format(parameter))
22-
if parameter in ['mean_surface_net_short_wave_radiation_flux',
23-
'mean_surface_net_long_wave_radiation_flux',
24-
'mean_surface_downward_long_wave_radiation_flux',
25-
'mean_surface_latent_heat_flux',
26-
'mean_surface_sensible_heat_flux',
27-
'mean_surface_downward_short_wave_radiation_flux']:
28-
# masked_array = np.ma.divide(masked_array, (3600. * 3.0))
29-
units = 'W m**-2'
30-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
31-
elif parameter in ['specific_humidity']:
32-
units = 'kg kg-1'
33-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
34-
elif parameter in ['10m_u_component_of_wind', '10m_v_component_of_wind']:
35-
units = 'm s-1'
36-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
37-
elif parameter in ['2m_temperature', '2m_dewpoint_temperature']:
38-
masked_array = np.ma.subtract(masked_array, 273.15)
39-
units = 'Celsius'
40-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
41-
elif parameter in ['evaporation']:
42-
Rho_w = 1000. # kg m - 3
43-
masked_array = np.ma.multiply(masked_array, (Rho_w / (1 * 3600.)))
44-
units = 'kg m-2 s-1'
45-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
46-
elif parameter in ['mean_sea_level_pressure']:
47-
# masked_array = np.ma.divide(masked_array, 100) #(1 mb = 100 Pa)
48-
units = 'Pa'
49-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
50-
elif parameter in ['total_cloud_cover']:
51-
dset.renameVariable(metadata['short_name'], 'cloud')
52-
units = 'nondimensional'
53-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
54-
elif parameter in ['total_precipitation']:
55-
# Convert meter (m) to rate (kgm-2s-1)
56-
Rho_w = 1000 # kg m - 3
57-
masked_array = np.ma.multiply(masked_array, (Rho_w / (1 * 3600.)))
58-
units = 'kg m-2 s-1'
59-
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
60-
else:
61-
raise Exception("[ECMWF_convert_to_ROMS] Unable to find parameter {} to convert to ROMS format".format(parameter))
62-
# longitude = dset.variables['longitude'][:]
63-
# latitude = dset.variables['latitude'][:]
64-
65-
# do_plot = False
66-
# if do_plot:
67-
# self.plotter.plot_data(longitude, latitude, masked_array, time, parameter)
68-
69-
self.write_to_ROMS_netcdf_file(config_ecmwf,
70-
masked_array,
71-
units,
72-
out_filename,
73-
parameter,
74-
dset)
75-
dset.close()
76-
77-
# We change the reference date to be equal to the standard ROMS
78-
# reference time 1948-01-01 so that we can optionally use ocean_time as time name
79-
def change_reference_date(self, ds, config_ecmwf: ECMWF_query):
80-
81-
era5_time = ds.variables['time'][:]
82-
era5_time_units = ds.variables['time'].units
83-
era5_time_cal = ds.variables['time'].calendar
84-
logging.debug("[ECMWF_convert_to_ROMS] Original time: {} to {} cal: {} units: {}".format(era5_time[0],era5_time[-1], era5_time_cal, era5_time_units))
85-
86-
dates = num2date(era5_time, units=era5_time_units, calendar=era5_time_cal)
87-
logging.debug(
88-
f"[ECMWF_convert_to_ROMS] Converted time: {dates[0]} to {dates[-1]}")
89-
90-
# Convert back to julian day and convert to days since 1948-01-01 as that is standard for ROMS
91-
# days_to_seconds = 86400.0
92-
times = netCDF4.date2num(dates, units=config_ecmwf.time_units) # * days_to_seconds
93-
logging.debug(
94-
f"[ECMWF_convert_to_ROMS] Converted time: {times[0]} to {times[-1]} units: {config_ecmwf.time_units}")
95-
96-
return times, config_ecmwf.time_units, era5_time_cal
97-
98-
def write_to_ROMS_netcdf_file(self, config_ecmwf: ECMWF_query, data_array, var_units: str, netcdf_file,
99-
parameter: str, ds):
100-
"""
101-
:param config_ecmwf: The config object containing the metadata
102-
:param data_array: the data array downloaded from ECMWF and converted to correct ROMS units
103-
:param units: the units to write to file
104-
:param netcdf_file: name of file
105-
:param parameter: the parameter to write to file - name converted to ROMS name using metadata
106-
:param longitude: longitude dimension of data
107-
:param latitude: latitude dimension of data
108-
:param time: time dimension of data
109-
110-
https://www.myroms.org/index.php?page=forcing
111-
"""
112-
metadata = config_ecmwf.get_parameter_metadata(parameter)
113-
logging.info(
114-
"[ECMWF_convert_to_ROMS] Writing {} to ROMS netcdf file".format(parameter))
115-
116-
longitude = ds.variables['longitude'][:]
117-
latitude = ds.variables['latitude'][:]
118-
time, time_units, time_calendar = self.change_reference_date(ds, config_ecmwf)
119-
13+
def __init__(self):
14+
self.plotter = ECMWF_plot.ECMWF_plot()
15+
16+
def convert_to_ROMS_units_standards(self, out_filename: str, metadata, parameter: str, config_ecmwf: ECMWF_query):
17+
dset = netCDF4.Dataset(out_filename, 'r+')
18+
19+
da = dset.variables[metadata['short_name']][:]
20+
masked_array = np.ma.masked_where(da == dset.variables[metadata['short_name']].missing_value, da)
21+
logging.debug("[ECMWF_convert_to_ROMS] Will convert for parameter: {}".format(parameter))
22+
if parameter in ['mean_surface_net_short_wave_radiation_flux',
23+
'mean_surface_net_long_wave_radiation_flux',
24+
'mean_surface_downward_long_wave_radiation_flux',
25+
'mean_surface_latent_heat_flux',
26+
'mean_surface_sensible_heat_flux',
27+
'mean_surface_downward_short_wave_radiation_flux']:
28+
# masked_array = np.ma.divide(masked_array, (3600. * 3.0))
29+
units = 'W m**-2'
30+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
31+
elif parameter in ['specific_humidity']:
32+
units = 'kg kg-1'
33+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
34+
elif parameter in ['10m_u_component_of_wind', '10m_v_component_of_wind']:
35+
units = 'm s-1'
36+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
37+
elif parameter in ['2m_temperature', '2m_dewpoint_temperature']:
38+
masked_array = np.ma.subtract(masked_array, 273.15)
39+
units = 'Celsius'
40+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
41+
elif parameter in ['evaporation']:
42+
Rho_w = 1000. # kg m - 3
43+
masked_array = np.ma.multiply(masked_array, (Rho_w / (1 * 3600.)))
44+
units = 'kg m-2 s-1'
45+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
46+
elif parameter in ['mean_sea_level_pressure']:
47+
# masked_array = np.ma.divide(masked_array, 100) #(1 mb = 100 Pa)
48+
units = 'Pa'
49+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
50+
elif parameter in ['total_cloud_cover']:
51+
dset.renameVariable(metadata['short_name'], 'cloud')
52+
units = 'nondimensional'
53+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
54+
elif parameter in ['total_precipitation']:
55+
# Convert meter (m) to rate (kgm-2s-1)
56+
Rho_w = 1000 # kg m - 3
57+
masked_array = np.ma.multiply(masked_array, (Rho_w / (1 * 3600.)))
58+
units = 'kg m-2 s-1'
59+
logging.debug("[ECMWF_convert_to_ROMS] Converted parameter: {}".format(parameter))
60+
else:
61+
raise Exception("[ECMWF_convert_to_ROMS] Unable to find parameter {} to convert to ROMS format".format(parameter))
62+
# longitude = dset.variables['longitude'][:]
63+
# latitude = dset.variables['latitude'][:]
64+
65+
# do_plot = False
66+
# if do_plot:
67+
# self.plotter.plot_data(longitude, latitude, masked_array, time, parameter)
68+
69+
self.write_to_ROMS_netcdf_file(config_ecmwf,
70+
masked_array,
71+
units,
72+
out_filename,
73+
parameter,
74+
dset)
75+
dset.close()
76+
77+
# We change the reference date to be equal to the standard ROMS
78+
# reference time 1948-01-01 so that we can optionally use ocean_time as time name
79+
def change_reference_date(self, ds, config_ecmwf: ECMWF_query):
80+
81+
era5_time = ds.variables['time'][:]
82+
era5_time_units = ds.variables['time'].units
83+
era5_time_cal = ds.variables['time'].calendar
84+
logging.debug("[ECMWF_convert_to_ROMS] Original time: {} to {} cal: {} units: {}".format(era5_time[0],era5_time[-1], era5_time_cal, era5_time_units))
85+
86+
dates = num2date(era5_time, units=era5_time_units, calendar=era5_time_cal)
87+
logging.debug(
88+
f"[ECMWF_convert_to_ROMS] Converted time: {dates[0]} to {dates[-1]}")
89+
90+
# Convert back to julian day and convert to days since 1948-01-01 as that is standard for ROMS
91+
# days_to_seconds = 86400.0
92+
times = netCDF4.date2num(dates, units=config_ecmwf.time_units) # * days_to_seconds
93+
logging.debug(
94+
f"[ECMWF_convert_to_ROMS] Converted time: {times[0]} to {times[-1]} units: {config_ecmwf.time_units}")
95+
96+
return times, config_ecmwf.time_units, era5_time_cal
97+
98+
def write_to_ROMS_netcdf_file(self, config_ecmwf: ECMWF_query, data_array, var_units: str, netcdf_file,
99+
parameter: str, ds):
100+
"""
101+
:param config_ecmwf: The config object containing the metadata
102+
:param data_array: the data array downloaded from ECMWF and converted to correct ROMS units
103+
:param units: the units to write to file
104+
:param netcdf_file: name of file
105+
:param parameter: the parameter to write to file - name converted to ROMS name using metadata
106+
:param longitude: longitude dimension of data
107+
:param latitude: latitude dimension of data
108+
:param time: time dimension of data
109+
110+
https://www.myroms.org/index.php?page=forcing
111+
"""
112+
metadata = config_ecmwf.get_parameter_metadata(parameter)
113+
logging.info(
114+
"[ECMWF_convert_to_ROMS] Writing {} to ROMS netcdf file".format(parameter))
115+
116+
longitude = ds.variables['longitude'][:]
117+
latitude = ds.variables['latitude'][:]
118+
time, time_units, time_calendar = self.change_reference_date(ds, config_ecmwf)
120119
netcdf_roms_filename = f"{out_filename[0:-3]}_roms.nc"
121-
if os.path.exists(netcdf_roms_filename):
120+
if os.path.exists(netcdf_roms_filename):
122121
os.remove(netcdf_roms_filename)
123-
logging.info(
124-
"[ECMWF_convert_to_ROMS] Writing final product to file {}".format(netcdf_roms_filename))
125-
126-
f1 = netCDF4.Dataset(netcdf_roms_filename, 'w')
127-
f1.title = "{} ECMWF model forcing for parameter {}".format(config_ecmwf.dataset.upper(), parameter)
128-
f1.description = "Created by Trond Kristiansen (at) niva.no." \
129-
"Atmospheric data on original grid but converted to ROMS units and parameter names." \
130-
"Files created using the ECMWF_tools toolbox:" \
131-
"https://github.com/trondkr/ERA5-ROMS"
132-
f1.history = f"Created {datetime.now()}"
133-
f1.link = "https://github.com/trondkr/"
134-
f1.Conventions = "CF-1.0"
135-
fill_val = 1.0e35
136-
data_array[data_array.mask] = fill_val
137-
138-
# Define dimensions
139-
f1.createDimension('lon', len(longitude))
140-
f1.createDimension('lat', len(latitude))
141-
f1.createDimension(metadata['time_name'], None)
142-
143-
vnc = f1.createVariable('lon', 'd', 'lon', fill_value=fill_val)
144-
vnc.long_name = 'Longitude'
145-
vnc.units = 'degree_east'
146-
vnc.standard_name = 'longitude'
147-
vnc[:] = longitude
148-
149-
vnc = f1.createVariable('lat', 'd', 'lat', fill_value=fill_val)
150-
vnc.long_name = 'Latitude'
151-
vnc.units = 'degree_north'
152-
vnc.standard_name = 'latitude'
122+
logging.info(
123+
"[ECMWF_convert_to_ROMS] Writing final product to file {}".format(netcdf_roms_filename))
124+
125+
f1 = netCDF4.Dataset(netcdf_roms_filename, 'w')
126+
f1.title = "{} ECMWF model forcing for parameter {}".format(config_ecmwf.dataset.upper(), parameter)
127+
f1.description = "Created by Trond Kristiansen (at) niva.no." \
128+
"Atmospheric data on original grid but converted to ROMS units and parameter names." \
129+
"Files created using the ECMWF_tools toolbox:" \
130+
"https://github.com/trondkr/ERA5-ROMS"
131+
f1.history = f"Created {datetime.now()}"
132+
f1.link = "https://github.com/trondkr/"
133+
f1.Conventions = "CF-1.0"
134+
fill_val = 1.0e35
135+
data_array[data_array.mask] = fill_val
136+
137+
# Define dimensions
138+
f1.createDimension('lon', len(longitude))
139+
f1.createDimension('lat', len(latitude))
140+
f1.createDimension(metadata['time_name'], None)
141+
142+
vnc = f1.createVariable('lon', 'd', 'lon', fill_value=fill_val)
143+
vnc.long_name = 'Longitude'
144+
vnc.units = 'degree_east'
145+
vnc.standard_name = 'longitude'
146+
vnc[:] = longitude
147+
148+
vnc = f1.createVariable('lat', 'd', 'lat', fill_value=fill_val)
149+
vnc.long_name = 'Latitude'
150+
vnc.units = 'degree_north'
151+
vnc.standard_name = 'latitude'
153152
# For latitude we need to reverse the order provided by ECMWF.
154153
# The same goes with the data
155-
vnc[:] = latitude[::-1]
156-
157-
vnc = f1.createVariable(metadata['time_name'], 'd', (metadata['time_name'],), fill_value=fill_val)
158-
vnc.long_name = 'time'
159-
vnc.units = time_units
160-
vnc.field = 'time, scalar, series'
161-
vnc.calendar = time_calendar
162-
vnc[:] = time
163-
164-
vnc = f1.createVariable(metadata['roms_name'], 'd', (metadata['time_name'], 'lat', 'lon'), fill_value=fill_val)
165-
vnc.long_name = metadata["name"]
166-
vnc.standard_name = metadata["short_name"]
167-
vnc.coordinates = f"lon lat {metadata['time_name']}"
168-
vnc.units = var_units
169-
vnc.missing_value = fill_val
154+
vnc[:] = latitude[::-1]
155+
156+
vnc = f1.createVariable(metadata['time_name'], 'd', (metadata['time_name'],), fill_value=fill_val)
157+
vnc.long_name = 'time'
158+
vnc.units = time_units
159+
vnc.field = 'time, scalar, series'
160+
vnc.calendar = time_calendar
161+
vnc[:] = time
162+
163+
vnc = f1.createVariable(metadata['roms_name'], 'd', (metadata['time_name'], 'lat', 'lon'), fill_value=fill_val)
164+
vnc.long_name = metadata["name"]
165+
vnc.standard_name = metadata["short_name"]
166+
vnc.coordinates = f"lon lat {metadata['time_name']}"
167+
vnc.units = var_units
168+
vnc.missing_value = fill_val
170169

171-
vnc[:, :, :] = data_array[:,::-1,:]
172-
logging.info(
173-
f"[ECMWF_convert_to_ROMS] Finished writing to file {netcdf_roms_filename}")
174-
os.remove(netcdf_file)
175-
f1.close()
170+
vnc[:, :, :] = data_array[:,::-1,:]
171+
logging.info(
172+
f"[ECMWF_convert_to_ROMS] Finished writing to file {netcdf_roms_filename}")
173+
os.remove(netcdf_file)
174+
f1.close()

0 commit comments

Comments
 (0)