Source

MOZART-global to AQMEII-NA / cartesianize_elevations.sh

#!/usr/bin/env bash
# Requires R, NCL.
# Driver for cartesianize_elevations.{r,ncl} (in that order).
# Configure as needed for your platform.

# Convert array with dimensions=(lon, lat, z), where z=geometric height above mean sea level
# to a fully Cartesian grid with dimensions=(x, y, z) all relative to center of the CMAQ sphere.

# constants with some simple manipulations------------------------------

THIS_FN="$(basename $0)"
# helpers will do the real work
THIS_PRE_NCL="${THIS_FN%.*}" # everything left of the extension
THIS_PRE_R="$(echo -e ${THIS_PRE_NCL} | sed -e 's/_/./g')"
export CALL_NCL_FN="${THIS_PRE_NCL}.ncl"
export CALL_R_FN="${THIS_PRE_R}.r"

# modules on EMVL. TODO: fixme! (these fail from here, are currently just reminders.)
# You may not need them at all!
module add netcdf-4.1.2
module add ncl_ncarg-6.0.0

# helper VMs

## NCL
### Ensure $NCARG_ROOT is set for NCL--it should be in your dotfiles, but, JIC
### tlrPanP5
NCL_VERSION='ncl_ncarg-6.1.0.Linux_Debian_x86_64_nodap_gcc445'
export NCARG_ROOT="${HOME}/bin/${NCL_VERSION}"
NCL_EXEC='ncl'
### terrae
# NCL_VERSION='ncl_ncarg/ncl_ncarg-6.1.0.Linux_RedHat_x86_64_gcc412'
# # in Jerry Herwehe's homespace temporarily (EMVL has gotta upgrade RHEL)
# export NCARG_ROOT="/home/hhg/${NCL_VERSION}"
# NCL_EXEC="${NCARG_ROOT}/bin/ncl"

## R
### tlrPanP5
R_EXEC='Rscript' # TODO: pass commandline args
### terrae
## R_DIR='/usr/local/R-2.15.0/bin'
# R_DIR='/usr/local/apps/R-2.15.2/intel-13.0/bin'
# R="${R_DIR}/R"
# RSCRIPT="${R_DIR}/Rscript"
# R_EXEC="${RSCRIPT}"

# workspace
export WORK_DIR="$(pwd)" # keep it simple for now: same dir as top of repo
# helpers
export CALL_NCL_FP="${WORK_DIR}/${CALL_NCL_FN}"
export CALL_R_FP="${WORK_DIR}/${CALL_R_FN}"

# TODO: visualization!
# # for plotting
# PDF_VIEWER='evince'  # whatever works on your platform
# # temporally disaggregate multiple plots
# DATE_FORMAT='%Y%m%d_%H%M'
# export PDF_DIR="${WORK_DIR}"

# source grids

## directories
SG_DIR="${WORK_DIR}" # keeping it simple

## files and URIs (from bitbucket repo)
export IN_URI='https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na/downloads/2008N2O_restart_region_z.txt'
IN_FN="$(basename ${IN_URI})"
IN_FN_ROOT="${IN_FN%.*}"
IN_FN_EXT="${IN_FN##*.}"

NETCDF_EXT='nc'  # stay consistent
ASCII_EXT="${IN_FN_EXT}"

# the original, ultimate, ur-source of this data
SG_ORIGINAL_URI='https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na/downloads/2008N2O_restart.nc'
SG_ORIGINAL_FN="$(basename ${SG_ORIGINAL_URI})"
# used only for netCDF strings: file not used, existence not tested
export SG_ORIGINAL_FP="${SG_DIR}/${SG_ORIGINAL_FN}"

# ASCII CSV input to R
SG_ASCII_FN="${IN_FN_ROOT}.${ASCII_EXT}"
export SG_ASCII_FP="${SG_DIR}/${SG_ASCII_FN}"
export SG_ASCII_COL_NAMES_CSV_ORDERED='lon,lat,z' # dimension names in order
export SG_ASCII_COL_COUNT='3'
export SG_ASCII_DATA_TYPE='double'

# intermediate grids

## directories
IG_DIR="${WORK_DIR}"

## files
IG_FN_ROOT="${IN_FN_ROOT%_*}_xyz" # everything left of the last '_'
# ASCII CSV output by R for R->NCL data exchange
IG_ASCII_FN="${IG_FN_ROOT}.${ASCII_EXT}"
export IG_ASCII_FP="${IG_DIR}/${IG_ASCII_FN}"

# target grids

## directories
TG_DIR="${WORK_DIR}"

## files
TG_NETCDF_FN="${IG_FN_ROOT}.${NETCDF_EXT}"
export TG_NETCDF_FP="${TG_DIR}/${TG_NETCDF_FN}" # for input to ESMF_RegridWeightGen

### global attributes
# export TG_NETCDF_TITLE="${TG_NETCDF_DATAVAR_LONGNAME} derived from ${SG_ORIGINAL_FP}" # dependency below
export TG_NETCDF_SOURCEFILE="${SG_ORIGINAL_URI}"
export TG_NETCDF_CONVENTIONS='ESMF Unstructured Grid File Format'
export TG_NETCDF_HISTORY='see https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na'
# export TG_NETCDF_CREATIONDATE="$(date)" # set @ runtime

### dimensions
export TG_NETCDF_DIM_ROW_NAME='nodeCount'  # from ESMF Unstructured Grid File Format
# export TG_NETCDF_DIM_ROW_COUNT='' # will compute
export TG_NETCDF_DIM_COL_NAME='coordDim'   # from ESMF Unstructured Grid File Format
export TG_NETCDF_DIM_COL_COUNT="${SG_ASCII_COL_COUNT}"

### datavar for Cartesianized elevations, i.e., (x,y,z)
export TG_NETCDF_DATAVAR_NAME='nodeCoords' # from ESMF Unstructured Grid File Format
export TG_NETCDF_DATAVAR_LONGNAME='Cartesianized regional grid nodes'
export TG_NETCDF_TITLE="${TG_NETCDF_DATAVAR_LONGNAME} derived from ${TG_NETCDF_SOURCEFILE}"
export TG_NETCDF_DATAVAR_UNITS='m along dimension'

# payload---------------------------------------------------------------

## setup-----------------------------------------------------------------

mkdir -p ${WORK_DIR}

### get (or remove) data------------------------------------------------

#### NCL will not overwrite target ASCII, so we will. (TODO: backup/rename)
if [[ -r "${TG_ASCII_FP}" ]] ; then
  echo -e "WARNING: ${THIS_FN}: about to delete previously output ASCII file='${TG_ASCII_FP}'"
  for CMD in \
    "rm ${TG_ASCII_FP}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
fi

#### NCL will not overwrite target netCDF, so we will. (TODO: backup/rename)
if [[ -r "${TG_NETCDF_FP}" ]] ; then
  echo -e "WARNING: ${THIS_FN}: about to delete previously output netCDF file='${TG_NETCDF_FP}'"
  for CMD in \
    "rm ${TG_NETCDF_FP}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
fi

#### get ASCII source from web if not local
if [[ ! -r "${SG_ASCII_FP}" ]] ; then
  for CMD in \
    "wget --no-check-certificate -c -O ${SG_ASCII_FP} ${IN_URI}" \
    "head ${SG_ASCII_FP}" \
    "tail ${SG_ASCII_FP}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
fi

## call R script---------------------------------------------------------

# TODO: pass args to Rscript by commandline, instead of envvars
# ${R_EXEC} # bail to R and copy script lines
for CMD in \
  "${R_EXEC} ${CALL_R_FP}" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

# ## call NCL script-------------------------------------------------------

# TODO: pass args to NCL by commandline, instead of envvars
# ${NCL_EXEC} # bail to NCL and copy script lines
for CMD in \
  "${NCL_EXEC} ${CALL_NCL_FP}" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

# ## show output files--------------------------------------------------

if [[ -r "${TG_NETCDF_FP}" ]] ; then
  for CMD in \
    "ls -alht ${WORK_DIR} | head" \
    "ncdump -h ${TG_NETCDF_FP}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
else
    echo -e "ERROR: ${THIS_FN}: output netCDF='${TG_NETCDF_FP}' not readable"
fi
# $ ls -alht /home/tlroche/code/regridding/MOZART_global_to_AQMEII-NA | head
# total 85M
# -rw-r--r-- 1 tlroche tlroche 843K Jan 30 21:08 2008N2O_restart_region_xyz.nc
# ...

# $ ncdump -h /home/tlroche/code/regridding/MOZART_global_to_AQMEII-NA/2008N2O_restart_region_xyz.nc
# netcdf \2008N2O_restart_region_xyz {
# dimensions:
#         nodeCount = 35910 ;
#         coordDim = 3 ;
# variables:
#         double nodeCoords(nodeCount, coordDim) ;
#                 nodeCoords:units = "m along dimension" ;
#                 nodeCoords:long_name = "Cartesianized regional grid nodes" ;
#                 nodeCoords:_FillValue = 9.96920996838687e+36 ;
#
# // global attributes:
#                 :creation_date = "Wed Jan 30 21:08:40 EST 2013" ;
#                 :history = "see https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na" ;
#                 :Conventions = "ESMF Unstructured Grid File Format" ;
#                 :source_file = "https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na/downloads/2008N2O_restart.nc" ;
#                 :title = "Cartesianized regional grid nodes derived from https://bitbucket.org/tlroche/mozart-global-to-aqmeii-na/downloads/2008N2O_restart.nc" ;
# }

# # TODO: plot output
#   # ... and display output PDF.
#   if [[ -r "${OUT_PDF_FP}" ]] ; then
#     for CMD in \
#       "${PDF_VIEWER} ${OUT_PDF_FP} &" \
#     ; do
#       echo -e "$ ${CMD}"
#       eval "${CMD}"
#     done
#   else
#     echo -e "ERROR: ${THIS_FN}: output PDF='${OUT_PDF_FP}' not readable"
#   fi