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

CDO based post-processing application #1871

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8f8411f
Draft of CDO and NCO post-processing script.
henrywinterbottom-wxdev Sep 20, 2023
45b81e3
Added vector rotation for a single grid rotation angle.
henrywinterbottom-wxdev Sep 20, 2023
cbcb0ef
Updated documentation strings/blocks/sections throughout.
henrywinterbottom-wxdev Sep 20, 2023
d145bf3
Removed debugging steps.
henrywinterbottom-wxdev Sep 20, 2023
4a7ea4e
Fixed shellcheck exceptions.
henrywinterbottom-wxdev Sep 20, 2023
68b3345
Some cosmetic clean up and fixed incorrect usage resulting from shel…
henrywinterbottom-wxdev Sep 21, 2023
224d921
Added files for CICE6 and MOM6 interpolation via cdo_post.sh; using s…
henrywinterbottom-wxdev Sep 21, 2023
571276e
Renamed script and fixed issues also noted in PR 1875.
henrywinterbottom-wxdev Sep 25, 2023
7cc57af
Updates addressing PR review.
henrywinterbottom-wxdev Sep 26, 2023
3684f3d
Updated incorrect syntax.
henrywinterbottom-wxdev Sep 26, 2023
9f7433a
Updated stdout/stderr redirect; not written to .
henrywinterbottom-wxdev Sep 26, 2023
20283e7
Updated stdout/stderr path and added an environment variable; cleaned…
henrywinterbottom-wxdev Sep 26, 2023
7a37748
Cleaned up stdout/stderr path; now clobbering netCDF-formatted output…
henrywinterbottom-wxdev Sep 26, 2023
f4983cc
Created stand-alone script containing the string manipulation utilili…
henrywinterbottom-wxdev Sep 26, 2023
f4016dd
Updated relative to .
henrywinterbottom-wxdev Sep 26, 2023
3ecdc03
Added missing for netCDF file purging.
henrywinterbottom-wxdev Sep 26, 2023
8e3ecf7
Updated docstring oversight.
henrywinterbottom-wxdev Sep 26, 2023
14d7438
Changed permissions such that the file is now executable.
henrywinterbottom-wxdev Sep 27, 2023
6897fe1
Bug correction for vector rotations.
henrywinterbottom-wxdev Sep 27, 2023
a6bf789
Corrections for remapping of grid angle rotations.
henrywinterbottom-wxdev Sep 28, 2023
018ec23
Updated docstrings; reorganization such that exceptions are correctly…
henrywinterbottom-wxdev Oct 2, 2023
f5c378a
Combining PRs; this commit adds and ; these components are necessary…
henrywinterbottom-wxdev Oct 2, 2023
164312d
Removed , , and .
henrywinterbottom-wxdev Oct 2, 2023
a9cefd0
Addressed linter warnings and exceptions.
henrywinterbottom-wxdev Oct 6, 2023
f3675e2
Linter updates; disabled and commented where necessary.
henrywinterbottom-wxdev Oct 6, 2023
f86a64b
Updated comments.
henrywinterbottom-wxdev Oct 6, 2023
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
9 changes: 9 additions & 0 deletions parm/post/cice6_interp.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
hi_h remapbil CICE6_INTERP_NC 0
hs_h remapbil CICE6_INTERP_NC 0
Tsfc_h remapbil CICE6_INTERP_NC 0
aice_h remapbil CICE6_INTERP_NC 0
uvel_h,vvel_h remapbil CICE6_INTERP_NC 1 ANGLE
frzmlt_h remapbil CICE6_INTERP_NC 0
albsni_h remapbil CICE6_INTERP_NC 0
mlt_onset_h remapbil CICE6_INTERP_NC 0
frz_onset_h remapbil CICE6_INTERP_NC 0
18 changes: 18 additions & 0 deletions parm/post/mom6_interp.csv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. speed should not be directly interpolated using remapbil. It should be recalculated using the remapped SSU and SSV. speed = sqrt(SSU^2 + SSV^2)
  2. evap is not required to output in operational forecast files and can be removed.
  3. lprec is not required to output in operational forecast files and can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GwenChen-NOAA Thank you for your feedback. These values were provided to me by @jiandewang.

Those three variables can be removed from the comma-delimited list. Since speed can be (re)calculated it should be the job of a script/application beyond that of remap.sh.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

speed is outputted internally from model so there is no need to recalculate it

Copy link
Contributor

@GwenChen-NOAA GwenChen-NOAA Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jiandewang, speed in the tripolar netCDF files is outputted from model and no need to change. speed in the latlon netCDF or GRIB2 files needs to be recalculated, because SSU and SSV have been remapped to a new grid. This is how wind speed and direction are handled in UPP. Directly interpolating speed to a new grid treats speed as a scalar variable, which is incorrect.

@HenryWinterbottom-NOAA, speed calculation is a simple function. Should be easy to add it into remap.sh and append the output into the latlon netCDF files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jiandewang, speed in the tripolar netCDF files is outputted from model and no need to change. speed in the latlon netCDF or GRIB2 files needs to be recalculated, because SSU and SSV have been remapped to a new grid. This is how wind speed and direction are handled in UPP. Directly interpolated speed to a new grid treats speed as a scalar variable, which is incorrect.

@HenryWinterbottom-NOAA, speed calculation is a simple function. Should be easy to add it into remap.sh and append the output into the latlon netCDF files.

Thank you for following up @GwenChen-NOAA. The remap.sh script is not intended for a specific application (i.e., it is agnostic to the respective component model output to be remapped). The purpose is to generate netCDF files containing the specified/respective variables to be defined on a new destination grid. It does not care whether it is an ice or an ocean or any other component model variable fields that are being remapped. Therefore, the speed in this case should be computed elsewhere, not within remap.sh.

Please see my branch here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aerorahul and I talked a little about this before his A/L. I'll comment once we have a more detail conversation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HenryWinterbottom-NOAA, can you point me to a sample latlon netCDF file generated using the latest code? I need it for testing. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GwenChen-NOAA The following contains a sample file that was used for debugging:

/scratch1/NCEPDEV/da/Henry.Winterbottom/scratch/Neil.Barton/vector_reorder_nonzero.nc

It contains the analysis/forecast variables SSH, SSU, and SSV.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HenryWinterbottom-NOAA, I looked at your sample data. The remapped SSH looks very good to me. The remapped SSU and SSV have more grid points along the coast with missing data, which may be caused by the rotation and land-sea mask handling. Since most variables are scalar, I think this PR is sufficient. Thanks for your good work!

vector_reorder_nonzero ssh
vector_reorder_nonzero ssu

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GwenChen-NOAA Thank you for the feedback.

I will begin the PR and send to @aerorahul and @WalterKolczynski-NOAA for final approval.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
SST remapbil MOM6_INTERP_NC 0
SSS remapbil MOM6_INTERP_NC 0
SSH remapbil MOM6_INTERP_NC 0
speed remapbil MOM6_INTERP_NC 0
MLD_003 remapbil MOM6_INTERP_NC 0
so remapbil MOM6_INTERP_NC 0
temp remapbil MOM6_INTERP_NC 0
latent remapbil MOM6_INTERP_NC 0
sensible remapbil MOM6_INTERP_NC 0
SW remapbil MOM6_INTERP_NC 0
LW remapbil MOM6_INTERP_NC 0
evap remapbil MOM6_INTERP_NC 0
lprec remapbil MOM6_INTERP_NC 0
LwLatSens remapbil MOM6_INTERP_NC 0
Heat_PmE remapbil MOM6_INTERP_NC 0
SSU,SSV remapbil MOM6_INTERP_NC 1 cos_rot,sin_rot
uo,vo remapbil MOM6_INTERP_NC 1 cos_rot,sin_rot
taux,tauy remapbil MOM6_INTERP_NC 1 cos_rot,sin_rot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with the NCL/Python remapping programs, The following variables should use conservative remapping (referred to as remapcon in CDO):

  1. latent
  2. sensible
  3. SW
  4. LW
  5. evap
  6. lprec
  7. fprec
  8. LwLatSens
  9. Heat_PmE
  10. taux,tauy

327 changes: 327 additions & 0 deletions ush/remap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
#! /usr/bin/env bash

#######
# Remapping script to remap variables within a netCDF-formatted file
# to specified destination grid projections.
#
# Syntax:
# remap.sh variable_file destination_grid output_netcdf
#
# Arguments:
#
# variable_file: ASCII formatted file containing attributes
# specific to the variables to be remapped to the
# destination grid projection(s); supported
# formats are as follows.
#
# <scalar variable> <CDO remapping type> <input variable netCDF file> 0
# <vector variables> <CDO remapping type> <input variable netCDF file> 1
# <grid rotation variable(s)>
#
# An example using the format described above is as follows.
#
# aice_h remapbil /path/to/ice/model/file 0
# uo,vo remapbil /path/to/ocean/model/file 1 cos_rot,sin_rot
#
# The example above will perform the following tasks using this
# script.
#
# * Remap the ice model `aice_h` scalar variable, **without**
# rotation, using the CDO `remapbil` type;
#
# * Rotate the ocean model current velocity vectors `uo` and
# `vo` using the `cos_rot` and `sin_rot` values within the
# ocean model netCDF file and subsequently remap them using
# the CDO `remapbil` type.
#
# The tested CDO interpolation types are as follows.
#
# * remapbil: bilinear interpolation;
# * remapcon: conservative remapping;
# * remapnn: nearest-neighbor interpolation.
#
# dstgrid_config: A netCDF-formatted or CDO-type grid description
# file; and example of such a CDO-type grid
# description file, to remap a source grid
# projected variable to a nominal 1p0 grid
# projection is as follows.
#
# gridtype = lonlat
# xsize = 360
# ysize = 181
# xfirst = -179.0
# xinc = 1.0
# yfirst = -90.0
# yinc = 1.0
#
# The latter format is preferred as it provides both readability
# and ease of destination grid configuration.
#
# output_netcdf: A netCDF-formatted file path to contain the
# specified variables remapped to the destination
# grid projection.

#######

source "${HOMEgfs}/ush/preamble.sh"
source "${HOMEgfs}/ush/string_utils.sh"
REMAP_LOG="${PWD}/remap.log"
TMP_NC_FILE="${PWD}/tmp_nc.nc"
rm -f "${REMAP_LOG}" >& /dev/null

# Collect the command line arguments and check the validity.
variable_file="${1}"
dstgrid_config="${2}"
output_path="${3}"

#######

if [[ "$#" -ne 3 ]]; then
echo "FATAL ERROR: invalid argument syntax provided to ${BASH_SOURCE[0]}"
echo "Usage: ${BASH_SOURCE[0]} <variable_file> <input_path> <output_path>"
exit 100
fi

#######

# nc_concat - Concatenate netCDF files and manage file paths.
#
# Description:
# This function performs the concatenation of two netCDF files:
# `output_path` and `var_interp_path`. If the `output_path` file
# exists, the function merges `var_interp_path` into it and manages
# temporary files accordingly. If `output_path` does not exist, it
# creates a new netCDF file by renaming `var_interp_path` to
# `output_path`.
#
# Parameters:
# $1 - The path to the variable-interpolated netCDF file.
#
# Global Variables:
# output_path - The path to the output netCDF file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make output_path an argument. Don't rely on globals.

#
# Example usage:
# nc_concat "variable_interpolated.nc"
#
# This example will concatenate the variable-interpolated file into
# the output netCDF file, handling the case where the output file may
# or may not exist.
function nc_concat(){
local var_interp_path="${1}"
local nc_output_path="${2}"

if [[ -e "${nc_output_path}" ]]; then
echo "netCDF-formatted file path ${output_path} exists; merging ${var_interp_path}."
cdo merge "${nc_output_path}" "${var_interp_path}" "${TMP_NC_FILE}" >> "${REMAP_LOG}" 2>&1
mv "${TMP_NC_FILE}" "${nc_output_path}"
rm -f "${var_interp_path}" >> /dev/null
else
echo "netCDF-formatted file path ${nc_output_path} does not exist and will be created."
mv "${var_interp_path}" "${nc_output_path}"
fi
}

#######

# cdo_remap - Perform CDO remapping and concatenate the result.
#
# Description:
# This function remaps a specific variable `varname` from an input
# netCDF file `varfile` using the specified interpolation method
# `interp_type`. It creates an intermediate netCDF file
# `varname.interp.nc` containing the remapped variable, and then it
# concatenates this intermediate file into the output netCDF file
# defined by the global variable `output_path`.
#
# Parameters:
# $1 - The name of the variable to remap.
# $2 - The path to the input netCDF file.
# $3 - The interpolation method to use (e.g., "remapbil").
#
# Global Variables:
# output_path - The path to the output netCDF file.
# dstgrid_config - The configuration for destination grid specifications.
Comment on lines +141 to +142
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, make these arguments.

#
# Example usage:
# cdo_remap "temperature" "input_file.nc" "remapbil"
#
# This example remaps the "temperature" variable using bilinear
# interpolation from the input file and appends the result to the
# output netCDF file.
function cdo_remap(){
local varname="${1}"
local varfile="${2}"
local interp_type="${3}"
local nc_output_path="${4}"
local var_interp_path="${PWD}/${varname}.interp.nc"

echo "Remapping variable ${varname} from file ${varfile} using ${interp_type} interpolation."
cdo "${interp_type}","${dstgrid_config}" -selname,"${varname}" "${varfile}" "${var_interp_path}" >> "${REMAP_LOG}" 2>&1
nc_concat "${var_interp_path}" "${nc_output_path}"
}

#######

# cdo_rotate - Rotate and remap vector variables in a netCDF file.
#
# Description:
# This function rotates vector variables specified by `varnames` in
# an input netCDF file `varfile` using the specified interpolation
# method `interp_type` and the rotation angles defined in
# `angles`. It creates an intermediate netCDF file `rotate.nc` to
# store the rotated variables, performs remapping if required, and
# renames the components before appending them to the output netCDF
# file defined by the global variable `output_path`.
#
# Parameters:
# $1 - Comma-delimited variable names to rotate (e.g., "u,v").
# $2 - The path to the input netCDF file.
# $3 - The interpolation method to use (e.g., "remapbil").
# $4 - Comma-delimited rotation angles or trigonometric functions
# (e.g., "theta" or "cosang,sinang").
#
# Global Variables:
# output_path - The path to the output netCDF file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before.

#
# Example usage:
# cdo_rotate "u,v" "input_file.nc" "remapbil" "theta"
#
# This example rotates the "u" and "v" vector components using a
# single angle variable "theta" and appends the rotated vectors to the
# output netCDF file.
#
# Vector Rotation Options:
# nangles = 1:
# Rotate the specificed vectors accordingly; here it is assumed
# that a single angle (e.g., `theta`) defines the grid rotation
# angle; the units of `theta` are assumed to be radians.
#
# nangles = 2:
# Rotate the specified vectors accordingly; here it is assumed
# that the `cos(theta)` and `sin(theta)` have been computed
# a'priori and assigned the input file variable names defined by
# `cosang` and `sinang` respectively.
#
function cdo_rotate(){
local varnames="${1}"
local varfile="${2}"
local interp_type="${3}"
local angles="${4}"
local var_rotate_path="${PWD}/rotate.nc"
local nc_output_path="${PWD}/rotate_vars.nc"

comma_split_string "${varnames}"
varname_array=("${global_array[@]}")
comma_split_string "${angles}"
angle_array=("${global_array[@]}")
strip_whitespace "${varname_array[0]}"
xvar="${out_string}"
strip_whitespace "${varname_array[1]}"
yvar="${out_string}"
nangles="${#angle_array[@]}"

# Interpolate the ocean vectors to the destination grid.
echo "Interpolating variable ${xvar} and ${yvar} to destination grid."
cdo_remap "${xvar}" "${varfile}" "${interp_type}" "${nc_output_path}"
cdo_remap "${yvar}" "${varfile}" "${interp_type}" "${nc_output_path}"
echo "Rotating and remapping variables ${xvar} and ${yvar} from file ${varfile}."

if (( nangles == 1 )); then
strip_whitespace "${angle_array[0]}"
theta="${out_string}"
cdo_remap "${theta}" "${varfile}" "${interp_type}" "${nc_output_path}"
cdo -expr,"xr=cos(${theta})*${xvar}+sin(${theta})*${yvar}; yr=cos(${theta})*${yvar}-sin(${theta})*${xvar}" -selname,"${xvar}","${yvar}","${theta}" "${output_path}" "${var_rotate_path}" >> "${REMAP_LOG}" 2>&1

elif (( nangles == 2 )); then
strip_whitespace "${angle_array[0]}"
cosang="${out_string}"
cdo_remap "${cosang}" "${varfile}" "${interp_type}" "${nc_output_path}"
strip_whitespace "${angle_array[1]}"
sinang="${out_string}"
cdo_remap "${sinang}" "${varfile}" "${interp_type}" "${nc_output_path}"
cdo -expr,"xr=${cosang}*${xvar}+${sinang}*${yvar}; yr=${cosang}*${yvar}-${sinang}*${xvar}" -selname,"${xvar}","${yvar}","${cosang}","${sinang}" "${nc_output_path}" "${var_rotate_path}" >> "${REMAP_LOG}" 2>&1
varname_update "xr" "${xvar}" "${var_rotate_path}"
cdo_remap "${xvar}" "${var_rotate_path}" "${interp_type}" "${output_path}"
varname_update "yr" "${yvar}" "${var_rotate_path}"
cdo_remap "${yvar}" "${var_rotate_path}" "${interp_type}" "${output_path}"
Comment on lines +240 to +250
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the vector remapping, it is suggested to do the following so that there is more consistency with the NCL/Python remapping programs:

  1. Replace missing values with 0.0 before any interpolation or vector rotation.
  2. On the interpolated u and v fields, for grid points where the interpolated mask equals 1 (non-ocean points), set those values on the interpolated u and v fields to a netcdf FillValue. This mask can be derived from a 2D and 3D scalar variable (e.g. SST for the 2D variable and Temperature for the 3D variable).

I think once the above 2 items are added, the CDO remapping will be in great shape.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EricSinsky-NOAA:

Replace missing values with 0.0 before any interpolation or vector rotation.

This was explored and produced a discontinuity due to the tripolar remapping as noted by @LydiaStefanova-NOAA . Therefore this does not seem like a usable solution.

The CDO application does not provide a way, at least that I am aware of, to handle the mask as you are suggesting. If there is a feature that I am unaware of I would ask that you fork my branch and attempt to add it. Otherwise this issue and PR need to be closed ASAP.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no CDO feature that I am currently aware of that can handle masks in such a way. It may require some more time and attention to add these features. However, since these items are only suggestions and not required for the CDO-based remapping to fit in the global-workflow, these items can be addressed in a separate issue and future PR only if needed, and if there are no objections from anyone. As remap.sh currently stands, I still think the results are considerably close to the original NCL remapping program ush/ocnpost.ncl.

Copy link

@DeniseWorthen DeniseWorthen Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not follow this repo, so I apologize if I'm out-of sync. A basic question: How (or where) does CDO obtain the land mask for the destination grid?

In the NCL/Python versions, the destination land mask can be thought of as an "output", meaning the destination land mask is given by the points where a source grid ocean point cannot be mapped fully to a destination grid point (ie, the destination point would be represented by a combination of a land and ocean point on the source grid). This is more and more important as the bathymetry closes in since the ocean model bathymetry will not in general match something like etopo5.

This is an entirely separate issue than the polar seam. That is the result of the fact that the last latitude on the T-cell tripole grid is at 89.64 and so no T-cell grid point can be mapped to 90N.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DeniseWorthen It is unclear what CDO uses as a land mask for the destination grid by default. It does look like there is a way to create a mask file and apply it to the interpolated field such as in this example on the CDO forum: https://code.mpimet.mpg.de/boards/53/topics/10933

Here are the basics of what I gathered from this example so far:

  1. Interpolate field: cdo -remapbil,r360x180 infile.nc infile_r360x180.nc
  2. create mask file with the same resolution as the destination grid: cdo -f nc -remapbil,r360x180 -topo topo_r360x180.nc
  3. mask the land areas using the mask file: cdo -expr,'topo = ((topo<0.0)) ? 1.0 : topo/0.0' topo_r360x180.nc mask_land.nc
  4. mask interpolated field with the mask file: cdo -mul mask_land.nc infile_r360x180.nc infile_r360x180_mask_land.nc

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @EricSinsky-NOAA I took some time and rewrote the entire original ocnpost.ncl routine in Fortran. It reproduces the fields created by the original NCL to O~-8 in all fields: https://github.com/DeniseWorthen/ocnpost90

I wasn't asked to do this, but a fortran code is a) portable b) fast and c) debuggable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DeniseWorthen Thanks for that. I suspect this will be what we ultimately go with. Once Rahul is back on Weds we will discuss the best way to proceed.

Thanks to everyone who's been working on this, particularly those who wrote stuff that may not be used, which I know can be frustrating.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DeniseWorthen Thank you for writing your NCL code in FORTRAN! I do agree that FORTRAN is a great option too for this sort of application, particularly because of its efficiency and flexibility. At first glance, your FORTRAN ocnpost program looks very close to your original NCL ocnpost program.


else
echo "FATAL ERROR: Vector rotations with ${nangles} attributes is not supported. Aborting!!!"
exit 102
fi

echo "Updating variable arrays following vector rotation."
rm -f "${var_rotate_path}" >> /dev/null
}

#######

# varname_update - Rename a variable in a netCDF file and write to a new file.
#
# Description: This function renames a variable in a netCDF file from
# `old_varname` to `new_varname` and writes the result to the
# (existing) netCDF file specified by `ncfile`.
#
# Parameters:
# $1 - The old variable name to be renamed.
# $2 - The new variable name to use.
# $3 - The path to the input netCDF file; note that this is updated
# with every call to this function.
#
# Example usage:
# varname_update "old_variable" "new_variable" "input_file.nc"
#
# This example renames the variable "old_variable" to "new_variable"
# in the input netCDF file and writes the result to the specified
# netCDF file.
function varname_update(){
local old_varname="${1}"
local new_varname="${2}"
local ncfile="${3}"

echo "Renaming variable ${old_varname} to ${new_varname} and writing to file ${ncfile}."
ncrename -O -v "${old_varname}","${new_varname}" "${ncfile}" >> "${REMAP_LOG}" 2>&1
}

#######

# Clobber the output file; otherwise the respective variables will be
# written multiple times to the file; for example VAR, VAR_1, VAR_2,
# etc.,
rm -f "${output_path}" >& /dev/null

# Define a local file path to be used for file manipulations.
#workgrid_path="${PWD}/workgrid.nc"

# Read the configuration file for the the variables to be remapped and
# proceed accordingly.
while IFS= read -r line; do

# Get the attributes for the respective variable(s).
varname=$(awk '{print $1}' <<< "${line}")
interp_type=$(awk '{print $2}' <<< "${line}")
srcgrid=$(awk '{print $3}' <<< "${line}")
rotate=$(awk '{print $4}' <<< "${line}")
angle=$(awk '{print $5}' <<< "${line}")

if (( rotate == 0 )); then
# No rotation necessary; interpolate/remap the variables and
# directly.
echo "Remapping variable ${varname} without rotation."
cdo_remap "${varname}" "${srcgrid}" "${interp_type}" "${output_path}"

elif (( rotate == 1 )); then
# Rotation necessary; rotate the respective vector quantities
# relative to the source grid projection and subsequently
# remap the variables to the specified destination grid.
echo "Remapping variables ${varname} with rotation."
cdo_rotate "${varname}" "${srcgrid}" "${interp_type}" "${angle}"

else
echo "FATAL ERROR: Rotation option ${rotate} not recognized. Aborting!!!"
exit 101
fi

done < "${variable_file}"

exit 0
Loading