GRIB files are the file format used at ECMWF. GRIB
is a WMO standard and consists of GRIB Edition 1 and Edition 2
The ERA5 dataset, produced by the European Centre for Medium-Range
Weather Forecasts (ECMWF), provides a wealth of climate and weather
data. However, the data is often distributed in the GRIB format, which
can be less user-friendly than the NetCDF format, commonly used in
scientific computing. This blog post will walk you through the process
of converting ERA5 GRIB files to NetCDF.
Climate change is one of the most pressing issues of our time, and
understanding its impacts requires access to high-quality climate data.
The ERA5 dataset provides crucial information on past and present
climate conditions, helping researchers analyze trends and signals
related to climate change. However, the ERA5 data is often stored in
GRIB format, which can be challenging to work with. By converting ERA5
GRIB files to NetCDF format, we can more easily integrate climate change
signals into ERA5.
By applying the Pseudo-Global-Warming (PGW) approach, you can use the
CMIP6 climate change signals to generate a difference and then add this
to the initial conditions, such as those provided by ERA5.
Main Script
▶
loop.sh
1 2 3 4 5 6 7 8 9 10 11
#!/bin/bash
ym="20220630"
for iday in {0..360..3}; do # Next_day=$(date +%Y-%m-%d_%H:%M:%S -d "$YYYYMMDD + 1 hour") export ERA5_datetime=$(date +%Y%m%d%H -d "$ym + $iday hour") echo${ERA5_datetime}
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-10 09:45:06 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------#
export ERA5_datetime=${ERA5_datetime:-"2022063000"} export ERA5_path=${ERA5_path:-"/home/wpsze/ERA5/"} export PGW_ERA5_path=${PGW_ERA5_path:-"/home/wpsze/PGW/ERA5/"}# save future projection of ERA5 IC export PGW_script_path=${PGW_script_path:-"/home/wpsze/PGW/"}
# Convert ERA5.grib to .nc if [[ ! -f "ERA5-0p25-SL-${yyyymmddhh}.nc" ]]; then echo"ERA5-0p25-SL/PL-${yyyymmddhh}.nc doesn't exist, generating them ... " time python3 ${PGW_script_path}/grib2netcdf.py else echo"ERA5-0p25-SL/PL-${yyyymmddhh}.nc exist." fi
# rename/rebuild singal.nc if [[ ! -f "signal.nc" ]]; then echo"singal.nc doesn't exits, soft-link and rebuild ..." ln -sf ${cmip6_signal_file} original-signal.nc time python3 ${PGW_script_path}/rename_signal.py else echo"signal.nc exists." fi
# regrid signal.nc (1.25deg) to 0.25deg if [[ ! -f "signal_0p25.nc" ]]; then cdo remapbil,r1440x721 signal.nc signal_0p25.nc else echo"signal_0p25.nc exists." fi
# Add singal.nc into ERA5.nc time python3 ${PGW_script_path}/2d_interp.py time python3 ${PGW_script_path}/3d_interp.py # time python3 ${PGW_script_path}/3d_interp_with_uv.py
# Convert nc file to grib file cp ERA5-0p25-SL-${yyyymmddhh}.grib original-SL.grib cp ERA5-0p25-PL-${yyyymmddhh}.grib original-PL.grib time sh ${PGW_script_path}/netcdf2grib.sh # time sh ${PGW_script_path}/netcdf2grib_with_uv.sh
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-03 17:26:38 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------# import os import xarray as xr
Interpolating
2D SST/SKT from Signal NetCDF to ERA5 NetCDF
Here’s a Python script for interpolating Sea Surface Temperature
(SST) and Surface Skin Temperature (SKT) from a signal NetCDF file to
match the ERA5 grid. This process involves horizontal interpolation to
ensure that the temperatures align accurately with the finer resolution
of the ERA5 dataset. Accurate temperature data is crucial for climate
modeling and analysis. By interpolating these temperatures, we can
effectively integrate them into broader climate studies.
Manipulate signal.nc
Modify signal.nc because the original signal.nc is notproperly defined in a format recognized by CDO, making it impossible toapply CDO command tools.
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-07 17:37:01 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------#
import numpy as np import xarray as xr
# Load the signal and ERA5 NetCDF files signal_nc = xr.open_dataset('signal.nc') # Replace with actual signal file path
#================== Save ================================================= # Save the result to a new NetCDF file test.to_netcdf('signal.nc', format='NETCDF4')
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-04 16:34:39 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------# import os import numpy as np import xarray as xr # from scipy.interpolate import interp1d
# Load the signal and ERA5 NetCDF files signal_nc = xr.open_dataset('signal_0p25.nc') # Replace with actual signal file path era5_nc = xr.open_dataset('ERA5-SL.nc') # Replace with actual ERA5 file path
# Extract 2D SST variables sst_signal = signal_nc['diff_ts'] # SST from signal file (2D array) skt_signal = signal_nc['diff_ts'] # Skin temperature from signal file (2D array) lat_signal = signal_nc['lat'] lon_signal = signal_nc['lon']
sst_era5 = era5_nc['sst'] # SST from ERA5 file (2D array) skt_era5 = era5_nc['skt'] # Skin temperature from ERA5 file (2D array)
# # Reverse the SST data along the latitude dimension #reversed_sst_signal = sst_signal[::-1, :] # Assuming latitude is the first dimension
# # Update the coordinates to reflect the new latitude order #reversed_latitude = lat_signal[::-1] # Reverse latitude coordinates, from [-90,90] to [90,-90]
# # Update the SST variable to use the reversed latitude #reversed_sst_signal = reversed_sst_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid # method ({"linear", "nearest", "zero", "slinear", "quadratic", # "cubic", "quintic", "polynomial", "pchip", "barycentric", "krogh", # "akima", "makima"}) – Interpolation method to use (see descriptions above). fill_value='extrapolate' # reversed_sst_signal = reversed_sst_signal.interp(latitude=sst_era5.coords['latitude'].values, # longitude=sst_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['sst'] = sst_era5 + sst_signal.values[::-1,:] # Reverse latitude coordinates, from [-90,90] to [90,-90]
# # Reverse the SST data along the latitude dimension #reversed_skt_signal = skt_signal[::-1, :] # Assuming latitude is the first dimension
# # Update the coordinates to reflect the new latitude order # # reversed_latitude = lat_signal[::-1] # Reverse latitude coordinates (Done before!!)
# # Update the SST variable to use the reversed latitude #reversed_skt_signal = reversed_skt_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# # Define new latitude and longitude arrays for 0.25-degree grid # # Perform horizontal interpolation to 0.25-degree grid # reversed_skt_signal = reversed_skt_signal.interp(latitude=sst_era5.coords['latitude'].values, # longitude=sst_era5.coords['longitude'].values)
# # Add signal to ERA5 era5_nc['skt'] = skt_era5 + skt_signal.values[::-1,:] # Reverse latitude coordinates, from [-90,90] to [90,-90]
#================== Save ================================================= # Save the result to a new NetCDF file era5_nc.to_netcdf(f'new_ERA5-0p25-SL-{yyyymmddhh}.nc')
print(f"Horizontal interpolation completed and save
Interpolating
3D Temperature from Signal NetCDF to ERA5 NetCDF
Here's a Python script for interpolating a 3D temperature field from
a signal NetCDF file to match the grid of an ERA5 NetCDF file.
In this part, we will demonstrate how to interpolate a 3D temperature
field (ta) from a signal NetCDF file to match the grid of
an ERA5 NetCDF file containing its own 3D temperature field
(TT). This process is essential for applying climate change
signals to ERA5 data effectively.
Introduction
In this blog, we'll discuss how to interpolate a 3D temperature field
(ta) from a signal NetCDF file to match the grid of an ERA5
NetCDF file, which contains a different temperature variable
(TT). This procedure involves two main steps: vertical
interpolation to align the vertical levels and horizontal interpolation
to match the latitude and longitude coordinates.
Motivation
By applying the Pseudo-Global-Warming (PGW) approach using CMIP6
climate change signals, we can generate a difference that can be added
to the initial conditions like ERA5. Accurate interpolation is crucial
for effective climate modeling and analysis.
Steps for Interpolation
Vertical Interpolation: Adjust the temperature data
from the signal file to the vertical levels of the ERA5 file.
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-04 16:31:50 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------# import os import numpy as np import xarray as xr from scipy.interpolate import interp1d
# Load the signal and ERA5 NetCDF files signal_nc = xr.open_dataset('signal_0p25.nc') # Replace with actual signal file path era5_nc = xr.open_dataset('ERA5-PL.nc') # Replace with actual ERA5 file path
#================ Vertical levels ======================================= # Vertical levels signal_levels = signal_nc['level'].values/100# Vertical levels from signal file, lev(ncl14), convert to hPa unit lat_signal = signal_nc['lat'] lon_signal = signal_nc['lon']
# Update the coordinates to reflect the new latitude order reversed_latitude = lat_signal[::-1] # Reverse latitude coordinates, from [-90,90] to [90,-90]
era5_levels = era5_nc['isobaricInhPa'] # Vertical levels from ERA5 file, 'level' if grib_to_netcdf, 'isobaricInhPa' if xarray/cfgrib
#================ T air_temperature in K ================================ print("=== processing: T air_temperature in K ")
# Extract variables ta_signal = signal_nc['diff_ta'] # 3D temperature from signal file, diff_ta(ncl0, ncl1, ncl2) TT_era5 = era5_nc['t'] # 3D temperature from ERA5 file, t(isobaricInhPa, latitude, longitude)
# Reverse the TT data along the latitude dimension reversed_ta_signal = ta_signal[:, ::-1, :] # latitude is the second dimension
# Update the TT variable to use the reversed latitude reversed_ta_signal = reversed_ta_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ## interpolated_ta = interpolated_ta.interp(latitude=TT_era5.coords['latitude'].values, longitude=TT_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['t'][1:29,:,:] = TT_era5[1:29,:,:] + interpolated_ta[1:29,:,:]
#================ Relative Humidity (RH) in % ================================ print("=== processing: Relative Humidity (RH) in % ")
# Extract variables rh_signal = signal_nc['diff_rh'] # 3D RH from signal file, diff_ta(ncl5, ncl6, ncl7) RH_era5 = era5_nc['r'] # 3D RH from ERA5 file, t(isobaricInhPa, latitude, longitude)
# Reverse the RH data along the latitude dimension reversed_rh_signal = rh_signal[:, ::-1, :] # latitude is the second dimension
# Update the RH variable to use the reversed latitude reversed_rh_signal = reversed_rh_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ##interpolated_rh = interpolated_rh.interp(latitude=RH_era5.coords['latitude'].values, longitude=RH_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['r'][1:29,:,:] = RH_era5[1:29,:,:] + interpolated_rh[1:29,:,:]
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-04 16:31:50 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------# import os import numpy as np import xarray as xr from scipy.interpolate import interp1d
# Load the signal and ERA5 NetCDF files signal_nc = xr.open_dataset('signal_0p25.nc') # Replace with actual signal file path era5_nc = xr.open_dataset(f'ERA5-0p25-PL-{yyyymmddhh}.nc') # Replace with actual ERA5 file path
#================ Vertical levels ======================================= # Vertical levels signal_levels = signal_nc['level'].values/100# Vertical levels from signal file, lev(ncl14), convert to hPa unit lat_signal = signal_nc['lat'] lon_signal = signal_nc['lon']
# Update the coordinates to reflect the new latitude order reversed_latitude = lat_signal[::-1] # Reverse latitude coordinates, from [-90,90] to [90,-90]
era5_levels = era5_nc['isobaricInhPa'] # Vertical levels from ERA5 file, 'level' if grib_to_netcdf, 'isobaricInhPa' if xarray/cfgrib
#================ T air_temperature in K ================================ print("=== processing: T air_temperature in K ")
# Extract variables ta_signal = signal_nc['diff_ta'] # 3D temperature from signal file, diff_ta(ncl0, ncl1, ncl2) TT_era5 = era5_nc['t'] # 3D temperature from ERA5 file, t(isobaricInhPa, latitude, longitude)
# Reverse the TT data along the latitude dimension reversed_ta_signal = ta_signal[:, ::-1, :] # latitude is the second dimension, # Reverse latitude coordinates, from [-90,90] to [90,-90]
# Update the TT variable to use the reversed latitude reversed_ta_signal = reversed_ta_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ## interpolated_ta = interpolated_ta.interp(latitude=TT_era5.coords['latitude'].values, longitude=TT_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['t'][1:29,:,:] = TT_era5[1:29,:,:] + interpolated_ta[1:29,:,:]
#================ Relative Humidity (RH) in % ================================ print("=== processing: Relative Humidity (RH) in % ")
# Extract variables rh_signal = signal_nc['diff_rh'] # 3D RH from signal file, diff_ta(ncl5, ncl6, ncl7) RH_era5 = era5_nc['r'] # 3D RH from ERA5 file, t(isobaricInhPa, latitude, longitude)
# Reverse the RH data along the latitude dimension reversed_rh_signal = rh_signal[:, ::-1, :] # latitude is the second dimension, # Reverse latitude coordinates, from [-90,90] to [90,-90]
# Update the RH variable to use the reversed latitude reversed_rh_signal = reversed_rh_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ##interpolated_rh = interpolated_rh.interp(latitude=RH_era5.coords['latitude'].values, longitude=RH_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['r'][1:29,:,:] = RH_era5[1:29,:,:] + interpolated_rh[1:29,:,:]
#================ u eastward_wind ================================ print("=== processing: u eastward_wind (m s**-1) ")
# Extract variables ua_signal = signal_nc['diff_ua'] # 3D diff_ua from signal file, diff_ua(level, latitude, longitude) u_era5 = era5_nc['u'] # 3D u from ERA5 file, u(isobaricInhPa, latitude, longitude)
# Reverse the RH data along the latitude dimension reversed_ua_signal = ua_signal[:, ::-1, :] # latitude is the second dimension, # Reverse latitude coordinates, from [-90,90] to [90,-90]
# Update the RH variable to use the reversed latitude reversed_ua_signal = reversed_ua_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ##interpolated_rh = interpolated_rh.interp(latitude=RH_era5.coords['latitude'].values, longitude=RH_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['u'][1:29,:,:] = u_era5[1:29,:,:] + interpolated_ua[1:29,:,:]
#================ v northward_wind ================================ print("=== processing: v northward_wind (m s**-1) ")
# Extract variables va_signal = signal_nc['diff_va'] # 3D diff_va from signal file, diff_va(level, latitude, longitude) v_era5 = era5_nc['v'] # 3D v from ERA5 file, u(isobaricInhPa, latitude, longitude)
# Reverse the RH data along the latitude dimension reversed_va_signal = va_signal[:, ::-1, :] # latitude is the second dimension, # Reverse latitude coordinates, from [-90,90] to [90,-90]
# Update the RH variable to use the reversed latitude reversed_va_signal = reversed_va_signal.assign_coords(latitude=reversed_latitude.values, longitude=lon_signal.values)
# Define new latitude and longitude arrays for 0.25-degree grid # Perform horizontal interpolation to 0.25-degree grid ##interpolated_rh = interpolated_rh.interp(latitude=RH_era5.coords['latitude'].values, longitude=RH_era5.coords['longitude'].values)
# Add signal to ERA5 era5_nc['v'][1:29,:,:] = v_era5[1:29,:,:] + interpolated_va[1:29,:,:]
# Save the result to a new NetCDF file era5_nc.to_netcdf(f'new_ERA5-0p25-PL-{yyyymmddhh}.nc')
print(f"Interpolation completed and saved to 'interpolated_ERA5-0p25-PL-{yyyymmddhh}.nc.")
Explanation of the Code
Loading Data: The script uses xarray
to load the signal and ERA5 NetCDF files.
Vertical Interpolation: A function
(vertical_interpolate) is defined to perform linear
interpolation on the vertical levels of the temperature data.
Saving the Result: The interpolated temperature
data is saved to a new NetCDF file.
Conclusion
This interpolation approach allows for aligning temperature data from
different datasets, which is essential for climate modeling. By
accurately matching the grids of the signal and ERA5 data, we can
effectively analyze and apply climate change signals in our
research.
Converting
NetCDF Files back to GRIB Format: A Step-by-Step Guide
Introduction
In the realm of climate data analysis, the ability to convert between
different file formats is essential. While NetCDF is widely used for
storing multidimensional scientific data, GRIB (Generalized
Regularly-distributed Information in Binary form) is prevalent in
meteorological applications. This blog will guide you through the
process of converting NetCDF files back to GRIB format, ensuring you're
equipped to handle various data formats in your climate studies.
Motivation
The motivation behind converting NetCDF files to GRIB format can stem
from several factors:
Compatibility: Many meteorological models and tools
predominantly use GRIB format. Converting your NetCDF data ensures
compatibility with these systems.
Efficiency: GRIB files are often more compact than
their NetCDF counterparts, making them easier to store and share,
especially when dealing with large datasets.
Standardization: For specific applications,
adhering to a standard format like GRIB can enhance data
interoperability across different platforms and tools.
After conversion, it’s crucial to verify that the GRIB file has been
created correctly. You can do this by checking the contents:
1
grib_ls output_file.grib
Verify the initial condition
To plot the vertical profiles of the given data, we can use Python
with the matplotlib library. Here's how visualize the profiles of
signal_1p25, signal_0p25, diff_era5 and diff-MPAS-init.nc against the
specified levels.
#------------------------------------------------# #Author: wpsze #Email: wpsze #date: 2025-02-06 08:54:13 #Version: 0.0 #Description: The purpose of the script #Copyright (C): 2025 All rights reserved #------------------------------------------------#
import xarray as xr import numpy as np import pandas as pd import matplotlib.pyplot as plt
SMALL_SIZE = 8 MEDIUM_SIZE = 10 BIGGER_SIZE = 24
plt.rcParams["figure.figsize"] = (10,8) plt.rc('font', size=BIGGER_SIZE) # controls default text sizes plt.rc('axes', titlesize=BIGGER_SIZE) # fontsize of the axes title plt.rc('axes', labelsize=BIGGER_SIZE) # fontsize of the x and y labels plt.rc('xtick', labelsize=BIGGER_SIZE) # fontsize of the tick labels plt.rc('ytick', labelsize=BIGGER_SIZE) # fontsize of the tick labels plt.rc('legend', fontsize=BIGGER_SIZE) # legend fontsize plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
tmp = diff_init["skintemp"] print(f"diff init (future-past) skintemp = {np.nanmean(tmp)}") #============== vertial ============================= # Extract the variable 'ta' (ensure to adjust the variable name if it's different) ta_signal = dsignal['diff_ta'] ta_signal_0p25 = dsignal_0p25['diff_ta'] ta_era5 = diff_PL['t']
# Assuming the vertical dimension is named 'level' or 'plev'; adjust as necessary levels = ta_signal['level'].values # Adjust depending on your dimensions levels_era5 = diff_PL['isobaricInhPa'].values # Adjust depending on your dimensions
# Add labels and title plt.xlabel('diff Temperature (K)') # Adjust based on your variable unit plt.ylabel('Pressure Level (hPa)') # Adjust based on your vertical coordinate plt.title('Vertical Profiles of diff Temperature (ta)') plt.legend() plt.grid() plt.gca().invert_yaxis() # Invert y-axis for pressure levels plt.tight_layout()
# Show the plot # plt.show() plt.savefig("diff_ta.png", dpi=300)
#============== vertial ============================= # Extract the variable 'ta' (ensure to adjust the variable name if it's different) ta_signal = dsignal['diff_rh'] ta_signal_0p25 = dsignal_0p25['diff_rh'] ta_era5 = diff_PL['r']
# Assuming the vertical dimension is named 'level' or 'plev'; adjust as necessary levels = ta_signal['level'].values # Adjust depending on your dimensions levels_era5 = diff_PL['isobaricInhPa'].values # Adjust depending on your dimensions
# Add labels and title plt.xlabel('diff RH (%)') # Adjust based on your variable unit plt.ylabel('Pressure Level (hPa)') # Adjust based on your vertical coordinate plt.title('Vertical Profiles of diff RH (%)') plt.legend() plt.grid() plt.gca().invert_yaxis() # Invert y-axis for pressure levels plt.tight_layout()
# Show the plot # plt.show() plt.savefig("diff_rh.png", dpi=300)
# Add labels and title plt.xlabel('diff RH (%)') # Adjust based on your variable unit plt.ylabel('level') # Adjust based on your vertical coordinate plt.title('Vertical Profiles of diff RH (%)') plt.legend() plt.grid() plt.tight_layout()
# Show the plot # plt.show() plt.savefig("diff_init_rh.png", dpi=300)
NCL references
Discussion Summary
Which Variables Can Be Used?
The selection of variables is highly dependent on the specific goals
and context of the case study. Commonly utilized variables include:
Temperature (T): Essential for understanding
thermal dynamics.
Relative Humidity (RH): Important for moisture
content and cloud formation.
Additional variables may include geopotential and wind components,
depending on the focus of the study.
Importing Wind Components (u, v): !!!
The decision to import wind components (u and v) should be guided by
their relevance to the study. Wind data is crucial for:
Enhancing model accuracy, especially in studies involving
atmospheric dynamics.
Providing insights into transport processes and weather
patterns.
The PGW method is designed to isolate the thermodynamic
effects of climate change while largely preserving the
historical synoptic patterns and dynamics of the atmosphere, such as the
large-scale wind fields that govern tropical cyclone steering.
In most PGW implementations, the future climate signal is
applied to thermodynamic variables (e.g., temperature and specific
humidity profiles) rather than dynamic variables like the 3D wind
field. This is because altering the wind field directly
could disrupt the atmospheric balance (e.g., geostrophic or hydrostatic
equilibrium), leading to unrealistic adjustments in the model during the
initial spin-up period. Instead, the wind fields are typically
left unchanged in the initial conditions, allowing the model to
dynamically adjust the winds in response to the perturbed thermodynamic
state as the simulation evolves.
For tropical cyclones, the steering flow—defined as the vertically
averaged environmental wind that guides the storm’s motion—is a critical
factor. This flow is influenced by the large-scale circulation patterns
(e.g., subtropical ridges, troughs, and jet streams), which are part of
the initial and boundary conditions derived from reanalysis data (e.g.,
ERA-Interim or NCEP) in a control run. In a PGW simulation, the
assumption is often that the future climate signal does not
significantly alter these large-scale wind patterns in the initial
state. Therefore, in many studies, the 3D wind field is not
explicitly modified by adding a future wind signal to the initial
conditions. The focus is instead on how thermodynamic changes
(e.g., warmer SSTs, increased atmospheric moisture) affect cyclone
intensity, structure, and potentially its track indirectly through
feedback on the dynamics.
If your goal is to isolate the thermodynamic effects of
warming (e.g., how increased SSTs or humidity affect TC
intensity), then not adding a 3D wind perturbation is standard practice.
The steering flow will remain consistent with the historical case, and
any changes in TC behavior will stem from thermodynamic feedbacks.
If your goal is to explore how future changes in
large-scale circulation might affect TC steering, then you could
consider adding a 3D wind perturbation derived from GCM projections
(e.g., CMIP5 or CMIP6 under a scenario like RCP8.5). However,
this is less common in PGW because:
GCMs show significant disagreement on future wind field changes,
especially at regional scales relevant to TC steering.
Adding wind perturbations risks introducing imbalances that could
destabilize the model unless carefully adjusted (e.g., via pressure
corrections to maintain hydrostatic balance).
The steering flow’s response to climate change is often studied
separately using full transient GCM simulations rather than PGW.
In practice, some PGW studies avoid wind perturbations
entirely to maintain consistency with the historical storm track and
focus on intensity or precipitation changes. Others might use
sensitivity experiments to test the impact of hypothetical wind changes,
but this is not the norm.
Interpolation Methods:
Horizontal Interpolation: Bilinear interpolation is
commonly used for its simplicity and effectiveness in providing smooth
transitions between grid points.
Vertical Interpolation: The choice between linear
and logarithmic interpolation should be based on the nature of the
variable being interpolated:
Linear Interpolation is suitable for most
variables.
Logarithmic Interpolation may be more appropriate
for variables with a wide range of values, such as pressure or
density.
Consideration of Vertical Levels:
When performing vertical interpolation, it is important to consider
whether to include levels such as 100 hPa. Generally:
If the climate signal data does not extend above certain levels
(e.g., 50 hPa), it is prudent to exclude those levels to avoid
introducing inconsistencies into the model.
Data Integration Formats:
The climate signal can be integrated into different formats based on
the model being used:
For ERA5, climate signals can be added to the ICBC
(Initial Condition Boundary Condition) files in GRIB format.
In WRF, data may be added directly to
met_em files, which are used for meteorological input.
ungrib
Extract meteorological fields from GRIB files
metgrid
Horizontally interpolate meteorological fields (from ungrib) to
simulation grids (defined by geogrid)
real.exe
Initialization will calculate reference state, vertical coordinate
interpolation, disturbance field calculation, output boundary
conditions, surface data mask, etc.
So, it is fine for adding signal into met_em because met_em
only does horizontal interpolation.
wrf.exe
For MPAS, it is no met_em step and only from
static.nc to init.nc. Therefore, the only way
is to add signal into ICBC=ERA5.
Long-term Simulations:
For extended runs in both MPAS and WRF, it is essential to
regularly update SST data. This practice helps maintain
the relevance of the model outputs to current climate conditions,
ensuring that the simulations reflect the most recent data and improving
the accuracy of long-term forecasts.
Read MPAS| ERA5| Update SST and sea-ice fraction
Integrating and interpolating climate variables in models like WRF
and MPAS involves careful consideration of the variables used, the
methods of interpolation, and the formats for data integration. By
addressing these factors, researchers can enhance the accuracy and
reliability of climate and weather predictions. Proper handling of SST
and other variables in both short-term and long-term simulations is
crucial for effective climate modeling and analysis.
cdo -v -f grb -copy sstatlantic_addhifreq.nc ofile.grb
cdo -v -f grb2 -copy sstatlantic_addhifreq.nc ofile.grb
if grib2 format.
The large GRIB file has data with 2602x1402=3648004 grid points. CDO
stores netCDF double precision floats to 24bit packed GRIB per default.
The result is a GRIB record with 10944120 bytes. The max. record length
in the GRIB1 standard is 8388607 bytes. CDO uses the ECMWF
extension of the GRIB1 standard for larger GRIB records. These
large GRIB records can only be read by CDO or tools from the ECMWF.
You can create a 16bit GRIB record to reduce the record size:
cdo -b 16 -f grb copy file.nc file.grb
Due to the fact that the NetCDF data model is much more free and
extensible than the GRIB one, it is not possible to write a generic
xarray.Dataset to a GRIB file. The aim for cfgrib is to implement write
support for a subset of carefully crafted datasets that fit the GRIB
data model. In particular the only coordinates that we target at the
moment are the one returned by opening a GRIB with the cfgrib flavour of
cfgrib.open_dataset, namely:number, time, step, a vertical coordinate
(isobaricInhPa, heightAboveGround, surface, etc), and the horizontal
coordinates (for example latitude and longitude for a regular_ll grid
type).