[nco] 01/06: Imported Upstream version 4.6.7

Bas Couwenberg sebastic at debian.org
Fri May 26 21:01:00 UTC 2017


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository nco.

commit 1cb3c57a3db3c6747bf4fef7cbf9f59105075ebc
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri May 26 22:39:07 2017 +0200

    Imported Upstream version 4.6.7
---
 CMakeLists.txt           | 262 +++++++++----
 bld/nco.spec             |  11 +-
 bld/nco_dst.pl           |  30 +-
 bm/NCO_rgr.pm            |  11 +
 configure                |  21 +-
 configure.ac             |   3 +-
 configure.eg             |  30 +-
 data/buggy.cdl           |  18 +
 data/clc.cdl             |  56 +++
 data/in.cdl              |   4 +
 data/ncclimo             |  16 +-
 data/ncremap             | 668 +++++++++++++++++++++++++-------
 data/nsm.cdl             |  55 +++
 data/trj.cdl             |  29 ++
 debian/changelog         |   6 +
 doc/ANNOUNCE             | 241 ++++++------
 doc/ChangeLog            | 227 +++++++++++
 doc/VERSION              |   2 +-
 doc/debian.txt           | 162 ++++----
 doc/index.shtml          |  66 ++--
 doc/nco.texi             | 897 +++++++++++++++++++++++++++++++++++--------
 doc/nco_qt_msvc.shtml    |   2 +-
 man/ncap.1               |   2 +-
 man/ncap2.1              |   2 +-
 man/ncbo.1               |   2 +-
 man/ncecat.1             |   2 +-
 man/nces.1               |   2 +-
 man/ncflint.1            |   2 +-
 man/ncpdq.1              |   2 +-
 man/ncra.1               |   2 +-
 man/ncrcat.1             |   2 +-
 man/ncremap.1            |  21 +-
 man/ncwa.1               |   2 +-
 qt/nco.pri               |   1 +
 src/nco++/fmc_all_cls.cc | 624 +++++++++++++++++++++++++++++-
 src/nco++/fmc_all_cls.hh |  11 +-
 src/nco++/prs_cls.cc     | 266 +++++++++----
 src/nco++/prs_cls.hh     |   8 +-
 src/nco/ncks.c           |  11 +-
 src/nco/nco.h            |  14 +-
 src/nco/nco_att_utl.c    |  48 ++-
 src/nco/nco_cnk.c        |   1 +
 src/nco/nco_cnv_csm.c    |   4 +-
 src/nco/nco_ctl.c        |  30 +-
 src/nco/nco_fl_utl.c     |   2 +-
 src/nco/nco_grp_utl.c    |   9 +-
 src/nco/nco_mss_val.c    |   6 +-
 src/nco/nco_mta.c        | 139 ++++++-
 src/nco/nco_mta.h        |   8 +-
 src/nco/nco_netcdf.c     |   4 +-
 src/nco/nco_prn.c        |  34 +-
 src/nco/nco_rgr.c        | 975 +++++++++++++++++++++++++++++++++++------------
 src/nco/nco_var_utl.c    |  21 +-
 53 files changed, 3993 insertions(+), 1081 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e48c446..c7d08fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,17 +1,18 @@
 #CMake build, Pedro Vicente 
-#options
-#FIND_SZIP try to locate SZIP library (default ON)
+#command line options for library dependencies
+#-DFIND_SZIP=BOOL try to locate SZIP library (default ON)
 #library dependencies
-#NETCDF_INCLUDE
-#NETCDF_LIBRARY
-#HDF5_LIBRARY
-#HDF5_LIBRARY
-#HDF5_HL_LIBRARY
-#ZLIB_LIBRARY
-#SZIP_LIBRARY
-#CURL_LIBRARY
-
-#Logic for finding header files and library dependencies:
+#-DNETCDF_INCLUDE=PATH
+#-DNETCDF_LIBRARY=FILE
+#-DHDF5_LIBRARY=FILE
+#-DHDF5_LIBRARY=FILE
+#-DHDF5_HL_LIBRARY=FILE
+#-DZLIB_LIBRARY=FILE
+#-DSZIP_LIBRARY=FILE
+#-DCURL_LIBRARY=FILE
+
+#///////////////////////////////////////////////////////
+#logic for finding header files and library dependencies:
 #find_path
 #find_library
 #are used (with optional location hints); the first argument contains the found file if found.
@@ -19,11 +20,30 @@
 #if not found the first argument variable is the same as a user option that contains the file location full path.
 #the same message "-- Found file at location" is made
 #but there is not an attempt at this time to validate the user input file (.h or .a)
+#///////////////////////////////////////////////////////
 
 cmake_minimum_required(VERSION 2.8)
 project (nco)
 set(BUILD_SHARED_LIBRARIES OFF)
 
+#//////////////////////////
+#preprocessor definitions
+#//////////////////////////
+
+add_definitions(-DHAVE_NETCDF4_H)
+if (MSVC)
+
+  #//////////////////////////
+  #visual studio defines math symbols in math.h, avoid duplicate definition
+  #//////////////////////////
+  
+  add_definitions(-D_MATH_DEFINES_DEFINED)
+endif(MSVC)
+
+#//////////////////////////
+#detect dependencies
+#//////////////////////////
+
 find_path(NETCDF_INCLUDE_FOUND netcdf.h HINTS ${NETCDF_INCLUDE} "/usr/include")
 if(NOT NETCDF_INCLUDE_FOUND)
   message(FATAL_ERROR "netcdf.h header file not found")
@@ -59,7 +79,7 @@ else()
   message("-- Found zlib library at: " ${ZLIB_LIBRARY})
 endif()
 
-option(FIND_SZIP "Try to link with SZIP libarry" ON)
+option(FIND_SZIP "Try to link with SZIP library" ON)
 
 if (FIND_SZIP)
 message("-- Trying to find SZIP library...")
@@ -85,7 +105,11 @@ if (MSVC)
   set(CMAKE_CXX_FLAGS_MINSIZEREL     "/MT /O1 /Ob1 /D NDEBUG")
   set(CMAKE_CXX_FLAGS_RELEASE        "/MT /O2 /Ob2 /D NDEBUG")
   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG")
-  #Compile as C++ Code (/TP)
+  
+  #//////////////////////////
+  #compile as C++ Code (/TP)
+  #//////////////////////////
+  
   set(CMAKE_C_FLAGS_DEBUG "/TP /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
   set(CMAKE_C_FLAGS_MINSIZEREL     "/TP /MT /O1 /Ob1 /D NDEBUG")
   set(CMAKE_C_FLAGS_RELEASE        "/TP /MT /O2 /Ob2 /D NDEBUG")
@@ -94,7 +118,11 @@ if (MSVC)
 
 else (MSVC)  
 
-if (CMAKE_VERSION VERSION_LESS "3.1")
+#//////////////////////////
+#compile as C99
+#//////////////////////////
+
+if (CMAKE_VERSION VERSION_LESS "3.1")  
   if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
     set (CMAKE_C_FLAGS "--std=gnu99 ${CMAKE_C_FLAGS}")
   endif ()
@@ -104,74 +132,148 @@ endif ()
 
 endif(MSVC)
 
+#//////////////////////////
+#compiler includes
+#//////////////////////////
+
 include_directories(${NETCDF_INCLUDE_FOUND})
 
+#//////////////////////////
+#link with libraries
+#//////////////////////////
+
 set(LIB_DEP ${LIB_DEP} ${NETCDF_LIBRARY} ${HDF5_HL_LIBRARY} ${HDF5_LIBRARY})
 set(LIB_DEP ${LIB_DEP} ${CURL_LIBRARY} ${ZLIB_LIBRARY} ${SZIP_LIBRARY})
-set(LIB_DEP ${LIB_DEP} ${WINSOCK_LIBRARY} m)
-
-set(SRC ${SRC} src/nco/libnco.h)
-set(SRC ${SRC} src/nco/nco_att_utl.c src/nco/nco_att_utl.h)
-set(SRC ${SRC} src/nco/nco_aux.c src/nco/nco_aux.h)
-set(SRC ${SRC} src/nco/nco_bnr.c src/nco/nco_bnr.h)
-set(SRC ${SRC} src/nco/nco_cln_utl.c src/nco/nco_cln_utl.h)
-set(SRC ${SRC} src/nco/nco_cnf_dmn.c src/nco/nco_cnf_dmn.h)
-set(SRC ${SRC} src/nco/nco_cnf_typ.c src/nco/nco_cnf_typ.h)
-set(SRC ${SRC} src/nco/nco_cnk.c src/nco/nco_cnk.h)
-set(SRC ${SRC} src/nco/nco_cnv_arm.c src/nco/nco_cnv_arm.h)
-set(SRC ${SRC} src/nco/nco_cnv_csm.c src/nco/nco_cnv_csm.h)
-set(SRC ${SRC} src/nco/nco_ctl.c src/nco/nco_ctl.h)
-set(SRC ${SRC} src/nco/nco_dbg.c src/nco/nco_dbg.h)
-set(SRC ${SRC} src/nco/nco_dmn_utl.c src/nco/nco_dmn_utl.h)
-set(SRC ${SRC} src/nco/nco_fl_utl.c src/nco/nco_fl_utl.h)
-set(SRC ${SRC} src/nco/nco_getopt.c src/nco/nco_getopt.h)
-set(SRC ${SRC} src/nco/nco_grp_trv.c src/nco/nco_grp_trv.h)
-set(SRC ${SRC} src/nco/nco_grp_utl.c src/nco/nco_grp_utl.h)
-set(SRC ${SRC} src/nco/nco.h)
-set(SRC ${SRC} src/nco/nco_lmt.c src/nco/nco_lmt.h)
-set(SRC ${SRC} src/nco/nco_lst_utl.c src/nco/nco_lst_utl.h)
-set(SRC ${SRC} src/nco/nco_md5.c src/nco/nco_md5.h)
-set(SRC ${SRC} src/nco/nco_mmr.c src/nco/nco_mmr.h)
-set(SRC ${SRC} src/nco/nco_mpi.h)
-set(SRC ${SRC} src/nco/nco_msa.c src/nco/nco_msa.h)
-set(SRC ${SRC} src/nco/nco_mss_val.c src/nco/nco_mss_val.h)
-set(SRC ${SRC} src/nco/nco_mta.c src/nco/nco_mta.h)
-set(SRC ${SRC} src/nco/nco_netcdf.c src/nco/nco_netcdf.h)
-set(SRC ${SRC} src/nco/nco_omp.c src/nco/nco_omp.h)
-set(SRC ${SRC} src/nco/nco_pck.c src/nco/nco_pck.h)
-set(SRC ${SRC} src/nco/nco_ppc.c src/nco/nco_ppc.h)
-set(SRC ${SRC} src/nco/nco_prn.c src/nco/nco_prn.h)
-set(SRC ${SRC} src/nco/nco_rec_var.c src/nco/nco_rec_var.h)
-set(SRC ${SRC} src/nco/nco_rgr.c src/nco/nco_rgr.h)
-set(SRC ${SRC} src/nco/nco_rth_flt.c src/nco/nco_rth_flt.h)
-set(SRC ${SRC} src/nco/nco_rth_utl.c src/nco/nco_rth_utl.h)
-set(SRC ${SRC} src/nco/nco_scl_utl.c src/nco/nco_scl_utl.h)
-set(SRC ${SRC} src/nco/nco_scm.c src/nco/nco_scm.h)
-set(SRC ${SRC} src/nco/nco_sld.c src/nco/nco_sld.h)
-set(SRC ${SRC} src/nco/nco_sng_utl.c src/nco/nco_sng_utl.h)
-set(SRC ${SRC} src/nco/nco_srm.c src/nco/nco_srm.h)
-set(SRC ${SRC} src/nco/nco_typ.h)
-set(SRC ${SRC} src/nco/nco_uthash.h)
-set(SRC ${SRC} src/nco/nco_var_avg.c src/nco/nco_var_avg.h)
-set(SRC ${SRC} src/nco/nco_var_lst.c src/nco/nco_var_lst.h)
-set(SRC ${SRC} src/nco/nco_var_rth.c src/nco/nco_var_rth.h)
-set(SRC ${SRC} src/nco/nco_var_scv.c src/nco/nco_var_scv.h)
-set(SRC ${SRC} src/nco/nco_var_utl.c src/nco/nco_var_utl.h)
-
-add_executable(ncks src/nco/ncks.c ${SRC})
-add_executable(ncbo src/nco/ncbo.c ${SRC})
-add_executable(ncecat src/nco/ncecat.c ${SRC})
-add_executable(ncflint src/nco/ncflint.c ${SRC})
-add_executable(ncpdq src/nco/ncpdq.c ${SRC})
-add_executable(ncra src/nco/ncra.c ${SRC})
-add_executable(ncrename src/nco/ncrename.c ${SRC})
-
-target_link_libraries (ncks ${LIB_DEP})
-target_link_libraries (ncbo ${LIB_DEP})
-target_link_libraries (ncecat ${LIB_DEP})
-target_link_libraries (ncflint ${LIB_DEP})
-target_link_libraries (ncpdq ${LIB_DEP})
-target_link_libraries (ncra ${LIB_DEP})
-target_link_libraries (ncrename ${LIB_DEP})
+
+if (MSVC)
+  set(LIB_DEP ${LIB_DEP} ${WINSOCK_LIBRARY})
+else (MSVC)
+  set(LIB_DEP ${LIB_DEP} m)
+endif(MSVC)
+
+#//////////////////////////
+#nco lib sources 
+#//////////////////////////
+
+set(nco_SOURCES ${nco_SOURCES} src/nco/libnco.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_att_utl.c src/nco/nco_att_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_aux.c src/nco/nco_aux.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_bnr.c src/nco/nco_bnr.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cln_utl.c src/nco/nco_cln_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cnf_dmn.c src/nco/nco_cnf_dmn.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cnf_typ.c src/nco/nco_cnf_typ.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cnk.c src/nco/nco_cnk.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cnv_arm.c src/nco/nco_cnv_arm.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_cnv_csm.c src/nco/nco_cnv_csm.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_ctl.c src/nco/nco_ctl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_dbg.c src/nco/nco_dbg.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_dmn_utl.c src/nco/nco_dmn_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_fl_utl.c src/nco/nco_fl_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_getopt.c src/nco/nco_getopt.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_grp_trv.c src/nco/nco_grp_trv.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_grp_utl.c src/nco/nco_grp_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_lmt.c src/nco/nco_lmt.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_lst_utl.c src/nco/nco_lst_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_md5.c src/nco/nco_md5.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_mmr.c src/nco/nco_mmr.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_mpi.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_msa.c src/nco/nco_msa.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_mss_val.c src/nco/nco_mss_val.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_mta.c src/nco/nco_mta.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_netcdf.c src/nco/nco_netcdf.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_omp.c src/nco/nco_omp.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_pck.c src/nco/nco_pck.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_ppc.c src/nco/nco_ppc.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_prn.c src/nco/nco_prn.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_rec_var.c src/nco/nco_rec_var.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_rgr.c src/nco/nco_rgr.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_rth_flt.c src/nco/nco_rth_flt.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_rth_utl.c src/nco/nco_rth_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_scl_utl.c src/nco/nco_scl_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_scm.c src/nco/nco_scm.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_sld.c src/nco/nco_sld.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_sng_utl.c src/nco/nco_sng_utl.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_srm.c src/nco/nco_srm.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_typ.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_uthash.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_var_avg.c src/nco/nco_var_avg.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_var_lst.c src/nco/nco_var_lst.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_var_rth.c src/nco/nco_var_rth.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_var_scv.c src/nco/nco_var_scv.h)
+set(nco_SOURCES ${nco_SOURCES} src/nco/nco_var_utl.c src/nco/nco_var_utl.h)
+
+add_library(nco STATIC ${nco_SOURCES})
+add_executable(ncks src/nco/ncks.c)
+add_executable(ncbo src/nco/ncbo.c)
+add_executable(ncecat src/nco/ncecat.c)
+add_executable(ncflint src/nco/ncflint.c)
+add_executable(ncpdq src/nco/ncpdq.c)
+add_executable(ncra src/nco/ncra.c)
+add_executable(ncrename src/nco/ncrename.c)
+
+set(nco_LIB nco)
+
+target_link_libraries (ncks ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncbo ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncecat ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncflint ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncpdq ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncra ${nco_LIB} ${LIB_DEP})
+target_link_libraries (ncrename ${nco_LIB} ${LIB_DEP})
+
+#/////////////////////////////////////////////////////////////////////////////////////
+#ncap2 
+#/////////////////////////////////////////////////////////////////////////////////////
+
+#options
+#command line options for library dependencies
+#-DANTLR_INCLUDE=PATH
+#-DANTLR_LIBRARY=FILE
+
+#//////////////////////////
+#detect dependencies
+#note: cmake can detect relative paths, e.g, antlr/AST.hpp
+#//////////////////////////
+
+find_path(ANTLR_INCLUDE_FOUND antlr/AST.hpp HINTS ${ANTLR_INCLUDE})
+if(NOT ANTLR_INCLUDE_FOUND)
+  message("-- ANTLR header files not found")
+else()
+  message("-- Found ANTLR header files at: " ${ANTLR_INCLUDE_FOUND})
+endif()
+
+find_library(ANTLR_LIBRARY NAMES antlr)
+if(NOT ANTLR_LIBRARY)
+  message("-- ANTLR library not found")
+else()
+  message("-- Found ANTLR library at: " ${ANTLR_LIBRARY})
+endif()
+
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/Invoke.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncap2.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncap2_utl.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncap2_att.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/sdo_utl.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/sym_cls.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/fmc_cls.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/fmc_all_cls.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/fmc_gsl_cls.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/prs_cls.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/NcapVar.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/NcapVarVector.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncoLexer.cpp)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncoParser.cpp)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/ncoTree.cpp)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/Invoke.cc)
+set(ncap2_SOURCES ${ncap2_SOURCES} src/nco++/nco_gsl.c)
+
+if(ANTLR_INCLUDE_FOUND)
+  add_executable(ncap2 ${ncap2_SOURCES})
+  target_include_directories(ncap2 PRIVATE src/nco ${ANTLR_INCLUDE_FOUND})
+  target_link_libraries (ncap2 ${nco_LIB} ${LIB_DEP} ${ANTLR_LIBRARY}) 
+endif(ANTLR_INCLUDE_FOUND)
+
+
 
 
diff --git a/bld/nco.spec b/bld/nco.spec
index 5516c46..7c409dc 100644
--- a/bld/nco.spec
+++ b/bld/nco.spec
@@ -2,17 +2,17 @@
 # http://cvs.fedoraproject.org/viewvc/devel/nco/nco.spec?view=co
 
 Name:           nco
-Version:        4.6.6
+Version:        4.6.7
 Release:        1%{?dist}
 Summary:        Programs that manipulate netCDF files
 Group:          Applications/Engineering
 License:        GPL3
 URL:            http://nco.sf.net/
 
-# Obtain NCO version 4.6.6-1 tar.gz from Sourceforge using CVS:
+# Obtain NCO version 4.6.7-1 tar.gz from Sourceforge using CVS:
 # cvs -d:pserver:anonymous at nco.cvs.sf.net:/cvsroot/nco login
-# cvs -z3 -d:pserver:anonymous at nco.cvs.sf.net:/cvsroot/nco co -r nco-4.6.6-1 -d nco-%{version} nco
-# tar czf nco-%{version}.tar.gz --exclude='nco-4.6.6/debian*' --exclude='.cvsignore' --exclude=ncap_lex.c --exclude='ncap_yacc.[ch]' ./nco-%{version}
+# cvs -z3 -d:pserver:anonymous at nco.cvs.sf.net:/cvsroot/nco co -r nco-4.6.7-1 -d nco-%{version} nco
+# tar czf nco-%{version}.tar.gz --exclude='nco-4.6.7/debian*' --exclude='.cvsignore' --exclude=ncap_lex.c --exclude='ncap_yacc.[ch]' ./nco-%{version}
 Source0:        nco-%{version}.tar.gz
 #Patch0:		nco_install_C_headers.patch
 #Patch1:         nco_find_udunits-dat.patch
@@ -108,6 +108,9 @@ fi
 # %{_libdir}/libnco++.so
 
 %changelog
+* Fri May 26 2017 Charlie Zender <zender at uci.edu> - 4.6.7-1
+- new upstream 4.6.7
+
 * Fri Apr 21 2017 Charlie Zender <zender at uci.edu> - 4.6.6-1
 - new upstream 4.6.6
 
diff --git a/bld/nco_dst.pl b/bld/nco_dst.pl
index a43f5cb..7e78a19 100755
--- a/bld/nco_dst.pl
+++ b/bld/nco_dst.pl
@@ -5,20 +5,20 @@
 
 # Usage:
 # Export tagged, public versions
-# /usr/bin/scp ${DATA}/nco-4.6.6.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
-
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln nco-4.6.6 # Build, do not release on SF
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln --sf nco-4.6.6 # Build, release on SF
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --nst_all nco-4.6.6 # Install, do not build
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln --nst_all nco-4.6.6 # Build and install
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --acd_cnt nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --acd_prs nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --cgd_cnt nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --cray_prs nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --bbl_cnt nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --blk_cnt nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --dat_cnt nco-4.6.6
-# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --ute_prs nco-4.6.6
+# /usr/bin/scp ${DATA}/nco-4.6.7.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
+
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln nco-4.6.7 # Build, do not release on SF
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln --sf nco-4.6.7 # Build, release on SF
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --nst_all nco-4.6.7 # Install, do not build
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln --nst_all nco-4.6.7 # Build and install
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --acd_cnt nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --acd_prs nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --cgd_cnt nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --cray_prs nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --bbl_cnt nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --blk_cnt nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --dat_cnt nco-4.6.7
+# ${HOME}/nco/bld/nco_dst.pl --dbg=2 --cln --ute_prs nco-4.6.7
 
 # Export daily snapshot
 # ${HOME}/nco/bld/nco_dst.pl --dbg=2 
@@ -256,7 +256,7 @@ if($bld){
 # Set up FTP server
     chdir $dst_pth_pfx or die "$prg_nm: ERROR unable to chdir to $dst_pth_pfx: $!\n"; # $! is system error string
     cmd_prc("$cp_cmd $doc_fl ./$dst_vrs/doc"); # Copy derived documentation to source directory
-    cmd_prc("$tar_cmd cvzf $dst_fl --exclude='nco-4.6.6/debian*' --exclude='.cvsignore' --exclude=ncap_lex.c --exclude=ncap_yacc.[ch] ./$dst_vrs"); # Create gzipped tarfile
+    cmd_prc("$tar_cmd cvzf $dst_fl --exclude='nco-4.6.7/debian*' --exclude='.cvsignore' --exclude=ncap_lex.c --exclude=ncap_yacc.[ch] ./$dst_vrs"); # Create gzipped tarfile
     cmd_prc("$rsh_cmd $www_mch $rm_cmd $www_drc/src/$dst_fl"); # Remove any distribution with same name
     if($dly_snp){cmd_prc("$rsh_cmd $www_mch $rm_cmd -r $www_drc/src/nco-????????.tar.gz");} # Remove previous daily snapshots from WWW server
     cmd_prc("$rcp_cmd $dst_fl $www_mch:$www_drc/src"); # Copy local tarfile to WWW server
diff --git a/bm/NCO_rgr.pm b/bm/NCO_rgr.pm
index 0cfe881..c2f95ea 100644
--- a/bm/NCO_rgr.pm
+++ b/bm/NCO_rgr.pm
@@ -2964,6 +2964,17 @@ if($RUN_NETCDF4_TESTS_VERSION_GE_431){
     NCO_bm::tst_run(\@tst_cmd);
     $#tst_cmd=0; # Reset array
 
+# ncks #122
+# ncks -O -h --rgr grid=./foo_grid.nc#latlon=64,128#no_area#lat_typ=gss#lon_typ=Grn_ctr --gaa foo5,foo6=bar4 ~/nco/data/in.nc ~/foo.nc
+# ncks -M ~/foo.nc | grep foo6 | cut -d ' ' -f 11
+    $dsc_sng="Multi-argument parsing test with flags";
+    $tst_cmd[0]="ncks -O -h --rgr grid=./foo_grid.nc#latlon=64,128#no_area#lat_typ=gss#lon_typ=Grn_ctr --gaa foo5,foo6=bar4 $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -M %tmp_fl_00% | grep foo6 | cut -d ' ' -f 11";
+    $tst_cmd[2]="bar4";
+    $tst_cmd[3]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array
+
 #####################
 #### ncpdq tests #### -OK !
 #####################
diff --git a/configure b/configure
index 2c86414..9915c7a 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NCO netCDF Operators 4.6.6.
+# Generated by GNU Autoconf 2.69 for NCO netCDF Operators 4.6.7.
 #
 # Report bugs to <nco-bugs at lists.sourceforge.net>.
 #
@@ -592,8 +592,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='NCO netCDF Operators'
 PACKAGE_TARNAME='nco'
-PACKAGE_VERSION='4.6.6'
-PACKAGE_STRING='NCO netCDF Operators 4.6.6'
+PACKAGE_VERSION='4.6.7'
+PACKAGE_STRING='NCO netCDF Operators 4.6.7'
 PACKAGE_BUGREPORT='nco-bugs at lists.sourceforge.net'
 PACKAGE_URL=''
 
@@ -1394,7 +1394,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures NCO netCDF Operators 4.6.6 to adapt to many kinds of systems.
+\`configure' configures NCO netCDF Operators 4.6.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1465,7 +1465,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of NCO netCDF Operators 4.6.6:";;
+     short | recursive ) echo "Configuration of NCO netCDF Operators 4.6.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1633,7 +1633,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-NCO netCDF Operators configure 4.6.6
+NCO netCDF Operators configure 4.6.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2499,7 +2499,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by NCO netCDF Operators $as_me 4.6.6, which was
+It was created by NCO netCDF Operators $as_me 4.6.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2847,6 +2847,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+#AC_INIT([NCO netCDF Operators],[m4_esyscmd([git describe --abbrev=7 --dirty --always --tags])],[nco-bugs at lists.sourceforge.net],[nco])
 
 # Print GNU copyright in configure script
 
@@ -3749,7 +3750,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='nco'
- VERSION='4.6.6'
+ VERSION='4.6.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21494,7 +21495,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by NCO netCDF Operators $as_me 4.6.6, which was
+This file was extended by NCO netCDF Operators $as_me 4.6.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21560,7 +21561,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-NCO netCDF Operators config.status 4.6.6
+NCO netCDF Operators config.status 4.6.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index c078e85..46f5760 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,7 +51,8 @@
 
 # Process configure input with autoconf to produce configure script
 # (package name,version,bug-report-address,tarball name)
-AC_INIT([NCO netCDF Operators],[4.6.6],[nco-bugs at lists.sourceforge.net],[nco])
+AC_INIT([NCO netCDF Operators],[4.6.7],[nco-bugs at lists.sourceforge.net],[nco])
+#AC_INIT([NCO netCDF Operators],[m4_esyscmd([git describe --abbrev=7 --dirty --always --tags])],[nco-bugs at lists.sourceforge.net],[nco])
 
 # Print GNU copyright in configure script
 AC_COPYRIGHT
diff --git a/configure.eg b/configure.eg
index cbae6af..8efba56 100644
--- a/configure.eg
+++ b/configure.eg
@@ -231,15 +231,15 @@ Status: Works
 Commands for LINUX are the only ones "regularly" used after ~2010
 ************************************************************************
 # Post upgrade requests to sysadmins at ALCF, LCRC, NCAR, NCSA, NERSC, OLCF
-# support at anl.gov # ALCF Maintainer = Adam
+# support at anl.gov # ALCF Maintainer = Adam (email borken)
 # conda update nco # Anaconda Maintainer = Filipe Fernandes (github: ocefpaf)
-# support at lcrc.anl.gov # LCRC
+# support at lcrc.anl.gov # LCRC Maintainer = Adam
 # cislhelp at ucar.edu # NCAR
 # Yan Liu <yanliu at illinois.edu> # NCSA Maintainer = Yan Liu (github: yanliu-chn)
 # https://nersc.service-now.com/navpage.do # NERSC Maintainer = Yun (Helen) He
 # https://www.olcf.ornl.gov/support/submit-ticket # OLCF
-# Subject: Upgrade NCO module to 4.6.5
-# Request: NCO 4.6.5 was released yesterday and contains many features of interest to your ACME users. Please upgrade the system NCO module to 4.6.5 and make that the default NCO module. Thanks!
+# Subject: Please upgrade NCO module to 4.6.6
+# Request: NCO 4.6.6 was released 4/21 and contains many features of interest to your ACME users. Please upgrade the system NCO module to 4.6.6 and make that the default NCO module. Thanks!
 
 zender at dust:~/nco$ pvmgetarch;uname -a;~/nco/autobld/config.guess
 LINUX
@@ -297,8 +297,9 @@ make install >> nco.make.${GNU_TRP}.foo 2>&1
 scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU_TRP}.foo nco.make.${GNU_TRP}.foo dust.ess.uci.edu:Sites/nco/rgr
 
 # 20160421: gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on roger:
+# Sysadmin upgrade request: Yan Liu <yanliu at illinois.edu>
 # Latest sysadmin-compiled module usage: module load nco/4.6.5 # 20170315
-# Personal recipe last used successfully: 20170315
+# Personal recipe last used successfully: 20170424
 module load netcdf/4.4.0
 module load udunits
 export GNU_TRP=`~/nco/autobld/config.guess`
@@ -313,8 +314,8 @@ scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU
 
 # gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on cori:
 # Sysadmin upgrade request: https://nersc.service-now.com/navpage.do
-# Latest sysadmin-compiled module usage: module load nco/4.6.4 # 20170210 (without ncap2)
-# Used 20151204-
+# Latest sysadmin-compiled module usage: module load nco/4.6.6 # 20170501 (without ncap2)
+# Personal recipe last used successfully: 20170411
 module load szip
 module load gsl
 module load udunits
@@ -332,8 +333,8 @@ scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU
 # acme: http://www.gnu.org/software/automake/manual/automake.html search for "shared by two hosts" use 
 # gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on edison:
 # Sysadmin upgrade request: https://nersc.service-now.com/navpage.do
-# Latest sysadmin-compiled module usage: module load nco/4.6.5 # 20170322 (with ncap2)
-# Personal recipe last used successfully: 20170411
+# Latest sysadmin-compiled module usage: module load nco/4.6.6 # 20170420 (with ncap2)
+# Personal recipe last used successfully: 20170519
 module load szip
 module load gsl
 module load udunits
@@ -351,7 +352,7 @@ scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU
 # gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on aims4:
 # Sysadmin upgrade request: 
 # Latest sysadmin-compiled module usage: 
-# Personal recipe last used successfully: 20170315
+# Personal recipe last used successfully: 20170428
 export GNU_TRP=`~/nco/autobld/config.guess`
 cd ~/nco;/bin/rm -f *.${GNU_TRP}.foo;make distclean
 ANTLR_ROOT=${HOME} CC='gcc' CXX='g++' NETCDF_ROOT='/usr/local/uvcdat/2016-01-21/Externals' UDUNITS2_PATH='/usr/local/uvcdat/2016-01-21/Externals' ./configure --prefix=${HOME} --bindir=${MY_BIN_DIR} --datadir=${HOME}/nco/data --libdir=${MY_LIB_DIR} --mandir=${HOME}/nco/man > nco.configure.${GNU_TRP}.foo 2>&1
@@ -365,6 +366,7 @@ scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU
 # gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on blues/anvil
 # Sysadmin upgrade request: support at lcrc.anl.gov
 # Latest sysadmin-compiled module usage: soft add +nco-4.6.5 # 20170316
+# Personal recipe last used successfully: 20170421
 # fails to link to udunits...why?
 # nm -a /soft/udunits/2.1.21/lib/libudunits2.a | grep ut_read_xml
 # First use: 20161223 Latest use: 20161223
@@ -396,7 +398,7 @@ scp nco.configure.${GNU_TRP}.foo nco.config.log.${GNU_TRP}.foo nco.libtool.${GNU
 # icc/icpc 20160217 Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on yellowstone:
 # Sysadmin upgrade request: cislhelp at ucar.edu
 # Latest sysadmin-compiled module usage: module load nco/4.5.5 # 20160228
-# Personal recipe last used successfully: 20170315
+# Personal recipe last used successfully: 20170421
 module add intel;module add gsl;module add netcdf/4.3.0;
 export PATH=${PATH}:/glade/apps/opt/netcdf/4.3.0/intel/12.1.5/bin # needed for ncgen
 export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/glade/apps/opt/netcdf/4.3.0/intel/12.1.5/lib # needed to run NCO
@@ -406,8 +408,8 @@ cd ~/nco/bld;make NETCDF_ROOT='/glade/apps/opt/netcdf/4.3.0/intel/default' UDUNI
 # gcc/g++ 20160107 Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on rhea:
 # Sysadmin upgrade request: https://www.olcf.ornl.gov/support/submit-ticket
 # Latest ticket: 347675 on 20170316
-# Latest sysadmin-compiled module usage: module load nco/4.6.5 # 20170411
-# Personal recipe last used successfully: 20170315
+# Latest sysadmin-compiled module usage: module load nco/4.6.6 # 20170515
+# Personal recipe last used successfully: 20170519
 export LINUX_CC='gcc -std=c99 -pedantic -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE'
 export LINUX_CXX='g++ -std=c++11'
 export LINUX_FC='gfortran'
@@ -424,7 +426,7 @@ cd ~/nco/bld;make ANTLR_ROOT=${HOME} NETCDF_ROOT='/sw/redhat6/netcdf/4.3.3.1/rhe
 # Sysadmin upgrade request: https://www.olcf.ornl.gov/support/submit-ticket
 # Latest ticket: 347675 on 20170316
 # Latest sysadmin-compiled module usage: module load nco/4.6.5 # 20170411
-# Personal recipe last used successfully: 20170315
+# Personal recipe last used successfully: 20170421
 export LINUX_CC='gcc -std=c99 -pedantic -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE'
 module add gcc # change GCC from v 4.3.4 to 4.9.0
 #module add gsl # not used yet
diff --git a/data/buggy.cdl b/data/buggy.cdl
index e4a25b7..6253921 100644
--- a/data/buggy.cdl
+++ b/data/buggy.cdl
@@ -66,6 +66,22 @@ netcdf buggy {
  nan_scl:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
  nan_scl:_FillValue = nan;
 
+ float nan_val;
+ nan_val:long_name = "Intended for scalar representation of IEEE NaN without missing values";
+ nan_val:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
+ nan_val:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
+ nan_val:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
+ nan_val:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
+ nan_val:note7 = "20170505 For testing without missing values"; 
+
+ float nan_val_dbl;
+ nan_val_dbl:long_name = "Intended for scalar representation of IEEE NaN without missing values";
+ nan_val_dbl:note = "20120308 Apparently netCDF ncgen chokes on variable names of nan and NaN";
+ nan_val_dbl:note2 = "20120330 netCDF ncgen on AIX/bluefire chokes on variable/attribute values of nan";
+ nan_val_dbl:note3 = "20120625 netCDF ncgen on netCDF 4.1.1 on apparently chokes on variable/attribute values of nan";
+ nan_val_dbl:note6 = "It is too troublesome to distribute in.cdl with references to NaNs because users always build with old netCDF versions that do not support it. So just comment out nan's for now.";
+ nan_val_dbl:note7 = "20170505 For testing without missing values"; 
+
  int lat_time(lat,time);
  lat_time:purpose = "record variable where record dimension is not first dimension"; 
  lat_time:bug = "ncgen until 4.3.3-rc2 20140922 fails to parse this because of Jira NCF-315. Some variables with non-leading record dimensions (like lat_tm2, lat_tm3) did work before today in \"standalone\" files like buggy.cdl, but lat_time did not.";
@@ -106,6 +122,8 @@ netcdf buggy {
 
   nan_arr=0,nan;
   nan_scl=nan;
+  nan_val=nan;
+  nan_val_dbl=nan;
 
    // 20130208: netCDF 4.2.1.1- fail as nc_get_var1_uint() returns -60 = NetCDF: Numeric conversion not representable on (valid) input values exceeding INT_MAX=2147483647. This was bug netCDF #PUX-602809 fixed in daily snapshot 20130210.
    uint_var=4294967295; // UINT_MAX = 4294967295, NC_FILL_UINT is 4294967295U
diff --git a/data/clc.cdl b/data/clc.cdl
new file mode 100644
index 0000000..2e6ae06
--- /dev/null
+++ b/data/clc.cdl
@@ -0,0 +1,56 @@
+// ncgen -k netCDF-4 -b -o ~/nco/data/clc.nc ~/nco/data/clc.cdl
+
+netcdf clc {
+  :Conventions = "CF-1.5";
+  :history = "Tue Apr 25 12:46:10 PDT 2017: ncgen -k netCDF-4 -b -o ~/nco/data/clc.nc ~/nco/data/clc.cdl";
+  :Purpose = "Demonstrate a collection of related datasets stored in hierarchical format";
+
+  group: model { 
+  :Source = "Model simulations, e.g., of temperature";
+  dimensions:
+  lat=2;
+  lon=3;
+  time=unlimited;
+  variables: // Variable attributes omitted for clarity
+  float temperature(time,lat,lon);
+  double time(time);
+  double lat(lat);
+  double lon(lon);
+  data:
+  lat=-90,90.;
+  lon=0.,120.,240.;
+  temperature=273.,273.,273.,273.,273.,273.;
+  time=1.;
+  } // end model
+  
+  group: measurements_remote_sensing { 
+  :Source = "Satellite measurements of same region as modelled, and on a different spatio-temporal grid";
+  dimensions:
+  lat=3;
+  lon=4;
+  time=unlimited;
+  variables: // Variable attributes omitted for clarity
+  float temperature(time,lat,lon);
+  double time(time);
+  double lat(lat);
+  double lon(lon);
+  data:
+  lat=-90,0.,90.;
+  lon=0.,90.,180.,270.;
+  temperature=273.,273.,273.,273.,273.,273.,273.,273.,273.,273.,273.,273.;
+  time=1.;
+  } // end measurements_remote_sensing
+
+  group: measurements_in_situ { 
+  :Source = "In situ measurements, e.g., from an automated weather station with its own time-frequency";
+  dimensions:
+  time=unlimited;
+  variables: // Variable attributes omitted for clarity
+  float temperature_10m(time);
+  double time(time);
+  data:
+  temperature_10m=271,272,273,274;
+  time=1.,2.,3.,4.;
+  } // end measurements_in_situ
+  
+} // end root group
diff --git a/data/in.cdl b/data/in.cdl
index 8de9268..a39abdb 100644
--- a/data/in.cdl
+++ b/data/in.cdl
@@ -225,6 +225,9 @@ variables:
 	lat_cal:units = "days since 1964-2-28"; 
 	lat_cal:calendar = "360_day";
 
+	double tm_scn;
+        tm_scn:units = "seconds since 2013-01-01";
+
 	double tm_std;
         tm_std:units = "days since 2013-01-01";
 
@@ -1606,6 +1609,7 @@ data:
 	time=1.,2.,3.,4.,5.,6.,7.,8.,9.,10.;
 	time_bnds=0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,4.5,5.5,5.5,6.5,6.5,7.5,7.5,8.5,8.5,9.5,9.5,10.5;
 	climatology_bounds=0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,4.5,5.5,5.5,6.5,6.5,7.5,7.5,8.5,8.5,9.5,9.5,10.5;
+	tm_scn=59;
 	tm_std=59;
 	tm_grg=59;
 	tm_jln=59;
diff --git a/data/ncclimo b/data/ncclimo
index 060a02f..d10eede 100755
--- a/data/ncclimo
+++ b/data/ncclimo
@@ -207,13 +207,17 @@ esac # !HOSTNAME
 # ncclimo --dbg=1 -s 1979 -e 1979 --var=FSNT,AODVIS,T --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_out=${DATA}/ne30/clm ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-??.nc
 # Split directory:
 # ncclimo --dbg=1 --ypf=50 -s 1979 -e 1983 --var=FSNT,AODVIS --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_in=${DATA}/ne30/raw --drc_out=${DATA}/ne30/clm
-# Split all
+# Split all:
 # cd ${DATA}/ne30/raw;ls *1979-??*.nc *198[01]-??*.nc | ncclimo --dbg=1 -s 1979 -e 1981 --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_out=${DATA}/ne30/clm
+# Split ALM:
+# ncclimo --dbg=1 -s 2000 -e 2000 --var=FSDS,TBOT --drc_out=${DATA}/ne30/clm ${DATA}/ne30/raw/F_acmev03_enso_camse_clm45bgc_ne30_co2cycle.clm2.h0.2000-??.nc
 # Split production:
 # cd /scratch2/scratchdirs/golaz/ACME_simulations/20161117.beta0.A_WCYCL1850S.ne30_oEC_ICG.edison/run;ls *cam.h0.000[1-9]* | ncclimo --dbg=1 --yr_srt=1 --yr_end=9 --var=FSNT,AODVIS,T --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_out=${DATA}/ne30/clm > ~/ncclimo.out 2>&1 &
 # cd /scratch2/scratchdirs/golaz/ACME_simulations/20161117.beta0.A_WCYCL1850S.ne30_oEC_ICG.edison/run;ls *cam.h0.0[012]??* | ncclimo --dbg=1 --yr_srt=1 --yr_end=250 --var=FSNT,AODVIS,T --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_out=${DATA}/ne30/clm > ~/ncclimo.out 2>&1 &
 # Daily pipe:
 # cd ${DATA}/ne30/raw;ls *h1*.nc | ncclimo --dbg=1 --job_nbr=8 --caseid=famipc5_ne30_v0.3_00007 --clm_md=dly -s 2001 -e 2002 --var=PRECT,TREFHT --drc_out=${DATA}/ne30/clm > ~/ncclimo.out 2>&1 &
+# SGS
+# ncclimo -d 1 -v TBOT -m clm2 -c essgcm14 -s 1 -e 1 -i ${DATA}/essgcm14 -o ~/rgr --map=${DATA}/maps/map_t42_to_fv129x256_aave.20150621.nc
 
 # Best performance on resolutions finer than ne30 (~1x1 degree) requires a job scheduler/batch processor
 # Cobalt (cooley), SLURM (cori,edison), Maui (a PBS-variant) (blues), Torque (a PBS-variant) (hopper), and PBS (rhea) schedulers allow both interactive and non-interactive (i.e., script) batch jobs
@@ -332,7 +336,7 @@ if [ -z "${nco_exe}" ]; then
     echo "${spt_nm}: ERROR Unable to find NCO, nco_exe = ${nco_exe}"
     exit 1
 fi # !nco_exe
-# Use StackOverflow method to find NCO directory
+# StackOverflow method finds NCO directory
 while [ -h "${nco_exe}" ]; do
   drc_nco="$( cd -P "$( dirname "${nco_exe}" )" && pwd )"
   nco_exe="$(readlink "${nco_exe}")"
@@ -408,7 +412,7 @@ rgr_map='' # [sng] Regridding map
 #rgr_map="${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc"
 rgr_opt='' # [sng] Regridding options (e.g., '--rgr col_nm=lndgrid', '--rgr col_nm=nCells')
 spl_opt='' # [sng] Splitter options (non-MPAS only) (e.g., '--no_cll_msr')
-spl_rgr_opt='--rgr no_stagger=Y' # [sng] Splitter regridding options
+spl_rgr_opt='--rgr no_stagger' # [sng] Splitter regridding options
 sbs_flg='No' # [sng] Split (subset) climatologies
 thr_nbr=2 # [nbr] Thread number for regridder
 tpd_out=1 # [nbr] Timesteps-per-day in ouput
@@ -853,6 +857,12 @@ if [ -n "${rgr_map}" ]; then
 	echo "${spt_nm}: HINT Supply the full path-name for the regridding map"
 	exit 1
     fi # ! -f
+    if [ "${mdl_nm}" = 'clm2' ]; then
+	printf "${spt_nm}: ERROR ${spt_nm} refuses to regrid ALM/CLM output because doing so correctly requires additional steps required for sub-gridscale (SGS) data. These steps can currently only be performed by invoking ncremap with extra arguments.\n"
+	printf "${spt_nm}: HINT Use ${spt_nm} to generate climatology/time-series files from ALM/CLM, and then issue a separate ncremap command with the extra information to regrid those files. To regrid ALM/CLM data, ncremap requires specification of the source and destination grid files (with -s grd_src and -g grd_dst, respectively).\n"
+	printf "${spt_nm}: INFO This restriction prevents users from inadvertently generating regridded output that is up to a few percent wrong. Naively regridding sub-gridscale output will generate inaccurate results in all destination gridcells that contain contributions gridcells whose surface fraction (e.g., landfrac) is less than 1.0 on the source grid. Using ncremap ensures that values from sub-gridcell features like coastlines and islands are treated correctly. For more information, con [...]
+	exit 1
+    fi # !mdl_nm
     rgr_opt="${rgr_opt} --map ${rgr_map}"
 fi # !rgr_map
 if [ -n "${thr_usr}" ]; then 
diff --git a/data/ncremap b/data/ncremap
index e06cc51..08a77b7 100755
--- a/data/ncremap
+++ b/data/ncremap
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# Purpose: Regrid (subsets of) netCDF files between different Swath, Curvilinear, Rectangular, or Unstructured data (SCRUD) grids, generate required/requested rectangular grids and/or mapfiles in SCRIP format
+# Purpose: Regrid (subsets of) netCDF files between different Swath, Curvilinear, Rectangular, and Unstructured data (SCRUD) grids, generate any required/requested global or regional rectangular grid, output SCRIP, UGRID, and/or skeleton data formats
 
 # Copyright (C) 2015--2017 Charlie Zender
 # This file is part of NCO, the netCDF Operators. NCO is free software.
@@ -164,9 +164,9 @@ esac # !HOSTNAME
 
 # Test cases (for Charlie's machines)
 # Map-only:
-# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -g ${DATA}/grids/t62_SCRIP.20150901.nc -m ~/map.nc -w esmf -a bilinear
-# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -g ${DATA}/grids/t62_SCRIP.20150901.nc -m ~/map.nc -w tempest
-# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -m ~/map.nc -w tempest
+# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -g ${DATA}/grids/t62_SCRIP.20150901.nc -m ~/map.nc -a bilinear -a bilinear
+# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -g ${DATA}/grids/t62_SCRIP.20150901.nc -m ~/map.nc -a tempest
+# ncremap -s ${DATA}/grids/oEC60to30.SCRIP.150729.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -m ~/map.nc -a tempest
 # Regrid:
 # ls ${DATA}/ne30/raw/*1979*.nc | ncremap -m ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
 # ncremap -a conserve -v FSNT -I ${DATA}/ne30/raw -s ${DATA}/grids/ne30np4_pentagons.091226.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
@@ -184,8 +184,8 @@ esac # !HOSTNAME
 # ncremap -i ${DATA}/hdf/cice_hi_flt.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
 # ncremap -i ${DATA}/hdf/cam_time.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
 # CESM & ACME:
-# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.cam.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
-# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.clm2.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
+# ncremap -s ${DATA}/grids/ne120np4_pentagons.100310.nc -i ${DATA}/ne120/raw/b1850c5_m2a.cam.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
+# ncremap -s ${DATA}/grids/ne120np4_pentagons.100310.nc -i ${DATA}/ne120/raw/b1850c5_m2a.clm2.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
 # ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.cice.h.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
 # ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.pop.h.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
 # ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.rtm.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
@@ -194,15 +194,29 @@ esac # !HOSTNAME
 # ncremap -P mpas -i ${DATA}/hdf/hist.ice.0003-12-01_00.00.00.nc -m ${DATA}/maps/map_mpas120_TO_T62_aave.121116.nc -O ~/rgr
 # New MPAS filename conventions (as of ~201612):
 # ncremap -P mpas -i ${DATA}/hdf/mpaso.hist.am.timeSeriesStatsMonthly.0001-01-01.nc -m ${DATA}/maps/map_oEC60to30_to_t62_bilin.20160301.nc -O ~/rgr
-# ncremap -P mpas --rgr_opt="--rgr cll_msr=Y" -i ${DATA}/hdf/mpascice.hist.am.timeSeriesStatsMonthly.0251-01-01.nc -m ${DATA}/maps/map_oEC60to30_to_t62_bilin.20160301.nc -O ~/rgr
+# ncremap -P mpas -i ${DATA}/hdf/mpascice.hist.am.timeSeriesStatsMonthly.0251-01-01.nc -m ${DATA}/maps/map_oEC60to30_to_t62_bilin.20160301.nc -O ~/rgr
 # ACME benchmarks:
 # ncremap -v FSNT,AODVIS -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -m ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
-# ncremap -v FSNT,AODVIS -w esmf    -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr
-# ncremap -v FSNT,AODVIS -w tempest -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr
+# ncremap -v FSNT,AODVIS -a bilinear    -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr
+# ncremap -v FSNT,AODVIS -a tempest -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr
 # Positional arguments:
 # ncremap --var=FSNT,AODVIS --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc --drc_out=~/rgr ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-??.nc
-# cell_measures:
-# ncremap --nco_opt="--rgr cll_msr=Y" -v FSNT,AODVIS -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -m ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
+# Omit cell_measures:
+# ncremap --no_cll_msr --var=FSNT,AODVIS -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -m ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
+# SGS (201705):
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/ne30/raw/F_acmev03_enso_camse_clm45bgc_ne30_co2cycle.clm2.h0.2000-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/alm_rgr.nc # 20170510 1D->2D works conserve and bilinear, no inferral
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/essgcm14/essgcm14.clm2.h0.0000-01.nc -s ${DATA}/grids/t42_SCRIP.20150901.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/t42_rgr.nc # 20170510 2D->2D works conserve and bilinear, no inferral
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/essgcm14/essgcm14.clm2.h0.0000-01.nc -s ${DATA}/grids/t42_SCRIP.20150901.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -o ~/t42_rgr.nc # 20170510 2D->2D works bilinear and conserve, infer D not S
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/essgcm14/essgcm14.clm2.h0.0000-01.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -o ~/t42_rgr.nc # 20170510 2D->2D works bilinear and conserve ~2% wrong, infer S and D
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/essgcm14/essgcm14.clm2.h0.0000-01.nc -d ${DATA}/hdf/b1850c5cn_doe_polar_merged_0_cesm1_2_0_HD+MAM4+tun2b.hp.e003.cam.h0.0001-01.nc -o ~/t42_rgr.nc # 20170510 2D->2D works bilinear and conserve ~2% wrong, infer S and D
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/ne30/rgr/F_acmev03_enso_camse_clm45bgc_ne30_co2cycle.clm2.h0.2000-01.nc -d ${DATA}/essgcm14/essgcm14.cam2.h0.0000-01.nc -o ~/fv09_rgr.nc # 20170510 2D->2D bilinear works and conserve ~2% wrong, infer S and D
+# ncremap --vrb=3 -P sgs --var=area,FSDS,landfrac,landmask,TBOT -i ${DATA}/ne30/rgr/F_acmev03_enso_camse_clm45bgc_ne30_co2cycle.clm2.h0.2000-01.nc -d ${HOME}/skl_t42.nc -o ~/fv09_rgr.nc # 20170510 2D->2D works bilinear and conserve ~2% wrong, infer S and D
+# ncremap --vrb=3 -p nil -P sgs -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ${DATA}/ne30/rgr ${DATA}/ne30/raw/F_acmev03_enso_camse_clm45bgc_ne30_co2cycle.clm2.h0.2000-??.nc > ~/ncremap.out 2>&1 &
+# ncremap --vrb=3 -P sgs -a conserve --sgs_frc=aice --sgs_msk=tmask --sgs_nrm=100 --var=hi,uvel,aice,aisnap,albsno,blkmask,evap,evap_ai,fswabs,fswabs_ai,fswdn,fswthru,fswthru_ai,ice_present,snow,snow_ai,tarea,tmask,uarea -i ${DATA}/hdf/ctl_brcp85c5cn_deg1.enm.cice.h.2050-07.nc -s ${DATA}/grids/gx1v7_151008.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/cice_rgr.nc # 20170525 normalization required to get mask right
+# ncremap --vrb=3 -P cice -a conserve --var=hi,uvel,aice,aisnap,albsno,blkmask,evap,evap_ai,fswabs,fswabs_ai,fswdn,fswthru,fswthru_ai,ice_present,snow,snow_ai,tarea,tmask,uarea -i ${DATA}/hdf/ctl_brcp85c5cn_deg1.enm.cice.h.2050-07.nc -s ${DATA}/grids/gx1v7_151008.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/cice_rgr.nc # 20170525 cice short-cut
+# CICE/CESM on POP grid: full grid inferral (and thus conservative remapping) fails because masked vertices/cells missing, must use bilinear or supply grid-file for conservative
+# ncremap -a bilinear -i ${DATA}/hdf/ctl_brcp85c5cn_deg1.enm.cice.h.2050-07.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/wenshan.nc # 20170515: grid centers/bounds in non-masked regions suffice for bilinear interpolation
+# ncremap -a conserve -i ${DATA}/hdf/ctl_brcp85c5cn_deg1.enm.cice.h.2050-07.nc -s ${DATA}/grids/gx1v7_151008.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -o ~/wenshan.nc # 20170521: conservative requires supplied tri-pole grid for centers/bounds in masked regions
 # Debugging and Benchmarking:
 # ncremap -D 1 -i ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr > ~/ncremap.out 2>&1 &
 
@@ -217,7 +231,7 @@ if [ -z "${nco_exe}" ]; then
     echo "ERROR: Unable to find NCO, nco_exe = ${nco_exe}"
     exit 1
 fi # !nco_exe
-# Use stackoverflow method to find NCO directory
+# StackOverflow method finds NCO directory
 while [ -h "${nco_exe}" ]; do
   drc_nco="$( cd -P "$( dirname "${nco_exe}" )" && pwd )"
   nco_exe="$(readlink "${nco_exe}")"
@@ -245,7 +259,7 @@ fi # !TERM
 
 # Defaults for command-line options and some derived variables
 # Modify these defaults to save typing later
-alg_typ='bilinear' # [nbr] Algorithm for ESMF interpolation (bilinear|patch|neareststod|nearestdtos|conserve)
+alg_typ='bilinear' # [nbr] Algorithm for interpolation (bilinear|conserve|nearestdtos|neareststod|patch|tempest)
 bch_pbs='No' # [sng] PBS batch (non-interactive) job
 bch_slr='No' # [sng] SLURM batch (non-interactive) job
 cln_flg='Yes' # [flg] Clean-up (remove) intermediate files before exiting
@@ -258,18 +272,16 @@ drc_out="${drc_pwd}" # [sng] Output file directory
 drc_out_xmp="~/rgr" # [sng] Output file directory for examples
 dst_fl='' # [sng] Destination file
 dst_xmp='dst.nc' # [sng] Destination file for examples
-#esmf_opt='--src_regional --dst_regional --ignore_unmapped' # [sng] ESMF_RegridWeightGen options
-#esmf_opt='--ignore_unmapped --netcdf4' # [sng] ESMF_RegridWeightGen options
-esmf_opt='--ignore_unmapped' # [sng] ESMF_RegridWeightGen options
 fl_nbr=0 # [nbr] Number of files to remap
 gaa_sng="--gaa remap_script=${spt_nm} --gaa remap_command=\"'${cmd_ln}'\" --gaa remap_hostname=${HOSTNAME} --gaa remap_version=${nco_vrs}" # [sng] Global attributes to add
 grd_dst='' # [sng] Destination grid-file
-grd_dst_glb="${DATA}/grids/180x360_SCRIP.20150901.nc" # [sng] Grid-file (destination) global
 grd_dst_xmp='grd_dst.nc' # [sng] Destination grid-file for examples
 grd_sng='' # [sng] Grid string
 grd_src='' # [sng] Source grid-file
 grd_src_xmp='grd_src.nc' # [sng] Source grid-file for examples
 hdr_pad='10000' # [B] Pad at end of header section
+hnt_dst='' # [sng] ERWG hint for destination grid
+hnt_src='' # [sng] ERWG hint for source grid
 in_fl='' # [sng] Input file
 in_xmp='in.nc' # [sng] Input file for examples
 inp_aut='No' # [sng] Input file list automatically generated (in ncclimo, or specified with -i in ncremap)
@@ -282,33 +294,45 @@ map_xmp='map.nc' # [sng] Map-file for examples
 mlt_map_flg='Yes' # [sng] Multi-map flag
 mpi_flg='No' # [sng] Parallelize over nodes
 msh_fl='' # [sng] Mesh-file (for Tempest)
+msk_dst='' # [sng] Mask-template variable in destination file
+msk_out='' # [sng] Mask variable in regridded file
+msk_src='' # [sng] Mask-template variable in source file
 nco_opt='-O --no_tmp_fl' # [sng] NCO defaults (e.g., '-O -6 -t 1')
 nco_usr='' # [sng] NCO user-configurable options (e.g., '-D 1')
 nd_nbr=1 # [nbr] Number of nodes
 out_fl='' # [sng] Output file
 out_xmp='out.nc' # [sng] Output file for examples
 par_typ='nil' # [sng] Parallelism type
-pdq_typ='' # [sng] Permutation type
-#rgr_opt='--rgr lat_nm_out=lat --rgr lon_nm_out=lon --rnr=0.0' # [sng] Regridding options
+prc_typ='' # [sng] Procedure type
 rgr_opt='--rgr lat_nm_out=lat --rgr lon_nm_out=lon' # [sng] Regridding options
+rnr_thr='' # [frc] Renormalization option
+sgs_frc='landfrac' # [sng] Sub-grid fraction variable
+sgs_msk='landmask' # [sng] Sub-grid mask variable
+sgs_nrm='1.0' # [frc] Sub-grid normalization
 std_flg='No' # [sng] Input available from pipe to stdin
 thr_nbr=2 # [nbr] Thread number for regridder
 tmp_out_fl='ncremap_grd_tmp.nc' # [sng] Temporary output file
-#tps_opt='--mono' # [sng] TempestRemap options
-tps_opt='' # [sng] TempestRemap options
+ugrid_fl='' # [sng] UGRID file
 unq_sfx=".pid${spt_pid}" # [sng] Unique suffix
 #var_lst='FSNT,AODVIS' # [sng] Variables to process (empty means all)
 var_lst='' # [sng] Variables to process (empty means all)
 var_rgr='' # [sng] CF template variable
 var_xmp='FSNT' # [sng] Variable list for examples
 vrb_lvl=2 # [sng] Verbosity level
-vrb_0=0 # [sng] Verbosity level: Quiet
-vrb_1=1 # [sng] Verbosity level: Standard, minimal file I/O
-vrb_2=2 # [sng] Verbosity level: All file I/O
-vrb_3=3 # [sng] Verbosity level: English
-vrb_4=4 # [sng] Verbosity level: Pedantic
+vrb_0=0 # [enm] Verbosity level: Quiet
+vrb_1=1 # [enm] Verbosity level: Standard, minimal file I/O
+vrb_2=2 # [enm] Verbosity level: All file I/O
+vrb_3=3 # [enm] Verbosity level: English
+vrb_4=4 # [enm] Verbosity level: Pedantic
 vrs_prn='No' # [sng] Print version information
-wgt_gnr='esmf' # [sng] Weight-generator program
+wgt_exe_esmf='ESMF_RegridWeightGen' # [sng] ESMF executable
+wgt_exe_tps='GenerateOfflineMap' # [sng] TempestRemap executable
+wgt_typ='esmf' # [sng] Weight-generator program
+wgt_opt='' # [sng] Weight-generator options
+#wgt_opt_esmf='--ignore_unmapped --netcdf4' # [sng] ESMF_RegridWeightGen options
+wgt_opt_esmf='--ignore_unmapped' # [sng] ESMF_RegridWeightGen options
+#wgt_opt_tps='--mono' # [sng] TempestRemap options
+wgt_opt_tps='' # [sng] TempestRemap options
 xtn_var='' # [sng] Extensive variables (e.g., 'TSurfStd_ct')
 
 # Set temporary-file directory
@@ -326,10 +350,9 @@ function fnc_usg_prn { # NB: dash supports fnc_nm (){} syntax, not function fnc_
     printf "${fnt_rvr}Basic usage:\n${fnt_nrm} ${fnt_bld}$spt_nm -i in_fl -d dst_fl -o out_fl${fnt_nrm}\n"
     printf "${fnt_nrm} ${fnt_bld}${spt_nm} --input_file=in_fl --destination=dst_fl --output_file=out_fl${fnt_nrm}\n\n"
     echo "Command-line options [long-option synonyms in ${fnt_tlc}italics${fnt_nrm}]:"
-    echo "${fnt_rvr}-a${fnt_nrm} ${fnt_bld}alg_typ${fnt_nrm}  Algorithm for ESMF weight generation (default ${fnt_bld}${alg_typ}${fnt_nrm}) [${fnt_tlc}alg_typ, algorithm, regrid_algorithm${fnt_nrm}]"
+    echo "${fnt_rvr}-a${fnt_nrm} ${fnt_bld}alg_typ${fnt_nrm}  Algorithm for weight generation (default ${fnt_bld}${alg_typ}${fnt_nrm}) [${fnt_tlc}alg_typ, algorithm, regrid_algorithm${fnt_nrm}]"
     echo "${fnt_rvr}-d${fnt_nrm} ${fnt_bld}dst_fl${fnt_nrm}   Data file to infer destination grid from (empty means none, i.e., use grd_fl, grd_sng or map_fl)) (default ${fnt_bld}${dst_fl}${fnt_nrm}) [${fnt_tlc}dst_fl, destination_file, template_file, template${fnt_nrm}]"
     echo "${fnt_rvr}-D${fnt_nrm} ${fnt_bld}dbg_lvl${fnt_nrm}  Debug level (default ${fnt_bld}${dbg_lvl}${fnt_nrm}) [${fnt_tlc}dbg_lvl, dbg, debug, debug_level${fnt_nrm}]"
-    echo "${fnt_rvr}-E${fnt_nrm} ${fnt_bld}esmf_opt${fnt_nrm} ESMF ESMF_RegridWeightGen options (default ${fnt_bld}${esmf_opt}${fnt_nrm}) [${fnt_tlc}esmf_opt, esmf, esmf_options${fnt_nrm}]"
     echo "${fnt_rvr}-G${fnt_nrm} ${fnt_bld}grd_sng${fnt_nrm}  Grid generation argument string (empty means none) (default ${fnt_bld}${grd_sng}${fnt_nrm}) [${fnt_tlc}grd_sng, grid_generation, grid_gen, grid_string${fnt_nrm}]"
     echo "${fnt_rvr}-g${fnt_nrm} ${fnt_bld}grd_dst${fnt_nrm}  Grid-file (destination) (empty means none, i.e., infer from dst_fl or use grd_sng or map_fl) (default ${fnt_bld}${grd_dst}${fnt_nrm}) [${fnt_tlc}grd_dst, grid_dest, dest_grid, destination_grid${fnt_nrm}]"
     echo "${fnt_rvr}-I${fnt_nrm} ${fnt_bld}drc_in${fnt_nrm}   Input directory (empty means none) (default ${fnt_bld}${drc_in}${fnt_nrm}) [${fnt_tlc}drc_in, in_drc, dir_in, in_dir, input${fnt_nrm}]"
@@ -337,26 +360,37 @@ function fnc_usg_prn { # NB: dash supports fnc_nm (){} syntax, not function fnc_
     echo "${fnt_rvr}-j${fnt_nrm} ${fnt_bld}job_nbr${fnt_nrm}  Job simultaneity for parallelism (default ${fnt_bld}${job_nbr}${fnt_nrm}) [${fnt_tlc}job_nbr, job_number, jobs${fnt_nrm}]"
     echo "${fnt_rvr}-M${fnt_nrm}          Multi-map-file toggle (unset means generate one map-file per input file) [${fnt_tlc}mlt_map, no_multimap${fnt_nrm}]"
     echo "${fnt_rvr}-m${fnt_nrm} ${fnt_bld}map_fl${fnt_nrm}   Map-file (empty means generate internally) (default ${fnt_bld}${map_fl}${fnt_nrm}) [${fnt_tlc}map_fl, map, map_file, rgr_map, regrid_map${fnt_nrm}]"
+    echo " ${fnt_bld}--msk_dst${fnt_nrm}  Mask-template variable in destination file (empty means none) (default ${fnt_bld}${msk_dst}${fnt_nrm}) [${fnt_tlc}msk_dst, dst_msk, mask_destination, mask_dst${fnt_nrm}]"
+    echo " ${fnt_bld}--msk_out${fnt_nrm}  Mask variable in regridded file (empty means none) (default ${fnt_bld}${msk_out}${fnt_nrm}) [${fnt_tlc}msk_out, out_msk, mask_output, mask_rgr${fnt_nrm}]"
+    echo " ${fnt_bld}--msk_src${fnt_nrm}  Mask-template variable in source file (empty means none) (default ${fnt_bld}${msk_src}${fnt_nrm}) [${fnt_tlc}msk_src, src_msk, mask_source, mask_src${fnt_nrm}]"
     echo "${fnt_rvr}-n${fnt_nrm} ${fnt_bld}nco_opt${fnt_nrm}  NCO options (empty means none) (default ${fnt_bld}${nco_opt}${fnt_nrm}) [${fnt_tlc}nco_opt, nco_options${fnt_nrm}]"
     echo " ${fnt_bld}--no_cll_msr${fnt_nrm}  Omit cell_measures variables (e.g., 'area') [${fnt_tlc}no_area, no_cll_msr, no_cell_measures${fnt_nrm}]"
     echo " ${fnt_bld}--no_frm_trm${fnt_nrm}  Omit formula_terms variables (e.g., 'hyba', 'PS') [${fnt_tlc}no_frm_trm, no_formula_terms${fnt_nrm}]"
     echo " ${fnt_bld}--no_stg_grd${fnt_nrm}  Omit staggered grid variables ('slat, slon, w_stag') [${fnt_tlc}no_stg_grd, no_stg, no_stagger, no_staggered_grid${fnt_nrm}]"
     echo "${fnt_rvr}-O${fnt_nrm} ${fnt_bld}drc_out${fnt_nrm}  Output directory (default ${fnt_bld}${drc_out}${fnt_nrm}) [${fnt_tlc}drc_out, out_drc, dir_out, out_dir, output${fnt_nrm}]"
     echo "${fnt_rvr}-o${fnt_nrm} ${fnt_bld}out_fl${fnt_nrm}   Output-file (regridded file) (empty copies Input filename) (default ${fnt_bld}${out_fl}${fnt_nrm}) [${fnt_tlc}out_fl, out_file, output_file${fnt_nrm}]"
-    echo "${fnt_rvr}-P${fnt_nrm} ${fnt_bld}pdq_typ${fnt_nrm}  Permutation type (empty means none) (default ${fnt_bld}${pdq_typ}${fnt_nrm}) [${fnt_tlc}pdq_typ, prm_typ, permutation, permute${fnt_nrm}]"
+    echo "${fnt_rvr}-P${fnt_nrm} ${fnt_bld}prc_typ${fnt_nrm}  Procedure type (empty means none) (default ${fnt_bld}${prc_typ}${fnt_nrm}) [${fnt_tlc}prc_typ, pdq_typ, prm_typ, procedure${fnt_nrm}]"
     echo "${fnt_rvr}-p${fnt_nrm} ${fnt_bld}par_typ${fnt_nrm}  Parallelism type (default ${fnt_bld}${par_typ}${fnt_nrm}) [${fnt_tlc}par_typ, par_md, parallel_type, parallel_mode, parallel${fnt_nrm}]"
     echo "${fnt_rvr}-R${fnt_nrm} ${fnt_bld}rgr_opt${fnt_nrm}  Regrid options (empty means none) (default ${fnt_bld}${rgr_opt}${fnt_nrm}) [${fnt_tlc}rgr_opt, regrid_options${fnt_nrm}]"
+    echo "${fnt_rvr}-r${fnt_nrm} ${fnt_bld}rnr_thr${fnt_nrm}  Renormalization threshold (empty means none) (default ${fnt_bld}${rnr_thr}${fnt_nrm}) [${fnt_tlc}rnr_thr, thr_rnr, renormalize_threshold${fnt_nrm}]"
+    echo " ${fnt_bld}--rgn_dst${fnt_nrm}  Regional destination grid [${fnt_tlc}rgn_dst, dst_rgn, regional_destination${fnt_nrm}]"
+    echo " ${fnt_bld}--rgn_src${fnt_nrm}  Regional source grid [${fnt_tlc}rgn_src, src_rgn, regional_source${fnt_nrm}]"
     echo "${fnt_rvr}-s${fnt_nrm} ${fnt_bld}grd_src${fnt_nrm}  Grid-file (source) (empty means infer or use map_fl) (default ${fnt_bld}${grd_src}${fnt_nrm}) [${fnt_tlc}grd_src, grid_source, source_grid, src_grd${fnt_nrm}]"
+    echo " ${fnt_bld}--sgs_frc${fnt_nrm}  Sub-grid fraction variable (empty means none) (default ${fnt_bld}${sgs_frc}${fnt_nrm}) [${fnt_tlc}sgs_frc, ice_frc, lnd_frc, ocn_frc, subgrid_fraction${fnt_nrm}]"
+    echo " ${fnt_bld}--sgs_msk${fnt_nrm}  Sub-grid mask variable (empty means none) (default ${fnt_bld}${sgs_msk}${fnt_nrm}) [${fnt_tlc}sgs_msk, ice_msk, lnd_msk, ocn_msk, subgrid_mask${fnt_nrm}]"
+    echo " ${fnt_bld}--sgs_nrm${fnt_nrm}  Sub-grid fraction normalization (empty means none) (default ${fnt_bld}${sgs_nrm}${fnt_nrm}) [${fnt_tlc}sgs_nrm, subgrid_normalization${fnt_nrm}]"
     echo " ${fnt_bld}--std_flg${fnt_nrm}  Stdin used for input (default ${fnt_bld}${inp_std}${fnt_nrm}) [${fnt_tlc}stdin, std_flg, inp_std, redirect, standard_input${fnt_nrm}]"
-    echo "${fnt_rvr}-T${fnt_nrm} ${fnt_bld}tps_opt${fnt_nrm}  TempestRemap GenerateOfflineMap options (default ${fnt_bld}${tps_opt}${fnt_nrm}) [${fnt_tlc}tps_opt, tempest_opt, tempest, tempest_options${fnt_nrm}]"
+    echo "${fnt_rvr}-T${fnt_nrm} ${fnt_bld}drc_tmp${fnt_nrm}  Temporary directory (for intermediate files) (default ${fnt_bld}${drc_tmp}${fnt_nrm}) [${fnt_tlc}drc_tmp, tmp_drc, dir_tmp, tmp_dir, tmp${fnt_nrm}]"
     echo "${fnt_rvr}-t${fnt_nrm} ${fnt_bld}thr_nbr${fnt_nrm}  Thread number for regridder (default ${fnt_bld}${thr_nbr}${fnt_nrm}) [${fnt_tlc}thr_nbr, thread_number, thread, threads${fnt_nrm}]"
-    echo "${fnt_rvr}-U${fnt_nrm} ${fnt_bld}drc_tmp${fnt_nrm}  Temporary directory (for intermediate files) (default ${fnt_bld}${drc_tmp}${fnt_nrm}) [${fnt_tlc}drc_tmp, tmp_drc, dir_tmp, tmp_dir, tmp${fnt_nrm}]"
+    echo "${fnt_rvr}-U${fnt_nrm}          Unpack input prior to regridding [${fnt_tlc}unpack, upk, upk_inp${fnt_nrm}]"
     echo "${fnt_rvr}-u${fnt_nrm} ${fnt_bld}unq_sfx${fnt_nrm}  Unique suffix (prevents intermediate files from sharing names) (default ${fnt_bld}${unq_sfx}${fnt_nrm}) [${fnt_tlc}unq_sfx, unique_suffix, suffix${fnt_nrm}]"
+    echo " ${fnt_bld}--ugrid_fl${fnt_nrm} UGRID file (empty means none) (default ${fnt_bld}${ugrid_fl}${fnt_nrm}) [${fnt_tlc}ugrid_fl, ugrid, ugrid_file${fnt_nrm}]"
     echo "${fnt_rvr}-V${fnt_nrm} ${fnt_bld}var_rgr${fnt_nrm}  CF template variable (empty means none) (default ${fnt_bld}${var_rgr}${fnt_nrm}) [${fnt_tlc}var_rgr, rgr_var, var_cf, cf_var, cf_variable${fnt_nrm}]"
     echo "${fnt_rvr}-v${fnt_nrm} ${fnt_bld}var_lst${fnt_nrm}  Variable list (empty means all) (default ${fnt_bld}${var_lst}${fnt_nrm}) [${fnt_tlc}var_lst, variable_list, var, vars, variable, variables${fnt_nrm}]"
     echo " ${fnt_bld}--version${fnt_nrm}  Version and configuration information [${fnt_tlc}version, vrs, config, configuration, cnf${fnt_nrm}]"
     echo " ${fnt_bld}--vrb_lvl${fnt_nrm}  Verbosity level (default ${fnt_bld}${vrb_lvl}${fnt_nrm}) [${fnt_tlc}vrb_lvl, vrb, verbosity, print_verbosity${fnt_nrm}]"
-    echo "${fnt_rvr}-w${fnt_nrm} ${fnt_bld}wgt_gnr${fnt_nrm}  Weight-generator (default ${fnt_bld}${wgt_gnr}${fnt_nrm}) [${fnt_tlc}wgt_gnr, weight_generator, generator${fnt_nrm}]"
+    echo "${fnt_rvr}-W${fnt_nrm} ${fnt_bld}wgt_opt${fnt_nrm}  Weight-generator options (default ${fnt_bld}${wgt_opt_esmf}${fnt_nrm}) [${fnt_tlc}wgt_opt, esmf_opt, esmf_options, tempest_opt, tps_opt${fnt_nrm}]"
+    echo "${fnt_rvr}-w${fnt_nrm} ${fnt_bld}wgt_cmd${fnt_nrm}  Weight-generator command (default ${fnt_bld}${wgt_exe_esmf}${fnt_nrm}) [${fnt_tlc}wgt_cmd, wgt_gnr, weight_command, weight_generator${fnt_nrm}]"
     echo "${fnt_rvr}-x${fnt_nrm} ${fnt_bld}xtn_var${fnt_nrm}  Extensive variables (empty means none) (default ${fnt_bld}${xtn_var}${fnt_nrm}) [${fnt_tlc}xtn_var, xtn_lst, extensive, var_xtn, extensive_variables${fnt_nrm}]"
     printf "\n"
     printf "Examples: ${fnt_bld}$spt_nm -i ${in_xmp} -m ${map_xmp} -o ${out_xmp} ${fnt_nrm}\n"
@@ -365,7 +399,7 @@ function fnc_usg_prn { # NB: dash supports fnc_nm (){} syntax, not function fnc_
     printf "          ${fnt_bld}$spt_nm -s ${grd_src_xmp} -g ${grd_dst_xmp} -m ${map_xmp} ${fnt_nrm}\n"
     printf "          ${fnt_bld}$spt_nm -a bilinear -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
     printf "          ${fnt_bld}$spt_nm -a conserve -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
-    printf "          ${fnt_bld}$spt_nm -w tempest  -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
+    printf "          ${fnt_bld}$spt_nm -a tempest  -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
     printf "          ${fnt_bld}$spt_nm -v ${var_xmp} -i ${in_xmp} -m ${map_xmp} -o ${out_xmp} ${fnt_nrm}\n"
     printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -m ${map_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
     printf "          ${fnt_bld}$spt_nm -M -I ${drc_in_xmp} -d ${dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
@@ -400,13 +434,12 @@ fi # !arg_nbr
 # Parse command-line options:
 # http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
 # http://tuxtweaks.com/2014/05/bash-getopts
-while getopts :a:CD:d:E:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:s:T:t:U:u:V:v:w:x:-: OPT; do
+while getopts :a:CD:d:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:r:s:T:t:Uu:V:v:W:w:x:-: OPT; do
     case ${OPT} in
 	a) alg_typ="${OPTARG}" ;; # Algorithm
 	C) clm_flg='Yes' ;; # Climo flag (undocumented)
 	D) dbg_lvl="${OPTARG}" ;; # Debugging level
 	d) dst_fl="${OPTARG}" ;; # Destination file
-	E) esmf_opt="${OPTARG}" ;; # ESMF options
 	g) grd_dst="${OPTARG}" ;; # Destination grid-file
 	G) grd_sng="${OPTARG}" ;; # Grid generation string
 	I) drc_in="${OPTARG}" ;; # Input directory
@@ -417,17 +450,19 @@ while getopts :a:CD:d:E:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:s:T:t:U:u:V:v:w:x:-: OPT; d
 	n) nco_usr="${OPTARG}" ;; # NCO options
 	O) drc_usr="${OPTARG}" ;; # Output directory
 	o) out_fl="${OPTARG}" ;; # Output file
-	P) pdq_typ="${OPTARG}" ;; # Permutation type
+	P) prc_typ="${OPTARG}" ;; # Procedure type
 	p) par_typ="${OPTARG}" ;; # Parallelism type
+	r) rnr_thr="${OPTARG}" ;; # Renormalization threshold
 	R) rgr_opt="${OPTARG}" ;; # Regridding options
 	s) grd_src="${OPTARG}" ;; # Source grid-file
-	T) tps_opt="${OPTARG}" ;; # Tempest options
+	T) tmp_usr="${OPTARG}" ;; # Temporary directory
 	t) thr_usr="${OPTARG}" ;; # Thread number
-	U) tmp_usr="${OPTARG}" ;; # Temporary directory
+	U) pdq_opt='-U' ;;        # Unpack input
 	u) unq_usr="${OPTARG}" ;; # Unique suffix
 	V) var_rgr="${OPTARG}" ;; # CF template variable 
 	v) var_lst="${OPTARG}" ;; # Variables
-	w) wgt_usr="${OPTARG}" ;; # Weight-generator
+	W) wgt_opt="${OPTARG}" ;; # Weight-generator options
+	w) wgt_usr="${OPTARG}" ;; # Weight-generator command
 	x) xtn_var="${OPTARG}" ;; # Extensive variables
 	-) LONG_OPTARG="${OPTARG#*=}"
 	   case ${OPTARG} in
@@ -439,7 +474,6 @@ while getopts :a:CD:d:E:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:s:T:t:U:u:V:v:w:x:-: OPT; d
 	       clm_flg=?* | climatology_flag=?* ) clm_flg='Yes' ;; # -C # Climo flag (undocumented)
 	       dbg_lvl=?* | dbg=?* | debug=?* | debug_level=?* ) dbg_lvl="${LONG_OPTARG}" ;; # -d # Debugging level
 	       dst_fl=?* | destination_file=?* | template_file=?* | template=?* ) dst_fl="${LONG_OPTARG}" ;; # -d # Destination file
-	       esmf_opt=?* | esmf=?* | esmf_options=?* ) esmf_opt="${LONG_OPTARG}" ;; # -E # ESMF options
 	       grd_dst=?* | grid_dest=?* | dest_grid=?* | destination_grid=?* ) grd_dst="${LONG_OPTARG}" ;; # -g # Destination grid-file
 	       grd_sng=?* | grid_generation=?* | grid_gen=?* | grid_string=?* ) grd_sng="${LONG_OPTARG}" ;; # -G # Grid generation string
 	       drc_in=?* | in_drc=?* | dir_in=?* | in_dir=?* | input=?* ) drc_in="${LONG_OPTARG}" ;; # -i # Input directory
@@ -448,6 +482,9 @@ while getopts :a:CD:d:E:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:s:T:t:U:u:V:v:w:x:-: OPT; d
 	       mlt_map | multimap | no_multimap | nomultimap ) mlt_map_flg='No' ;; # -M # Multi-map flag
 	       mlt_map=?* | multimap=?* | no_multimap=?* | nomultimap=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # -M # Multi-map flag
 	       map_fl=?* | map=?* | map_file=?* | rgr_map=?* | regrid_map=?* ) map_fl="${LONG_OPTARG}" ;; # -m # Map-file
+	       msk_dst=?* | dst_msk=?* | mask_destination=?* | mask_dst=?* ) msk_dst="${LONG_OPTARG}" ;; # # Mask-template variable in destination file
+	       msk_out=?* | out_msk=?* | mask_output=?* | mask_out=?* ) msk_out="${LONG_OPTARG}" ;; # # Mask variable in regridded file
+	       msk_src=?* | src_msk=?* | mask_source=?* | mask_src=?* ) msk_src="${LONG_OPTARG}" ;; # # Mask-template variable in source file
 	       nco_opt=?* | nco=?* | nco_options=?* ) nco_usr="${LONG_OPTARG}" ;; # -n # NCO options
 	       no_area | no_cll_msr | no_cell_measures ) no_cll_msr='Yes' ;; # # Omit cell_measures variables
 	       no_area=?* | no_cell_msr=?* | no_cell_measures=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # # Omit cell_measures variables
@@ -457,21 +494,32 @@ while getopts :a:CD:d:E:f:g:G:h:I:i:j:Mm:n:O:o:P:p:R:s:T:t:U:u:V:v:w:x:-: OPT; d
 	       no_stg_grd=?* | no_stg=?* | no_stagger=?* | no_staggered_grid ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # # Omit staggered grid variables
 	       drc_out=?* | out_drc=?* | dir_out=?* | out_dir=?* | output=?* ) drc_usr="${LONG_OPTARG}" ;; # -O # Output directory
 	       out_fl=?* | output_file=?* | out_file=?* ) out_fl="${LONG_OPTARG}" ;; # -o # Output file
-	       pdq_typ=?* | prm_typ=?* | permutation=?* | permute=?* ) pdq_typ="${LONG_OPTARG}" ;; # -P # Permutation type
+	       prc_typ=?* | pdq_typ=?* | prm_typ=?* | procedure=?* ) prc_typ="${LONG_OPTARG}" ;; # -P # Procedure type
 	       par_typ=?* | par_md=?* | parallel_type=?* | parallel_mode=?* | parallel=?* ) par_typ="${LONG_OPTARG}" ;; # -p # Parallelism type
 	       rgr_opt=?* | regrid_options=?* ) rgr_opt="${LONG_OPTARG}" ;; # -R # Regridding options
+	       rnr_thr=?* | thr_rnr=?* | renormalization_threshold=?* ) rnr_thr="${LONG_OPTARG}" ;; # -r # Renormalization threshold
+	       rgn_dst=?* | dst_rgn=?* | regional_destination=?* ) hnt_dst='--dst_regional' ;; # # Regional destination grid
+	       rgn_dst=?* | dst_rgn=?* | regional_destination=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # # Regional destination grid
+	       rgn_src=?* | src_rgn=?* | regional_source=?* ) hnt_src='--src_regional' ;; # # Regional source grid
+	       rgn_src=?* | src_rgn=?* | regional_source=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # # Regional source grid
 	       grd_src=?* | grid_source=?* | source_grid=?* | src_grd=?* ) grd_src="${LONG_OPTARG}" ;; # -s # Source grid-file
+	       sgs_frc=?* | ice_frc=?* | lnd_frc=?* | ocn_frc=?* | subgrid_fraction=?* ) sgs_frc="${LONG_OPTARG}" ;; # # Sub-grid fraction variable
+	       sgs_msk=?* | ice_msk=?* | lnd_msk=?* | ocn_msk=?* | subgrid_mask=?* ) sgs_msk="${LONG_OPTARG}" ;; # # Sub-grid mask variable
+	       sgs_nrm=?* | subgrid_normalization=?* ) sgs_nrm="${LONG_OPTARG}" ;; # # Sub-grid fraction normalization
 	       stdin | inp_std | std_flg | redirect | standard_input ) inp_std='Yes' ;; # # Input file list from stdin
 	       stdin=?* | inp_std=?* | std_flg=?* | redirect=?* | standard_input=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # # Input file list from stdin
-	       tps_opt=?* | tempest_opt=?* | tempest=?* | tempest_options=?* ) tps_opt="${LONG_OPTARG}" ;; # -T # Tempest options
+	       drc_tmp=?* | tmp_drc=?* | dir_tmp=?* | tmp_dir=?* | tmp=?* ) tmp_usr="${LONG_OPTARG}" ;; # -T # Temporary directory
 	       thr_nbr=?* | thread_number=?* | thread=?* | threads=?* ) thr_usr="${LONG_OPTARG}" ;; # -t # Thread number
-	       drc_tmp=?* | tmp_drc=?* | dir_tmp=?* | tmp_dir=?* | tmp=?* ) tmp_usr="${LONG_OPTARG}" ;; # -U # Temporary directory
+	       unpack=?* | upk=?* | upk_inp=?* ) pdq_opt='-U' ;; # -U # Unpack input
+	       unpack=?* | upk=?* | upk_inp=?* ) echo "No argument allowed for --${OPTARG switch}" >&2; exit 1 ;; # -U # Unpack input
+	       ugrid_fl=?* | ugrid=?* | ugrid_file=?* ) ugrid_fl="${LONG_OPTARG}" ;; # # UGRID file
 	       unq_sfx=?* | unique_suffix=?* | suffix=?* ) unq_usr="${LONG_OPTARG}" ;; # -u # Unique suffix
 	       var_rgr=?* | rgr_var=?* | var_cf=?* | cf_var=?* | cf_variable=?* ) var_rgr="${LONG_OPTARG}" ;; # -V # CF template variable 
 	       var_lst=?* | variable_list=?* | var=?* | vars=?* | variable=?* | variables=?* ) var_lst="${LONG_OPTARG}" ;; # -v # Variables
 	       vrb_lvl=?* | vrb=?* | verbosity=?* | print_verbosity=?* ) vrb_lvl="${LONG_OPTARG}" ;; # # Print verbosity
 	       version | vrs | config | configuration | cnf ) vrs_prn='Yes' ;; # # Print version information
-	       wgt_gnr=?* | weight_generator=?* | generator=?* ) wgt_usr="${LONG_OPTARG}" ;; # -w # Weight-generator
+	       wgt_opt=?* | esmf_opt=?* | esmf_options=?* | tps_opt=?* | tempest_opt=?* | tempest_options=?* ) wgt_opt="${LONG_OPTARG}" ;; # -W # Weight-generator options
+	       wgt_cmd=?* | weight_command=?* | wgt_gnr=?* | weight_generator=?* ) wgt_usr="${LONG_OPTARG}" ;; # -w # Weight-generator command
 	       xtn_var=?* | extensive=?* | var_xtn=?* | extensive_variables=?* ) xtn_var="${LONG_OPTARG}" ;; # -x # Extensive variables
                '' ) break ;; # "--" terminates argument processing
                * ) printf "\nERROR: Illegal option ${fnt_bld}--${OPTARG}${fnt_nrm}\n" >&2; fnc_usg_prn ;;
@@ -498,19 +546,19 @@ if [ ${vrs_prn} = 'Yes' ]; then
     printf "Config: ${spt_nm} running from directory ${drc_spt}\n"
     printf "Config: calling NCO binaries in directory ${drc_nco}\n"
     printf "Config: binaries linked to netCDF library version ${lbr_vrs}\n"
-    wgt_cmd='ESMF_RegridWeightGen'
-    cmd_wgt=`command -v ${wgt_cmd} 2> /dev/null`
+    tst_cmd=${wgt_exe_esmf}
+    cmd_wgt=`command -v ${tst_cmd} 2> /dev/null`
     if [ $? -eq 0 ]; then
-	printf "Config: ESMF weight-generation command ${wgt_cmd} found as ${cmd_wgt}\n"
+	printf "Config: ESMF weight-generation command ${tst_cmd} found as ${cmd_wgt}\n"
     else
-	printf "Config: ESMF weight-generation command ${wgt_cmd} not found\n"
+	printf "Config: ESMF weight-generation command ${tst_cmd} not found\n"
     fi # !err
-    wgt_cmd='GenerateOverlapMesh'
-    cmd_wgt=`command -v ${wgt_cmd} 2> /dev/null`
+    tst_cmd=${wgt_exe_tps}
+    cmd_wgt=`command -v ${tst_cmd} 2> /dev/null`
     if [ $? -eq 0 ]; then
-	printf "Config: Tempest weight-generation command ${wgt_cmd} found as ${cmd_wgt}\n"
+	printf "Config: Tempest weight-generation command ${tst_cmd} found as ${cmd_wgt}\n"
     else
-	printf "Config: Tempest weight-generation command ${wgt_cmd} not found\n"
+	printf "Config: Tempest weight-generation command ${tst_cmd} not found\n"
     fi # !err
     exit 0
 fi # !vrs_prn
@@ -584,8 +632,10 @@ fi # !out_fl
 att_fl="${drc_tmp}/ncremap_tmp_att.nc" # [sng] Missing value workflow (MPAS) default
 grd_dst_dfl="${drc_tmp}/ncremap_tmp_grd_dst.nc" # [sng] Grid-file (destination) default
 grd_src_dfl="${drc_tmp}/ncremap_tmp_grd_src.nc" # [sng] Grid-file (source) default
+hnt_dst_fl="${drc_tmp}/ncremap_tmp_hnt_dst.txt" # [sng] Hint (for ERWG) destination
+hnt_src_fl="${drc_tmp}/ncremap_tmp_hnt_src.txt" # [sng] Hint (for ERWG) source
 ncwa_fl="${drc_tmp}/ncremap_tmp_ncwa.nc" # [sng] ncwa workflow (HIRDLS, MLS) default
-pdq_fl="${drc_tmp}/ncremap_tmp_pdq.nc" # [sng] Permuted data default (AIRS, HIRDLS, MLS, MPAS) 
+pdq_fl="${drc_tmp}/ncremap_tmp_pdq.nc" # [sng] Permuted/Unpacked data default (AIRS, HIRDLS, MLS, MOD04, MPAS) 
 tmp_out_fl="${drc_tmp}/${tmp_out_fl}" # [sng] Temporary output file
 znl_fl="${drc_tmp}/ncremap_tmp_znl.nc" # [sng] Zonal workflow (HIRDLS, MLS) default
 
@@ -603,13 +653,15 @@ fi # !unq_sfx
 att_fl=${att_fl}${unq_sfx}
 grd_dst_dfl=${grd_dst_dfl}${unq_sfx}
 grd_src_dfl=${grd_src_dfl}${unq_sfx}
+hnt_dst_fl=${hnt_dst_fl}${unq_sfx}
+hnt_src_fl=${hnt_src_fl}${unq_sfx}
 ncwa_fl=${ncwa_fl}${unq_sfx}
 pdq_fl=${pdq_fl}${unq_sfx}
 tmp_out_fl=${tmp_out_fl}${unq_sfx}
 znl_fl=${znl_fl}${unq_sfx}
 
+# Algorithm options are bilinear|conserve|nearestdtos|neareststod|patch|tempest
 if [ ${alg_typ} = 'bilinear' ] || [ ${alg_typ} = 'bln' ]; then 
-    # ESMF algorithms are bilinear|patch|neareststod|nearestdtos|conserve
     alg_opt='bilinear'
 elif [ ${alg_typ} = 'conserve' ] || [ ${alg_typ} = 'conservative' ] || [ ${alg_typ} = 'cns' ]; then 
     alg_opt='conserve'
@@ -619,7 +671,29 @@ elif [ ${alg_typ} = 'neareststod' ] || [ ${alg_typ} = 'nsd' ] || [ ${alg_typ} =
     alg_opt='neareststod'
 elif [ ${alg_typ} = 'patch' ] || [ ${alg_typ} = 'pch' ] || [ ${alg_typ} = 'ptc' ]; then 
     alg_opt='patch'
+elif [ ${alg_typ} = 'tempest' ] || [ ${alg_typ} = 'tps' ] || [ ${alg_typ} = 'tmp' ]; then 
+    alg_opt='tempest'
+else 
+    echo "${spt_nm}: ERROR ${alg_typ} is not a valid interpolation option\n"
+    echo "${spt_nm}: HINT Valid interpolation options are bilinear|conserve|nearestdtos|neareststod|patch|tempest\n"
+    exit 1
 fi # !alg_typ
+if [ ${alg_opt} = 'tempest' ]; then
+    wgt_typ='tempest'
+fi # alg_opt
+if [ ${wgt_typ} = 'esmf' ]; then
+    wgt_cmd="${wgt_exe_esmf}"
+    wgt_exe="${wgt_exe_esmf}"
+    wgt_opt="${wgt_opt_esmf}"
+else 
+    wgt_cmd="${wgt_exe_tps}"
+    wgt_exe="${wgt_exe_tps}"
+    wgt_opt="${wgt_opt_tps}"
+fi # !wgt_typ
+if [ -n "${wgt_usr}" ]; then 
+    wgt_cmd=${wgt_usr}
+fi # !wgt_usr    
+
 if [ -z "${drc_in}" ]; then
     drc_in="${drc_pwd}"
 else # !drc_in
@@ -650,11 +724,26 @@ if [ "${no_frm_trm}" = 'Yes' ]; then
     nco_opt="${nco_opt} --no_frm_trm"
 fi # !no_frm_trm
 if [ "${no_stg_grd}" = 'Yes' ]; then 
-    rgr_opt="${rgr_opt} --rgr no_stagger=Y"
+    rgr_opt="${rgr_opt} --rgr no_stagger"
 fi # !no_stg_grd
+if [ -n "${rnr_thr}" ]; then 
+    rgr_opt="${rgr_opt} --rgr rnr=${rnr_thr}"
+fi # !rnr_thr
 if [ -n "${var_lst}" ]; then 
     nco_var_lst="-v ${var_lst}"
 fi # !var_lst
+if [ -n "${msk_dst}" ]; then 
+    nco_msk_dst="--rgr msk_var=${msk_dst}"
+fi # !msk_dst
+if [ -n "${msk_out}" ]; then 
+    nco_msk_out="--rgr msk_var=${msk_out}"
+fi # !msk_out
+if [ -n "${msk_src}" ]; then 
+    nco_msk_src="--rgr msk_var=${msk_src}"
+fi # !msk_src
+if [ -n "${ugrid_fl}" ]; then 
+    nco_ugrid_fl="--rgr ugrid=${ugrid_fl}"
+fi # !ugrid_fl
 if [ -n "${var_rgr}" ]; then 
     nco_var_rgr="--rgr_var=${var_rgr}"
 fi # !var_rgr
@@ -677,39 +766,58 @@ elif [ "${par_typ}" = 'mpi' ]; then
     mpi_flg='Yes'
     par_opt=' &'
 fi # !par_typ
-if [ -n "${pdq_typ}" ]; then
-    if [ "${pdq_typ}" != 'airs' ] && [ "${pdq_typ}" != 'hirdls' ] && [ "${pdq_typ}" != 'mls' ] && [ "${pdq_typ}" != 'mpas' ] && [ "${pdq_typ}" != 'nil' ]; then 
-	    echo "ERROR: Invalid -P pdq_typ option = ${pdq_typ}"
-	    echo "HINT: Valid pdq_typ arguments are 'airs', 'hirdls', 'mls', 'mpas', and 'nil'"
+if [ -n "${prc_typ}" ]; then
+    if [ "${prc_typ}" != 'airs' ] && [ "${prc_typ}" != 'alm' ] && [ "${prc_typ}" != 'clm' ] && [ "${prc_typ}" != 'cice' ] && [ "${prc_typ}" != 'hirdls' ] && [ "${prc_typ}" != 'mls' ] && [ "${prc_typ}" != 'mod04' ] && [ "${prc_typ}" != 'mpas' ] && [ "${prc_typ}" != 'nil' ] && [ "${prc_typ}" != 'sgs' ] ; then 
+	    echo "ERROR: Invalid -P prc_typ option = ${prc_typ}"
+	    echo "HINT: Valid prc_typ arguments are 'airs', 'alm', 'clm', 'cice', 'hirdls', 'mls', 'mod04', 'mpas', 'nil', and 'sgs'"
 	    exit 1
-    fi # !pdq_typ
-fi # !pdq_typ
-if [ "${pdq_typ}" = 'airs' ]; then 
+    fi # !prc_typ
+fi # !prc_typ
+if [ "${prc_typ}" = 'airs' ]; then 
     pdq_opt='-a StdPressureLev,GeoTrack,GeoXTrack'
 fi # !airs
-if [ "${pdq_typ}" = 'hirdls' ]; then 
+if [ "${prc_typ}" = 'hirdls' ]; then 
     pdq_opt='-a Pressure,Latitude,lon'
 fi # !hirdls
-if [ "${pdq_typ}" = 'mls' ]; then 
+if [ "${prc_typ}" = 'mls' ]; then 
     pdq_opt='-a CO_Pressure,CO_Latitude,lon'
 fi # !mls
-if [ "${pdq_typ}" = 'mpas' ]; then 
-#    pdq_opt='-a Time,nVertLevels,maxEdges,MaxEdges2,nEdges,nCells' # Ocean only
-#    pdq_opt='-a Time,nCategories,ONE,nEdges,nCells' # Ice only
+if [ "${prc_typ}" = 'mod04' ]; then 
+    pdq_opt='-U'
+    hnt_dst='--dst_regional'
+fi # !mod04
+if [ "${prc_typ}" = 'mpas' ]; then 
+#    pdq_opt='-a Time,nVertLevels,maxEdges,MaxEdges2,nEdges,nCells' # Ocean
+#    pdq_opt='-a Time,nCategories,ONE,nEdges,nCells' # Ice
     pdq_opt='-a Time,nVertLevels,maxEdges,MaxEdges2,nCategories,ONE,nEdges,nCells' # Ocean and Ice in one swell foop
     rgr_opt="${rgr_opt} --rnr=0.0"
 fi # !mpas
+if [ "${prc_typ}" = 'alm' ] || [ "${prc_typ}" = 'clm' ]; then 
+    # Set ALM/CLM-specific options first, then change prc_typ to sgs
+    rds_rth='6.37122e6' # [m] Radius of Earth in ALM/CLM (SHR_CONST_REARTH)
+    sgs_frc='landfrac'
+    sgs_msk='landmask'
+    sgs_nrm='1.0'
+    prc_alm='Yes'
+    prc_typ='sgs'
+fi # !alm, !clm
+if [ "${prc_typ}" = 'cice' ]; then 
+    # Set CICE-specific options first, then change prc_typ to sgs
+    rds_rth='6371229.0' # [m] Radius of Earth in MPAS-CICE (global attribute sphere_radius)
+    sgs_frc='aice'
+    sgs_msk='tmask'
+    sgs_nrm='100.0'
+    prc_cice='Yes'
+    prc_typ='sgs'
+fi # !alm
+if [ "${prc_typ}" = 'sgs' ]; then 
+    nco_dgn_area='--rgr diagnose_area'
+    wgt_opt_esmf='--user_areas --ignore_unmapped'
+    wgt_opt=${wgt_opt_esmf}
+fi # !sgs
 if [ -n "${thr_usr}" ]; then 
     thr_nbr="${thr_usr}"
 fi # !thr_usr
-if [ -n "${wgt_usr}" ]; then 
-    wgt_gnr="${wgt_usr}"
-fi # !wgt_usr    
-if [ "${wgt_gnr}" != 'esmf' ] && [ "${wgt_gnr}" != 'tempest' ]; then 
-	    echo "ERROR: Invalid -w wgt_gnr option = ${wgt_gnr}"
-	    echo "HINT: Valid wgt_gnr arguments are 'esmf' and 'tempest'"
-	    exit 1
-fi # !wgt_gnr
 
 if [ -n "${dst_fl}" ]; then 
     if [ ! -f "${dst_fl}" ]; then
@@ -739,7 +847,7 @@ else
     grd_src=${grd_src_dfl} # [sng] Grid-file default
 fi # !grd_src
 if [ -z "${grd_sng}" ]; then 
-    grd_sng_dfl="--rgr grd_ttl='Default internally-generated grid' --rgr grid=${grd_dst_dfl} --rgr latlon=100,100 --rgr snwe=30.0,70.0,-130.0,-90.0" # [sng] Grid string default
+    grd_sng_dfl="--rgr grd_ttl='Default internally-generated grid' --rgr scrip=${grd_dst_dfl} --rgr latlon=100,100 --rgr snwe=30.0,70.0,-130.0,-90.0" # [sng] Grid string default
     grd_sng="${grd_sng_dfl}"
 else
     grd_sng_usr_flg='Yes'
@@ -783,16 +891,16 @@ if [ -n "${map_fl}" ]; then
 	fi # ! -f
     fi # !map_mk
 else # !map_fl
-    if [ "${wgt_gnr}" = 'esmf' ]; then 
-	map_fl_dfl="${drc_tmp}/ncremap_tmp_map_${wgt_gnr}_${alg_opt}.nc${unq_sfx}" # [sng] Map-file default
+    if [ "${wgt_typ}" = 'esmf' ]; then 
+	map_fl_dfl="${drc_tmp}/ncremap_tmp_map_${wgt_typ}_${alg_opt}.nc${unq_sfx}" # [sng] Map-file default
     fi # !esmf
-    if [ "${wgt_gnr}" = 'tempest' ]; then 
-	map_fl_dfl="${drc_tmp}/ncremap_tmp_map_${wgt_gnr}.nc${unq_sfx}" # [sng] Map-file default
+    if [ "${wgt_typ}" = 'tempest' ]; then 
+	map_fl_dfl="${drc_tmp}/ncremap_tmp_map_${wgt_typ}.nc${unq_sfx}" # [sng] Map-file default
     fi # !tempest
     map_fl=${map_fl_dfl}
 fi # !map_fl
-if [ "${map_mk}" = 'Yes' ] && [ "${wgt_gnr}" = 'tempest' ]; then 
-    msh_fl_dfl="${drc_tmp}/ncremap_tmp_msh_ovr_${wgt_gnr}.g${unq_sfx}" # [sng] Mesh-file default
+if [ "${map_mk}" = 'Yes' ] && [ "${wgt_typ}" = 'tempest' ]; then 
+    msh_fl_dfl="${drc_tmp}/ncremap_tmp_msh_ovr_${wgt_typ}.g${unq_sfx}" # [sng] Mesh-file default
     msh_fl=${msh_fl_dfl}
 fi # !tempest
 
@@ -941,15 +1049,26 @@ if [ ${dbg_lvl} -ge 2 ]; then
     printf "dbg: map_mk   = ${map_mk}\n"
     printf "dbg: mlt_map  = ${mlt_map_flg}\n"
     printf "dbg: mpi_flg  = ${mpi_flg}\n"
+    printf "dbg: msk_dst  = ${msk_dst}\n"
+    printf "dbg: msk_out  = ${msk_out}\n"
+    printf "dbg: msk_src  = ${msk_src}\n"
     printf "dbg: nco_opt  = ${nco_opt}\n"
     printf "dbg: nd_nbr   = ${nd_nbr}\n"
     printf "dbg: out_fl   = ${out_fl}\n"
     printf "dbg: par_typ  = ${par_typ}\n"
+    printf "dbg: rgr_opt  = ${rgr_opt}\n"
+    printf "dbg: rnr_thr  = ${rnr_thr}\n"
+    printf "dbg: sgs_frc  = ${sgs_frc}\n"
+    printf "dbg: sgs_msk  = ${sgs_msk}\n"
+    printf "dbg: sgs_nrm  = ${sgs_nrm}\n"
     printf "dbg: spt_pid  = ${spt_pid}\n"
     printf "dbg: thr_nbr  = ${thr_nbr}\n"
+    printf "dbg: ugrid_fl = ${ugrid_fl}\n"
     printf "dbg: unq_sfx  = ${unq_sfx}\n"
     printf "dbg: var_lst  = ${var_lst}\n"
     printf "dbg: var_rgr  = ${var_rgr}\n"
+    printf "dbg: wgt_cmd  = ${wgt_cmd}\n"
+    printf "dbg: wgt_opt  = ${wgt_opt}\n"
     printf "dbg: wgt_usr  = ${wgt_usr}\n"
     printf "dbg: Will regrid ${fl_nbr} files:\n"
     for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
@@ -1000,13 +1119,13 @@ if [ ${vrb_lvl} -ge ${vrb_3} ]; then
     printf "Output files to directory ${drc_out}\n"
 fi # !vrb_lvl
 if [ "${map_mk}" != 'Yes' ] && [ "${map_usr_flg}" = 'Yes' ] && [ -n "${wgt_usr}" ]; then
-    printf "${spt_nm}: ERROR Specifying both '-m map_fl' and '-w wgt_gnr' is only allowed when creating a map (weight generator is superfluous when map is supplied)\n"
+    printf "${spt_nm}: ERROR Specifying both '-m map_fl' and '-w wgt_cmd' is only allowed when creating a map (weight generator is superfluous when user supplies map)\n"
     exit 1
 fi # wgt_usr
     
 if [ "${dst_usr_flg}" = 'Yes' ]; then 
     if [ "${grd_dst_usr_flg}" = 'Yes' ]; then 
-	printf "${spt_nm}: ERROR Specify either '-d dst_fl' or '-g grd_dst' not both\n"
+	printf "${spt_nm}: ERROR Specify either '-d dst_fl' or '-g grd_dst', not both\n"
 	exit 1
     fi # !grd_dst_usr_flg
 fi # !dst_usr_flg
@@ -1018,21 +1137,56 @@ fi # !dst_usr_flg
 # Generate destination grid, if necessary, once (only) before loop over input files
 # Block 1: Destination grid
 # Generate destination grid at most one-time (unlike source grid)
-# Eventually we will allow destination grid to be provided as grid-file, map-file, or data-file
+# Eventually we will allow destination grid to be provided as grid-file, map-file, or data-file without a switch
 # Currently we require user to know (and specify) means by which destination grid is provided
 if [ ${vrb_lvl} -ge ${vrb_3} ]; then
     if [ ${fl_nbr} -eq 0 ]; then
 	printf "Map-only run: no input data detected therefore will exit after generating map\n"
     fi # !fl_nbr
-    if [ -n "${pdq_opt}" ]; then 
-	printf "Input data shaped in \"${pdq_typ}\"-order, will permute with \"ncpdq ${pdq_opt}\"\n"
+    if [ -n "${pdq_opt}" ] && [ -n "${pdq_typ}" ]; then 
+	printf "Input data shaped in \"${prc_typ}\"-order, will permute with \"ncpdq ${pdq_opt}\"\n"
+    fi # !pdq_opt
+    if [ -n "${pdq_opt}" ]; then
+	if [ -n "${pdq_typ}" ]; then 
+	    printf "Input data shaped in \"${prc_typ}\"-order, will first permute with \"ncpdq ${pdq_opt}\"\n"
+	else
+	    printf "Input assumed to contain packed data, will first unpack with \"ncpdq ${pdq_opt}\"\n"
+	fi # !pdq_typ
     fi # !pdq_opt
-    if [ "${pdq_typ}" = 'mpas' ]; then
-	printf "Input assumed to be MPAS-O/I data: will apply renormalized regridding (--rnr=0.0)\n"
+    if [ "${prc_typ}" = 'mpas' ]; then
+	printf "Input assumed to be MPAS-O/I data: will renormalize (with --rnr=0.0) regridding\n"
 	if [ "${clm_flg}" = 'No' ]; then
  	    printf "Input assumed to be barenaked of attributes: will annotate NC_DOUBLE variables with _FillValue prior to regridding\n"
 	fi # !clm_flg
     fi # !mpas
+    if [ "${prc_typ}" = 'sgs' ]; then 
+	printf "Input assumed to contain sub-gridscale (SGS, aka \"fractional area\") data: Intensive values valid for gridcell fraction specified by \"${sgs_frc}\" variable, not for entire gridcell_area (except where ${sgs_frc} = 1.0). Will first conservatively regrid ${sgs_frc}, and then normalize subsequent regridding to conserve ${sgs_frc}*gridcell_area*field_value (not gridcell_area*field_value).\n"
+	if [ ${fl_nbr} -eq 0 ] || [ "${map_usr_flg}" = 'Yes' ]; then
+	    printf "${spt_nm}: ERROR Sub-gridscale handling currently requires at least one data file (for the surface fractions of each gridcell)\n"
+	    echo "${spt_nm}: HINT Supply a data file with \"-i fl_in\""
+	    exit 1
+	fi # !fl_nbr
+	if [ "${wgt_typ}" = 'tempest' ]; then
+	    printf "${spt_nm}: ERROR Sub-gridscale handling currently does not support TempestRemap.\n"
+	    echo "${spt_nm}: HINT Use ESMF weight-generator (and ask Charlie to implement SGS for Tempest)"
+	    exit 1
+	fi # !wgt_typ
+	if [ "${grd_src_usr_flg}" != 'Yes' ]; then
+	    printf "${spt_nm}: ERROR Sub-gridscale handling currently requires the user to specify the SCRIP source grid-file. Moreover, the source grid-file must include the (normally non-essential) grid_area field. It is infeasible to permit SGS source-grid inferral, because weight-generators assume great circle arcs but 2D-grids usually have small-circles in latitude, and this can lead to significant area mis-matches. Despite this, sub-gridscale handling is happy to infer destination (not so [...]
+	    echo "${spt_nm}: HINT Supply source grid-file with \"-s grd_src\". If the source grid-file is unavailable, first multiply sub-grid fields by ${sgs_frc} (with, e.g., ncap2 -s \"foo*=${sgs_frc};\" in.nc out.nc) and then regrid as normal without invoking sub-gridscale handling, i.e., omit the '-P sgs' option."
+	    exit 1
+	    # 20170511: Inferring source grids leads to ~2% biases with conservative regridding and 2D source grids
+	    # printf "${spt_nm}: Sub-gridscale handling will attempt to infer the source SCRIP grid-file from the input data file. This will only work for rectangular 2D data files, because SGS requires the source grid-file to contain the (normally non-essential) grid_area field for the input grid.\n"
+	fi # !grd_src_usr_flg
+	if [ "${grd_dst_usr_flg}" != 'Yes' ]; then
+	    printf "${spt_nm}: Sub-gridscale handling will attempt to infer the destination SCRIP grid-file from the provided output data file template (which will not be touched).\n"
+	fi # !grd_dst_usr_flg
+	if [ "${map_usr_flg}" = 'Yes' ]; then
+	    printf "${spt_nm}: ERROR Sub-grid handling forbids specification of a precomputed map-file. Sub-grid handling must generate map-files from specially pre-processed SCRIP grid-files. Allowing pre-computed map-files risks users inadvertently supplying incorrect map-files. The supplied or inferred SCRIP grid-files must include the (normally non-essential) grid_area field, which ${spt_nm} can normally infer from rectangular 2-D datafiles, though not from 1-D (unstructured) datafiles.\n"
+	    echo "${spt_nm}: HINT Remove map-file specification by eliminating the \"-m map_fl\" option"
+	    exit 1
+	fi # !fl_nbr
+    fi # !sgs
 fi # !vrb_lvl
 if [ "${map_mk}" != 'Yes' ] && [ "${map_usr_flg}" = 'Yes' ]; then 
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
@@ -1046,7 +1200,7 @@ else # !map_usr_flg
 	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
 	    printf "Destination grid will be inferred from data-file\n"
 	fi # !vrb_lvl
-	cmd_dst[${fl_idx}]="ncks ${nco_opt} --rgr nfr=y ${nco_var_rgr} --rgr grid=${grd_dst} ${dst_fl} ${tmp_out_fl}"
+	cmd_dst[${fl_idx}]="ncks ${nco_opt} --rgr infer --rgr hnt_dst=${hnt_dst_fl} ${nco_dgn_area} ${nco_msk_dst} ${nco_var_rgr} --rgr scrip=${grd_dst} ${dst_fl} ${tmp_out_fl}"
     else # !dst_usr_flg
 	if [ "${grd_dst_usr_flg}" = 'Yes' ]; then 
 	    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
@@ -1072,7 +1226,7 @@ else # !map_usr_flg
 	if [ ${dbg_lvl} -ne 2 ]; then
 	    eval ${cmd_dst[${fl_idx}]}
 	    if [ $? -ne 0 ]; then
-		printf "${spt_nm}: ERROR Failed to generate destination grid. Debug this:\n${cmd_dst[${fl_idx}]}\n"
+		printf "${spt_nm}: ERROR Failed to infer destination grid. Debug this:\n${cmd_dst[${fl_idx}]}\n"
 		exit 1
 	    fi # !err
 	    if [ "${grd_sng_usr_flg}" = 'Yes' ]; then 
@@ -1081,22 +1235,13 @@ else # !map_usr_flg
 	fi # !dbg
     fi # !dst_usr_flg || grd_dst_usr_flg
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
-	printf "Weight-generation type: ${wgt_gnr}\n"
+	printf "Weight-generation type: ${wgt_typ}\n"
     fi # !vrb_lvl
-    if [ "${wgt_gnr}" = 'esmf' ]; then 
-	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
-	    printf "ESMF's ESMF_RegridWeightGen will generate mapping weights and map-file\n"
-	    printf "Algorithm used to generate weights in map-file is: ${alg_opt}\n"
-	fi # !vrb_lvl
-	wgt_cmd='ESMF_RegridWeightGen'
-    fi # !esmf
-    if [ "${wgt_gnr}" = 'tempest' ]; then 
-	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
-	    printf "TempestRemap's GenerateOverlapMesh and GenerateOfflineMap will generate mapping weights and map-file\n"
-	fi # !vrb_lvl
-	wgt_cmd='GenerateOfflineMap'
-    fi # !tempest
-    command -v ${wgt_cmd} 2>&1 > /dev/null || { printf "${spt_nm}: ERROR cannot find weight-generation command ${wgt_cmd}. Please install the executable, or change your PATH to find it.\n${spt_nm}: HINT ESMF_RegridWeightGen is often provided in NCL packages. Tempest executables must be installed from source (https://github.com/ClimateGlobalChange/tempestremap)."; exit 1; }
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "Algorithm used to generate weights in map-file is: ${alg_opt}\n"
+	printf "Will generate mapping weights and map-file with \'${wgt_cmd}\'\n"
+    fi # !vrb_lvl
+    command -v ${wgt_exe} 2>&1 > /dev/null || { printf "${spt_nm}: ERROR cannot find weight-generation command executable ${wgt_exe}. Please install the executable, or change your PATH to find it.\n${spt_nm}: HINT ESMF_RegridWeightGen is often provided in NCL packages. Tempest executables must be installed from source (https://github.com/ClimateGlobalChange/tempestremap).\n"; exit 1; }
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
 	if [ ${fl_nbr} -ge 2 ]; then 
 	    if [ "${mlt_map_flg}" = 'Yes' ]; then 
@@ -1108,20 +1253,214 @@ else # !map_usr_flg
     fi # !vrb_lvl
 fi # !map_usr
 
-# If user provides source gridfile, assume it applies to every input file
+if [ "${prc_typ}" = 'sgs' ]; then 
+
+    fl_idx=0
+    grd_dst_sgs="${drc_tmp}/ncremap_tmp_grd_dst_sgs.nc${unq_sfx}" # [sng] Fractional destination grid-file
+    grd_src_sgs="${drc_tmp}/ncremap_tmp_grd_src_sgs.nc${unq_sfx}" # [sng] Fractional source grid-file
+    frc_in_sgs="${drc_tmp}/ncremap_tmp_frc_in_sgs.nc${unq_sfx}" # [sng] Sub-grid fraction on input data grid
+    frc_out_sgs="${drc_tmp}/ncremap_tmp_frc_out_sgs.nc${unq_sfx}" # [sng] Sub-grid fraction on output data grid
+
+    if [ "${grd_src_usr_flg}" != 'Yes' ]; then
+	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	    printf "Source grid will be inferred from data-file\n"
+	    if [ ${fl_nbr} -ge 2 ]; then 
+		printf "Sub-grid mode assumes all input data-files on same grid as first file, so only one source grid-file will be inferred, and only one map-file will be generated, and it will be re-used\n"
+	    fi # !fl_nbr
+	fi # !vrb_lvl
+	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	    printf "Infer source grid-file from input data file...\n"
+	fi # !vrb_lvl
+	cmd_src[${fl_idx}]="ncks ${nco_opt} --rgr infer --rgr hnt_src=${hnt_src_fl} ${nco_dgn_area} ${nco_msk_src} ${nco_ugrid_fl} ${nco_var_rgr} --rgr scrip=${grd_src} ${fl_in[${fl_idx}]} ${tmp_out_fl}"
+	
+	# Block 2 Loop 2: Execute and/or echo commands
+	if [ ${dbg_lvl} -ge 1 ]; then
+	    echo ${cmd_src[${fl_idx}]}
+	fi # !dbg
+	if [ ${dbg_lvl} -ne 2 ]; then
+	    eval ${cmd_src[${fl_idx}]}
+	    if [ $? -ne 0 ]; then
+		printf "${spt_nm}: ERROR Failed to infer source grid. Debug this:\n${cmd_src[${fl_idx}]}\n"
+		exit 1
+	    fi # !err
+	fi # !dbg
+    fi # !grd_src
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Duplicate destination grid-file for modification into fractional destination grid-file...\n"
+    fi # !vrb_lvl
+    cmd_cp_dst[${fl_idx}]="/bin/cp -f ${grd_dst} ${grd_dst_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_cp_dst[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_cp_dst[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_dst_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to duplicate destination grid-file to fractional destination grid-file. Debug this:\n${cmd_cp_dst[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Duplicate source grid for modification into fractional source grid-file...\n"
+    fi # !vrb_lvl
+    cmd_cp_src[${fl_idx}]="/bin/cp -f ${grd_src} ${grd_src_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_cp_src[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_cp_src[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_src_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to duplicate source grid to fractional source grid-file. Debug this:\n${cmd_cp_src[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Append sub-grid fraction from data-file to fractional source grid-file\n"
+    fi # !vrb_lvl
+    cmd_lnd_src[${fl_idx}]="ncks -A -C -v ${sgs_frc} ${fl_in[${fl_idx}]} ${grd_src_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_lnd_src[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_lnd_src[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_src_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to append sub-grid fraction from data file to fractional source grid-file. Debug this:\n${cmd_lnd_src[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Derive fraction, mask, and area in fractional source grid-file...\n"
+    fi # !vrb_lvl
+    # 0. Normalize sub-grid fraction (e.g., from percent to fraction) if necessary
+    # 1. Eliminate _FillValue and missing_value attributes before using where() which would evaluate _FillValue as false, and necessitate using a weird where() condition
+    # 2. Set (formerly) missing values to 0 sub-grid fraction
+    # 3. Set 0 sub-grid fraction to 0 imask
+    # 4. Compute active grid area
+    cmd_wheresrc[${fl_idx}]="ncap2 -O -s '${sgs_frc}=${sgs_frc}; if(${sgs_nrm} != 1.0){${sgs_frc}/=${sgs_nrm}; ${sgs_frc}@units=\"1\";} if(${sgs_frc}@missing_value.exists()) ram_delete(${sgs_frc}@missing_value); delete_miss(${sgs_frc}); where(${sgs_frc} > 1.0f) ${sgs_frc}=0.0f; where(${sgs_frc} == 0.0f) grid_imask=0; grid_area*=${sgs_frc}' ${grd_src_sgs} ${grd_src_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_wheresrc[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_wheresrc[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_src_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to derive fraction, mask, and area in fractional source grid-file. Debug this:\n${cmd_wheresrc[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Create sub-grid fraction ${sgs_frc} data file for regridding...\n"
+    fi # !vrb_lvl
+    cmd_lnd_in[${fl_idx}]="ncks -O -v ${sgs_frc} ${grd_src_sgs} ${frc_in_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_lnd_in[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_lnd_in[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${frc_in_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to extract sub-grid fraction from fractional source grid-file. Debug this:\n${cmd_lnd_in[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Regrid sub-grid fraction ${sgs_frc} to destination grid...\n"
+    fi # !vrb_lvl
+    # NB: Do not regrid sub-grid mask as it is extensive and may contain _FillValue (ALM/CLM landmask does)
+    cmd_lnd_rmp[${fl_idx}]="ncremap --vrb=0 -a ${alg_opt} -v ${sgs_frc} -i ${frc_in_sgs} -s ${grd_src} -g ${grd_dst} -o ${frc_out_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_lnd_rmp[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_lnd_rmp[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${frc_out_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to regrid sub-grid fraction. Debug this:\n${cmd_lnd_rmp[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Derive sub-grid mask ${sgs_msk} from regridded sub-grid fraction...\n"
+    fi # !vrb_lvl
+    # Allow for possibility that sgs_frc is 3D (time,lat,lon) as in CICE
+    # And be CAREFUL changing this
+    cmd_msk[${fl_idx}]="ncap2 -O -s 'if(${sgs_frc}.ndims() < 3) sgsarea=${sgs_frc}*area; else sgsarea=${sgs_frc}(0,:,:);${sgs_msk}=0*int(sgsarea);where(sgsarea > 0) ${sgs_msk}=1; elsewhere ${sgs_msk}=0;${sgs_msk}@long_name=\"surface mask (0=invalid and 1=valid)\";if(${sgs_msk}@cell_measures.exists()) ram_delete(${sgs_msk}@cell_measures)' ${frc_out_sgs} ${frc_out_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_msk[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_msk[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${frc_out_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to derive mask from regridded sub-grid fraction. Debug this:\n${cmd_msk[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Append regridded sub-grid fraction to destination fractional grid-file...\n"
+    fi # !vrb_lvl
+    cmd_lnd_dst[${fl_idx}]="ncks -A -C -v ${sgs_frc} ${frc_out_sgs} ${grd_dst_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_lnd_dst[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_lnd_dst[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_dst_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to append regridded sub-grid fraction to destination fractional grid-file. Debug this:\n${cmd_lnd_dst[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	printf "SGS: Derive mask and area in fractional destination grid-file...\n"
+    fi # !vrb_lvl
+    # 1. Set 0 sub-grid fraction to 0 imask
+    # 2. Compute active grid area
+    cmd_wheredst[${fl_idx}]="ncap2 -O -s 'where(${sgs_frc} == 0.0f) grid_imask=0; elsewhere grid_imask=1;grid_area*=${sgs_frc}' ${grd_dst_sgs} ${grd_dst_sgs}"
+    if [ ${dbg_lvl} -ge 1 ]; then
+	echo ${cmd_wheredst[${fl_idx}]}
+    fi # !dbg
+    if [ ${dbg_lvl} -ne 2 ]; then
+	eval ${cmd_wheredst[${fl_idx}]}
+	if [ $? -ne 0 ] || [ ! -f ${grd_dst_sgs} ]; then
+	    printf "${spt_nm}: ERROR Failed to derive mask and area in fractional destination grid-file. Debug this:\n${cmd_wheredst[${fl_idx}]}\n"
+	    exit 1
+	fi # !err
+    fi # !dbg
+
+    # Ensure map-generation uses modified grid files
+    grd_src=${grd_src_sgs}
+    grd_dst=${grd_dst_sgs}
+fi # !sgs
+
+# If user provides source gridfile, or it was inferred in sub_grid mode, assume it applies to every input file
 # Do not infer source gridfiles from input files within file loop
 # Generate map-file once outside of file loop, and re-use it for every input file
-if [ "${grd_src_usr_flg}" = 'Yes' ]; then
+if [ "${grd_src_usr_flg}" = 'Yes' ] || [ "${prc_typ}" = 'sgs' ]; then
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
 	printf "Source grid supplied by user as ${grd_src}\n"
     fi # !vrb_lvl
     fl_idx=0
-    if [ "${wgt_gnr}" = 'esmf' ]; then 
-	cmd_map[${fl_idx}]="ESMF_RegridWeightGen -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${esmf_opt} > /dev/null"
+    if [ "${wgt_typ}" = 'esmf' ]; then 
+	rgn_opt=''
+	if [ -n "${hnt_src}" ]; then
+	    rgn_opt="${rgn_opt} ${hnt_src}"
+	elif [ -f "${hnt_src_fl}" ]; then
+	    rgn_opt="${rgn_opt} `cat ${hnt_src_fl}`"
+	fi # !hnt_src_fl
+	if [ -n "${hnt_dst}" ]; then
+	    rgn_opt="${rgn_opt} ${hnt_dst}"
+	elif [ -f "${hnt_dst_fl}" ]; then
+	    rgn_opt="${rgn_opt} `cat ${hnt_dst_fl}`"
+	fi # !hnt_dst_fl
+	cmd_map[${fl_idx}]="${wgt_cmd} -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${wgt_opt} ${rgn_opt} > /dev/null"
     fi # !esmf
-    if [ "${wgt_gnr}" = 'tempest' ]; then 
+    if [ "${wgt_typ}" = 'tempest' ]; then 
 	cmd_msh[${fl_idx}]="GenerateOverlapMesh --a ${grd_src} --b ${grd_dst} --out ${msh_fl} > /dev/null"
-	cmd_map[${fl_idx}]="GenerateOfflineMap --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${tps_opt} > /dev/null"
+	cmd_map[${fl_idx}]="${wgt_cmd} --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${wgt_opt} > /dev/null"
 	if [ ${dbg_lvl} -ge 1 ]; then
 	    echo ${cmd_msh[${fl_idx}]}
 	fi # !dbg
@@ -1140,14 +1479,14 @@ if [ "${grd_src_usr_flg}" = 'Yes' ]; then
 	eval ${cmd_map[${fl_idx}]}
 	if [ $? -ne 0 ] || [ ! -f ${map_fl} ]; then
 	    printf "${spt_nm}: ERROR Failed to generate map-file. Debug this:\n${cmd_map[${fl_idx}]}\n"
-	    if [ "${wgt_gnr}" = 'esmf' ]; then 
+	    if [ "${wgt_typ}" = 'esmf' ]; then 
 		printf "${spt_nm}: HINT When ESMF fails to generate map-files, it often puts additional debugging information in the file named PET0.RegridWeightGen.Log in the invocation directory (${drc_pwd})\n"
 	    fi # !esmf
 	    exit 1
 	fi # !err
 	if [ "${map_usr_flg}" = 'Yes' ]; then
 	    hst_att="`date`: ${cmd_ln};${cmd_map[${fl_idx}]}"
-	    if [ "${wgt_gnr}" = 'tempest' ]; then 
+	    if [ "${wgt_typ}" = 'tempest' ]; then 
 		hst_att="${hst_att};${cmd_msh[${fl_idx}]}"
 	    fi # !tempest
 	    cmd_att[${fl_idx}]="ncatted -O ${gaa_sng} --gaa history='${hst_att}' ${map_fl}"
@@ -1191,12 +1530,15 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	echo "HINT: To prevent inadvertent data loss, ${spt_nm} insists that Input file and Output filenames differ"
 	exit 1
     fi # !basename
+    fl_out[${fl_idx}]=${out_fl}
 
     # Generate new map unless map-file was supplied or already-generated
+    # NB: Sub-grid infers (if necessary) source grid outside file loop, and forbids multiple source grids
+    # Sub-grid also produces map before file loop, and will not make maps inside file loop
     if [ "${map_mk}" = 'Yes' ]; then
 
 	# Block 1: Special cases
-	if [ "${pdq_typ}" = 'hirdls' ] || [ "${pdq_typ}" = 'mls' ]; then
+	if [ "${prc_typ}" = 'hirdls' ] || [ "${prc_typ}" = 'mls' ]; then
 	    # Pre-process zonal input files so grid inferral works
 	    # 20160214: fix record variable to work around ncpdq problem
 	    cmd_znl[${fl_idx}]="ncecat -u lon ${nco_opt} ${nco_var_lst} ${in_fl} ${in_fl} ${in_fl} ${in_fl} ${znl_fl/znl/znl1};ncap2 ${nco_opt} -s 'lon[\$lon]={0.0,90.0,180.0,270.0}' ${znl_fl/znl/znl1} ${znl_fl/znl/znl2}"
@@ -1218,10 +1560,10 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	if [ ! -f "${in_fl}" ]; then
 	    echo "${spt_nm}: ERROR Unable to find input file ${in_fl}"
 	    echo "HINT: All files implied to exist must be in the directory specified by their filename or in ${drc_in} before ${spt_nm} will proceed"
-	    exit 1
+		exit 1
 	fi # ! -f
 	# Infer source grid-file from input data file
-	cmd_src[${fl_idx}]="ncks ${nco_opt} --rgr nfr=y ${nco_var_rgr} --rgr grid=${grd_src} ${in_fl} ${tmp_out_fl}"
+	cmd_src[${fl_idx}]="ncks ${nco_opt} --rgr infer --rgr hnt_src=${hnt_src_fl} ${nco_msk_src} ${nco_ugrid_fl} ${nco_var_rgr} --rgr scrip=${grd_src} ${in_fl} ${tmp_out_fl}"
 	
 	# Block 2 Loop 2: Execute and/or echo commands
 	if [ ${dbg_lvl} -ge 1 ]; then
@@ -1230,7 +1572,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	if [ ${dbg_lvl} -ne 2 ]; then
 	    eval ${cmd_src[${fl_idx}]}
 	    if [ $? -ne 0 ]; then
-		printf "${spt_nm}: ERROR Failed to generate source grid. Debug this:\n${cmd_src[${fl_idx}]}\n"
+		printf "${spt_nm}: ERROR Failed to infer source grid. Debug this:\n${cmd_src[${fl_idx}]}\n"
 		exit 1
 	    fi # !err
 	fi # !dbg
@@ -1241,13 +1583,24 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	    printf "Grid(src): ${grd_src}\n"
 	    printf "Grid(dst): ${grd_dst}\n"
 	fi # !vrb_lvl
-	if [ "${wgt_gnr}" = 'esmf' ]; then 
-	    cmd_map[${fl_idx}]="ESMF_RegridWeightGen -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${esmf_opt} > /dev/null"
+	if [ "${wgt_typ}" = 'esmf' ]; then 
+	    rgn_opt=''
+	    if [ -n "${hnt_src}" ]; then
+		rgn_opt="${rgn_opt} ${hnt_src}"
+	    elif [ -f "${hnt_src_fl}" ]; then
+		rgn_opt="${rgn_opt} `cat ${hnt_src_fl}`"
+	    fi # !hnt_src_fl
+	    if [ -n "${hnt_dst}" ]; then
+		rgn_opt="${rgn_opt} ${hnt_dst}"
+	    elif [ -f "${hnt_dst_fl}" ]; then
+		rgn_opt="${rgn_opt} `cat ${hnt_dst_fl}`"
+	    fi # !hnt_dst_fl
+	    cmd_map[${fl_idx}]="${wgt_cmd} -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${wgt_opt} ${rgn_opt} > /dev/null"
 	fi # !esmf
-	if [ "${wgt_gnr}" = 'tempest' ]; then 
+	if [ "${wgt_typ}" = 'tempest' ]; then 
 	    printf "Mesh-File: ${msh_fl}\n"
 	    cmd_msh[${fl_idx}]="GenerateOverlapMesh --a ${grd_src} --b ${grd_dst} --out ${msh_fl} > /dev/null"
-	    cmd_map[${fl_idx}]="GenerateOfflineMap --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${tps_opt} > /dev/null"
+	    cmd_map[${fl_idx}]="${wgt_cmd} --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${wgt_opt} > /dev/null"
 	    if [ ${dbg_lvl} -ge 1 ]; then
 		echo ${cmd_msh[${fl_idx}]}
 	    fi # !dbg
@@ -1268,7 +1621,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	    eval ${cmd_map[${fl_idx}]}
 	    if [ $? -ne 0 ] || [ ! -f ${map_fl} ]; then
 		printf "${spt_nm}: ERROR Failed to generate map-file. Debug this:\n${cmd_map[${fl_idx}]}\n"
-		if [ "${wgt_gnr}" = 'esmf' ]; then 
+		if [ "${wgt_typ}" = 'esmf' ]; then 
 		    printf "${spt_nm}: HINT When ESMF fails to generate map-files, it often puts additional debugging information in the file named PET0.RegridWeightGen.Log in the invocation directory (${drc_pwd})\n"
 		fi # !esmf
 		exit 1
@@ -1293,7 +1646,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
     
     # Block 4: Special cases
     # Block 4a: Add missing metadata to MPAS files unless script was invoked by ncclimo (it makes no sense to give naked files to ncclimo and then annotate here, so assume ncclimo is working with annotated files)
-    if [ "${pdq_typ}" = 'mpas' ] && [ "${clm_flg}" = 'No' ]; then
+    if [ "${prc_typ}" = 'mpas' ] && [ "${clm_flg}" = 'No' ]; then
 	cmd_att[${fl_idx}]="ncatted -O -t -a _FillValue,,o,d,-9.99999979021476795361e+33 ${in_fl} ${att_fl};"
 	if [ ${vrb_lvl} -ge ${vrb_2} ]; then
 	    printf "att(in)  : ${in_fl}\n"
@@ -1312,7 +1665,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	fi # !dbg
     fi # !mpas
 	
-    # Block 4b: Generic Permutation (AIRS, HIRDLS, MLS, MPAS)
+    # Block 4b: Generic Permutation/Unpacking (AIRS, HIRDLS, MLS, MOD04, MPAS)
     if [ -n "${pdq_opt}" ]; then
 	if [ ${vrb_lvl} -ge ${vrb_2} ]; then
 	    printf "PDQ(in)  : ${in_fl}\n"
@@ -1337,7 +1690,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
 	printf "Map/Wgt  : ${map_fl}\n"
 	printf "Regridded: ${out_fl}\n"
     fi # !vrb_lvl
-    cmd_rgr[${fl_idx}]="${cmd_mpi[${fl_idx}]} ncks -t ${thr_nbr} ${nco_opt} ${nco_var_rgr} ${nco_var_lst} ${rgr_opt} --map=${map_fl} ${in_fl} ${out_fl}"
+    cmd_rgr[${fl_idx}]="${cmd_mpi[${fl_idx}]} ncks -t ${thr_nbr} ${nco_opt} ${nco_var_rgr} ${nco_var_lst} ${nco_msk_out} ${rgr_opt} --map=${map_fl} ${in_fl} ${out_fl}"
     
     # Block 5 Loop 2: Execute and/or echo commands
     if [ ${dbg_lvl} -ge 1 ]; then
@@ -1380,7 +1733,7 @@ for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
     fi # !par_typ
     
     # Block 7: Special case post-processing
-    if [ "${pdq_typ}" = 'hirdls' ] || [ "${pdq_typ}" = 'mls' ]; then
+    if [ "${prc_typ}" = 'hirdls' ] || [ "${prc_typ}" = 'mls' ]; then
 	# NB: Move file to avert problem with --no_tmp_fl causing self-overwrite
 	cmd_znl[${fl_idx}]="/bin/mv ${out_fl} ${ncwa_fl};ncwa -a lon ${nco_opt} ${nco_var_lst} ${ncwa_fl} ${out_fl}"
 	# Block 7 Loop 2: Execute and/or echo commands
@@ -1414,11 +1767,66 @@ if [ -n "${par_opt}" ]; then
     fi # !bch_flg
 fi # !par_typ
 
+# fxm: Parallelize post-processing, if any
+if [ "${prc_typ}" = 'sgs' ]; then 
+    for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
+	if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+	    printf "SGS: Append full gridcell area, regridded sub-grid fraction, and re-derived sub-grid mask to regridded file...\n"
+	fi # !vrb_lvl
+	# These replace user-areas area, user-areas sub-grid fraction, and naïvely regridded (rather than accurately re-derived) sub-grid mask, respectively
+	cmd_grd_rpl[${fl_idx}]="ncks -A -C -v area,${sgs_frc},${sgs_msk} ${frc_out_sgs} ${fl_out[${fl_idx}]}"
+	if [ ${dbg_lvl} -ge 1 ]; then
+	    echo ${cmd_grd_rpl[${fl_idx}]}
+	fi # !dbg
+	if [ ${dbg_lvl} -ne 2 ]; then
+	    eval ${cmd_grd_rpl[${fl_idx}]}
+	    if [ $? -ne 0 ] || [ ! -f ${fl_out[${fl_idx}]} ]; then
+		printf "${spt_nm}: ERROR Failed to replace area, ${sgs_frc}, and ${sgs_msk} with full gridcell area, regridded sub-grid fraction, and re-derived sub-grid mask in output data file. Debug this:\n${cmd_grd_rpl[${fl_idx}]}\n"
+		exit 1
+	    fi # !err
+	fi # !dbg
+	if [ -n "${prc_alm}" ]; then
+	    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+		printf "SGS: Implement idiosyncratic ALM characteristics in regridded file...\n"
+	    fi # !vrb_lvl
+	    # Convert area from [sr] to [km2]
+	    cmd_alm[${fl_idx}]="ncap2 -O -s 'area*=${rds_rth}^2/1.0e6;area at long_name=\"Gridcell area\";area at units=\"km^2\"' ${fl_out[${fl_idx}]} ${fl_out[${fl_idx}]}"
+	    if [ ${dbg_lvl} -ge 1 ]; then
+		echo ${cmd_alm[${fl_idx}]}
+	    fi # !dbg
+	    if [ ${dbg_lvl} -ne 2 ]; then
+		eval ${cmd_alm[${fl_idx}]}
+		if [ $? -ne 0 ] || [ ! -f ${fl_out[${fl_idx}]} ]; then
+		    printf "${spt_nm}: ERROR Failed to replace convert output area from [sr] to [km2]. Debug this:\n${cmd_alm[${fl_idx}]}\n"
+		    exit 1
+		fi # !err
+	    fi # !dbg
+	fi # !prc_alm
+	if [ -n "${prc_cice}" ]; then
+	    if [ ${vrb_lvl} -ge ${vrb_3} ]; then
+		printf "SGS: Implement idiosyncratic CICE characteristics in regridded file...\n"
+	    fi # !vrb_lvl
+	    # Convert area from [sr] to [m2], and aice from [frc] to [%]
+	    cmd_cice[${fl_idx}]="ncap2 -O -s 'area*=${rds_rth}^2;area at long_name=\"Gridcell area\";area at units=\"m^2\";${sgs_frc}*=100;${sgs_frc}@units=\"%\"' ${fl_out[${fl_idx}]} ${fl_out[${fl_idx}]}"
+	    if [ ${dbg_lvl} -ge 1 ]; then
+		echo ${cmd_cice[${fl_idx}]}
+	    fi # !dbg
+	    if [ ${dbg_lvl} -ne 2 ]; then
+		eval ${cmd_cice[${fl_idx}]}
+		if [ $? -ne 0 ] || [ ! -f ${fl_out[${fl_idx}]} ]; then
+		    printf "${spt_nm}: ERROR Failed to replace convert output area from [sr] to [m2] and ${sgs_frc} from [frc] to [%]. Debug this:\n${cmd_cice[${fl_idx}]}\n"
+		    exit 1
+		fi # !err
+	    fi # !dbg
+	fi # !prc_cice
+    done # !fl_idx
+fi # !sgs
+
 if [ "${cln_flg}" = 'Yes' ]; then
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
-	printf "Cleaning-up intermediate files...\n"
+	printf "Clean-up intermediate files...\n"
     fi # !vrb_lvl
-    /bin/rm -f ${att_fl} ${grd_dst_dfl} ${grd_src_dfl} ${map_fl_dfl} ${msh_fl_dfl} ${ncwa_fl} ${pdq_fl} ${tmp_out_fl} ${znl_fl/znl/znl1} ${znl_fl/znl/znl2}
+    /bin/rm -f ${att_fl} ${frc_in_sgs} ${frc_out_sgs} ${grd_dst_sgs} ${grd_dst_dfl} ${grd_src_sgs} ${grd_src_dfl} ${hnt_dst_fl} ${hnt_src_fl} ${map_fl_dfl} ${msh_fl_dfl} ${ncwa_fl} ${pdq_fl} ${tmp_out_fl} ${znl_fl/znl/znl1} ${znl_fl/znl/znl2}
 else # !cln_flg
     if [ ${vrb_lvl} -ge ${vrb_3} ]; then
 	printf "Explicitly instructed not to clean-up intermediate files.\n"
diff --git a/data/nsm.cdl b/data/nsm.cdl
new file mode 100644
index 0000000..9fcb0ad
--- /dev/null
+++ b/data/nsm.cdl
@@ -0,0 +1,55 @@
+// -*-C++-*-
+// Generate netCDF file with:
+// ncgen -k netCDF-4 -b -o ~/nco/data/nsm.nc ~/nco/data/nsm.cdl
+
+netcdf nsm {
+  :Conventions = "CF-1.5";
+  :history = "Tue Apr 25 12:46:10 PDT 2017: ncgen -k netCDF-4 -b -o ~/nco/data/clc.nc ~/nco/data/clc.cdl";
+  :Purpose = "Demonstrate a model ensemble stored in hierarchical format";
+
+  group: cesm_01 {
+      :Scenario = "Historical";
+      :Model = "CESM";
+      :Realization = "1";
+
+    dimensions:
+      time=unlimited;
+    variables:
+      float temperature(time);
+      double time(time);
+    data:
+      temperature=272.1,272.1,272.1,272.1;
+      time=1.,2.,3.,4.;
+    } // cesm_01
+
+  group: cesm_02 {
+      :Scenario = "Historical";
+      :Model = "CESM";
+      :Realization = "2";
+
+    dimensions:
+      time=unlimited;
+    variables:
+      float temperature(time);
+      double time(time);
+    data:
+      temperature=272.2,272.2,272.2,272.2;
+      time=1.,2.,3.,4.;
+    } // cesm_02
+    
+  group: cesm_03 {
+      :Scenario = "Historical";
+      :Model = "CESM";
+      :Realization = "3";
+
+    dimensions:
+      time=unlimited;
+    variables:
+      float temperature(time);
+      double time(time);
+    data:
+      temperature=272.3,272.3,272.3,272.3;
+      time=1.,2.,3.,4.;
+    } // cesm_03
+    
+} // root group
diff --git a/data/trj.cdl b/data/trj.cdl
new file mode 100644
index 0000000..1db3652
--- /dev/null
+++ b/data/trj.cdl
@@ -0,0 +1,29 @@
+// -*-C++-*-
+// Generate netCDF file with:
+// ncgen -k netCDF-4 -b -o ~/nco/data/trj.nc ~/nco/data/trj.cdl
+
+netcdf trj {
+  :Conventions = "CF-1.6";
+  :history = "Tue Apr 25 12:46:10 PDT 2017: ncgen -k netCDF-4 -b -o ~/nco/data/trj.nc ~/nco/data/trj.cdl";
+  :Purpose = "Demonstrate trajectory profiles stored in hierarchical format";
+  :CF_documentation = "http://cfconventions.org/cf-conventions/cf-conventions.html#trajectory-profiles";
+
+  group: argo_01 {
+      :Platform_ID = "Buoy 01";
+      :featureType = "trajectoryProfile";
+
+    dimensions:
+    profile=unlimited;
+    z=3;
+    variables:
+      double lat(profile);
+      double lon(profile);
+      double alt(profile,z);
+      double time(profile);
+      float temperature(profile,z);
+    data:
+      temperature=;
+      time=1.;
+    } // argo_01
+    
+} // root group
diff --git a/debian/changelog b/debian/changelog
index ab2d7e2..d32ffa0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+nco (4.6.7-1) unstable; urgency=low
+
+  * new upstream version ncap2 in-fill, MTA flags, ERWG rgn hints, SGS, ncremap re-org, ncatted nc4 fll_val
+
+ -- Charlie Zender <zender at uci.edu>  Fri, 26 May 2017 12:25:23 -0700
+
 nco (4.6.6-1) unstable; urgency=low
 
   * new upstream version no_cll_msr,no_frm_trm,no_stg_grd,hsi,lst_rnk_ge2,UGRID 2D,JSON shape,OMI
diff --git a/doc/ANNOUNCE b/doc/ANNOUNCE
index 1e30471..3687463 100644
--- a/doc/ANNOUNCE
+++ b/doc/ANNOUNCE
@@ -1,154 +1,153 @@
 $Header$ -*-text-*-
 
-The netCDF Operators NCO version 4.6.6 are ready. 
+The netCDF Operators NCO version 4.6.7 are ready. 
 
 http://nco.sf.net (Homepage, Mailing lists)
 http://github.com/nco (Source Code, Releases, Developers)
 
 What's new?
-4.6.6 contains a potpurri of new features:
-Output 2D rectangular grids formatted as UGRID meshes.
-Calendar dates print for bounds and climatology variables.
-Revamped HPSS/hsi support. The splitter produces cleaner output. 
-The regridder groks more files and masks, and annotates output with
-more helpful metadata. CDL mode handles compound record variables.
-JSON output has changed slightly to re-use NcML keywords. 
-ncclimo and ncremap have new extract/exclude options.
-
-EVERYONE WHO USES NCKS TO PRINT DATA PLEASE READ THIS:
-
-We would like to change the default behavior of ncks printing.
+The main new features in 4.6.7 are in the regridder, which
+introduces a sub-grid regridding option, more automated handling
+and flexibility with regional grids, and easier flag specification.
+ncap2 added specialty functions to simplify handling of missing
+values and in-filling large missing regions with interpolated data.
+ncatted received an important bugfix for netCDF4 with _FillValue. 
+
+PLEASE READ THIS IF YOU USE NCKS TO PRINT DATA:
+The ncks default printing will change to CDL in summer 2017.
 For 20+ years ncks has, by default, dumped the text representation
-of a file in (what we call) "traditional" mode. ncdump produces a
-format called CDL that is more useful than traditional mode for most
-NCO users. ncks has produced CDL since only 2013 and so CDL is not the
-default. ncdump has always printed CDL very cleanly and clearly there
-was little point in making CDL the default for ncks. 
-Now ncks CDL mode rivals ncdump, and is superior in some ways.
-In particular, ncks now prints times as human-readable calendar dates,
-the last ncdump feature I used that ncks did not have.
-We may change the default printed output of ncks to CDL.
-Then one would type simply "ncks" instead of "ncks --cdl". 
-A new "--trd" option would still print traditional output.
-Let us know if this bothers or pleases you prior to 4.6.7.
+of a file in (what we call) "traditional" mode, which best facilitates
+meticulous data examination in line-by-line format.
+ncdump produces CDL format that is more useful for most NCO users.
+ncdump has always printed clean CDL and for many years there was
+little point in defaulting ncks printed output to CDL.
+However, ncks CDL mode now rivals ncdump in many ways.
+In particular, ncks --cln now prints times as human-readable calendar
+dates, the last ncdump feature that I used which ncks lacked. 
+Hence in summer 2017 ncks default printed output will change to CDL. 
+Then one will type simply "ncks" instead of "ncks --cdl". 
+We just added a new "--trd" option to print traditional output.
+User --trd in your scripts and their behavior will not change.
+Otherwise your printing scripts will start to print CDL this summer.
 You have been warned :)
 
-Work on NCO 4.6.7 has commenced. Planned improvements include 
+Work on NCO 4.6.8 has commenced. Planned improvements include 
 support for conda installs on MS Windows, more ncclimo and ncremap
-features. 
+features, more ncap2 chunking flexibility. 
 
 Enjoy,
 Charlie
 
 NEW FEATURES (full details always in ChangeLog):
 
-A. ncremap and ncclimo support new extract/exclude switches:
-   --no_cll_msr: Exclude cell_measures variables
-   --no_frm_trm: Exclude formula_terms variables
-   --no_ntv_tms: Exclude native-grid timeseries (splitter only)
-   --no_stg_grd: Exclude staggered grid coordinates
-   By default, these variables are always extracted.
-   Use the above switches to exclude them instead, e.g.,
-   ncclimo --no_cll_msr --no_frm_trm --no_ntv_tms --no_stg_grd ...
-   http://nco.sf.net/nco.html#no_cll_msr
-   http://nco.sf.net/nco.html#no_frm_trm
-   http://nco.sf.net/nco.html#no_ntv_tms
-   http://nco.sf.net/nco.html#no_stg_grd
-
-B. ncclimo's splitter mode no longer requires variable lists. 
-   Previously the splitter required a '-v var_lst' option to know
-   which variables to split into timeseries. Now when the -v option
-   is omitted the splitter creates timeseries of all variables of
-   rank R >= 2. Typically this includes all spatial variables. 
-   Variables known to be extensive (like grid properties) are
-   automatically excluded from this list. However, we expect there
-   will be some cases where the splitter creates timeseries from
-   R >= 2 variables that are not desirable. We are happy to encode
-   manual exceptions as we receive notice of them.
-   ncclimo -s 1979 -e 1981 -o $drc_out in*.nc
-   http://nco.sf.net/nco.html#ncclimo
-
-C. The regridder now produces UGRID output for 2D rectangular grids.
-   Invoke ncremap in grid inferral mode with "--rgr ugrid=foo.nc"
-   and voilà, an annoted UGRID file is produce along with the
-   default SCRIP gridfile. The NCO UGRID is more complete than that 
-   produced by ESMF_Scrip2Unstruct, but ESMF can create UGRID for much 
-   more comlex grids. The NCO regridder can currently only generate
-   UGRID for rectangular 2D input grids, and there are no plans to
-   extend this to curvilinear or unstructured input grids.
-   ncks --rgr nfr=Y --rgr grid=scrip.nc --rgr ugrid=ugrid.nc in.nc out.nc
-   http://nco.sf.net/nco.html#rgr
-
-D. ncks now prints the units, if any, in comments after CDL values
-   when debugging is enabled with dbg_lvl >=1:
-   zender at foo: ncks --cdl -D 1 in.nc
-   lat = -90, 90 ; // units="degrees_north"
-   lon = 0, 90, 180, 270 ; // units="degrees_east"
-   tpt = 273.1, 273.2, ... 274 ; // units="kelvin"
-   http://nco.sf.net/nco.html#cdl
-
-E. ncap2 now implements the CF cell_methods convention.
-   ncra, nces, and ncwa have long implemented this, and now the
-   relevant ncap2 methods (avg, min, max, etc.) record the operation
-   type in the cell_methods attribute.
+A. ncremap has a new sub-gridscale (SGS) mode, -P sgs.
+   In sub-grid mode, ncremap performs substantial pre- and
+   post-processing so that regridding conserves fields that may
+   represent only a fraction of the entire gridcell.
+   The sub-gridscale fraction represented by each field is contained
+   in variable whose can be set with the new --sgs_frc option
+   (default is "landfrac"). SGS mode eases regridding of datasets
+   (e.g., from ALM, CLM, CICE) that output data normalized to a
+   fraction (rather than the entire extent) of the gridcell.
+   SGS mode automatically derives new binary masks (--sgs_msk)
+   and allows for additional normalization (--sgs_nrm).
+   Specific flavors of SGS can be selected (-P alm, clm, or cice).
+   These ensure regridded datasets recreate the idiosyncratic units
+   (e.g., %, km2) employed by raw ALM, CLM, and CICE model output.
+   Discerning these regridded from raw datasets is difficult :)
+   ncremap -P sgs -s src_grd.nc -i in.nc -d 1x1.nc -o rgr.nc
+   ncremap -P alm -s src_grd.nc -i in.nc -d 1x1.nc -o rgr.nc
+   ncremap -P cice -s src_grd.nc -i in.nc -d 1x1.nc -o rgr.nc
+   ncremap -P sgs --sgs_frc=aice --sgs_msk=tmask --src_nrm=100 ... 
+   http://nco.sf.net/nco.html#sgs
+   Thanks to Forrest Hoffmann and Min Xu for prototyping the
+   algorithm and verifying the results.
+
+B. ncremap now automatically indicates to the ERWG weight generator
+   when either or both source and destination grids are regional.
+   This information can considerably reduce the time and space
+   the weight generator requires to generate and store the map-file.
+   ncremap uses fuzzy logic to determine this for inferred grids.
+   The user may inform ncremap whether supplied grids (i.e.,
+   specified with -s or -g) are regional with the new --rgn_dst
+   and --rgn_src flags:
+   ncremap -i in.nc -d dst.nc -m map.nc # Inferred (no option necessary)
+   ncremap -s grd_src.nc -g grd_dst.nc -m map.nc --rgn_src # Supplied
+   Users may notice significantly faster throughput due to this.
+   http://nco.sf.net/nco.html#rgn_src
+
+C. ncremap switches have been "rationalized" to eliminate poor UI
+   decisions made in early development. Please read the old/new 
+   option meanings and change your scripts accordingly. Now -a
+   subsumes the old role of -w. HINT: use long-options (e.g.,
+   --algorithm=conserve) to future-proof your scripts. 
+   Meaning of -a:
+   Old: Interpolation algorithm for ESMF only
+   New: Interpolation algorithm for ESMF and Tempest ('tempest')
+   Meaning of -E:
+   Old: Options for ESMF_RegridWeightGen (now use -W)
+   New: Unused
+   Meaning of -T:
+   Old: Options for TempestRemap (now use -W)
+   New: temporary directory (replaces old -U)
+   Meaning of -U:
+   Old: temporary directory
+   New: unpack flag (tells ncremap to unpack data before regridding)
+   Meaning of -w:
+   Old: Weight-generator keyword. Valid options were 'esmf' and 'tempest'. 
+   New: Weight-generator command string (e.g., "mpirun ESMF_RegridWeightGen -n 24") 
+     Supercedes default 'ESMF_RegridWeightGen' or 'GenerateOfflineMap'
+   Meaning of -W:
+   Old: Unused
+   New: Options for weight-generator (replaces old -E and -T)
+   http://nco.sf.net/nco.html#ncremap
+
+D. ncap2 has a new function named missing(), aka mask_miss() that
+   returns an array of the same size of its argument, with values
+   of zero where valid data are present and one where missing data
+   are present. The resulting array can be useful in characterizing
+   and masking the original array.
+   ncap2 -s 'mss_val=three_dmn_var_dbl.missing().ttl($time)' in.nc out.nc
+   Thanks to Adrian Tompkins for suggesting this feature.
+   http://nco.sf.net/nco.html#mask_miss
+
+E. ncap2 now propagates existing chunking parameters from the input
+   file to the output file, and similarly chunks created variables.
+   The rest of NCO has long implemented comprehensive chunking
+   features and now ncap2 supports the basic methods.
    ncap2 -s 'avg=one_dmn_rec_var.avg()' ~/nco/data/in.nc ~/foo.nc
    http://nco.sf.net/nco.html#cll_mth
 
-F. Since 4.6.5 ncks has printed the human-legible calendar string
-   corresponding to values with UDUnits date units (time since
-   basetime, e.g., "days since 2000-01-01") and CF calendar attribute,
-   if any. Now ncks also translates and prints time values associated
-   with CF climatology and bounds variables as human legible dates.
-   As before, enact this with the --calendar option when printing.
-   Using dbg_lvl >= 1 in CDL mode prints both the value and calendar
-   string (one in comments): 
-   zender at aerosol:~$ ncks -D 1 --cdl --cal -v tm_365 ~/nco/data/in.nc
-   tm_365 = "2013-03-01"; // double value: 59
-   zender at aerosol:~$ ncks -D 1 --cdl -v tm_365 ~/nco/data/in.nc
-   tm_365 = 59; // calendar format: "2013-03-01"
-   This option is similar to the ncdump -t option.
-   Does this work how you'd like? Let us know.
-   http://nco.sf.net/nco.html#cal
-
-G. ncks now prints "(no units)" instead of "(null)" as the units
-   string for variables with no units. And in CDL mode ncks, when
-   invoked with debugging (e.g., -D 1) prints the units string in the
-   comment section after the values of a variable.
+F. ncks now has a --trd (or --traditional) option to print output
+   in the "tradiational" format. Start to use this unless you prefer
+   CDL output which will become the default in summer 2017, possibly
+   in NCO 4.7.0. At that time, the --cdl option will become default.
 
 BUG FIXES:
 
-A. NCO now exits with a clear message instead of core dump on missing
-   files on HPSS systems with the hsi command.
+A. ncatted allows writing an empty NC_CHAR or NC_STRING attribute.
+   Previously ncatted would core dump. ncks also prints such values.
+   No workaround. Solution is to upgrade.
 
-B. ncremap will no longer define mask variables in inferred grid
-   files unless it finds a mask variable in the source file.
-   Previously ncremap could define a mask variable in the inferred
-   grid file and never fill-it with data.
+B. ncap2 could die when performing computations with pre-chunked
+   and/or deflated data. Workaround is to convert to netCDF3
+   before computations. Solution is to upgrade.
+   Thanks to Dave Blodgett for reporting this issue.
 
-C. ncremap now invokes the neareststod algorithm when requested.
-   Previously a typo caused ncremap to invoke nearestdtos when
-   neareststod was specified (doh!). Solution is to upgrade.
-
-D. ncremap now converts non-default masks correctly in infer mode.
-   Previously a "mask" variable in an input file whose grid structure
-   was being inferred could be incorrectly handled for some numeric
-   types. This likely only affected masks with missing values.
-   Sources of files possibly affected include AMSR and CICE.
-
-E. ncks now prints braces required to disambiguate compound
-   record dimensions in CDL mode. Such braces have been required by 
-   ncgen-like parsers since ~2013 in order to unambiguously determine
-   the record dimension sizes in variables with multiple record
-   dimensions. This fix only affects CDL printing of netCDF4 files
-   that contain compound record variables. 
+C. ncatted now correctly handles creation, modification, overwriting
+   of _FillValue attributes in netCDF4 data. Since about 4.6.2
+   fiddling with netCDF4 _FillValue attributes with existing data
+   could lead to data loss. The workaround is to convert to netCDF3,
+   fiddle, then convert back to netCDF4. The solution is to upgrade.
+   Thanks to Kyle Wilcox for reporting this issue.
 
 KNOWN PROBLEMS DUE TO NCO:
 
    This section of ANNOUNCE reports and reminds users of the
    existence and severity of known, not yet fixed, problems. 
-   These problems occur with NCO 4.6.6 built/tested under
-   MacOS 10.12.3 with netCDF 4.4.1 on HDF5 1.8.16 and with
-   Linux with netCDF 4.4.2-development (20161116) on HDF5 1.8.16.
+   These problems occur with NCO 4.6.7 built/tested under
+   MacOS 10.12.5 with netCDF 4.4.1 on HDF5 1.10.0-patch1 and with
+   Linux with netCDF 4.4.2-development (20170322) on HDF5 1.8.17.
 
 A. NOT YET FIXED (NCO problem)
    Correctly read arrays of NC_STRING with embedded delimiters in ncatted arguments
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 41d3b71..52299b7 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,5 +1,232 @@
+2017-05-26  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.6.8-alpha01 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.8-alpha01 final changes';git push
+	git tag -a 4.6.8-alpha01 -m 'Same as 4.6.7 except for minor fixes';git push --tags
+
+	* NCO 4.6.7 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7 final changes';git push
+	git tag -a 4.6.7 -m 'ncap2 in-fill, MTA flags, ERWG rgn hints, SGS, ncremap re-org, ncatted nc4 fll_val';git push --tags
+
+	* MSVC fixes, version fix
+
+	* False alarm release
+
+	* Document -P alm, clm, cice
+
+2017-05-25  Charlie Zender  <zender at uci.edu>
+
+	* Add ncremap -P alm, clm, cice options for SGS to implement model-specific idiosyncratic conventions
+
+2017-05-24  Charlie Zender  <zender at uci.edu>
+
+	* Add sub-grid fraction normalization option sgs_nrm for CICE
+
+	* Fix compiler warnings from recent code
+
+2017-05-23  Charlie Zender  <zender at uci.edu>
+
+	* NCO_NETCDF4_AND_FILLVALUE rides again! Fix bug reported by Kyle Wilcox:
+	Adding _FillValue to written variable works in 4.5.5, 4.6.1, wipes whole variable in 4.6.6 :)
+
+	* Add NEMO (IPSL version) coordinates to regridder database
+
+	* Improve CF-inferral algorithm to handle coordinate attributes with > 2 names
+
+2017-05-22  Charlie Zender  <zender at uci.edu>
+
+	* Warn when grid to infer runs N-S instead of S-N
+
+	* Infer NCEP NCAR Reanalysis 1 as Gaussian grid, requires relaxing weight tolerance to < 1.0e-6
+
+2017-05-20  Charlie Zender  <zender at uci.edu>
+
+	* Searched unsuccessfully for tri-pole grid production routines
+
+	* Realized CICE grid is displaced pole or tri-pole. Abandoned empirical inferral routine due to fold nasti-ness at pole.
+
+2017-05-19  Charlie Zender  <zender at uci.edu>
+
+	* CICE grid partially inferred over masked cells
+
+	* NCO 4.6.7-beta02 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-beta02 final changes';git push
+	git tag -a 4.6.7-beta02 -m 'ncap2 in-fill, MTA flags, ERWG rgn hints, SGS, ncremap rationalization';git push --tags
+
+	* Add stubs to infer entire grid from regional rectangular CICE in curvilinear format with masked land
+
+	* Add fl_fmt=CDF5 options to documentation
+
+	* Re-run test cases, fix rationalization bugs, improve documentation...
+
+2017-05-18  Charlie Zender  <zender at uci.edu>
+
+	* Document new ncremap options
+
+	* Rationalize ncremap options. Changes to -a -E -T -w -W -U.
+
+	* NCO 4.6.7-beta01 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-beta01 final changes';git push
+	git tag -a 4.6.7-beta01 -m 'ncap2 in-fill, MTA flags, ERWG rgn hints, SGS';git push --tags
+
+2017-05-17  Charlie Zender  <zender at uci.edu>
+
+	* Document --rgn_dst/src, -r rgr_thr
+
+	* Add ncremap -r rgr_thr option
+
+	* Make mod04 automatically unpack
+
+	* Change --hnt_dst/src options to --rgn_dst/src flags
+
+	* Add ncremap -P mod04 and make -a tempest synonymous with -w tempest
+
+2017-05-16  Charlie Zender  <zender at uci.edu>
+
+	* Add ncremap --hnt_dst/src options to manually specify	'--dst_regional' for supplied (not inferred) grids
+
+2017-05-15  Charlie Zender  <zender at uci.edu>
+
+	* Allow ncatted to write empty NC_STRING
+
+2017-05-13 Henry Butowsky  <henryb at hush.com>
+
+	* ncap2 add "missing()" and synonym "mask_miss()" to utl_cls()
+	It creates 0/1 array for expression (var == var_miss), returned type same as input type
+
+2017-05-12  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.6.7-alpha06 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha06 final changes';git push
+	git tag -a 4.6.7-alpha06 -m 'Polish and document SGS option';git push --tags
+
+	* Change ncremap pdq_typ to prc_typ to reflect expanded role
+
+	* Document SGS algorithm
+
+	* Disallow SGS source grid inferral due to biases from latitude great/small circle assumptions
+
+2017-05-11  Charlie Zender  <zender at uci.edu>
+
+	* Use dgn_area/diagnose_area flag if ncremap SGS calls nco_grd_nfr()
+
+2017-05-10  Charlie Zender  <zender at uci.edu>
+
+	* Diagnose bad option values in nco_rgr_ini() before calling abort()
+
+	* Re-diagnose inferred area if input area variable has and uses missing values
+
+	* Always infer lat_ntf[0]=-90.0, lat_ntf[lat_nbr]=90.0 for Gaussian grids
+
+2017-05-09  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.6.7-alpha05 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha05 final changes';git push
+	git tag -a 4.6.7-alpha05 -m 'ncremap with sub-gridscale data (-P sgs) works';git push --tags
+
+2017-05-08  Charlie Zender  <zender at uci.edu>
+
+	* Improve verbosity for debugging and generalize names away from ALM/CLM to SGS for "sub-gridcell", and also "fractional area"
+
+	* Allow ncremap to infer source grid when regridding "fractional area" files (not fully working)
+
+2017-05-07  Charlie Zender  <zender at uci.edu>
+
+	* Prevent ncclimo from inadavertently incorrectly (without SGS) regridding ALM/CLM files
+
+	* ncremap move ALM files from homedir to intermediate location
+
+	* Add "none" as synonym for unchunk policy
+
+2017-05-05  Charlie Zender  <zender at uci.edu>
+
+	* Delete missing values with ncap2, eliminate corresponding ncatted step for almu in ncremap
+
+2017-05-04  Charlie Zender  <zender at uci.edu>
+
+	* Revert and allow landmask to be regridded since errors less than not having it at all:
+	T42 CLM with almu has global-mean errors of ~0.005 W/m2 and ~0.01 K (why not better? float landfrac may propagate errors)
+	T42 CLM without almu but with almu landmask has global-mean errors of ~2 W/m2 and ~2 K
+	T42 CLM without almu and with straight regridder land mask has global-mean errors of ~1.5 W/m2 and ~0 K
+
+2017-05-03  Charlie Zender  <zender at uci.edu>
+
+	* Add landmask to regridder exclusion list to keep ALM/CLM sane (users can re-derive it from landfrac)
+
+	* Re-formulate mask conversion in nco_grd_nfr() so output mask is 1 wherever input mask is non-zero and non-missing, and is otherwise 0
+
+2017-05-02  Charlie Zender  <zender at uci.edu>
+
+	* Add ALM/CLM unstructured grid ("almu") stubs to ncremap
+
+	* NCO 4.6.7-alpha04 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha04 final changes';git push
+	git tag -a 4.6.7-alpha04 -m 'Version 4.6.7-alpha04 new features: MTA flags, ncap2 in-fill, MSVC';git push --tags
+
+	* Fix Windows MSVC C++ compilation issues introduced in 4.6.6
+
+	* Henry added simple_fill_miss() weighted_fill_miss() to ncap2
+
+2017-05-01  Charlie Zender  <zender at uci.edu>
+
+	* Alter docs and ncclimo/ncremap to use MTA flag-handling
+
+	* Merge Jerome's MTA flag-handling
+
+2017-04-28  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.6.7-alpha03 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha03 final changes';git push
+	git tag -a 4.6.7-alpha03 -m 'Version 4.6.7-alpha03 new features: msk_src,msk_dst,msk_out,ugrid;';git push --tags
+
+	* Document mask features
+
+	* Add --msk_out to ncremap
+
+	* Generalize nco_grd_nfr() to handle msk_rnk_nbr > grd_rnk_nbr so, e.g., SST(time,lat,lon) works
+
+	* Fix numerous other nco_grd_nfr() errors in new mask code
+
+	* Fix uninitialized memory errors caught by valgrind in recent nco_grd_nfr() grid-span code
+
+2017-04-27  Charlie Zender  <zender at uci.edu>
+
+	* Add mask_b = mask_out = dst_grid_imask to regridded output when flg_msk_out == True
+
+2017-04-26  Charlie Zender  <zender at uci.edu>
+
+	* Add ugrid_fl option to direct ncremap to infer UGRID from source input file
+
+	* Regridder can now infer masks from missing values of any variable
+
+	* Add msk_src and msk_dst options to specify mask-template variables to ncremap
+
+2017-04-25  Charlie Zender  <zender at uci.edu>
+
+	* Add clc.cdl, nsm.cdl, and trj.cdl for EarthCube CF2 project
+
+	* Change "grid" argument to "scrip" to distinguish it from UGRID
+
+2017-04-24  Charlie Zender  <zender at uci.edu>
+
+	* Document UGRID
+
+	* NCO 4.6.7-alpha02 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha02 final changes';git push
+	git tag -a 4.6.7-alpha02 -m 'Version 4.6.7-alpha02 new features: auto-detect regional grids for ERWG';git push --tags
+
+	* nco_grd_nfr() always diagnose grid extent, nco_grd_xtn, even when corners unknown
+
+	* nco_grd_nfr() writes hint file ncremap_tmp_hnt_[dst/src].txt with regional ERWG flags
+
 2017-04-21  Charlie Zender  <zender at uci.edu>
 
+	* NCO 4.6.7-alpha01 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.6.7-alpha01 final changes';git push
+	git tag -a 4.6.7-alpha01 -m 'Version 4.6.7-alpha01 new features: Same as 4.6.6';git push --tags
+
+	* Add autoconf/configure stub to use same git-based version as bld/Makefile
+
 	* NCO 4.6.6 release procedure:
 	cd ~/nco;git commit -a -m 'Version 4.6.6 final changes';git push
 	git tag -a 4.6.6 -m 'Version 4.6.6 new features: no_cll_msr,no_frm_trm,no_stg_grd,hsi,lst_rnk_ge2,UGRID 2D,JSON shape,OMI';git push --tags
diff --git a/doc/VERSION b/doc/VERSION
index ec3f25f..5c6b98f 100644
--- a/doc/VERSION
+++ b/doc/VERSION
@@ -1 +1 @@
-4.6.6
+4.6.7
diff --git a/doc/debian.txt b/doc/debian.txt
index 04a176f..4943f20 100644
--- a/doc/debian.txt
+++ b/doc/debian.txt
@@ -29,18 +29,18 @@ apt-get install dh-make debhelper devscripts fakeroot gnupg debian-policy develo
 
 2. Debian build procedure recommends placing entire package source in
    subdirectory of main package. 
-   For starters, we wish to create .debs of tagged releases, e.g., nco-4.6.6
-   First we create a clean source distribution of nco and place it in nco-4.6.6
+   For starters, we wish to create .debs of tagged releases, e.g., nco-4.6.7
+   First we create a clean source distribution of nco and place it in nco-4.6.7
    Until we know what is necessary, however, we just copy a snapshot
    
    2.1 Clean all build files from development directory
 
 cd ~/nco;make distclean;cd bld;make clean;cd ~
 tar cvzf ./nco/nco.tar.gz ./nco/*
-cd ~/nco;tar xvzf nco.tar.gz;mv nco nco-4.6.6
-/bin/rm nco.tar.gz;tar cvzf nco-4.6.6.tar.gz ./nco-4.6.6/*
-cd ~/nco/nco-4.6.6
-dh_make -e zender at uci.edu -f ../nco-4.6.6.tar.gz
+cd ~/nco;tar xvzf nco.tar.gz;mv nco nco-4.6.7
+/bin/rm nco.tar.gz;tar cvzf nco-4.6.7.tar.gz ./nco-4.6.7/*
+cd ~/nco/nco-4.6.7
+dh_make -e zender at uci.edu -f ../nco-4.6.7.tar.gz
 
     2.2 The preceding steps created template debian files for a .deb,
     Those files now reside in ~/nco/debian.
@@ -55,7 +55,7 @@ dh_make -e zender at uci.edu -f ../nco-4.6.6.tar.gz
    from previous build
 
    cd ~/nco;/bin/rm *.gz
-   cd ~/nco/nco-4.6.6
+   cd ~/nco/nco-4.6.7
    dpkg-buildpackage -rfakeroot > foo 2>&1
    dpkg-buildpackage -rsudo > foo 2>&1
 
@@ -84,33 +84,33 @@ patch -p0 < nco_X.Y.Z-3.diff   # Patch destination with Debian diff
    make tags
 # Put cute version-specific string in nco_ctl.c:nco_nmn_get()
 # Install correct version numbers before updating Debian
-# tags-query replace 4.6.6 with X.Y.Z+1
+# tags-query replace 4.6.7 with X.Y.Z+1
 # If tags-query replace does not work, be sure to manually change
 # versions in configure.ac, debian/files, doc/ANNOUNCE, doc/debian.txt,
 # doc/index.shtml, doc/nco.texi, bld/nco_dst.pl, doc/VERSION
 # 20141201: Change NCO_VERSION_PATCH in src/nco.h!!!!!!!!!!!!!!!!!!!!!!
-   cd ~/nco/debian;dch -b --force-distribution --distribution=unstable -v 4.6.6-1 # Update changelog (-b forces this version number)
+   cd ~/nco/debian;dch -b --force-distribution --distribution=unstable -v 4.6.7-1 # Update changelog (-b forces this version number)
    emacs ~/nco/bld/nco.spec # Update changelog
 # For unknown reason rules file may lose its executable bit
    chmod a+x ~/nco/debian/rules
 # Rebuild autotools so new version # propagates
    cd ~/nco;aclocal;autoheader;automake --foreign;autoconf
 # Save all files in emacs before tagging
-   ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln nco-4.6.6
+   ${HOME}/nco/bld/nco_dst.pl --dbg=2 --bld --cln nco-4.6.7
 # Upload tarball to SF https://sourceforge.net/projects/nco/files 
-   cd;scp dust.ess.uci.edu:/var/www/html/nco/src/nco-4.6.6.tar.gz .
+   cd;scp dust.ess.uci.edu:/var/www/html/nco/src/nco-4.6.7.tar.gz .
 
 7. Ubuntu PPA
 https://help.launchpad.net/Packaging/PPA
-dput NCO nco_4.6.6-2~ppa1_source.changes
+dput NCO nco_4.6.7-2~ppa1_source.changes
 sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com
 
 # Location of build diagnostics for mentors to help 
-http://dust.ess.uci.edu/nco/src/nco_4.6.6-1.dpkg-buildpackage.txt
-http://dust.ess.uci.edu/nco/src/nco_4.6.6-1.dsc
-http://dust.ess.uci.edu/nco/src/nco_4.6.6-1_i386.changes
-http://dust.ess.uci.edu/nco/src/nco_4.6.6-1_i386.deb
-http://dust.ess.uci.edu/nco/src/nco_4.6.6.orig.tar.gz
+http://dust.ess.uci.edu/nco/src/nco_4.6.7-1.dpkg-buildpackage.txt
+http://dust.ess.uci.edu/nco/src/nco_4.6.7-1.dsc
+http://dust.ess.uci.edu/nco/src/nco_4.6.7-1_i386.changes
+http://dust.ess.uci.edu/nco/src/nco_4.6.7-1_i386.deb
+http://dust.ess.uci.edu/nco/src/nco_4.6.7.orig.tar.gz
 
 # Becoming a Debian developer
 http://www.debian.org/devel/join/newmaint
@@ -164,31 +164,31 @@ Matej Vela <vela at debian.org>, Daniel Baumann <daniel at debian.org>, Warren Turkal
 # export LD_LIBRARY_PATH=/usr/lib:/lib:/usr/X11R6/lib
 # sudo aptitude install antlr bison flex gsl-bin libgsl0-dev libantlr-dev netcdf-bin libnetcdfc7 libnetcdf-dev texinfo libcurl4-gnutls-dev libexpat1-dev libxml2-dev udunits-bin libudunits2-0 libudunits2-dev
 cd ~/nco;cvc
-sudo /bin/rm -rf ${DATA}/nco-4.6.6 ${DATA}/nco_4.6.6* ${DATA}/debian # Cleanup last build. sudo necessary for removal because dpkg-buildpackage uses sudo?
-# cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.6-1 -d nco-4.6.6 nco # Export based on tag
-cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -D "1 second ago" -d nco-4.6.6 nco # Export most recent
-tar cvzf ./nco_4.6.6.orig.tar.gz --exclude='nco-4.6.6/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.6 
-/bin/rm -rf ${DATA}/nco-4.6.6 # Remove cvs-exported directory
-tar xvzf ./nco_4.6.6.orig.tar.gz # Untar to get directory without excluded files
-mkdir -p ${DATA}/nco-4.6.6/debian/source;cd ~/nco/debian;/bin/cp changelog compat control convert copyright doc-base files info rules ${DATA}/nco-4.6.6/debian;cd ~/nco/debian/source;/bin/cp format ${DATA}/nco-4.6.6/debian/source # Replace debian directory with _CURRENT_ (main trunk) settings
+sudo /bin/rm -rf ${DATA}/nco-4.6.7 ${DATA}/nco_4.6.7* ${DATA}/debian # Cleanup last build. sudo necessary for removal because dpkg-buildpackage uses sudo?
+# cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.7-1 -d nco-4.6.7 nco # Export based on tag
+cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -D "1 second ago" -d nco-4.6.7 nco # Export most recent
+tar cvzf ./nco_4.6.7.orig.tar.gz --exclude='nco-4.6.7/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.7 
+/bin/rm -rf ${DATA}/nco-4.6.7 # Remove cvs-exported directory
+tar xvzf ./nco_4.6.7.orig.tar.gz # Untar to get directory without excluded files
+mkdir -p ${DATA}/nco-4.6.7/debian/source;cd ~/nco/debian;/bin/cp changelog compat control convert copyright doc-base files info rules ${DATA}/nco-4.6.7/debian;cd ~/nco/debian/source;/bin/cp format ${DATA}/nco-4.6.7/debian/source # Replace debian directory with _CURRENT_ (main trunk) settings
 #export DEB_BUILD_OPTIONS='disable-dap-netcdf disable-netcdf4 disable-udunits2'; # Disable optional packages based on available Debian support
-#cd ${DATA}/nco-4.6.6;dpkg-buildpackage -rsudo -uc -us > ~/foo.nco 2>&1 # -uc -us: Do not sign changes or source files
-#cd ${DATA}/nco-4.6.6;dpkg-buildpackage -rsudo -sa > ~/foo.nco 2>&1 # -sa: Include _orig.tar.gz in .changes 
-cd ${DATA}/nco-4.6.6;dpkg-buildpackage -rsudo > ~/foo.nco 2>&1
+#cd ${DATA}/nco-4.6.7;dpkg-buildpackage -rsudo -uc -us > ~/foo.nco 2>&1 # -uc -us: Do not sign changes or source files
+#cd ${DATA}/nco-4.6.7;dpkg-buildpackage -rsudo -sa > ~/foo.nco 2>&1 # -sa: Include _orig.tar.gz in .changes 
+cd ${DATA}/nco-4.6.7;dpkg-buildpackage -rsudo > ~/foo.nco 2>&1
 sudo dpkg --remove nco
-sudo dpkg --install ${DATA}/nco_4.6.6-1_*.deb
+sudo dpkg --install ${DATA}/nco_4.6.7-1_*.deb
 cd ~/nco/bld;MY_BIN_DIR=/usr/bin ../bm/nco_bm.pl --regress
 # http://lintian.debian.org/full/zender@uci.edu.html
-lintian ${DATA}/nco_4.6.6-1_*.deb
-ls -l ${DATA}/nco_4.6.6*
+lintian ${DATA}/nco_4.6.7-1_*.deb
+ls -l ${DATA}/nco_4.6.7*
 m ~/foo.nco
 # Upload Ubuntu (rather than Debian) packages to websites
-scp ${DATA}/nco_4.6.6* dust.ess.uci.edu:/var/www/html/nco/src
-scp ${DATA}/nco_4.6.6* zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
+scp ${DATA}/nco_4.6.7* dust.ess.uci.edu:/var/www/html/nco/src
+scp ${DATA}/nco_4.6.7* zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
 # NB: Make sure RPMs build before uploading to debian, since changing
 # Debian versions is a PITA
 # NB: Only upload pbuilder Debian Sid (not personal Ubuntu) .deb builds to Debian mentors
-# cd ${DATA};dupload -t mentors nco_4.6.6-1_*.changes
+# cd ${DATA};dupload -t mentors nco_4.6.7-1_*.changes
 bsrc # Reset shell environment for regular development
 
 # New build system #2
@@ -202,52 +202,52 @@ DIST=sid sudo pbuilder update # Update chroot before building package in it
 # dget http://ftp.debian.org/debian/pool/main/n/nco/nco_3.9.0-1.dsc
 # dget http://ftp.debian.org/debian/pool/main/n/netcdf/netcdf_3.6.1-1.dsc
 # apt-get source nco # Get package source
-sudo /bin/rm /var/cache/pbuilder/result/nco_4.6.6* # Cleanup prior build
+sudo /bin/rm /var/cache/pbuilder/result/nco_4.6.7* # Cleanup prior build
 # To pass DEB_BUILD_OPTIONS to pbuilder while using sudo, one must first
 # modify sudoers with visudo to prevent sudo from resetting environment
 #export DEB_BUILD_OPTIONS='disable-dap-netcdf disable-netcdf4 disable-udunits2'; # Disable optional packages based on available Debian support
-cd ${DATA};DIST=sid sudo pbuilder build nco_4.6.6-1.dsc > ~/foo.nco.pbuilder 2>&1
-cd /var/cache/pbuilder/result;debsign -k6F635D10 nco_4.6.6-1_*.changes
-lintian /var/cache/pbuilder/result/nco_4.6.6-1_*.deb
+cd ${DATA};DIST=sid sudo pbuilder build nco_4.6.7-1.dsc > ~/foo.nco.pbuilder 2>&1
+cd /var/cache/pbuilder/result;debsign -k6F635D10 nco_4.6.7-1_*.changes
+lintian /var/cache/pbuilder/result/nco_4.6.7-1_*.deb
 sudo dpkg --remove nco
-sudo dpkg --install /var/cache/pbuilder/result/nco_4.6.6-1_*.deb
+sudo dpkg --install /var/cache/pbuilder/result/nco_4.6.7-1_*.deb
 cd ~/nco/bld;MY_BIN_DIR=/usr/bin ../bm/nco_bm.pl --regress
 # NB: Upload pbuilder Debian Sid packages to Debian mentors, but not
 # to personal or NCO websites since most people use Ubuntu not Debian
 # NB: Debian versions are a PITA, ensure RPMs build before uploading to Debian
-cd /var/cache/pbuilder/result;dupload -t mentors nco_4.6.6-1_*.changes
+cd /var/cache/pbuilder/result;dupload -t mentors nco_4.6.7-1_*.changes
 
 # RPM builds as root
 export rpm_root='/usr/src/redhat'
 # export sudo_sng='' # sudo not-necessary when builing in user directories
 export sudo_sng='sudo' # sudo necessary when building in system directories
 cd ~/nco;cvc;cvu
-/bin/rm -rf ${DATA}/nco-4.6.6 ${DATA}/nco-4.6.6* # Cleanup last build
+/bin/rm -rf ${DATA}/nco-4.6.7 ${DATA}/nco-4.6.7* # Cleanup last build
 ${sudo_sng} /bin/rm -r -f \
-${rpm_root}/BUILD/nco-4.6.6 \
-${rpm_root}/RPMS/i386/nco-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-debuginfo-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-devel-4.6.6-?.i386.rpm \
-${rpm_root}/SOURCES/nco-4.6.6.tar.gz \
-${rpm_root}/SPECS/nco-4.6.6.spec \
-${rpm_root}/SRPMS/nco-4.6.6-?.src.rpm
-cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.6-1 -d nco-4.6.6 nco # Export based on tag
-${sudo_sng} ln -s ${HOME}/nco/bld/nco.spec ${rpm_root}/SPECS/nco-4.6.6.spec
-tar cvzf ./nco-4.6.6.tar.gz --exclude='nco-4.6.6/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.6 
-${sudo_sng} /bin/cp ${DATA}/nco-4.6.6.tar.gz ${rpm_root}/SOURCES
+${rpm_root}/BUILD/nco-4.6.7 \
+${rpm_root}/RPMS/i386/nco-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-debuginfo-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-devel-4.6.7-?.i386.rpm \
+${rpm_root}/SOURCES/nco-4.6.7.tar.gz \
+${rpm_root}/SPECS/nco-4.6.7.spec \
+${rpm_root}/SRPMS/nco-4.6.7-?.src.rpm
+cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.7-1 -d nco-4.6.7 nco # Export based on tag
+${sudo_sng} ln -s ${HOME}/nco/bld/nco.spec ${rpm_root}/SPECS/nco-4.6.7.spec
+tar cvzf ./nco-4.6.7.tar.gz --exclude='nco-4.6.7/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.7 
+${sudo_sng} /bin/cp ${DATA}/nco-4.6.7.tar.gz ${rpm_root}/SOURCES
 cd ${rpm_root}/SPECS
-${sudo_sng} rpmbuild -ba --sign nco-4.6.6.spec > ~/foo.nco 2>&1
+${sudo_sng} rpmbuild -ba --sign nco-4.6.7.spec > ~/foo.nco 2>&1
 scp \
-${rpm_root}/RPMS/i386/nco-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-debuginfo-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-devel-4.6.6-?.i386.rpm \
-${rpm_root}/SRPMS/nco-4.6.6-?.src.rpm \
+${rpm_root}/RPMS/i386/nco-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-debuginfo-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-devel-4.6.7-?.i386.rpm \
+${rpm_root}/SRPMS/nco-4.6.7-?.src.rpm \
 dust.ess.uci.edu:/var/www/html/nco/src
 scp \
-${rpm_root}/RPMS/i386/nco-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-debuginfo-4.6.6-?.i386.rpm \
-${rpm_root}/RPMS/i386/nco-devel-4.6.6-?.i386.rpm \
-${rpm_root}/SRPMS/nco-4.6.6-?.src.rpm \
+${rpm_root}/RPMS/i386/nco-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-debuginfo-4.6.7-?.i386.rpm \
+${rpm_root}/RPMS/i386/nco-devel-4.6.7-?.i386.rpm \
+${rpm_root}/SRPMS/nco-4.6.7-?.src.rpm \
 zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
 
 # RPM builds as user
@@ -256,33 +256,33 @@ zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
 export rpm_root="${DATA}/rpm/nco"
 #cd ~/nco;cvc;cvu # This risks committing unwanted *.[ch]pp files
 mkdir -p ${DATA}/rpm/nco/TMP ${DATA}/rpm/nco/BUILD
-/bin/rm -rf ${DATA}/nco-4.6.6 ${DATA}/nco-4.6.6* # Cleanup last build
+/bin/rm -rf ${DATA}/nco-4.6.7 ${DATA}/nco-4.6.7* # Cleanup last build
 /bin/rm -r -f \
-${rpm_root}/nco-4.6.6-?.src.rpm \
-${rpm_root}/nco-4.6.6.spec \
-${rpm_root}/nco-4.6.6.tar.gz \
-${rpm_root}/*/nco-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-debuginfo-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-devel-4.6.6-?.*.rpm
-# cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.6-1 -d nco-4.6.6 nco # Export based on tag
-cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -D "1 second ago" -dnco-4.6.6 nco # Export most recent and build as 4.6.6-1
-tar cvzf ./nco-4.6.6.tar.gz --exclude='nco-4.6.6/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.6 
-/bin/cp ${DATA}/nco-4.6.6.tar.gz ${rpm_root}
+${rpm_root}/nco-4.6.7-?.src.rpm \
+${rpm_root}/nco-4.6.7.spec \
+${rpm_root}/nco-4.6.7.tar.gz \
+${rpm_root}/*/nco-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-debuginfo-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-devel-4.6.7-?.*.rpm
+# cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -r nco-4.6.7-1 -d nco-4.6.7 nco # Export based on tag
+cd ${DATA};cvs -d zender at nco.cvs.sf.net:/cvsroot/nco export -kkv -D "1 second ago" -dnco-4.6.7 nco # Export most recent and build as 4.6.7-1
+tar cvzf ./nco-4.6.7.tar.gz --exclude='nco-4.6.7/debian*' --exclude='.cvsignore' --exclude='ncap_lex.c' --exclude='ncap_yacc.[ch]' ./nco-4.6.7 
+/bin/cp ${DATA}/nco-4.6.7.tar.gz ${rpm_root}
 ln -s ${HOME}/nco/bld/nco.spec ${rpm_root}/nco.spec
 cd ${rpm_root}
 rpmbuild -ba --sign nco.spec > ~/foo.nco 2>&1
-rpmlint ${rpm_root}/*/nco-4.6.6-?.*.rpm
+rpmlint ${rpm_root}/*/nco-4.6.7-?.*.rpm
 sudo yum remove nco
-sudo yum install ${rpm_root}/*/nco-4.6.6-?.*.rpm
+sudo yum install ${rpm_root}/*/nco-4.6.7-?.*.rpm
 scp \
-${rpm_root}/*/nco-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-debuginfo-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-devel-4.6.6-?.*.rpm \
-${rpm_root}/nco-4.6.6-?.*.src.rpm \
+${rpm_root}/*/nco-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-debuginfo-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-devel-4.6.7-?.*.rpm \
+${rpm_root}/nco-4.6.7-?.*.src.rpm \
 dust.ess.uci.edu:/var/www/html/nco/src
 scp \
-${rpm_root}/*/nco-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-debuginfo-4.6.6-?.*.rpm \
-${rpm_root}/*/nco-devel-4.6.6-?.*.rpm \
-${rpm_root}/nco-4.6.6-?.*.src.rpm \
+${rpm_root}/*/nco-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-debuginfo-4.6.7-?.*.rpm \
+${rpm_root}/*/nco-devel-4.6.7-?.*.rpm \
+${rpm_root}/nco-4.6.7-?.*.src.rpm \
 zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
diff --git a/doc/index.shtml b/doc/index.shtml
index fd62c95..88cd12e 100644
--- a/doc/index.shtml
+++ b/doc/index.shtml
@@ -70,7 +70,7 @@ Try to disable Spammers' machines:
 <p><h1 align="center">Bienvenue sur le netCDF Operator (NCO) site</h1>
 
 <p><h2>
-Current stable NCO version is 4.6.6 released <!--#flastmod file="src/nco-4.6.6.tar.gz"-->
+Current stable NCO version is 4.6.7 released <!--#flastmod file="src/nco-4.6.7.tar.gz"-->
 </h2>
 
 <table border=0 width=100%>
@@ -149,7 +149,9 @@ and
 <h2>Recent Releases & Milestones</h2>
 
 <ul>
-<li>2017 Apr 21: 4.6.6 (<i>In progress</i>)
+<li>2017 Jun ??: 4.6.8 (<i>In Progress...</i>)
+<li>2017 May 26: 4.6.7 (Sub-grid regridding)
+<li>2017 Apr 21: 4.6.6 (UGRID)
 <li>2017 Mar 15: 4.6.5 (Sundry features/fixes)
 <li>2017 Feb 07: 4.6.4 (<tt>ncclimo</tt> splitter)
 <li>2017 Jan 27: <i>Geosci. Model Dev.</i> publishes compression-error trade-off <a href="http://www.geosci-model-dev.net/10/413/2017">paper</a></li>
@@ -625,18 +627,30 @@ Identical copies of those tarballs are also stored
 <a href="http://nco.sf.net/src">here</a> on SourceForge for historical
 continuity.
 You may retrieve the source of tagged versions directly with, e.g.,
-<tt>git clone -b 4.6.6 http://github.com/nco/nco.git nco-4.6.6</tt></a>.
+<tt>git clone -b 4.6.7 http://github.com/nco/nco.git nco-4.6.7</tt></a>.
 <ul>
-<li><b>NCO 4.6.7</b>: (<i>Future</i>)
+<li><b>NCO 4.6.8</b>: (<i>Future</i>)
 <a href="http://nco.sf.net/nco.html#cnk">Chunking</a> bytes not elements;
 extensive hashing?;
 netCDF4 compound types?;
 <tt>ncks --xtn</tt> better extensive variable treatment;</li>
-<li><b>NCO 4.6.6</b>: (<i>In Progress, features in-progress or completed include</i>) 
+<li><b>NCO 4.6.8</b>: (<i>In Progress, features in-progress or complete include</i>) 
+<tt>ncks --iso8661</tt> put the &lquote;T&rquote; in time;</li>
+<li><b>NCO 4.6.7</b>: (<i>Current Stable Release</i>)
+Multi-argument (MTA) flag parsing;
+<tt>ncap2</tt> in-fill functions simple_fill_miss() + weighted_fill_miss();
+<tt>ncap2</tt> duplicates input variable chunking;
+<tt>ncatted</tt> NC4 bugfix;
+<tt>ncremap -P sgs, alm, clm, cice</tt> sub-gridscale remapping;
+<tt>ncremap</tt> msk_src/dst conversion;
+<tt>ncremap</tt> src/dst_regional hints to ERWG;</li>
+<li><b>NCO 4.6.6</b>: (<i>Current Stable Release</i>)
 <tt>ncks --cdl</tt> prints units when <i>dbg_lvl</i> ≥ 1;
 <tt>ncks --cdl</tt> prints braces for compound record variables;
-<tt>ncks --xtn</tt> better extensive variable treatment;</li>
-<li><b>NCO 4.6.5</b>: (<i>Current Stable Release</i>)
+<tt>ncks</tt> outputs UGRID-format rectangular grids;
+<tt>ncremap/ncclimo no_cll_msr,no_frm_trm,no_ntv_tms,no_stg_grd</tt> switches;
+<tt>ncremap</tt> masks;</li>
+<li><b>NCO 4.6.5</b>:
 <tt>ncks --cal</tt> prints human-legible ISO8601 dates;
 <tt>ncclimo/ncremap --version</tt> switch;
 <tt>ncremap --vrb_lvl</tt> verbosity level;
@@ -797,7 +811,7 @@ goodies besides NCO) to your automatically-searched channels with
 ‘<tt>conda config --add channels --conda-forge</tt>’, then
 install NCO with ‘<tt>conda install nco</tt>’.
 The default NCO installed by <tt>conda</tt> is generally within a month of the latest release. 
-<li><a href="https://github.com/conda-forge/nco-feedstock">nco-4.6.6</a> Executables Anaconda-compatible. Maintained by Filipe Fernandes.</li>
+<li><a href="https://github.com/conda-forge/nco-feedstock">nco-4.6.7</a> Executables Anaconda-compatible. Maintained by Filipe Fernandes.</li>
 Thanks to Rich Signell, Filipe Fernandes (and others?) for developing and maintaining the NCO package for conda.
 </ul>
 
@@ -806,7 +820,7 @@ Thanks to Rich Signell, Filipe Fernandes (and others?) for developing and mainta
 <h3><a href="http://www.debian.org">Debian</a> and <a href="http://www.ubuntu.com">Ubuntu</a> GNU/Linux</a></h3>
 <ul>
 <!--
-<li><a href="http://www.debian.org">Debian</a> and <a href="http://www.ubuntu.com">Ubuntu</a> GNU/Linux-compatible Intel systems, prebuilt binary executable <a href="http://www.debian.org">deb</a>: <a href="http://packages.debian.org/testing/math/nco.html">nco-4.6.6</a></li>
+<li><a href="http://www.debian.org">Debian</a> and <a href="http://www.ubuntu.com">Ubuntu</a> GNU/Linux-compatible Intel systems, prebuilt binary executable <a href="http://www.debian.org">deb</a>: <a href="http://packages.debian.org/testing/math/nco.html">nco-4.6.7</a></li>
 -->
 <a href="http://packages.debian.org/unstable/science/nco">Debian NCO</a> and 
 <a href="https://launchpad.net/ubuntu/+source/nco">Ubuntu NCO</a> homepages.
@@ -814,8 +828,8 @@ Thanks to Rich Signell, Filipe Fernandes (and others?) for developing and mainta
 NCO packages in the Debian/Ubuntu repositories (e.g., Sid and Raring) generally lag the packages distributed here by 6–12 months.
 <a name="beta"></a><a name="prerelease"> <!-- http://nco.sf.net#beta -->
 Newer (beta- or pre-release) packages are often available for intrepid Debian/Ubuntu users as described <a href="https://github.com/nco/nco/tree/master/doc/beta.txt">here</a>.
-<dt>Debian package for most recent NCO release (install with, e.g., ‘<tt>dpkg --install nco_4.6.6-1_i386.deb</tt>’):</dt>
-<li><a href="https://launchpad.net/ubuntu/+source/nco/4.6.6-1">nco_4.6.6-1_amd64.deb</a> : Executables AMD64-compatible</li>
+<dt>Debian package for most recent NCO release (install with, e.g., ‘<tt>dpkg --install nco_4.6.7-1_i386.deb</tt>’):</dt>
+<li><a href="https://launchpad.net/ubuntu/+source/nco/4.6.7-1">nco_4.6.7-1_amd64.deb</a> : Executables AMD64-compatible</li>
 Thanks to Daniel Baumann, Sebastian Couwenberg, Barry deFreese, Francesco Lovergine, 
 Brian Mays, Rorik Peterson, and Matej Vela for their help packaging
 NCO for Debian over the years. 
@@ -859,10 +873,10 @@ Thanks to Gavin Burris and Kyle Wilcox for documenting build procedures for RHEL
 <!-- 
 # Mac OS X 10.12 (Sierra) systems (aerosol):
 /usr/bin/scp ~/nco/doc/index.shtml zender,nco at web.sf.net:/home/project-web/nco/htdocs
-cd ~/bin;tar cvzf ${DATA}/nco-4.6.6.macosx.10.12.tar.gz nc*;scp ${DATA}/nco-4.6.6.macosx.10.12.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
+cd ~/bin;tar cvzf ${DATA}/nco-4.6.7.macosx.10.12.tar.gz nc*;scp ${DATA}/nco-4.6.7.macosx.10.12.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src
 -->
 The most up-to-date executables are probably those in the tarball below. Those unfamiliar with installing executables from tarballs may try the (older) <a href="http://en.wikipedia.org/wiki/Apple_Disk_Image">DMG</a> files (you may need to add <tt>/opt/local/bin</tt> to your executable path to access those operators).
-<li><a href="src/nco-4.6.6.macosx.10.12.tar.gz">nco-4.6.6.macosx.10.12.tar.gz</a> (<!--#fsize file="src/nco-4.6.6.macosx.10.12.tar.gz"-->): Executables MacOSX 10.12-compatible (last updated <!--#flastmod file="src/nco-4.6.6.macosx.10.12.tar.gz"-->). 
+<li><a href="src/nco-4.6.7.macosx.10.12.tar.gz">nco-4.6.7.macosx.10.12.tar.gz</a> (<!--#fsize file="src/nco-4.6.7.macosx.10.12.tar.gz"-->): Executables MacOSX 10.12-compatible (last updated <!--#flastmod file="src/nco-4.6.7.macosx.10.12.tar.gz"-->). 
 (NB: These executables require
   the <a href="http://trac.macosforge.org/projects/macports/wiki">MacPorts</a>
   <a href="#bld_macports">dependencies</a> for <a href="http://svn.macports.org/repository/macports/trunk/dports/science/nco">NCO</a>). Maintained by NCO Project.</li>
@@ -886,7 +900,7 @@ To build NCO from source yourself using MSVC or Qt, please see the <a href="nco_
 /usr/bin/scp /home/pvicente/nco/doc/index.shtml pvicente,nco at web.sf.net:/home/project-web/nco/htdocs
 /usr/bin/scp /home/pvicente/windows_setup/nco-4.6.6.windows.mvs.exe pvicente,nco at web.sf.net:/home/project-web/nco/htdocs/src
 -->
-<li><a href="src/nco-4.6.3.windows.mvs.exe">nco-4.6.5.windows.mvs.exe</a> (<!--#fsize file="src/nco-4.6.5.windows.mvs.exe"-->) : Windows Self-Extracting Installer (last updated <!--#flastmod file="src/nco-4.6.5.windows.mvs.exe"-->). Maintained by Pedro Vicente.</li>
+<li><a href="src/nco-4.6.6.windows.mvs.exe">nco-4.6.6.windows.mvs.exe</a> (<!--#fsize file="src/nco-4.6.6.windows.mvs.exe"-->) : Windows Self-Extracting Installer (last updated <!--#flastmod file="src/nco-4.6.6.windows.mvs.exe"-->). Maintained by Pedro Vicente.</li>
 </ul>
 
 <a name="cygwin"></a> <!-- http://nco.sf.net#cygwin -->
@@ -1057,11 +1071,11 @@ site.</li>
 The simplest way to acquire the source is to download the compressed tarball:
 <ul>
 <li>
-<!-- scp ${DATA}/nco-4.6.6.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src -->
-<a href="https://github.com/nco/nco/archive/4.6.6.tar.gz">nco-4.6.6.tar.gz</a> 
-(<!--#fsize file="src/nco-4.6.6.tar.gz"--> compressed tar-file)<br>
-<!--#exec cmd="openssl dgst -md5 src/nco-4.6.6.tar.gz"--><br>
-<!--#exec cmd="openssl dgst -sha1 src/nco-4.6.6.tar.gz"--> 
+<!-- scp ${DATA}/nco-4.6.7.tar.gz zender,nco at web.sf.net:/home/project-web/nco/htdocs/src -->
+<a href="https://github.com/nco/nco/archive/4.6.7.tar.gz">nco-4.6.7.tar.gz</a> 
+(<!--#fsize file="src/nco-4.6.7.tar.gz"--> compressed tar-file)<br>
+<!--#exec cmd="openssl dgst -md5 src/nco-4.6.7.tar.gz"--><br>
+<!--#exec cmd="openssl dgst -sha1 src/nco-4.6.7.tar.gz"--> 
 </li>
 </ul>
 
@@ -1080,8 +1094,8 @@ You may retrieve any NCO distribution you wish from
 <a href="https://help.github.com">GitHub</a>. 
 Usually you wish to retrieve a recent tagged (i.e., released) version.
 This command retrieves the entire NCO repository (< 20 MB) and
-then checks out NCO version <tt>4.6.6</tt>:
-<p><tt>git clone https://github.com/nco/nco.git;cd nco;git checkout 4.6.6</tt></p>
+then checks out NCO version <tt>4.6.7</tt>:
+<p><tt>git clone https://github.com/nco/nco.git;cd nco;git checkout 4.6.7</tt></p>
 These commands retrieve the current (“bleeding edge”)
 development version of NCO into a local directory named <tt>nco</tt>:
 <p><tt>git clone https://github.com/nco/nco.git ~/nco</tt></p> or
@@ -1089,9 +1103,9 @@ development version of NCO into a local directory named <tt>nco</tt>:
 Track changes to the development version using
 <p><tt>cd nco;git pull</tt></p>
 One difference between running a "tagged" release 
-(e.g., <tt>4.6.6</tt>) and the development version is that the
+(e.g., <tt>4.6.7</tt>) and the development version is that the
 tagged release operators will print a valid version number (e.g.,
-<tt>4.6.6</tt>) when asked to do so with the <tt>-r</tt> flag
+<tt>4.6.7</tt>) when asked to do so with the <tt>-r</tt> flag
 (e.g., <tt>ncks -r</tt>).
 The development version simply places today's date in place of the
 version.
@@ -1236,9 +1250,9 @@ Users should instead first download and install the ANTLR found <a href="http://
 
 <li>Once you have installed the pre-requisites as shown above, you may then build the latest stable NCO and install it in, e.g., <tt>/usr/local</tt> with: 
 <tt>
-<dt>wget https://github.com/nco/nco/archive/4.6.6.tar.gz</dt>
-<dt>tar xvzf 4.6.6.tar.gz</dt>
-<dt>cd nco-4.6.6</dt>
+<dt>wget https://github.com/nco/nco/archive/4.6.7.tar.gz</dt>
+<dt>tar xvzf 4.6.7.tar.gz</dt>
+<dt>cd nco-4.6.7</dt>
 <dt>./configure --prefix=/usr/local</dt>
 <dt>make</dt>
 <dt>sudo make install</dt>
diff --git a/doc/nco.texi b/doc/nco.texi
index 66821be..43b812f 100644
--- a/doc/nco.texi
+++ b/doc/nco.texi
@@ -39,6 +39,7 @@ Usage:
 export TEX='tex --src-specials'
 cd ~/nco/doc;texi2dvi nco.texi;makeinfo --html --ifinfo --no-split --output=nco.html nco.texi;makeinfo nco.texi;dvips -o nco.ps nco.dvi;texi2dvi --pdf nco.texi;makeinfo --xml --ifinfo --no-split --output=nco.xml nco.texi;makeinfo --no-headers --output=nco.txt nco.texi
 cd ~/nco/doc;/usr/bin/scp index.shtml nco_news.shtml ChangeLog TODO README VERSION nco.dvi nco.html nco.info* nco.pdf nco.ps nco.texi nco.txt nco.xml nco_rfr_crd.pdf ../data/ncap.in ../data/ncap2.in zender,nco at web.sf.net:/home/project-web/nco/htdocs;cd -
+cd ~/nco/doc;/usr/bin/scp index.shtml nco_news.shtml ChangeLog TODO README VERSION nco.dvi nco.html nco.info* nco.pdf nco.ps nco.texi nco.txt nco.xml nco_rfr_crd.pdf ../data/ncap.in ../data/ncap2.in dust.ess.uci.edu:Sites/nco;cd -
 dvips -o nco.ps nco.dvi 
 dvips -Ppdf -G0 -o nco.ps nco.dvi 
 makeinfo --html --ifinfo --no-split --output=nco.html nco.texi
@@ -118,12 +119,12 @@ Octave TeXInfo manual shows clean TeXInfo structure
 @setfilename nco.info
 
 @c Define edition, date, ...
- at set nco-edition 4.6.6
- at set doc-edition 4.6.6
+ at set nco-edition 4.6.7
+ at set doc-edition 4.6.7
 @set copyright-years 1995--2017
 @set update-year 2017
- at set update-date 21 April 2017
- at set update-month April 2017
+ at set update-date 26 May 2017
+ at set update-month May 2017
 
 @settitle @acronym{NCO} @value{nco-edition} User Guide
 
@@ -344,11 +345,13 @@ We gratefully acknowledge support for @acronym{NCO} development and
 maintenance provided by these institutions and programs:
 @acronym{DOE} @acronym{ACME} DE-SC0012998, 
 @acronym{NASA} @acronym{ACCESS} NNX12AF48A and NNX14AH55A, and
- at acronym{NSF} @acronym{SEI} IIS-0431203.
+ at acronym{NSF} @acronym{SEI} IIS-0431203 and AGS-1541031.
 Research supported as part of the Accelerated Climate Modeling for
 Energy (@acronym{ACME}) program, funded by the U.S. Department of
 Energy, Office of Science, Office of Biological and Environmental
 Research.  
+This material is based upon work supported by the National Science
+Foundation under Grants IIS-0431203 and AGS-1541031.
 @sp 2
 The original author of this software, Charlie Zender, wants to improve it
 with the help of your suggestions, improvements, bug-reports, and patches.@*
@@ -2675,9 +2678,17 @@ metadata operations.
 Use the @samp{--hdr_pad} and @samp{--header_pad} switches to request
 that @var{hdr_pad} bytes be inserted into the metadata section of the
 output file.
+There is little downside to padding a header with kilobyte of space,
+since subsequent manipulation of the file will annotate the
+ at code{history} attribute with all commands, let alone any explicit
+metadata additions with @command{ncatted}.
+ at example
+ncks --hdr_pad=1000  in.nc out.nc # Pad header with  1 kB space
+ncks --hdr_pad=10000 in.nc out.nc # Pad header with 10 kB space
+ at end example
 Future metadata expansions will not incur the netCDF3 performance
 penalty of copying the entire output file unless the expansion exceeds
-the amount of header padding exceeded.
+the amount of header padding.
 This can be beneficial when it is known that some metadata will be added
 at a future date.
 The operators which benefit most from judicious use of header padding
@@ -2919,6 +2930,7 @@ Users are expected to pick the unambiguous truncation of each option
 name that most suits their taste.
 
 @html
+<a name="MTA"></a> <!-- http://nco.sf.net/nco.html#MTA -->
 <a name="mta"></a> <!-- http://nco.sf.net/nco.html#mta -->
 <a name="multi-arguments"></a> <!-- http://nco.sf.net/nco.html#multi-arguments -->
 <a name="Multi-arguments"></a> <!-- http://nco.sf.net/nco.html#Multi-arguments -->
@@ -2926,6 +2938,7 @@ name that most suits their taste.
 @node Multi-arguments,  , Truncating Long Options, Command Line Options
 @subsection Multi-arguments
 @cindex Multi-arguments
+ at cindex @acronym{MTA}
 @cindex Options, multi-argument
 @cindex @code{--gaa @var{key}=@var{val}}
 @cindex @code{--ppc @var{key}=@var{val}}
@@ -2933,7 +2946,8 @@ name that most suits their taste.
 @cindex @code{--trr @var{key}=@var{val}}
 As of @acronym{NCO} version 4.6.2 (November, 2016), @acronym{NCO} accepts
 multiple key-value pair options for a single feature to be joined
-together into a single extended argument called a @dfn{multi-argument}. 
+together into a single extended argument called a @dfn{multi-argument},
+sometimes abbreviated @acronym{MTA}. 
 Only four @acronym{NCO} features accept multiple key-value pairs that
 can be aggregated into multi-arguments. 
 These features are:
@@ -3013,6 +3027,23 @@ If @var{val} is a long text string that could contain the default
 delimiter, then delimit with a unique multi-character string such as
 @samp{csz} in the third example. 
 
+As of @acronym{NCO} version 4.6.7 (May, 2017), multi-argument
+flags no longer need be specified as key-value pairs.
+By definition a flag sets a boolean value to either True or False.
+Previously @acronym{MTA} flags had to employ key-value pair syntax,
+e.g., @samp{--rgr infer=Y} or @samp{--rgr no_cll_msr=anything} in order 
+to parse correctly.
+Now the @acronym{MTA} parser accepts flags in the more intuitive syntax
+where they are listed by name, i.e., the flag name alone indicates the
+flag to set, e.g., @samp{--rgr infer} or @samp{--rgr no_cll_msr} are
+valid. 
+A consequence of this is that flags in multi-argument strings appear
+as straightforward flag names, e.g.,
+ at samp{--rgr infer#no_cll_msr#latlon=129,256}.
+It is also valid to prefix flags in multi-arument strings with
+single or double-dashes to make the flags more visible, e.g.,
+ at samp{--rgr latlon=129,256#--infer#-no_cll_msr}. 
+
 @html
 <a name="fl_in"></a> <!-- http://nco.sf.net/nco.html#fl_in -->
 <a name="in"></a> <!-- http://nco.sf.net/nco.html#in -->
@@ -6033,7 +6064,13 @@ hyperslab and multi-slab options.
 Also @samp{--auxiliary}.
 This switch supports hyperslabbing cell-based grids (aka unstructured
 grids) over coordinate ranges. 
-This works on datasets that associate coordinate variables to
+When these grids are stored as 1D-arrays of cell data, this feature is
+helpful at hyperslabbing and/or performing arithmetic on selected
+geographic regions.
+This feature cannot be used to select regions of 2D grids (instead use
+the @command{ncap2} @code{where} statement for such grids 
+ at ref{Where statement}).
+This feature works on datasets that associate coordinate variables to 
 grid-mappings using the @acronym{CF}-convention (@pxref{CF Conventions})   
 @code{coordinates} and @code{standard_name} attributes described 
 @uref{http://cfconventions.org/1.6.html#coordinate-system, here}. 
@@ -6160,6 +6197,7 @@ to avoid confusion.
 @cindex Gaussian grid
 @cindex Equi-Angular grid
 @cindex FV grid
+ at cindex FV grid
 @cindex CAM-FV grid
 @cindex grid, Fixed
 @cindex grid, Offset
@@ -6239,16 +6277,18 @@ gridfile.
 A human-readable grid description should be placed in @var{grd_ttl}.
 Examples include ``CAM-FV scalar grid 129x256'' and ``T42 Gaussian grid''. 
 
- at cindex @var{grid}
- at cindex @samp{--rgr grid=@var{grid}}
- at item Grid File: @var{grid}
+ at cindex @var{scrip_grid}
+ at cindex @samp{--rgr grid=@var{scrip_grid}}
+ at cindex @samp{--rgr scrip=@var{scrip_grid}}
+ at item Grid File: @var{scrip_grid}
 The grid-generation @acronym{API} was bolted-on to @acronym{NCO}
 and is somewhat primitive, e.g., having to repeat the @samp{--rgr}
 option. 
 Another aspect of this is that the output grid filename is distinct
 from the output filename of the host @command{ncks} command. 
-Specify the output gridfile name with @var{grid}, e.g., 
- at file{t42_SCRIP.20150901.nc}.
+Specify the output gridfile name @var{scrip_grid} with keywords
+ at code{grid} or @code{scrip}, e.g., @samp{--rgr grid=@var{scrip_grid}} or  
+ at samp{--rgr scrip=@file{t42_SCRIP.20150901.nc}}.
 It is conventional to include a datestamp in the gridfile name.
 This helps users identify up-to-date and out-of-date grids.
 Any valid netCDF file may be named as the source (e.g., @file{in.nc}). 
@@ -6427,43 +6467,49 @@ Generating common grids:
 @example
 @verbatim
 # 180x360 (1x1 degree) Equi-Angular grid, first longitude centered at Greenwich
-ncks --rgr grd_ttl='Equi-Angular grid 180x360' --rgr grid=${DATA}/grids/180x360_SCRIP.20150901.nc \
+ncks --rgr grd_ttl='Equi-Angular grid 180x360' --rgr scrip=${DATA}/grids/180x360_SCRIP.20150901.nc \
      --rgr latlon=180,360 --rgr lat_typ=uni --rgr lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
 
 # 129x256 CAM-FV grid, first longitude centered at Greenwich
-ncks --rgr grd_ttl='CAM-FV scalar grid 129x256' --rgr grid=${DATA}/grids/129x256_SCRIP.20150901.nc \
+ncks --rgr grd_ttl='CAM-FV scalar grid 129x256' --rgr scrip=${DATA}/grids/129x256_SCRIP.20150901.nc \
      --rgr latlon=129,256 --rgr lat_typ=fv --rgr lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
 
 # 91x180 CAM-FV grid, first longitude centered at Greenwich (2 degree grid)
 ncks --rgr grd_ttl='CAM-FV scalar grid 91x180'#latlon=91,180#lat_typ=fv#lon_typ=grn_ctr \
-     --rgr grid=${DATA}/grids/91x180_SCRIP.20170401.nc ~zender/nco/data/in.nc ~/foo.nc
+     --rgr scrip=${DATA}/grids/91x180_SCRIP.20170401.nc ~zender/nco/data/in.nc ~/foo.nc
 
 # 25x48 CAM-FV grid, first longitude centered at Greenwich (7.5 degree grid)
 ncks --rgr grd_ttl='CAM-FV scalar grid 25x48'#latlon=25,48#lat_typ=fv#lon_typ=grn_ctr \
-     --rgr grid=${DATA}/grids/25x48_SCRIP.20170401.nc ~zender/nco/data/in.nc ~/foo.nc
+     --rgr scrip=${DATA}/grids/25x48_SCRIP.20170401.nc ~zender/nco/data/in.nc ~/foo.nc
 
 # 128x256 Equi-Angular grid, Greenwich west edge of first longitude
 # This is the CAM-FV offset grid for the 129x256 CAM-FV scalar grid above
-ncks --rgr grd_ttl='Equi-Angular grid 128x256' --rgr grid=${DATA}/grids/128x256_SCRIP.20150901.nc \
+ncks --rgr grd_ttl='Equi-Angular grid 128x256' --rgr scrip=${DATA}/grids/128x256_SCRIP.20150901.nc \
      --rgr latlon=128,256 --rgr lat_typ=uni --rgr lon_typ=grn_wst ~zender/nco/data/in.nc ~/foo.nc
 
 # T42 Gaussian grid, first longitude centered at Greenwich
-ncks --rgr grd_ttl='T42 Gaussian grid' --rgr grid=${DATA}/grids/t42_SCRIP.20150901.nc \
+ncks --rgr grd_ttl='T42 Gaussian grid' --rgr scrip=${DATA}/grids/t42_SCRIP.20150901.nc \
      --rgr latlon=64,128 --rgr lat_typ=gss --rgr lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
 
 # NASA Climate Modeling Grid (CMG) 3600x7200 (0.05x0.05 degree) Equi-Angular grid
 # Date-line west edge of first longitude, east edge of last longitude
-ncks --rgr grd_ttl='Equi-Angular grid 3600x7200 (NASA CMG)' --rgr grid=${DATA}/grids/3600x7200_SCRIP.20160301.nc \
+ncks --rgr grd_ttl='Equi-Angular grid 3600x7200 (NASA CMG)' --rgr scrip=${DATA}/grids/3600x7200_SCRIP.20160301.nc \
      --rgr latlon=3600,7200 --rgr lat_typ=uni --rgr lon_typ=180_wst ~zender/nco/data/in.nc ~/foo.nc
+
+# 1x1 degree Equi-Angular Regional grid over Greenland, centered longitudes
+ncks --rgr grd_ttl='Equi-Angular Greenland grid ' --rgr scrip=${HOME}/greenland_SCRIP.nc \
+     --rgr latlon=30,90#snwe=55.0,85.0,-90.0,0.0#lat_typ=uni#lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
 @end verbatim
 @end example
 
 @html
 <a name="nfr"></a> <!-- http://nco.sf.net/nco.html#nfr -->
 <a name="infer"></a> <!-- http://nco.sf.net/nco.html#infer -->
+<a name="ugrid"></a> <!-- http://nco.sf.net/nco.html#ugrid -->
 @end html
 @cindex infer
 @cindex @code{--rgr nfr}
+ at cindex @code{--rgr infer}
 Often researchers face the problem not of generating a known, idealized
 grid but of understanding an unknown, possibly irregular or curvilinear
 grid underlying a dataset produced elsewhere.
@@ -6472,7 +6518,7 @@ coordinates (and boundaries, if available), reformat that information
 as necessary to diagnose gridcell areas, and output the results in
 @acronym{SCRIP} format.
 As of @acronym{NCO} @w{version 4.5.3}, released in October, 2015,
-the @samp{--rgr nfr='y'} switch activates the machinery to infer the grid
+the @samp{--rgr infer} flag activates the machinery to infer the grid
 rather than construct the grid from other user-specified switches.
 To infer the grid properties, @acronym{NCO} interrogates
 @var{input-file} for horizontal coordinate information, such as the
@@ -6485,14 +6531,131 @@ comprises quadrilateral cells whose edges are midway between cell
 centers, for both rectilinear and curvilinear grids. 
 @example
 @verbatim
-# Infer the grid of the AIRS swath from input, write it to grd_airs.nc
-ncks --rgr nfr=y --rgr grid=${DATA}/sld/rgr/grd_airs.nc \
+# Infer AIRS swath grid from input, write it to grd_scrip.nc
+ncks --rgr infer --rgr scrip=${DATA}/sld/rgr/grd_scrip.nc \
      ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.nc ~/foo.nc
 @end verbatim
 @end example
-When inferring grids, the grid file (@file{grd_airs.nc}) is written,
-the input file (@file{AIRS...nc}) is read, and the output file
-(@file{foo.nc}) is overwritten (its contents are immaterial).
+When inferring grids, the grid file (@file{grd_scrip.nc}) is written
+in @acronym{SCRIP} format, the input file (@file{AIRS...nc}) is read,
+and the output file (@file{foo.nc}) is overwritten (its contents are
+immaterial). 
+
+ at cindex @acronym{UGRID}
+ at cindex @code{--rgr ugrid}
+As of @acronym{NCO} @w{version 4.6.6}, released in April, 2017,
+inferred 2D rectangular grids may also be written in
+ at acronym{UGRID}-format (defined
+ at uref{http://ugrid-conventions.github.io/ugrid-conventions, here}).
+Request a @acronym{UGRID} mesh with the option
+ at samp{--rgr ugrid=@var{fl_ugrid}}.
+Currently a @acronym{SCRIP} grid must be requested in order for the
+ at acronym{UGRID} option to work, e.g.,
+ at example
+ at verbatim
+ncks --rgr infer --rgr ugrid=${HOME}/grd_ugrid.nc \
+     --rgr scrip=${HOME}/grd_scrip.nc ~/skl_180x360.nc ~/foo.nc
+ at end verbatim
+ at end example
+
+The @acronym{SCRIP} gridfile and @acronym{UGRID} meshfile metadata
+produced for the equiangular @w{1-by-1 degree} global grid are:
+ at example
+ at verbatim
+zender at aerosol:~$ ncks --cdl -m ~/grd_scrip.nc 
+netcdf grd_scrip {
+  dimensions:
+    grid_corners = 4 ;
+    grid_rank = 2 ;
+    grid_size = 64800 ;
+
+  variables:
+    double grid_area(grid_size) ;
+      grid_area:units = "steradian" ;
+
+    double grid_center_lat(grid_size) ;
+      grid_center_lat:units = "degrees" ;
+
+    double grid_center_lon(grid_size) ;
+      grid_center_lon:units = "degrees" ;
+
+    double grid_corner_lat(grid_size,grid_corners) ;
+      grid_corner_lat:units = "degrees" ;
+
+    double grid_corner_lon(grid_size,grid_corners) ;
+      grid_corner_lon:units = "degrees" ;
+
+    int grid_dims(grid_rank) ;
+
+    int grid_imask(grid_size) ;
+} // group /
+
+zender at aerosol:~$ ncks --cdl -m ~/grd_ugrid.nc 
+netcdf grd_ugrid {
+  dimensions:
+    maxNodesPerFace = 4 ;
+    nEdges = 129240 ;
+    nFaces = 64800 ;
+    nNodes = 64442 ;
+    two = 2 ;
+
+  variables:
+    int mesh ;
+      mesh:cf_role = "mesh_topology" ;
+      mesh:standard_name = "mesh_topology" ;
+      mesh:long_name = "Topology data" ;
+      mesh:topology_dimension = 2 ;
+      mesh:node_coordinates = "mesh_node_x mesh_node_y" ;
+      mesh:face_node_connectivity = "mesh_face_nodes" ;
+      mesh:face_coordinates = "mesh_face_x mesh_face_y" ;
+      mesh:face_dimension = "nFaces" ;
+      mesh:edge_node_connectivity = "mesh_edge_nodes" ;
+      mesh:edge_coordinates = "mesh_edge_x mesh_edge_y" ;
+      mesh:edge_dimension = "nEdges" ;
+
+    int mesh_edge_nodes(nEdges,two) ;
+      mesh_edge_nodes:cf_role = "edge_node_connectivity" ;
+      mesh_edge_nodes:long_name = "Maps every edge to the two nodes that it connects" ;
+      mesh_edge_nodes:start_index = 0 ;
+
+    double mesh_edge_x(nEdges) ;
+      mesh_edge_x:standard_name = "longitude" ;
+      mesh_edge_x:long_name = "Characteristic longitude of 2D mesh face" ;
+      mesh_edge_x:units = "degrees_east" ;
+
+    double mesh_edge_y(nEdges) ;
+      mesh_edge_y:standard_name = "latitude" ;
+      mesh_edge_y:long_name = "Characteristic latitude of 2D mesh face" ;
+      mesh_edge_y:units = "degrees_north" ;
+
+    int mesh_face_nodes(nFaces,maxNodesPerFace) ;
+      mesh_face_nodes:cf_role = "face_node_connectivity" ;
+      mesh_face_nodes:long_name = "Maps every face to its corner nodes" ;
+      mesh_face_nodes:start_index = 0 ;
+      mesh_face_nodes:_FillValue = -2147483648 ;
+
+    double mesh_face_x(nFaces) ;
+      mesh_face_x:standard_name = "longitude" ;
+      mesh_face_x:long_name = "Characteristic longitude of 2D mesh edge" ;
+      mesh_face_x:units = "degrees_east" ;
+
+    double mesh_face_y(nFaces) ;
+      mesh_face_y:standard_name = "latitude" ;
+      mesh_face_y:long_name = "Characteristic latitude of 2D mesh edge" ;
+      mesh_face_y:units = "degrees_north" ;
+
+    double mesh_node_x(nNodes) ;
+      mesh_node_x:standard_name = "longitude" ;
+      mesh_node_x:long_name = "Longitude of mesh nodes" ;
+      mesh_node_x:units = "degrees_east" ;
+
+    double mesh_node_y(nNodes) ;
+      mesh_node_y:standard_name = "latitude" ;
+      mesh_node_y:long_name = "Latitude of mesh nodes" ;
+      mesh_node_y:units = "degrees_north" ;
+} // group /
+ at end verbatim
+ at end example
 
 @html
 <a name="skl"></a> <!-- http://nco.sf.net/nco.html#skl -->
@@ -6517,8 +6680,8 @@ datasets of the same geometry.
 @example
 @verbatim
 # Generate T42 Gaussian grid file t42_SCRIP.nc and skeleton file t42_skl.nc
-ncks --rgr skl=${DATA}/grids/t42_skl.nc --rgr grid=${DATA}/grids/t42_SCRIP.nc \
-     --rgr latlon=64,128 --rgr lat_typ=gss --rgr lon_typ=Grn_ctr \
+ncks --rgr skl=${DATA}/grids/t42_skl.nc --rgr scrip=${DATA}/grids/t42_SCRIP.nc \
+     --rgr latlon=64,128#lat_typ=gss#lon_typ=Grn_ctr \
      ~zender/nco/data/in.nc ~/foo.nc
 @end verbatim
 @end example
@@ -6632,6 +6795,7 @@ regionally refined grids.
 Support for irregular 2D- and regional grids (e.g., swath-like data) is
 planned.  
 
+ at unnumberedsubsec Renormalization
 @html
 <a name="rnr"></a> <!-- http://nco.sf.net/nco.html#rnr -->
 <a name="renormalize"></a> <!-- http://nco.sf.net/nco.html#renormalize -->
@@ -6669,6 +6833,16 @@ not conservative.
 Both algorithms produce identical answers when no missing data maps to 
 the destination gridcell.
 
+The renormalized algorithm is useful because it solves some problems,
+like producing physically unrealistic temperature values, at the expense
+of incurring others, like non-conservation.
+Many land and ocean modelers eschew unrealistic gridpoint values, and
+conservative regridding often produces ``weird'' values along coastlines  
+or missing data gaps where state variables are regridded to/from small
+fractions of a gridcell.
+Renormalization ensures the output values are physically consistent,
+although the integral of their value times area is not conservative.
+
 @cindex @var{wgt_thr}
 By default, @acronym{NCO} implements the ``conservative'' algorithm
 because it has useful properties, is simpler to understand, and requires
@@ -6711,9 +6885,9 @@ algorithm when performing conservative regridding, and the
 bilinear interpolation or nearest-neighbor.
 Another consideration is whether the fields being regridded are fluxes
 or state variables. 
-For example, temperature (unlike heat) or concentrations (amount per
+For example, temperature (unlike heat) and concentrations (amount per
 unit volume) are not physically conserved quantities under
-areal-regridding so it often makes sense to interpolate them in a
+areal-regridding so it often makes sense to interpolate them in a 
 non-conservative fashion, to preserve their fine-scale structure. 
 Few researchers can digest the unphysical values of temperature that the  
 ``conservative'' option will produce in regions rife with missing
@@ -6721,7 +6895,7 @@ values.
 A counter-example is fluxes, which should be physically conserved under 
 areal-regridding.
 One should consider both the type of field and its conservation
-properties before choosing a regridding strategy.
+properties when choosing a regridding strategy.
 
 @acronym{NCO} automatically annotates the output with relevant metadata
 such as coordinate bounds, axes, and vertices (@w{@`{a} la} @acronym{CF}). 
@@ -6865,8 +7039,7 @@ These annotations include
     Since @var{area_nm} is a property of the grid, it is read directly
     from the @var{map-file} rather than regridded itself. 
     To omit the area variable from the output file, set the
-    @var{no_area_out} variable to any value, e.g.,
-    @samp{--no_area_out='Y'}. 
+    @var{no_area_out} flag.
     The @code{--no_cll_msr} switch to @command{ncremap} and
     @command{ncclimo} does this automatically.
 @cindex @code{frc}
@@ -6889,6 +7062,38 @@ These annotations include
     boundaries.   
     Since @var{frc_nm} is a property of the grid, it is read directly
     from the @var{map-file} rather than regridded itself. 
+ at cindex @code{mask}
+ at cindex @samp{--no_msk}
+ at cindex @samp{--no_mask}
+ at cindex @samp{--msk_out}
+ at cindex @samp{--mask_out}
+ at cindex @samp{--rgr no_msk_out}
+ at cindex @samp{--rgr no_mask}
+ at cindex @samp{--rgr msk_nm=@var{msk_nm}}
+ at cindex infer
+ at cindex @var{msk_nm}
+ at item Gridcell Mask: @var{mask}
+    The variable @var{msk_nm} (which defaults to @code{mask}) can, if
+    present, be copied from the @var{map-file} to hold the gridcell mask 
+    on the destination grid in @var{output-file}.
+    To store the mask in a different variable, use the option
+    @samp{--rgr msk_nm=@var{msk_nm}}.
+    Since @var{msk_nm} is a property of the grid, it is read directly
+    from the @var{map-file} rather than regridded itself. 
+    To include the mask variable in the output file, set the
+    @var{msk_out} flag.
+    To omit the mask variable from the output file, set the
+    @var{no_msk_out} flag.
+    In grid inferral and map-generation modes, this option tells the
+    regridder to generate an integer mask map from the variable
+    @var{msk_nm}. 
+    The mask will be one (i.e., points at that location will contribute
+    to regridding weights) where @var{msk_nm} has valid values. 
+    The mask will be zero (i.e., points at that location will not
+    contribute to regridding weights) where @var{msk_nm} has a missing
+    value.
+    This feature is useful when creating weights between masked grids,
+    e.g., ocean-only points or land-only points.
 @cindex @code{gw}
 @cindex @samp{--rgr lat_weight=@var{lat_wgt_nm}}
 @cindex @var{lat_wgt_nm}
@@ -6949,8 +7154,8 @@ These annotations include
     the input is on a cap (aka @acronym{FV}) grid so that the result
     can be processed by @acronym{AMWG} diagnostics. 
     Turn-off archiving the staggered grid (i.e., @code{slat},
-    @code{slon}, and @code{w_stag}) by setting @var{no_stagger}
-    to any value, e.g., @samp{--no_stagger='Y'}.
+    @code{slon}, and @code{w_stag}) by setting the @var{no_stagger}
+    flag. 
     The @code{--no_stg_grd} flag in @command{ncremap} and
     @command{ncclimo} sets this @code{--no_stagger} flag.
 @end table
@@ -7865,7 +8070,7 @@ variables that contain at least one record dimension) must be chunked.
 Also variables that are compressed or use checksums must be chunked.
 Such variables cannot be unchunked.@*  
 Alternate invocation: @code{ncunchunk}@*
- at var{cnk_plc} key values: @samp{uck}, @samp{cnk_uck}, @samp{plc_uck}, @samp{unchunk}@*
+ at var{cnk_plc} key values: @samp{uck}, @samp{cnk_uck}, @samp{plc_uck}, @samp{none}, @samp{unchunk}@*
 Mnemonic: @emph{U}n at emph{C}hun at emph{K}@*
 @end table
 @noindent
@@ -11546,7 +11751,7 @@ in-depth examples of @command{ncap2} solutions to complex problems.
 @noindent
 SYNTAX
 @example
-ncap2 [-3] [-4] [-6] [-7] [@uref{http://nco.sf.net/nco.html#-A,,-A}] [-C] [-c] 
+ncap2 [-3] [-4] [-5] [-6] [-7] [@uref{http://nco.sf.net/nco.html#-A,,-A}] [-C] [-c] 
 [-D @var{dbg}] [-F] [-f] [--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}] [-L @var{dfl_lvl}] [-l @var{path}]
 [--no_tmp_fl] [-O] [-o @var{output-file}] [-p @var{path}] [-R] [-r] [--ram_all]
 [-s @var{algebra}] [-S @var{fl.nco}] [-t @var{thr_nbr}] [-v]
@@ -12858,6 +13063,9 @@ n2=-999,-999,11,11,11,11,11,11,999,-999;
 @end example
 
 @html
+<a name="mask_miss"></a> <!-- http://nco.sf.net/nco.html#mask_miss -->
+<a name="has_miss"></a> <!-- http://nco.sf.net/nco.html#has_miss -->
+<a name="delete_miss"></a> <!-- http://nco.sf.net/nco.html#delete_miss -->
 <a name="set_miss"></a> <!-- http://nco.sf.net/nco.html#set_miss -->
 <a name="get_miss"></a> <!-- http://nco.sf.net/nco.html#get_miss -->
 <a name="change_miss"></a> <!-- http://nco.sf.net/nco.html#change_miss -->
@@ -12904,6 +13112,11 @@ with a variable. The methods that ``manipulate'' will only succeed on variables
 @cindex @code{has_miss()}
 Returns 1 (True) if the variable has a missing value associated with it. 
 else returns 0 (False)
+ at item missing()
+ at cindex @code{missing(), mask_miss()}
+This function creates a True/False mask array of where the missing value is set.
+It is syntatically equivalent to ( var_in == var_in.get_miss()). except that cant do this
+unless you delete the missing value before-hand!!
 @end table
 
 @example
@@ -12929,6 +13142,12 @@ print(three_dmn_var_dbl at _FillValue);
 print("Number of missing values in three_dmn_var_dbl: ");
 print(mss_val_nbr,"%d");
 print(three_dmn_var_dbl);
+
+// find the total number of missing values along dims $lat and $lon
+ms_ttl=three_mn_var_dbl.missing().ttl($lat,$lon);
+print(ms_ttl); //  0, 0, 0, 8, 0, 0, 0, 1, 0, 2 ;
+
+
 @end verbatim
 @end example
 
@@ -13189,7 +13408,7 @@ Variables that are frequently accessed within @code{for} or @code{where}
 clauses provide the greatest opportunities for optimization. 
 To declare and define a @acronym{RAM} variable simply prefix the variable name
 with an asterisk (@code{*}) when the variable is declared/initialized.
-To delete a @acronym{RAM} variables (and recover their memory) use the
+To delete @acronym{RAM} variables (and recover their memory) use the
 @code{ram_delete()} method. 
 To write a @acronym{RAM} variable to disk (like a regular variable) use
 @code{ram_write()}. 
@@ -13441,8 +13660,6 @@ As of @acronym{NCO} version 4.6.3 (December, 2016), The user can specify the dir
 export NCO_PATH=":/home/henryb/bin/:/usr/local/scripts:/opt/SOURCES/nco/data:"
 @end example
 
-
-
 @html
 <a name="srt"></a> <!-- http://nco.sf.net/nco.html#srt -->
 <a name="sort"></a> <!-- http://nco.sf.net/nco.html#sort -->
@@ -14780,7 +14997,6 @@ double gsl_stats_wmean (double w[], size_t wstride, double data[], size_t stride
 double gsl_stats_quantile_from_sorted_data (double sorted_data[], size_t stride, size_t n, double f) ;
 @end example
 
-
 @noindent Equivalent ncap2 wrapper functions
 @example
 short gsl_stats_max (var_data, data_stride, n);
@@ -14791,9 +15007,6 @@ double gsl_stats_quantile_from_sorted_data (var_sorted_data, data_stride, n, var
 @end example
 
 @noindent @acronym{GSL} has no notion of missing values or dimensionality beyond one. If your data has missing values which you want ignored in the calculations then use the @command{ncap2} built in aggregate functions(@ref{Methods and functions}). The @acronym{GSL} functions operate on a vector of values created from the var_data/stride/n arguments. The ncap wrappers check that there is no bounding error with regard to the size of the data and the final value in the vector. 
-
-Some examples
-
 @example
 @verbatim
 a1[time]={1,2,3,4,5,6,7,8,9,10};
@@ -16236,8 +16449,10 @@ ncatted -a long_name,T,o,c,temperature in.nc
 @cindex @code{_FillValue}
 Many model and observational datasets use missing values that are not
 annotated in the standard manner.
-For example, the MPAS ocean and ice models use
- at math{-9.99999979021476795361e+33} as the missing value.
+For example, at the time (2015--2016) of this writing,
+the @acronym{MPAS} ocean and ice models use
+ at math{-9.99999979021476795361e+33} as the missing value, yet do not
+store a @code{_FillValue} attribute with any variables.
 To prevent arithmetic from treating these values as normal, designate
 this value as the @code{_FillValue} attribute:
 @example
@@ -16442,7 +16657,7 @@ omitted in batch scripts.
 @noindent
 SYNTAX
 @example 
-ncbo [-3] [-4] [-6] [-7] [-A] [-C] [-c]
+ncbo [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F] 
@@ -18240,7 +18455,7 @@ Moreover, the climatologies can be generated in parallel.
 @noindent
 SYNTAX
 @example
-ncecat [-3] [-4] [-6] [-7] [-A] [-C] [-c]
+ncecat [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
@@ -18304,7 +18519,7 @@ the record dimension size if the requested record hyperslab
 (@pxref{Hyperslabs}) resolves to the same size for all files. 
 @cindex @acronym{CMIP}
 This allows easier gluing/averaging of unequal length timeseries from 
-simulation ensembles (e.g., the @acronym{CMIP} rchive). 
+simulation ensembles (e.g., the @acronym{CMIP} archive). 
 
 @cindex fixed dimension
 @cindex fix record dimension
@@ -18508,7 +18723,7 @@ of changing variable dimensionality, including the record dimension.
 @noindent
 SYNTAX
 @example
-nces [-3] [-4] [-6] [-7] [-A] [-C] [-c]
+nces [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
@@ -18737,7 +18952,7 @@ member in the first file.
 @noindent
 SYNTAX
 @example
-ncflint [-3] [-4] [-6] [-7] [-A] [-C] [-c]
+ncflint [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]]
@@ -18791,7 +19006,7 @@ computed as @math{@var{wgt2} = 1 @minus{} @var{wgt1}}.
 Note that weights larger @w{than 1} are allowed. 
 Thus it is possible to specify @math{@var{wgt1} = 2} and
 @math{@var{wgt2} = -3}.
-One can use this functionality to multiply all the values in a given
+One can use this functionality to multiply all values in a given
 file by a constant.
 
 @cindex normalization
@@ -19060,6 +19275,9 @@ then writes in netCDF format to @var{output-file}, and
 optionally writes it in flat binary format to @file{fl_bnr}, and
 optionally prints it to screen.
 
+ at cindex @code{--trd}
+ at cindex @code{--traditional}
+ at cindex traditional
 @command{ncks} prints netCDF input data in @acronym{ASCII},
 @acronym{CDL}, @acronym{JSON}, or @acronym{NcML/XML} text formats to
 @code{stdout}, like (an extended version of) @command{ncdump}.
@@ -19071,14 +19289,16 @@ Option @samp{-s} (or long options @samp{--sng_fmt} and @samp{--string})
 permits the user to format data using C-style format strings, while
 option @samp{--cdl} outputs @acronym{CDL},
 option @samp{--jsn} (or @samp{json}) outputs @acronym{JSON},
+option @samp{--trd} (or @samp{traditional}) outputs ``traditional'' format,
 and option @samp{--xml} (or @samp{ncml}) outputs @acronym{NcML}. 
 @command{ncks} exposes many flexible controls over printed output,
 including @acronym{CDL}, @acronym{JSON}, and @acronym{NcML}.
 
 Options @samp{-a}, @samp{--cdl}, @samp{-F} , @samp{-H},
 @samp{--hdn}, @samp{--jsn}, @samp{-M}, @samp{-m}, @samp{-P}, @samp{-Q},
- at samp{-q}, @samp{-s}, @samp{-u}, @samp{-V}, and @samp{--xml} (and their
-long option counterparts) control the formatted appearance of the data.
+ at samp{-q}, @samp{-s}, @samp{--trd}, @samp{-u}, @samp{-V}, and
+ at samp{--xml} (and their long option counterparts) control the formatted
+appearance of the data. 
 
 @cindex global attributes
 @cindex attributes, global
@@ -19191,7 +19411,8 @@ variables.
 Specifying @code{-a} results in the variables being extracted, printed,
 and written to disk in the order in which they were saved in the input
 file.
-Thus @code{-a} retains the original ordering of the variables.
+Thus @code{-a} retains the original (often non-alphabetic) variable
+ordering.
 Also @samp{--abc} and @samp{--alphabetize}.
 
 @html
@@ -19343,12 +19564,14 @@ detailed descriptions of the meanings of these hidden attributes.
 <a name="cdl"></a> <!-- http://nco.sf.net/nco.html#cdl -->
 <a name="hdp"></a> <!-- http://nco.sf.net/nco.html#hdp -->
 <a name="hncgen"></a> <!-- http://nco.sf.net/nco.html#hncgen -->
+<a name="h4_ncgen"></a> <!-- http://nco.sf.net/nco.html#h4_ncgen -->
 <a name="ncgen-hdf"></a> <!-- http://nco.sf.net/nco.html#ncgen-hdf -->
 @end html
 @cindex @command{hdp}
 @cindex @command{ncgen}
 @cindex @command{ncgen-hdf}
 @cindex @command{hncgen}
+ at cindex @command{h4_ncgen}
 @cindex @command{ncdump}
 @cindex @code{--cdl}
 @cindex @acronym{CDL}
@@ -19390,20 +19613,22 @@ ncgen -k netCDF-4 -b -o ~/in.nc ~/in.cdl
 ncks -v one ~/in.nc
 @end example
 The @acronym{HDF} version of @command{ncgen}, often named
- at command{hncgen} or @command{ncgen-hdf}, converts netCDF3 @acronym{CDL}
+ at command{hncgen}, @command{h4_ncgen}, or @command{ncgen-hdf}, converts netCDF3 @acronym{CDL}
 into an @acronym{HDF} file:  
 @example
 /usr/hdf4/bin/ncgen -b -o ~/in.hdf ~/in.cdl # HDF ncgen (local builds)
 /usr/bin/hncgen     -b -o ~/in.hdf ~/in.cdl # Same as HDF ncgen (RPM packages?)
+/usr/bin/h4_ncgen   -b -o ~/in.hdf ~/in.cdl # Same as HDF ncgen (Anaconda)
 /usr/bin/ncgen-hdf  -b -o ~/in.hdf ~/in.cdl # Same as HDF ncgen (Debian packages?)
 hdp dumpsds ~/in.hdf                        # ncdump/h5dump-equivalent for HDF4
+h4_ncdump dumpsds ~/in.hdf                  # ncdump/h5dump-equivalent for HDF4
 @end example
 Note that @acronym{HDF4} does not support netCDF-style groups, so the
 above commands fail when the input file contains groups.
 Only netCDF4 and @acronym{HDF5} support groups.
 In our experience the @acronym{HDF} @command{ncgen} command, by whatever 
-name installed, is not robust and can fail on valid netCDF3
- at acronym{CDL}.  
+name installed, is not robust and fails on many valid netCDF3
+ at acronym{CDL} constructs.
 
 @html
 <a name="dmn_rec_mk"></a> <!-- http://nco.sf.net/nco.html#dmn_rec_mk -->
@@ -19588,7 +19813,7 @@ rather than as more complex objects:
 % ncks --jsn_fmt=0 -v att_var ~/nco/data/in_grp.nc
 ...
 "att_var": {
-  "dims": ["time"],
+  "shape": ["time"],
   "type": "float",
   "attributes": {
     "byte_att": [0, 1, 2, 127, -128, -127, -2, -1],
@@ -19640,7 +19865,7 @@ as in the @math{@var{lvl} = 0} above:
 % ncks --jsn_fmt=1 -v att_var ~/nco/data/in.nc
 ...
 "att_var": {
-  "dims": ["time"],
+  "shape": ["time"],
   "type": "float",
   "attributes": {
     "byte_att": { "type": "byte", "data": [0, 1, 2, 127, -128, -127, -2, -1]},
@@ -19679,7 +19904,7 @@ exact reproduction of the original dataset:
 % ncks --jsn_fmt=2 -v att_var ~/nco/data/in.nc
 ...
 "att_var": {
-  "dims": ["time"],
+  "shape": ["time"],
   "type": "float",
   "attributes": {
     "byte_att": { "type": "byte", "data": [0, 1, 2, 127, -128, -127, -2, -1]},
@@ -19917,6 +20142,28 @@ This demonstrates conclusively that I cannot keep a secret.
 Also @samp{--ssh} and @samp{--scr}. 
 
 @html
+<a name="trd"></a> <!-- http://nco.sf.net/nco.html#trd -->
+<a name="traditional"></a> <!-- http://nco.sf.net/nco.html#traditional -->
+ at end html
+ at cindex @code{--trd}
+ at cindex @code{--traditional}
+ at item --trd, --traditional
+From 1995--2017 @command{ncks} dumped the @acronym{ASCII} text
+representation of netCDF files in what we now call ``traditional''
+mode. 
+Much of this manual contains output printed in traditional mode,
+which places one value per line, with complete dimensional
+information.
+Tradiational-mode metadata output includes lower-level information,
+such as @acronym{RAM} usage and internal variable IDs, than
+ at acronym{CDL}.  
+However, @acronym{CDL} is more useful than traditional mode for most
+users.  
+In summer 2017 @acronym{CDL} will become the default printing mode.
+Traditional mode will still be accessible using the @samp{--trd}
+option. 
+
+ at html
 <a name="units"></a> <!-- http://nco.sf.net/nco.html#units -->
 <a name="u"></a> <!-- http://nco.sf.net/nco.html#u -->
 @end html
@@ -20060,6 +20307,7 @@ include an NcML formatting characters (e.g., commas, angles, quotes).
 <a name="nclist"></a> <!-- http://nco.sf.net/nco.html#nclist -->
 <a name="ncdmnlist"></a> <!-- http://nco.sf.net/nco.html#ncdmnlist -->
 <a name="ncdmnsz"></a> <!-- http://nco.sf.net/nco.html#ncdmnsz -->
+<a name="ncgrplist"></a> <!-- http://nco.sf.net/nco.html#ncgrplist -->
 <a name="ncrecsz"></a> <!-- http://nco.sf.net/nco.html#ncrecsz -->
 <a name="ncmax"></a> <!-- http://nco.sf.net/nco.html#ncmax -->
 <a name="ncmdn"></a> <!-- http://nco.sf.net/nco.html#ncmdn -->
@@ -20082,6 +20330,7 @@ include an NcML formatting characters (e.g., commas, angles, quotes).
 @cindex @command{ncavg}
 @cindex @command{ncdmnlist}
 @cindex @command{ncdmnsz}
+ at cindex @command{ncgrplist}
 @cindex @command{nclist}
 @cindex @command{ncmax}
 @cindex @command{ncmdn}
@@ -20190,6 +20439,8 @@ function ncavg { ncap2 -O -C -v -s "foo=${1}.avg();print(foo)" ${2} ~/foo.nc | c
 ncdmnlist { ncks --cdl -m ${1} | cut -d ':' -f 1 | cut -d '=' -s -f 1 ; }
 # ncdmnsz $dmn_nm $fl_nm : What is dimension size?
 function ncdmnsz { ncks -m -M ${2} | grep -E -i ": ${1}, size =" | cut -f 7 -d ' ' | uniq ; }
+# ncgrplist $fl_nm : What groups are in file?
+function ncgrplist { ncks --cdl -m ${1} | grep 'group:' | cut -d ':' -f 2 | cut -d ' ' -f 2 | sort ; }
 # nclist $fl_nm : What variables are in file?
 function nclist { ncks -m ${1} | grep -E ': type' | cut -f 1 -d ' ' | sed 's/://' | sort ; }
 # ncmax $var_nm $fl_nm : What is maximum of variable?
@@ -20507,7 +20758,7 @@ For more details @xref{Wrapped Coordinates}.
 @noindent
 SYNTAX
 @example
-ncpdq [-3] [-4] [-6] [-7] [-A] [-a [-]@var{dim}[, at dots{}]] [-C] [-c]
+ncpdq [-3] [-4] [-5] [-6] [-7] [-A] [-a [-]@var{dim}[, at dots{}]] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]]
@@ -21106,7 +21357,7 @@ changing variable dimensionality, including the record dimension.
 @noindent
 SYNTAX
 @example
-ncra [-3] [-4] [-6] [-7] [-A] [-C] [-c] [--cb]
+ncra [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c] [--cb]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}][,[@var{subcycle}]]]] [-F]
@@ -21355,7 +21606,7 @@ The last example
 @noindent
 SYNTAX
 @example
-ncrcat [-3] [-4] [-6] [-7] [-A] [-C] [-c]
+ncrcat [-3] [-4] [-5] [-6] [-7] [-A] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}][,[@var{subcycle}]]]] [-F]
@@ -21491,14 +21742,16 @@ ncrcat -d time,6.,54. ??.nc 8506_8906.nc
 @noindent
 SYNTAX
 @example
-ncremap [-a @var{alg_typ}] [-D @var{dbg_lvl}] [-d @var{dst_fl}] [-E @var{esmf_opt}]
+ncremap [-a @var{alg_typ}] [-D @var{dbg_lvl}] [-d @var{dst_fl}]
 [-G @var{grd_sng}] [-g @var{grd_dst}] [-I @var{drc_in}] [-i @var{input-file}] [-j @var{job_nbr}]
-[-M] [-m @var{map_fl}] [-n @var{nco_opt}] [--no_cll_msr ] [--no_frm_trm] [--no_stg_grd]
+[-M] [-m @var{map_fl}] [--msk_dst=@var{msk_dst}] [--msk_out=@var{msk_out}] [--msk_src=@var{msk_src}]
+[-n @var{nco_opt}] [--no_cll_msr ] [--no_frm_trm] [--no_stg_grd]
 [-O @var{drc_out}] [-o @var{output-file}]
-[-P @var{pdq_typ}] [-p @var{par_typ}] [-R @var{rgr_opt}] [-s @var{grd_src}] [--stdin]
-[-T @var{tempest_opt}] [-t @var{thr_nbr}] [-U @var{drc_tmp}] [-u @var{unq_sfx}] 
+[-P @var{prc_typ}] [-p @var{par_typ}] [-R @var{rgr_opt}] [--rgn_dst] [--rgn_src]
+[-s @var{grd_src}] [--sgs_frc=@var{sgs_frc}] [--sgs_msk=@var{sgs_msk}] [--sgs_nrm=@var{sgs_nrm}]
+[--stdin] [-T @var{drc_tmp}] [-t @var{thr_nbr}] [-U] [-u @var{unq_sfx}] [--ugrid=@var{ugrid-file}]
 [-V @var{rgr_var}] [-v @var{var_lst}[, at dots{}]] [--version] [--vrb=@var{vrb_lvl}] 
-[-w @var{wgt_gnr}] [-x @var{xtn_lst}[, at dots{}]] 
+[-W @var{wgt_opt}] [-w @var{wgt_cmd}] [-x @var{xtn_lst}[, at dots{}]] 
 @end example
 
 @noindent
@@ -21605,13 +21858,13 @@ Features common to many operators are described in
 @cindex @code{--regrid_algorithm}
 @item -a @var{alg_typ} (@code{--alg_typ}, @code{--algorithm}, @code{--regrid_algorithm})
 Specifies the interpolation algorithm for weight-generation for use by
- at command{ESMF_RegridWeightGen} (@acronym{ERWG}).
+ at command{ESMF_RegridWeightGen} (@acronym{ERWG}) and/or TempestRemap.
 @command{ncremap} unbundles this algorithm choice from the rest of
-the @acronym{ERWG} invocation syntax because interpolation algorithms
-are more frequently change by users than other @acronym{ERWG} options
+the weight-generator invocation syntax because user more frequently
+change interpolation algorithms than other options
 (that can be changed with @samp{-E @var{esmf_opt}}).
-The @var{alg_typ} argument must be one of @acronym{ERWG}'s five
-interpolation algorithms: 
+The @var{alg_typ} argument must be @code{tempest} or one of
+ at acronym{ERWG}'s five interpolation algorithms:
 @code{bilinear} (default, acceptable abbreviation is @code{bln}), 
 @code{conserve} (or @code{conservative} or @code{cns}), 
 @code{nearestdtos} (or @code{nds} or @code{dtos}), 
@@ -21619,8 +21872,8 @@ interpolation algorithms:
 and @code{patch} (or @code{pch} or @code{ptc}). 
 See @acronym{ERWG} documentation
 @uref{http://www.earthsystemmodeling.org/esmf_releases/public/ESMF_6_3_0rp1/ESMF_refdoc/node3.html#SECTION03020000000000000000, here}
-for detailed descriptions of each algorithm. 
-This option currently has no effect on TempestRemap weight-generation. 
+for detailed descriptions of @acronym{ERWG} algorithms.
+Specifying @code{tempest} invokes TempestRemap weight-generation.
 
 @html
 <a name="dbg_lvl"></a> <!-- http://nco.sf.net/nco.html#dbg_lvl -->
@@ -21669,22 +21922,6 @@ be interpolated or guessed-at.
 @var{dst_fl} is not modified, and may have read-only permissions.
 
 @html
-<a name="esmf_opt"></a> <!-- http://nco.sf.net/nco.html#esmf_opt -->
- at end html
- at cindex @code{-E @var{esmf_opt}}
- at cindex @var{esmf_opt}
- at cindex @code{--esmf_opt}
- at cindex @code{--esmf}
- at cindex @code{--esmf_options}
- at item -E @var{esmf_opt} (@code{--esmf_opt}, @code{--esmf}, @code{--esmf_options})
- at command{ncremap} passes @var{esmf_opt} directly through to
- at acronym{ERWG}. 
-The user-specified contents of @var{esmf_opt} supercede its default
-contents (@samp{--ignore_unmapped}).
-Sometimes users may wish @acronym{ERWG} to assume regional grids,
-in which case @var{esmf_opt} could be @samp{-r --ignore_upmapped}.
-
- at html
 <a name="grd_dst"></a> <!-- http://nco.sf.net/nco.html#grd_dst -->
 @end html
 @cindex @code{-g @var{grd_dst}}
@@ -21898,6 +22135,100 @@ batches of data on different grids (e.g., swath-like data), and slow,
 tedious, and unnecessary when batch processing data on the same grids.
 
 @html
+<a name="msk_dst"></a> <!-- http://nco.sf.net/nco.html#msk_dst -->
+ at end html
+ at cindex @code{--msk_dst=@var{msk_dst}}
+ at cindex @var{msk_dst}
+ at cindex @code{--msk_dst}
+ at cindex @code{--dst_msk}
+ at cindex @code{--mask_destination}
+ at cindex @code{--mask_dst}
+ at item --msk_dst=@var{msk_dst} (@code{--msk_dst}, @code{--dst_msk}, @code{--mask_destination}, @code{--mask_dst})
+Specifies a template variable to use for the integer mask of the
+destination grid when inferring grid files and/or creating
+map-files (i.e., generating weights). 
+Any variable on the same horizontal grid as a data file can serve as a
+mask template for that grid. 
+The mask will be one (i.e., gridcells will participate in regridding) 
+where @var{msk_dst} has valid values in the data file from which
+ at acronym{NCO} infers the destination grid.   
+The mask will be zero (i.e., gridcells will not participate in
+regridding) where @var{msk_nm} has a missing value.  
+A typical example of this option would be to use Sea-surface Temperature
+(SST) as a template variable for an ocean mask because SST is often
+defined only over ocean, and missing values might denote locations to
+which regridded quantities should never be placed.
+ at var{msk_dst}, @var{msk_out}, and @var{msk_src} are related yet distinct:
+ at var{msk_dst} is the mask template variable in the destination file (whose grid will be inferred),
+ at var{msk_out} is the name to give the destination mask in any regridded file, and
+ at var{msk_src} is the mask template variable in the source file (whose grid will be inferred).
+
+ at html
+<a name="msk_out"></a> <!-- http://nco.sf.net/nco.html#msk_out -->
+ at end html
+ at cindex @code{--msk_out=@var{msk_out}}
+ at cindex @var{msk_out}
+ at cindex @code{--msk_out}
+ at cindex @code{--out_msk}
+ at cindex @code{--mask_destination}
+ at cindex @code{--mask_out}
+ at item --msk_out=@var{msk_out} (@code{--msk_out}, @code{--out_msk}, @code{--mask_destination}, @code{--mask_out})
+Use of this option tells @command{ncremap} to include a variable named 
+ at var{msk_out} in any regridded file.
+The variable @var{msk_out} will contain the integer-valued
+regridding mask on the destination grid.
+The mask will be one (i.e., fields may have valid values in this
+gridcell) or zero (i.e., fields will have missing values in this
+gridcell). 
+By default, @command{ncremap} does not output the destination mask to
+the regridded file.
+This option changes that default behavior and causes @command{ncremap}
+to ingest the default destination mask variable contained in the
+ at var{map-file}. 
+ at acronym{ERWG} generates @acronym{SCRIP}-format map-files that contain
+the destination mask in the variable named @code{mask_b}.
+ at acronym{SCRIP} generates map-files that contain the destination mask in
+the variable named @code{dst_grid_imask}. 
+The @code{msk_out} option works with map-files that adhere to either of
+these conventions. 
+Tempest generates map-files that do not typically contain the
+destination mask, and so the @code{msk_out} option has no effect on
+files that Tempest regrids.
+ at var{msk_dst}, @var{msk_out}, and @var{msk_src} are related yet distinct:
+ at var{msk_dst} is the mask template variable in the destination file (whose grid will be inferred),
+ at var{msk_out} is the name to give the destination mask in any regridded file, and
+ at var{msk_src} is the mask template variable in the source file (whose grid will be inferred).
+
+ at html
+<a name="msk_src"></a> <!-- http://nco.sf.net/nco.html#msk_src -->
+ at end html
+ at cindex @code{--msk_src=@var{msk_src}}
+ at cindex @var{msk_src}
+ at cindex @code{--msk_src}
+ at cindex @code{--src_msk}
+ at cindex @code{--mask_source}
+ at cindex @code{--mask_src}
+ at item --msk_src=@var{msk_src} (@code{--msk_src}, @code{--src_msk}, @code{--mask_source}, @code{--mask_src})
+Specifies a template variable to use for the integer mask of the
+source grid when inferring grid files and/or creating
+map-files (i.e., generating weights). 
+Any variable on the same horizontal grid as a data file can serve as a
+mask template for that grid. 
+The mask will be one (i.e., gridcells will participate in regridding) 
+where @var{msk_src} has valid values in the data file from which
+ at acronym{NCO} infers the source grid.   
+The mask will be zero (i.e., gridcells will not participate in
+regridding) where @var{msk_nm} has a missing value.  
+A typical example of this option would be to use Sea-surface Temperature
+(SST) as a template variable for an ocean mask because SST is often
+defined only over ocean, and missing values might denote locations from
+which regridded quantities should emanate.
+ at var{msk_dst}, @var{msk_out}, and @var{msk_src} are related yet distinct:
+ at var{msk_dst} is the mask template variable in the destination file (whose grid will be inferred),
+ at var{msk_out} is the name to give the destination mask in any regridded file, and
+ at var{msk_src} is the mask template variable in the source file (whose grid will be inferred).
+
+ at html
 <a name="nco_opt"></a> <!-- http://nco.sf.net/nco.html#nco_opt -->
 @end html
 @cindex @code{-n @var{nco_opt}}
@@ -21984,29 +22315,170 @@ using @samp{-I @var{in_drc}} or standard input) generates an error
 (output files will be named the same as input files).
 
 @html
+<a name="prc_typ"></a> <!-- http://nco.sf.net/nco.html#prc_typ -->
 <a name="pdq_typ"></a> <!-- http://nco.sf.net/nco.html#pdq_typ -->
- at end html
- at cindex @code{-P @var{pdq_typ}}
- at cindex @var{pdq_typ}
+<a name="sgs"></a> <!-- http://nco.sf.net/nco.html#sgs -->
+<a name="alm"></a> <!-- http://nco.sf.net/nco.html#alm -->
+<a name="sgs_frc"></a> <!-- http://nco.sf.net/nco.html#sgs_frc -->
+<a name="sgs_msk"></a> <!-- http://nco.sf.net/nco.html#sgs_msk -->
+<a name="sub-gridscale"></a> <!-- http://nco.sf.net/nco.html#sub-gridscale -->
+<a name="sub-grid"></a> <!-- http://nco.sf.net/nco.html#sub-grid -->
+<a name="subgrid"></a> <!-- http://nco.sf.net/nco.html#subgrid -->
+ at end html
+ at cindex @code{-P @var{prc_typ}}
+ at cindex @var{prc_typ}
+ at cindex @code{--prc_typ}
 @cindex @code{--pdq_typ}
 @cindex @code{--prm_typ}
- at cindex @code{--permutation}
- at cindex @code{--permute}
- at item -P @var{pdq_typ} (@code{--pdq_typ}, @code{--prm_typ}, @code{--permutation}, @code{--permute})
+ at cindex @code{--procedure}
+ at item -P @var{prc_typ} (@code{--prc_typ}, @code{--pdq_typ}, @code{--prm_typ}, @code{--procedure})
 Specifies the permutation mode desired.
-As of January~15, 2016, one can tell @command{ncremap} to automatically
-tagpermute the dimensions in the data file prior to regridding for a
-limited (though growning) number of data-file types that suffer from
-the @command{ncremap} limitation concerning dimension ordering.
-Valid types are @samp{airs} (for @acronym{NASA AIRS} satellite data), 
- at samp{mpas} (for @acronym{MPAS} ocean/ice model data), and @samp{nil} (for none).
-The default @var{pdq_typ} is @samp{nil}, which means @command{ncremap} 
-does not permute the dimension order prior to regridding.
-In @acronym{AIRS}-mode, @command{ncremap} calls @command{ncpdq} to
-permute dimensions from their order in the input file to this order:
+As of January~15, 2016, one can tell @command{ncremap} to invoke special
+processing procedures for different types of input data.
+For instance, to automatically permute the dimensions in the data file
+prior to regridding for a limited (though growing) number of data-file
+types that encounter the @command{ncremap} limitation concerning
+dimension ordering. 
+Valid procedure types are @samp{airs} for @acronym{NASA AIRS} satellite data, 
+ at samp{alm} or @samp{clm} @acronym{DOE ALM} and @acronym{NCAR CLM} model data,
+ at samp{cice} for @acronym{CICE} ice model data on 2D grids,
+ at samp{mpas} for @acronym{MPAS} ocean/ice model data on unstructured grids,
+ at samp{mod04} for @w{Level 2} @acronym{MODIS} @acronym{MOD04} product,
+ at samp{sgs} for datasets containing sub-gridscale (@acronym{SGS}) data
+(such as @acronym{ALM/CLM} land model data or @acronym{CICE} sea-ice
+model data), 
+and @samp{nil} (for none).
+The default @var{prc_typ} is @samp{nil}, which means @command{ncremap} 
+does not perform any special procedure prior to regridding.
+The @acronym{AIRS} procedure calls @command{ncpdq} to permute dimensions
+from their order in the input file to this order: 
 @code{StdPressureLev,GeoTrack,GeoXTrack}.
-In @acronym{MPAS}-mode the order is 
- at code{Time,nVertLevels,maxEdges,MaxEdges2,nEdges,nCells}. 
+The @acronym{ALM}, @acronym{CLM}, and @acronym{CICE} procedures set 
+idiosyncratic model values and then invoke the Sub-gridscale
+(@acronym{SGS}) procedure (see below). 
+The @acronym{MOD04} procedure unpacks input data.
+The @acronym{MPAS} procedure permutes input data into this order:
+ at code{Time,nVertLevels,maxEdges,MaxEdges2,nEdges,nCells}, and invokes
+renormalization.  
+
+ at cindex Sub-gridscale (@acronym{SGS}) data
+ at cindex @acronym{SGS}-mode
+ at cindex @var{sgs_frc}
+ at cindex @var{sgs_msk}
+ at cindex @var{sgs_nrm}
+ at cindex @code{--sgs_frc @var{sgs_frc}}
+ at cindex @code{--sgs_msk @var{sgs_msk}}
+ at cindex @code{--sgs_nrm @var{sgs_nrm}}
+In sub-grid mode, @command{ncremap} performs substantial pre- and
+post-processing to conserve fields that represent fractional parts
+of a gridcell.
+The sub-gridscale (@acronym{SGS}) fraction usually changes spatially
+with the geographic distribution of ice, ocean, vegetation, and so on.
+Spatial fields output by most geophysical models are intensive, 
+and so by default the regridder attempts to conserve the integral of the
+area times the field value such that the integral is equal on source and
+destination grids. 
+However some models (like @acronym{ALM}, @acronym{CLM}, and
+ at acronym{CICE}) output gridcell values intended to apply to only a
+fraction @var{sgs_frc} (which stands for ``sub-gridscale fraction'') of
+the gridcell. 
+For concreteness consider a sub-grid field that represents the land
+fraction.
+Land fraction is less than one in gridcells that resolve coastlines or 
+islands.  
+ at acronym{ALM} and @acronym{CLM}) happily output temperature values
+valid only for a small (i.e., @math{@var{sgs_frc} << 1}) island within
+the larger gridcell.
+Regridding weights that assume @math{@var{sgs_frc} = 1} everywhere would 
+create subtle, difficult-to-notice, biases in coastal regions that,
+on Earth, would alter global mean values (e.g., of temperature, fluxes)
+by up to a few percent at common grid resolutions.
+Though models like @acronym{ALM} and @acronym{CLM} may run on the same
+horizontal grid as the overlying atmosphere, they cannot be regridded
+with the atmosphere's grid weights that account for the whole gridcell
+instead of the sub-grid land fraction. 
+
+To correctly regrid sub-grid data, specify the @samp{-P sgs} option, 
+and names of the @var{sgs_frc} and @var{sgs_msk} variables (if they
+differ from their respective defaults @code{landfrac} and
+ at code{landmask}). 
+Trouble will ensue @var{sgs_frc} is a percentage, or an absolute area. 
+In that case provide the normalization factor @var{sgs_nrm} by which
+ at var{sgs_frc} must be @emph{divided} (not multiplied) to obtain a true
+fraction (between zero and one).
+Datasets (such as those from @acronym{CICE}) that store @var{sgs_frc} 
+in percent should specify the option
+ at samp{--sgs_nrm=100} to instruct @command{ncremap} to normalize the
+sub-grid area appropriately before regridding.
+ at command{ncremap} will re-derive @var{sgs_msk} based on the regridded 
+values of @var{sgs_frc}: @math{@var{sgs_msk} = 1} is assigned to
+destination gridcells with @math{@var{sgs_frc} > 0.0}, and all others
+ at math{@var{sgs_msk} = 0}.
+
+ at command{ncremap} supports convenience options to recover most of the  
+original, model-specific idiosyncracies in raw @acronym{ALM/CLM} and
+ at acronym{CICE} datasets.
+ at example
+# Invocations for ALM/CLM data
+ncremap -P alm -i in.nc -s src_grd.nc -d dst_data.nc -o out.nc
+ncremap -P sgs -i in.nc -s src_grd.nc -d dst_data.nc -o out.nc
+ncremap -P sgs --sgs_frc=landfrac --sgs_msk=landmask ... 
+
+# Equivalent invocations for CICE data
+ncremap -P cice -i in.nc -s src_grd.nc -d dst_data.nc -o out.nc
+ncremap -P sgs --sgs_frc=aice --sgs_msk=tmask --sgs_nrm=100 ... 
+ at end example
+
+Sub-gridscale handling currently requires the user to specify the
+source @acronym{SCRIP} grid-file. 
+Moreover, this source grid-file must include the (normally
+non-essential) @code{grid_area} field.
+It is infeasible to permit source-grid inferral, because
+weight-generators assume great circle arcs but 2D-grids usually have
+small-circles in latitude, and this can lead to area mis-matches.
+However, sub-gridscale handling will infer destination grids from
+2D-data files, if requested: 
+ at example
+ncremap -P sgs -i in.nc -s src_grd.nc -g dst_grd.nc  -o out.nc
+ncremap -P sgs -i in.nc -s src_grd.nc -d dst_data.nc -o out.nc
+ at end example
+
+The method used to regrid sub-grid values is somewhat involved.
+First, if necessary, we normalize the sub-grid variable to be a 
+fraction between zero and one.
+We then regrid the sub-grid fraction, and multiply the destination area  
+by the regridded fraction. 
+Then we duplicate the source and destination grids, to modify the
+copies without tampering with the originals.
+We multiply the grid-cell area in the duplicated source grid by  
+the sub-grid fraction in the input data file. 
+We multiply the grid-cell area in the duplicated destination
+grid by regridded sub-grid fraction.
+We then construct a map-file that conserves a field weighted by
+the altered source and destination gridcell areas.
+ at command{ncremap} then applies these regridding weights to all
+input fields to construct the regridded fields.
+We then overwrite the area, sub-grid fraction, and sub-grid
+mask with the correct values from the first step, the conservatively
+regridded sub-grid fraction.
+For generic data this is the final step.
+The @code{area} and @var{sgs_frc} fields in the regridded file will be
+in units of sterradians and fraction, respectively.
+However, @command{ncremap} offers custom options to reproduce the
+idiosyncratic data and metadata format of two particular models,
+ at acronym{ALM} and @acronym{CICE}.
+When invoked with @samp{-P alm} (or @samp{-P clm}), the final step
+converts the output @code{area} from sterradians to square kilometers. 
+When invoked with @samp{-P cice}, the final step converts the output
+ at code{area} from sterradians to square meters, and the output
+ at code{sgs_frc} from a fraction to a percent.
+
+During development of this procedure, we learned that regridding
+sub-grid values correctly versus incorrectly (i.e., with and 
+without @samp{-P sgs}, respectively) alters global-mean answers
+for land-based quantities by @w{about 1%} for typical grid resolutions  
+on Earth.
+This is small enough to be easily overlooked.
 
 @html
 <a name="par_typ"></a> <!-- http://nco.sf.net/nco.html#par_typ -->
@@ -22018,7 +22490,7 @@ In @acronym{MPAS}-mode the order is
 @cindex @code{--parallel_type}
 @cindex @code{--parallel_mode}
 @cindex @code{--parallel}
- at item -p @var{par_typ} (@code{--}, @code{--}, @code{--}, @code{--})
+ at item -p @var{par_typ} (@code{--par_typ}, @code{--par_md}, @code{--parallel_type}, @code{--parallel_mode}, @code{--parallel})
 Specifies the parallelism mode desired.
 Parallelism accelerates throughput when regridding multiple files in one  
 @command{ncremap} invocation.
@@ -22051,11 +22523,68 @@ when all source files share the same grid.
 @command{ncremap} passes @var{rgr_opt} directly through to the
 regridder.  
 This is useful to customize output grids and metadata.
+One use is to rename output variables and dimensions from the defaults
+provided by or derived from input data.
 The default value is @samp{--rgr lat_nm_out=lat --rgr lon_nm_out=lon},
 i.e., by default @command{ncremap} always names latitude and longitude
 ``lat'' and ``lon'', respectively, regardless of their input names.
 
 @html
+<a name="rnr_thr"></a> <!-- http://nco.sf.net/nco.html#rnr_thr -->
+ at end html
+ at cindex @code{-r @var{rnr_thr}}
+ at cindex @var{rnr_thr}
+ at cindex @code{--rnr_thr}
+ at cindex @code{--thr_rnr}
+ at cindex @code{--renormalize_threshold}
+ at item -r @var{rnr_thr} (@code{--rnr_thr}, @code{--thr_rnr}, @code{--renormalize_threshold})
+Use this option to request renormalization (see @ref{Regridding}) 
+and to specify the weight threshold.
+For example, @samp{-r 0.9} tells the regridder to renormalize
+with a weight threshold of 90%, so that all destination gridcells
+with at least 90% of their area contributed by valid source gridcells
+will be contain valid (not missing) values that are the area-weighted
+mean of the valid source values.
+This option was introduced because renormalization is a frequently used
+feature which previously could only be invoked by using the uglier and
+more generic @code{-R @var{rgr_opt}} option defined above.
+Specifying @samp{-r 0.9} or @samp{--rnr_thr=0.9} is equivalent to
+specifying @samp{-R '--rgr rnr=0.9'}.
+
+ at html
+<a name="rgn_dst"></a> <!-- http://nco.sf.net/nco.html#rgn_dst -->
+<a name="rgn_src"></a> <!-- http://nco.sf.net/nco.html#rgn_src -->
+ at end html
+ at cindex @var{rgn_dst}
+ at cindex @code{--rgn_dst}
+ at cindex @code{--dst_rgn}
+ at cindex @code{--regional_destination}
+ at item --rgn_dst (@code{--rgn_dst}, @code{--dst_rgn}, @code{--regional_destination})
+ at cindex @var{rgn_src}
+ at cindex @code{--rgn_src}
+ at cindex @code{--src_rgn}
+ at cindex @code{--regional_source}
+ at item --rgn_src (@code{--rgn_src}, @code{--src_rgn}, @code{--regional_source})
+Use these flags which take no argument to indicate that a user-supplied 
+(i.e., with @samp{-s @var{grd_src}} or @samp{-g @var{grd_dst}})
+grid is regional.
+The @acronym{ERWG} weight-generator needs to be told whether the source,
+destination, or both grids are regional or global in order to optimize
+weight production.
+ at command{ncremap} supplies this information to the regridder for grids
+it automatically infers from data files. 
+However, the regridder needs to be explicitly told if user-supplied
+(i.e., with either @samp{-s @var{grd_src}} or @samp{-g @var{grd_dst}})
+grids are regional because the regridder does not examine supplied grids 
+before calling @acronym{ERWG} which assumes, unless told otherwise,
+that grids are global in extent.
+The sole effect of these flags is to add the arguments
+ at samp{--src_regional} and/or @samp{--dst_regional} to @acronym{ERWG} 
+calls.
+Supplying regional grids without invoking these flags may dramatically 
+increase the map-file size and time to compute.
+
+ at html
 <a name="grd_src"></a> <!-- http://nco.sf.net/nco.html#grd_src -->
 @end html
 @cindex @code{-s @var{grd_src}}
@@ -22095,41 +22624,18 @@ Thus @acronym{NCO} will call @acronym{ERWG} only once, and will use that
 @command{GenerateOfflineMap} (not to @command{GenerateOverlapMesh}).
 The user-specified contents of @var{tempest_opt} supercede its default
 contents, which are currently empty.
-For example, to cause @command{GenerateOfflineMap} to use a
- at code{_FillValue} of @math{-1}, pass 
- at samp{-T "--fillvalue -1.0"} to @command{ncremap}.
-Other common options include enforcing monotonicity (which is not the
-default in TempestRemap) constraints. 
-To guarantee monotonicity in regridding from Finite Volume @acronym{FV} 
-to @acronym{FV} maps (e.g., @acronym{MPAS}-to-rectangular), pass 
- at samp{-T "-in_np 1"} to @command{ncremap}.
-To guarantee monotonicity in regridding from Finite Element @acronym{FE} 
-to @acronym{FV} maps, pass @samp{-T "--mono"}.
-
- at html
-<a name="thr_nbr"></a> <!-- http://nco.sf.net/nco.html#thr_nbr -->
- at end html
- at cindex @code{-t @var{thr_nbr}}
- at cindex @var{thr_nbr}
- at cindex @code{--thr_nbr}
- at cindex @code{--thread_number}
- at cindex @code{--threads}
- at item -t @var{thr_nbr} (@code{--thr_nbr}, @code{--thread_number}, @code{--threads})
-Specifies the number of threads used per regridding process
-(@pxref{OpenMP Threading}).
-The @acronym{NCO} regridder scales well up to 8--16 threads.
 
 @html
 <a name="tmp_drc"></a> <!-- http://nco.sf.net/nco.html#tmp_drc -->
 @end html
- at cindex @code{-U @var{tmp_drc}}
+ at cindex @code{-T @var{tmp_drc}}
 @cindex @var{tmp_drc}
 @cindex @code{--tmp_drc}
 @cindex @code{--drc_tmp}
 @cindex @code{--tmp_dir}
 @cindex @code{--dir_tmp}
 @cindex @code{--tmp}
- at item -U @var{tmp_drc} (@code{--tmp_drc}, @code{--drc_tmp}, @code{--tmp_dir}, @code{--dir_tmp}, @code{--tmp_drc})
+ at item -T @var{tmp_drc} (@code{--tmp_drc}, @code{--drc_tmp}, @code{--tmp_dir}, @code{--dir_tmp}, @code{--tmp_drc})
 Specifies the directory in which to place intermediate output files.
 Depending on how it is invoked, @command{ncremap} may generate
 a few or many intermediate files (grids and maps) that it will, by
@@ -22141,6 +22647,19 @@ the value of @code{$TMPDIR}, if any, or else @file{/tmp} if it exists,
 or else it uses the current working director (@code{$PWD}).
 
 @html
+<a name="thr_nbr"></a> <!-- http://nco.sf.net/nco.html#thr_nbr -->
+ at end html
+ at cindex @code{-t @var{thr_nbr}}
+ at cindex @var{thr_nbr}
+ at cindex @code{--thr_nbr}
+ at cindex @code{--thread_number}
+ at cindex @code{--threads}
+ at item -t @var{thr_nbr} (@code{--thr_nbr}, @code{--thread_number}, @code{--threads})
+Specifies the number of threads used per regridding process
+(@pxref{OpenMP Threading}).
+The @acronym{NCO} regridder scales well up to 8--16 threads.
+
+ at html
 <a name="unq_sfx"></a> <!-- http://nco.sf.net/nco.html#unq_sfx -->
 @end html
 @cindex @code{-u @var{unq_sfx}}
@@ -22223,6 +22742,40 @@ ncremap -R "--rgr lat_nm=xq --rgr lon_nm=zj" -i in.nc -d dst.nc -O ~/rgr # Manua
 @end example
 @noindent
 
+ at html
+<a name="upk_inp"></a> <!-- http://nco.sf.net/nco.html#upk_inp -->
+ at end html
+ at cindex @code{-U}
+ at cindex @code{--unpack}
+ at cindex @code{--upk}
+ at cindex @code{--upk_inp}
+ at item -U (@code{--unpack}, @code{--upk}, @code{--upk_inp})
+This switch (which takes no argument) causes @command{ncremap} to
+unpack (see @ref{Packed data}) input data before regridding it.
+This switch causes unpacking at the regridding stage that occurs
+after map generation.
+Hence this switch does not benefit grid inferral.
+Grid inferral examines only the coordinate variables in a dataset.
+If coordinates are packed (a terrible practice) in a file from which a
+grid will be inferred, users should first manually unpack the file (this
+option will not help). 
+Fortunately, coordinate variables are usually not packed, even in files
+with other packed data.
+
+Many institutions (like @acronym{NASA}) pack datasets to conserve space
+before distributing them. 
+This option allows one to regrid input data without having
+to manually unpack it first.
+Beware that @acronym{NASA} uses at least three different and
+incompatible versions of packing in its @acronym{L2} datasets.
+The unpacking algorithm employed by this option is the default netCDF
+algorithm, which is appropriate for @acronym{MOD04} and is inappropriate
+for @acronym{MOD08} and @acronym{MOD13}. 
+See @ref{Packed data} for more details and workarounds.
+
+ at html
+<a name="cnf"></a> <!-- http://nco.sf.net/nco.html#cnf -->
+ at end html
 @cindex @code{--version}
 @cindex @code{--vrs}
 @cindex @code{--config}
@@ -22239,13 +22792,13 @@ executables that may be used by the script.
 @html
 <a name="vrb_lvl"></a> <!-- http://nco.sf.net/nco.html#vrb_lvl -->
 @end html
- at cindex @code{--vrb @var{vrb_lvl}}
+ at cindex @code{--vrb=@var{vrb_lvl}}
 @cindex @var{vrb_lvl}
 @cindex @code{--vrb_lvl}
 @cindex @code{--vrb}
 @cindex @code{--verbosity}
 @cindex @code{--verbosity_level}
- at item --vrb @var{vrb_lvl} (@code{--vrb_lvl}, @code{--vrb}, @code{--verbosity}, @code{--verbosity_level})
+ at item --vrb=@var{vrb_lvl} (@code{--vrb_lvl}, @code{--vrb}, @code{--verbosity}, @code{--verbosity_level})
 Specifies a verbosity level similar to the rest of @acronym{NCO}.
 If @math{@var{vrb_lvl} = 0}, @command{ncremap} prints nothing except
 potentially serious warnings.
@@ -22259,19 +22812,61 @@ Note that @var{vrb_lvl} is distinct from @var{dbg_lvl} which is
 passed to the regridder (@command{ncks}) for additional diagnostics.
 
 @html
-<a name="wgt_gnr"></a> <!-- http://nco.sf.net/nco.html#wgt_gnr -->
+<a name="wgt_opt"></a> <!-- http://nco.sf.net/nco.html#wgt_opt -->
+ at end html
+ at cindex @code{-W @var{wgt_opt}}
+ at cindex @var{wgt_opt}
+ at cindex @code{--wgt_opt}
+ at cindex @code{--weight_options}
+ at cindex @code{--tps_opt}
+ at cindex @code{--tempest_options}
+ at cindex @code{--esmf_opt}
+ at cindex @code{--esmf_options}
+ at item -W @var{wgt_opt} (@code{--wgt_opt}, @code{--weight_options}, @code{--esmf_opt}, @code{--esmf_options}, @code{--tps_opt}, @code{--tempest_options}, )
+ at command{ncremap} passes @var{wgt_opt} directly through to the 
+weight-generator (currently @acronym{ERWG} or GenerateOfflineMap). 
+The user-specified contents of @var{wgt_opt}, if any, supercede the
+default contents for the weight-generator.
+The default option for @acronym{ERWG} is @samp{--ignore_unmapped}).
+The @acronym{ERWG} and TempestRemap documentation shows all available
+options. 
+For example, to cause @acronym{ERWG} to output to a netCDF4 file,  
+pass @samp{-W "--netcdf4"} to @command{ncremap}.
+
+GenerateOfflineMap is, by default, run without any options.
+To cause @command{GenerateOfflineMap} to use a @code{_FillValue} of
+ at math{-1}, pass @samp{-W "--fillvalue -1.0"} to @command{ncremap}.
+Other common options include enforcing monotonicity (which is not the
+default in TempestRemap) constraints. 
+To guarantee monotonicity in regridding from Finite Volume @acronym{FV} 
+to @acronym{FV} maps (e.g., @acronym{MPAS}-to-rectangular), pass 
+ at samp{-W "-in_np 1"} to @command{ncremap}.
+To guarantee monotonicity in regridding from Finite Element @acronym{FE} 
+to @acronym{FV} maps, pass @samp{-W "--mono"}.
+
+ at html
+<a name="wgt_cmd"></a> <!-- http://nco.sf.net/nco.html#wgt_cmd -->
 @end html
- at cindex @code{-w @var{wgt_gnr}}
- at cindex @var{wgt_gnr}
+ at cindex @code{-w @var{wgt_cmd}}
+ at cindex @var{wgt_cmd}
+ at cindex @code{--wgt_cmd}
 @cindex @code{--wgt_gnr}
+ at cindex @code{--weight_command}
 @cindex @code{--weight_generator}
- at item -w @var{wgt_gnr} (@code{--wgt_gnr}, @code{--weight_generator}, @code{--generator})
-Specifies the weight-generator to use when a map-file is not provided. 
-The @var{wgt_gnr} argument must be @code{esmf} for @acronym{ESMF}'s
- at command{ESMF_RegridWeightGen} (@acronym{ERWG}), or 
- at code{tempest} for TempestRemaps's
- at command{GenerateOverlapMesh} and @command{GenerateOfflineMap}.
-Specifying @var{wgt_gnr} and supplying (with @samp{-m}) a map-file
+ at item -w @var{wgt_cmd} (@code{--wgt_cmd}, @code{--weight_command}, @code{--wgt_gnr}, @code{--weight_generator})
+Specifies a (possibly extended) command to use to run the
+weight-generator when a map-file is not provided.  
+This command overrides the default executable executable for the
+weight generator, which is @command{ESMF_RegridWeightGen} for
+ at acronym{ESMF} and @command{GenerateOfflineMap} for TempestRemap.
+(There is currently no way to override @command{GenerateOverlapMesh}  
+for TempestRemap). 
+The @var{wgt_cmd} must accept the same arguments as the default
+command. 
+Examples include @samp{mpirun -np 24 ESMF_RegridWeightGen},
+ at samp{mpirun-openmpi-mp -np 16 ESMF_RegridWeightGen}, and other
+ways of exploiting parallelism that are system-dependent.
+Specifying @var{wgt_cmd} and supplying (with @samp{-m}) a map-file
 is not permitted (since the weight-generator would not be used).
 
 @html
@@ -22924,7 +23519,7 @@ Variables not prefixed with a period (@code{global}) must be present.
 @noindent
 SYNTAX
 @example
-ncwa [-3] [-4] [-6] [-7] [-A] [-a @var{dim}[, at dots{}]] [-B @var{mask_cond}] [-b] [-C] [-c]
+ncwa [-3] [-4] [-5] [-6] [-7] [-A] [-a @var{dim}[, at dots{}]] [-B @var{mask_cond}] [-b] [-C] [-c]
 [--cnk_byt @var{sz_byt}] [--cnk_csh @var{sz_byt}] [--cnk_dmn @var{nm}, at var{sz_lmn}] [--cnk_map @var{map}]
 [--cnk_min @var{sz_byt}] [--cnk_plc @var{plc}] [--cnk_scl @var{sz_lmn}]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
@@ -23571,6 +24166,7 @@ Auxiliary coordinate support.
 @cindex Scott Capps
 @item Scott Capps
 Large work-load testing
+ at cindex Dave Blodgett
 @cindex Peter Campbell
 @cindex Martin Dix
 @cindex Mark Flanner
@@ -23583,10 +24179,11 @@ Large work-load testing
 @cindex Michael Schulz
 @cindex Rich Signell
 @cindex Gary Strand
+ at cindex Adrian Tompkins
 @cindex Andrew Wittenberg
 @cindex George White
 @cindex Remik Ziemlinski
- at item Peter Campbell, Martin Dix, Mark Flanner, Markus Liebig, Keith Lindsay, Mike Page, Martin Schmidt, Michael Schulz, Lori Sentman, Rich Signell, Gary Strand, George White Andrew Wittenberg, Remik Ziemlinski
+ at item Dave Blodgett, Peter Campbell, Martin Dix, Mark Flanner, Markus Liebig, Keith Lindsay, Mike Page, Martin Schmidt, Michael Schulz, Lori Sentman, Rich Signell, Gary Strand, Adrian Tompkins, George White Andrew Wittenberg, Remik Ziemlinski
 Excellent bug reports and feature requests.
 @cindex Filipe Fernandes
 @cindex Hugo Oliveira
diff --git a/doc/nco_qt_msvc.shtml b/doc/nco_qt_msvc.shtml
index 1d49230..f735e45 100644
--- a/doc/nco_qt_msvc.shtml
+++ b/doc/nco_qt_msvc.shtml
@@ -33,7 +33,7 @@ This page is mostly important for developers that want to build NCO from source
 <tr>
 </table>
 
-<a target="_top" href="http://qt.nokia.com/products/">Qt</a> is a cross platform build system. As of NCO 4.2.1, it is possible to build NCO with Qt, in a Linux, Mac OSX or 
+<a target="_top" href="https://www.qt.io">Qt</a> is a cross platform build system. As of NCO 4.2.1, it is possible to build NCO with Qt, in a Linux, Mac OSX or 
 Windows enviroment. NCO can be built either from the Qt IDE, QtCreator, or from the command line. To build NCO with QtCreator, just open the file /qt/nco.pro. 
 To build NCO from the command line, do:
 <br>
diff --git a/man/ncap.1 b/man/ncap.1
index 8b6d172..a84d8ba 100644
--- a/man/ncap.1
+++ b/man/ncap.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncap \- netCDF Arithmetic Processor
 .SH SYNTAX
-ncap [\-3] [\-4] [\-6] [\-7] [\-A] [\-C] [\-c] [\-D 
+ncap [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-C] [\-c] [\-D 
 .IR dbg_lvl ]
 [\-F] [\-f]
 [\-\-glb
diff --git a/man/ncap2.1 b/man/ncap2.1
index 8a7b507..5f2171b 100644
--- a/man/ncap2.1
+++ b/man/ncap2.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncap2 \- netCDF Arithmetic Processor, Next Generation
 .SH SYNTAX
-ncap2 [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncap2 [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-D 
 .IR dbg_lvl ]
 [\-d 
diff --git a/man/ncbo.1 b/man/ncbo.1
index 485e3da..eb1adbf 100644
--- a/man/ncbo.1
+++ b/man/ncbo.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncbo \- netCDF Binary Operator
 .SH SYNTAX
-ncbo [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncbo [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] 
 [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
diff --git a/man/ncecat.1 b/man/ncecat.1
index d1f116a..8e77fe6 100644
--- a/man/ncecat.1
+++ b/man/ncecat.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncecat \- netCDF Ensemble Concatenator
 .SH SYNTAX
-ncecat [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncecat [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
 .IR sz_byt ] [\-\-cnk_dmn 
diff --git a/man/nces.1 b/man/nces.1
index ad41413..d19e409 100644
--- a/man/nces.1
+++ b/man/nces.1
@@ -6,7 +6,7 @@
 .SH NAME
 nces \- netCDF Ensemble Statistics
 .SH SYNTAX
-nces [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+nces [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
 .IR sz_byt ] [\-\-cnk_dmn 
diff --git a/man/ncflint.1 b/man/ncflint.1
index 97cb32b..0bca7b4 100644
--- a/man/ncflint.1
+++ b/man/ncflint.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncflint \- netCDF File Interpolator
 .SH SYNTAX
-ncflint [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncflint [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
 .IR sz_byt ] [\-\-cnk_dmn 
diff --git a/man/ncpdq.1 b/man/ncpdq.1
index 62643af..4ab115e 100644
--- a/man/ncpdq.1
+++ b/man/ncpdq.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncpdq \- netCDF Permute Dimensions Quickly, Pack Data Quietly...
 .SH SYNTAX
-ncpdq [\-3] [\-4] [\-6] [\-7] [\-A] [\-a 
+ncpdq [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-a 
 .IR dim [,...]]
 [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
diff --git a/man/ncra.1 b/man/ncra.1
index d3531d1..5f3a8b1 100644
--- a/man/ncra.1
+++ b/man/ncra.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncra \- netCDF Record Averager
 .SH SYNTAX
-ncra [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncra [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
 .IR sz_byt ] [\-\-cnk_dmn 
diff --git a/man/ncrcat.1 b/man/ncrcat.1
index 71f0966..5037c10 100644
--- a/man/ncrcat.1
+++ b/man/ncrcat.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncrcat \- netCDF Record Concatenator
 .SH SYNTAX
-ncrcat [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
+ncrcat [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-\-bfr
 .IR sz_byt ] [\-C] [\-c] [\-\-cnk_byt
 .IR sz_byt ] [\-\-cnk_csh
 .IR sz_byt ] [\-\-cnk_dmn 
diff --git a/man/ncremap.1 b/man/ncremap.1
index c7d24e7..e96d562 100644
--- a/man/ncremap.1
+++ b/man/ncremap.1
@@ -13,8 +13,6 @@ ncremap
 .IR dbg_lvl ] 
 [\-d
 .IR dst_fl ] 
-[\-E
-.IR esmf_opt ] 
 [\-G
 .IR grd_sng ] 
 [\-g
@@ -26,8 +24,10 @@ ncremap
 [\-j
 .IR job_nbr ] 
 [\-M] [\-m
-.IR map_fl ] 
-[\-n
+.IR map_fl ] [\--msk_dst =
+.IR msk_dst ] [\--msk_out =
+.IR msk_out ] [\--msk_src =
+.IR msk_src ] [\-n
 .IR nco_usr ] 
 [\--no_cll_msr ] [\--no_frm_trm] [\--no_stg_grd]
 [\-O
@@ -43,20 +43,19 @@ ncremap
 [\-s
 .IR grd_src ] [\--stdin ]
 [\-T
-.IR tempest_opt ] 
+.IR drc_tmp ] 
 [\-t
 .IR thr_nbr ] 
-[\-U
-.IR drc_tmp ] 
-[\-u
+[\-U] [\-u
 .IR unq_sfx ] 
 [\-V
 .IR rgr_var ] 
 [\-v
 .IR var_lst ] 
-[\--vrb_lvl ] 
-.IR vrb_lvl ] [\--version ] [\-w
-.IR wgt_gnr ] 
+[\--vrb_lvl = 
+.IR vrb_lvl ] [\--version ] [\-W
+.IR wgt_opt ] [\-w
+.IR wgt_cmd ] 
 [\-x
 .IR xtn_lst ] 
 
diff --git a/man/ncwa.1 b/man/ncwa.1
index abf443f..5e2e433 100644
--- a/man/ncwa.1
+++ b/man/ncwa.1
@@ -6,7 +6,7 @@
 .SH NAME
 ncwa \- netCDF Weighted Averager
 .SH SYNTAX
-ncwa [\-3] [\-4] [\-6] [\-7] [\-A] [\-a 
+ncwa [\-3] [\-4] [\-5] [\-6] [\-7] [\-A] [\-a 
 .IR dim [,...]]
 [\-B 
 .IR mask_cond] 
diff --git a/qt/nco.pri b/qt/nco.pri
index 2981fe1..626049a 100644
--- a/qt/nco.pri
+++ b/qt/nco.pri
@@ -27,6 +27,7 @@ win32{
  DEFINES += ENABLE_GSL
  DEFINES += ENABLE_DAP
  DEFINES += NEED_STRSEP
+ DEFINES += _MATH_DEFINES_DEFINED
 }
 
 win32{
diff --git a/src/nco++/fmc_all_cls.cc b/src/nco++/fmc_all_cls.cc
index fb0f88c..3cccc17 100644
--- a/src/nco++/fmc_all_cls.cc
+++ b/src/nco++/fmc_all_cls.cc
@@ -117,7 +117,7 @@
               while(tr=tr->getNextSibling());    
             } 
       
-            nbr_args=vtr_args.size();  
+            nbr_args=vtr_args.size();
 
             susg="usage: var_out="+sfnm+"(var_in,$dim1,$dim2...$dimn)";
 
@@ -129,7 +129,7 @@
             nbr_dim=var1->nbr_dim;  
 
             // Process function arguments if any exist !! 
-            for(idx=1; idx<nbr_args; idx++){  
+            for(idx=1; idx<nbr_args; idx++){
                 aRef=vtr_args[idx];
            
                 switch(aRef->getType()){
@@ -350,6 +350,12 @@
       fmc_vtr.push_back( fmc_cls("has_miss",this,(int)HAS_MISS));
       fmc_vtr.push_back( fmc_cls("ram_write",this,(int)RAM_WRITE));
       fmc_vtr.push_back( fmc_cls("ram_delete",this,(int)RAM_DELETE));
+      fmc_vtr.push_back( fmc_cls("mask_miss",this,(int)MASK_MISS));
+      /* synomn */
+      fmc_vtr.push_back( fmc_cls("missing",this,(int)MASK_MISS));
+      fmc_vtr.push_back( fmc_cls("linear_fill_miss",this,(int)LINEAR_FILL_MISS));
+      fmc_vtr.push_back( fmc_cls("simple_fill_miss",this,(int)SIMPLE_FILL_MISS));
+      fmc_vtr.push_back( fmc_cls("weighted_fill_miss",this,(int)WEIGHT_FILL_MISS));
      
     }
   }
@@ -391,13 +397,50 @@
       
      if(nbr_args ==0) 
        err_prn(fnc_nm,styp+" \""+sfnm+"\" has been called with no arguments"); 
-     
-     // deal with is_miss in a seperate function     
+
+
+
+     // deal with is_miss in a seperate function
+    /*
      if(fdx==NUM_MISS||fdx==HAS_MISS)
        return is_fnd(is_mtd, vtr_args,fmc_obj,walker);           
      if(fdx==GET_MISS)       
-       return get_fnd(is_mtd, vtr_args,fmc_obj,walker);             
-  
+       return get_fnd(is_mtd, vtr_args,fmc_obj,walker);
+    if(fdx==FILL_LINEAR_MISS)
+      return fill_fnd(is_mtd, vtr_args,fmc_obj,walker);
+
+    */
+
+    switch(fdx)
+    {
+      case NUM_MISS:
+      case HAS_MISS:
+        return is_fnd(is_mtd, vtr_args,fmc_obj,walker);
+        break;
+
+      case GET_MISS:
+        return get_fnd(is_mtd, vtr_args,fmc_obj,walker);
+        break;
+
+      case LINEAR_FILL_MISS:
+        return linear_fill_fnd(is_mtd, vtr_args,fmc_obj,walker);
+        break;
+
+      case MASK_MISS:
+        return mask_fnd(is_mtd, vtr_args,fmc_obj,walker);
+        break;
+
+      case SIMPLE_FILL_MISS:
+      case WEIGHT_FILL_MISS:
+        return fill_fnd(is_mtd, vtr_args,fmc_obj,walker);
+        break;
+
+        // do nothing just continue
+      default:
+        break;
+    }
+
+
 
     if( fdx==SET_MISS || fdx==CH_MISS) {
 
@@ -554,7 +597,7 @@
 
   
 var_sct * utl_cls::is_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker){
-  const std::string fnc_nm("srt_cls::imap_fnd");
+  const std::string fnc_nm("utl_cls::is_fnd");
     int nbr_args;
     int fdx=fmc_obj.fdx();
     long icnt;
@@ -618,7 +661,7 @@ var_sct * utl_cls::is_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &
  
 // custom function for GET_MISS
 var_sct * utl_cls::get_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker){
-  const std::string fnc_nm("srt_cls::imap_fnd");
+  const std::string fnc_nm("utl_cls::get_fnd");
     int nbr_args;
     int fdx=fmc_obj.fdx();
     var_sct *var=NULL_CEWI;
@@ -694,7 +737,570 @@ var_sct * utl_cls::get_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls
 
     return var_ret; 	
 
-} 
+}
+
+var_sct * utl_cls::linear_fill_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker){
+  const std::string fnc_nm("utl_cls::fill_linear_fnd");
+  nco_bool do_permute=False;
+  int idx;
+  int jdx;
+  int nbr_dim;
+  int nbr_args;
+  int re_dim_nbr;
+  int swp_nbr;
+  int fdx=fmc_obj.fdx();
+  long icnt;
+  var_sct *var=NULL_CEWI;
+  var_sct *var_int=NULL_CEWI;
+  nc_type styp=NC_INT; // used to hold the mapping type either NC_INT or NC_UINT64
+  std::string sfnm =fmc_obj.fnm(); //method name
+  std::string var_nm;
+  std::string dim_nm;
+  std::string susg;
+  prs_cls *prs_arg=walker.prs_arg;
+
+
+  sfnm =fmc_obj.fnm(); //method name
+
+  susg="usage: var_out="+sfnm+"(var_in,$dim?)";
+
+
+  nbr_args=args_vtr.size();
+  var=walker.out(args_vtr[0] );
+  nbr_dim=var->nbr_dim;
+
+  if(nbr_args==0)
+    err_prn(sfnm,"Function has been called with no arguments\n"+susg);
+
+  if(prs_arg->ntl_scn){
+    return var;
+
+  }
+
+  if(nbr_args >1)
+  {
+    RefAST aRef=args_vtr[1];
+    if(aRef->getType() != DIM_ID)
+      err_prn(sfnm, "Second argument must be a single dimension\n"+susg);
+
+    dim_nm=aRef->getText();
+
+    for(idx=0;idx<nbr_dim;idx++)
+      if(!strcmp(var->dim[idx]->nm, dim_nm.c_str())) break;
+
+    if(idx==nbr_dim)
+      err_prn(sfnm, "Unable to find dim " + dim_nm +" in var "+ SCS(var->nm)+".");
+
+    re_dim_nbr=idx;
+
+  }
+  // dim not specified so choose last dim in var
+  else
+  {
+    re_dim_nbr = var->nbr_dim - 1;
+    dim_nm=SCS(var->dim[re_dim_nbr]->nm );
+  }
+
+  std::vector<nco_bool>  bool_vtr(nbr_dim,False);
+  std::vector<int> dmn_idx_in_out(nbr_dim,0);
+  std::vector<int> dmn_idx_out_in(nbr_dim,0);
+
+  for(idx=0;idx<nbr_dim;idx++)
+    dmn_idx_in_out[idx]=idx;
+
+  // do we need to permute dims ?
+  if(nbr_dim ==1 || re_dim_nbr == nbr_dim-1)
+  {
+   do_permute=False;
+
+  }
+  else
+  {
+    dmn_sct *swp_dim;
+    do_permute=True;
+    // swap about last value;
+    dmn_idx_in_out[re_dim_nbr]=nbr_dim-1;
+    dmn_idx_in_out[nbr_dim-1]=re_dim_nbr;
+
+    var_int=nco_var_dpl(var);
+    swp_dim=var->dim[re_dim_nbr];
+
+    var_int->dim[re_dim_nbr]=var_int->dim[nbr_dim-1];
+    var_int->dim[nbr_dim-1]=swp_dim;
+
+    // create "out_in" mapping from "in_out" mapping
+    for(idx=0 ; idx <nbr_dim ; idx++)
+      for(jdx=0 ; jdx<nbr_dim; jdx++)
+        if( idx==dmn_idx_in_out[jdx]){
+          dmn_idx_out_in[idx]=jdx;
+          break;
+        }
+
+
+
+  }
+
+  //do opera
+  if(do_permute)
+  {
+    (void) nco_var_dmn_rdr_val(var, var_int, &dmn_idx_out_in[0], &bool_vtr[0]);
+  }
+
+  // do fill
+  if(1)
+  {
+
+    int slb_sz=var_int->dim[nbr_dim-1]->cnt;
+    int sz=var->sz/slb_sz;
+    double *dp;
+
+    cast_void_nctype(NC_DOUBLE,&var_int->val);
+    dp=var_int->val.dp;
+
+    for(idx=0;idx<sz;idx++)
+      for(jdx=0;jdx<slb_sz;jdx++)
+        dp[idx*slb_sz+jdx]=jdx;
+
+
+    cast_nctype_void(NC_DOUBLE,&var_int->val);
+  }
+
+  // permute back to original state
+  if(do_permute)
+  {
+
+    (void) nco_var_dmn_rdr_val(var_int, var, &dmn_idx_in_out[0], &bool_vtr[0]);
+    var_int = (var_sct *) nco_var_free(var_int);
+
+  }
+
+  return var;
+
+
+
+}
+
+
+/* fill_miss() method  assumes that the final two dims of the var are lat,lon */
+/* if type not double then converts to double for fill, then converts back to orginal type */
+var_sct * utl_cls::fill_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker){
+  const std::string fnc_nm("utl_cls::fill_fnd");
+  int idx;
+  int jdx;
+  int nbr_dim;
+  int nbr_args;
+  int fdx=fmc_obj.fdx();
+  long icnt;
+  double *lat_dp=NULL_CEWI;
+  double *lon_dp=NULL_CEWI;
+  nc_type lcl_typ;
+  var_sct *var=NULL_CEWI;
+  var_sct *var_lat=NULL_CEWI;
+  var_sct *var_lon=NULL_CEWI;
+
+  std::string sfnm =fmc_obj.fnm(); //method name
+  std::string susg;
+  prs_cls *prs_arg=walker.prs_arg;
+
+
+  sfnm =fmc_obj.fnm(); //method name
+
+  susg="usage: var_out="+sfnm+"(var_in)";
+
+
+
+  nbr_args=args_vtr.size();
+  var=walker.out(args_vtr[0] );
+  nbr_dim=var->nbr_dim;
+
+  if(nbr_args==0)
+    err_prn(sfnm,"Function has been called with no arguments\n"+susg);
+
+  if(prs_arg->ntl_scn){
+    return var;
+
+  }
+
+  // number of dims
+  if(var->nbr_dim<2)
+    err_prn(sfnm,"variable must have a least 2 dims.\"" + SCS(var->nm) + "\" has "+nbr2sng(var->nbr_dim)+ " dims." );
+
+  lcl_typ=var->type;
+  // if not double then convert to double
+  if(var->type != NC_DOUBLE )
+    nco_var_cnf_typ(NC_DOUBLE, var);
+
+  nbr_dim = var->nbr_dim;
+
+  if(fdx==WEIGHT_FILL_MISS) {
+    // grab lat & lon -- assume 1D and there names are the same as their dim names and the dim order is lat,lon
+    var_lat = prs_arg->ncap_var_init(std::string(var->dim[nbr_dim - 2]->nm), true); // lat second to last
+    var_lon = prs_arg->ncap_var_init(std::string(var->dim[nbr_dim - 1]->nm), true); // lon last dim
+
+    if (var_lat && var_lon) {
+
+      if (var_lat->type != NC_DOUBLE)
+        nco_var_cnf_typ(NC_DOUBLE, var_lat);
+
+      if (var_lon->type != NC_DOUBLE)
+        nco_var_cnf_typ(NC_DOUBLE, var_lon);
+
+      cast_void_nctype(var_lat->type, &var_lat->val);
+      cast_void_nctype(var_lon->type, &var_lon->val);
+
+      lat_dp = var_lat->val.dp;
+      lon_dp = var_lon->val.dp;
+    }
+    else
+      err_prn(sfnm,"to get the lat/lon coord-variables this function assumes that they are named after the final two dims in your variable argument.");
+
+
+  }
+
+  {
+    // move through data in blocks if number of dims >2
+    int blk_nbr;
+    size_t blk_sz;
+    size_t slb_sz;
+    void *vp;
+    void *msk_vp = NULL_CEWI;
+
+
+    blk_sz = var->dim[nbr_dim - 2]->cnt * var->dim[nbr_dim - 1]->cnt;
+    blk_nbr = var->sz / blk_sz;
+
+    slb_sz = nco_typ_lng(var->type);
+
+    // save pointer to restore later
+    vp = var->val.vp;
+    // create space here for use in beta_fill
+    msk_vp = nco_malloc(blk_sz * slb_sz);
+
+    for (idx = 0; idx < blk_nbr; idx++) {
+      var->val.vp = (char *) vp + (ptrdiff_t) (blk_sz * idx * slb_sz);
+      if(fdx==SIMPLE_FILL_MISS)
+         simple_fill(var, msk_vp);
+      else if(fdx==WEIGHT_FILL_MISS)
+         weight_fill(var,msk_vp,lat_dp,lon_dp);
+    }
+
+    var->val.vp = vp;
+
+
+    msk_vp = nco_free(msk_vp);
+
+  }
+
+  // convert back to original type
+  if(lcl_typ != var->type)
+     nco_var_cnf_typ(lcl_typ, var);
+
+
+  // free lat/lon
+  if(fdx==WEIGHT_FILL_MISS)
+  {
+    cast_nctype_void(var_lat->type,&var_lat->val);
+    cast_nctype_void(var_lon->type,&var_lon->val);
+    var_lat=nco_var_free(var_lat);
+    var_lon=nco_var_free(var_lon);
+  }
+
+
+
+  return var;
+
+}
+
+
+
+/* simple fill function for replacing _FillValue with average of nearest neighbour(s) */
+int utl_cls::simple_fill(var_sct* var, void* msk_vp){
+
+  // we now have a 2 D var assume [lat, lon]
+  int idx;
+  int jdx;
+  int nbr_dim=var->nbr_dim;
+  int imax_loop=1000;
+  int num_miss;
+  int cnt=0;
+  int lat_sz;
+  int lon_sz;
+  size_t slb_sz;
+  double dbl_mss_val;
+  double **msk_dp=NULL_CEWI;
+  double **dp=NULL_CEWI;
+
+  slb_sz=nco_typ_lng(var->type);
+  lat_sz=var->dim[nbr_dim-2]->cnt;
+  lon_sz=var->dim[nbr_dim-1]->cnt;
+
+
+  // make indexing easier
+  msk_dp=(double**)nco_malloc( sizeof(double*) * lat_sz);
+  dp=(double**)nco_malloc( sizeof(double*) * lat_sz);
+
+  cast_void_nctype(var->type, &var->val);
+  if(var->has_mss_val)
+    dbl_mss_val=*var->mss_val.dp;
+  else
+    dbl_mss_val=NC_FILL_DOUBLE;
+
+
+  // make indexing easier
+  for(idx=0;idx<lat_sz;idx++) {
+    dp[idx] = &(var->val.dp[lon_sz * idx]);
+    msk_dp[idx]= (double*)msk_vp+ptrdiff_t(lon_sz*idx);
+
+  }
+
+  // set num miss to get loop going
+  num_miss=999;
+
+
+  while( imax_loop-->0 && num_miss>0) {
+    double sum=0.0;
+    num_miss=0;
+    // set msk to latest values
+    memcpy((char*)msk_vp, (char*)var->val.dp, lat_sz * lon_sz * slb_sz);
+
+    // move from bottom to top (lat)  and left to right (lon)
+    for (idx = 0 ; idx < lat_sz; idx++)
+      for (jdx = 0; jdx < lon_sz; jdx++)
+        if (msk_dp[idx][jdx] == dbl_mss_val) {
+          sum = 0.0;
+          cnt = 0;
+          if (idx > 0 && msk_dp[idx - 1][jdx] != dbl_mss_val) {
+            sum += msk_dp[idx - 1][jdx];
+            cnt++;
+          }
+
+          if (idx < lat_sz - 1 && msk_dp[idx + 1][jdx] != dbl_mss_val) {
+            sum += msk_dp[idx + 1][jdx];
+            cnt++;
+          }
+
+          if (jdx > 0 && msk_dp[idx][jdx - 1] != dbl_mss_val) {
+            sum += msk_dp[idx][jdx - 1];
+            cnt++;
+          }
+
+          if (jdx < lon_sz - 1 && msk_dp[idx][jdx + 1] != dbl_mss_val) {
+            sum += msk_dp[idx][jdx + 1];
+            cnt++;
+          }
+
+          if (cnt > 0)
+            dp[idx][jdx] = sum / cnt;
+          else
+            num_miss++;
+        }
+
+    // get number of missing elements
+    // printf("beta_fill: inum=%d  num_miss=%ld\n", imax_loop, num_miss);
+
+
+  }
+
+  cast_nctype_void(var->type,&var->val);
+
+  dp=(double**)nco_free(dp);
+  msk_dp=(double**)nco_free(dp);
+
+  return NCO_NOERR;
+
+}
+
+
+/* fill function uses weighted value of eight nearest neighbours */
+int utl_cls::weight_fill(var_sct* var, void* msk_vp, double *lat, double *lon){
+
+  // we now have a 2 D var assume [lat, lon]
+  int idx;
+  int jdx;
+  int nbr_dim=var->nbr_dim;
+  int imax_loop=1000;
+  int num_miss;
+  int cnt=0;
+  int lat_sz;
+  int lon_sz;
+  size_t slb_sz;
+  double dbl_mss_val;
+  double **msk_dp=NULL_CEWI;
+  double **dp=NULL_CEWI;
+
+  slb_sz=nco_typ_lng(var->type);
+  lat_sz=var->dim[nbr_dim-2]->cnt;
+  lon_sz=var->dim[nbr_dim-1]->cnt;
+
+
+  // make indexing easier
+  msk_dp=(double**)nco_malloc( sizeof(double*) * lat_sz);
+  dp=(double**)nco_malloc( sizeof(double*) * lat_sz);
+
+  cast_void_nctype(var->type, &var->val);
+  if(var->has_mss_val)
+    dbl_mss_val=*var->mss_val.dp;
+  else
+    dbl_mss_val=NC_FILL_DOUBLE;
+
+
+  // make indexing easier
+  for(idx=0;idx<lat_sz;idx++) {
+    dp[idx] = &(var->val.dp[lon_sz * idx]);
+    msk_dp[idx]= (double*)msk_vp+ptrdiff_t(lon_sz*idx);
+
+  }
+
+  // set num miss to get loop going
+  num_miss=999;
+
+
+  while( imax_loop-->0 && num_miss>0) {
+
+    num_miss = 0;
+    // set msk to latest values
+    memcpy((char *) msk_vp, (char *) var->val.dp, lat_sz * lon_sz * slb_sz);
+
+    // move from bottom to top (lat)  and left to right (lon)
+    for (idx = 0; idx < lat_sz; idx++)
+      for (jdx = 0; jdx < lon_sz; jdx++)
+        if (msk_dp[idx][jdx] == dbl_mss_val) {
+          // sum numerator
+          double sum_nd = 0.0;
+          //  sum denominator
+          double sum_dd = 0.0;
+          // distance from target point - to neighbour
+          double dist = 0.0;
+          int cnt = 0;
+
+          for (int xdx = idx - 1; xdx <= idx + 1; xdx++) {
+            if (xdx < 0 || xdx >= lat_sz) continue;
+
+            for (int ydx = jdx - 1; ydx <= jdx + 1; ydx++) {
+              if (ydx < 0 || ydx >= lon_sz || xdx == idx && ydx == jdx) continue;
+
+              if (msk_dp[xdx][ydx] != dbl_mss_val) {
+                dist = point2point(lat[idx], lon[jdx], lat[xdx], lon[ydx]);
+                sum_nd += msk_dp[xdx][ydx] / dist /dist;
+                sum_dd += 1.0 / dist / dist ;
+                cnt++;
+              }
+
+              if (cnt > 0)
+                dp[idx][jdx] = sum_nd / sum_dd;
+              else
+                num_miss++;
+            }
+          }
+        }
+  }
+
+    // get number of missing elements
+    // printf("beta_fill: inum=%d  num_miss=%ld\n", imax_loop, num_miss);
+
+
+
+
+  cast_nctype_void(var->type,&var->val);
+
+  dp=(double**)nco_free(dp);
+  msk_dp=(double**)nco_free(dp);
+
+  return NCO_NOERR;
+
+}
+
+
+// distance between two points on a great circle
+double utl_cls::point2point(double lat1,double lon1,double lat2, double lon2) {
+
+double dist;
+double alpha;
+
+
+  if(lon1==lon2)
+    return fabs(lat2-lat1);
+  else if(lat1==lat2)
+    alpha=  pow(sin(lat1),2.0) +  pow( cos(lat1),2.0) * cos(lon2-lon1);
+  else
+    alpha=sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon2-lon1);
+
+  dist=fabs(acos(alpha));
+
+  return dist;
+
+}
+
+
+var_sct * utl_cls::mask_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker) {
+  const std::string fnc_nm("utl_cls::mask_fnd");
+  nco_bool do_permute = False;
+  int idx;
+  int jdx;
+  int nbr_dim;
+  int nbr_args;
+  int re_dim_nbr;
+  int swp_nbr;
+  int fdx = fmc_obj.fdx();
+  long icnt;
+  var_sct *var = NULL_CEWI;
+  var_sct * var_miss= NULL_CEWI;
+  nc_type styp = NC_INT; // used to hold the mapping type either NC_INT or NC_UINT64
+  std::string sfnm = fmc_obj.fnm(); //method name
+  std::string var_nm;
+  std::string dim_nm;
+  std::string susg;
+  prs_cls *prs_arg = walker.prs_arg;
+
+
+  sfnm = fmc_obj.fnm(); //method name
+
+  susg = "usage: var_out=" + sfnm + "(var_in)";
+
+
+  nbr_args = args_vtr.size();
+  var = walker.out(args_vtr[0]);
+  nbr_dim = var->nbr_dim;
+
+  if (nbr_args == 0)
+    err_prn(sfnm, "Function has been called with no arguments\n" + susg);
+
+  if (prs_arg->ntl_scn)
+  {
+    if(var->has_mss_val)
+      if(var->mss_val.vp) {
+        var->mss_val.vp = nco_free(var->mss_val.vp);
+        var->has_mss_val = False;
+      }
+
+
+    return var;
+
+  }
+
+  /* remember the default fill for var->type is used for val.vp in this function call */
+  var_miss=ncap_sclr_var_mk("~var_miss",var->type,true);
+
+  if(var->has_mss_val){
+
+    (void)memcpy(var_miss->val.vp, var->mss_val.vp, nco_typ_lng(var->type));
+    var->has_mss_val=False;
+    var->mss_val.vp=(void*)NULL;
+
+  }else{
+   wrn_prn(sfnm,"Warning method is using default fill value as \""+ SCS(var->nm)+ "\" has no missing value.");
+
+  }
+
+  /* remember this function calls frees up second operand miss_var */
+  (void)ncap_var_var_op(var,var_miss, EQ );
+
+  return var;
+
+
+}
+
+
 
 
 
diff --git a/src/nco++/fmc_all_cls.hh b/src/nco++/fmc_all_cls.hh
index 1b283f1..e9201b4 100644
--- a/src/nco++/fmc_all_cls.hh
+++ b/src/nco++/fmc_all_cls.hh
@@ -93,13 +93,20 @@ public:
 //Utility Functions /****************************************/
 class utl_cls: public vtl_cls {
 private:
-  enum {SET_MISS,CH_MISS,DEL_MISS,GET_MISS,NUM_MISS,HAS_MISS, RAM_WRITE,RAM_DELETE};
+  enum {SET_MISS,CH_MISS,DEL_MISS,GET_MISS,NUM_MISS,HAS_MISS, RAM_WRITE,RAM_DELETE, MASK_MISS,LINEAR_FILL_MISS, SIMPLE_FILL_MISS, WEIGHT_FILL_MISS};
    bool _flg_dbg;
 public:
   utl_cls(bool flg_dbg);
   var_sct *fnd(RefAST expr, RefAST fargs,fmc_cls &fmc_obj, ncoTree &walker);
   var_sct *is_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);  
-  var_sct *get_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);  
+  var_sct *get_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);
+    var_sct *mask_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);
+  var_sct *fill_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);
+  var_sct *linear_fill_fnd(bool &is_mtd, std::vector<RefAST> &args_vtr, fmc_cls &fmc_obj, ncoTree &walker);
+  int simple_fill(var_sct *var, void* msk_vp);
+  int weight_fill(var_sct *var, void* msk_vp, double *lat, double *lon);
+  double point2point(double lat1,double lon1,double lat2, double lon2);
+
 };
 
 //Basic Functions /****************************************/
diff --git a/src/nco++/prs_cls.cc b/src/nco++/prs_cls.cc
index c4fdc46..5808b7e 100644
--- a/src/nco++/prs_cls.cc
+++ b/src/nco++/prs_cls.cc
@@ -309,8 +309,9 @@ prs_cls::ncap_var_write_omp(
   /*  const char mss_val_sng[]="missing_value"; *//* [sng] Unidata standard string for missing value */
   const char add_fst_sng[]="add_offset"; /* [sng] Unidata standard string for add offset */
   const char scl_fct_sng[]="scale_factor"; /* [sng] Unidata standard string for scale factor */
-  const char fnc_nm[]="prs_cls::ncap_var_write"; 
-  
+  const char fnc_nm[]="prs_cls::ncap_var_write";
+
+  int idx;
   int rcd; /* [rcd] Return code */
   int var_out_id;
   
@@ -456,32 +457,38 @@ prs_cls::ncap_var_write_omp(
     /* Define variable */   
     if(!bdef){
       (void)nco_def_var(out_id,var->nm,var->type,var->nbr_dim,var->dmn_id,&var_out_id);
+
+      if(var->cnk_sz)
+        var->cnk_sz=(size_t*)nco_free(var->cnk_sz);
       
       /* Set HDF Lempel-Ziv compression level, if requested */
       int fl_fmt; /* [enm] Output file format */
       (void)nco_inq_format(out_id,&fl_fmt);
-      if(fl_fmt == NC_FORMAT_NETCDF4 || fl_fmt == NC_FORMAT_NETCDF4_CLASSIC){
-	if(var->nbr_dim > 0){
-	  if(dfl_lvl >= 0) (void)nco_def_var_deflate(out_id,var_out_id,var->shuffle,(int)True,dfl_lvl); else if(var->dfl_lvl >= 0) (void)nco_def_var_deflate(out_id,var_out_id,var->shuffle,(int)True,var->dfl_lvl);    
-	  
-	  /* Set chunk sizes, if requested */
-	  // fxm: must first allow cnk_sz specification in ncap2.cc main()
-           
-          /* if var does NOT contain a rec dim then set all chunking to contiguous */  
-	  {
-            int idx;
-            size_t cnks[NC_MAX_VAR_DIMS]={0};
-	    for(idx=0;idx<var->nbr_dim;idx++) 
-              if( var->dim[idx]->is_rec_dmn )
-		break; 
-
-            if( idx==var->nbr_dim)    
-               (void)nco_def_var_chunking(out_id,var_out_id,(int)NC_CONTIGUOUS,cnks);          
-          }
-
-
-	} /* endif netCDF4 */
-      } /* endif */
+      if( (fl_fmt == NC_FORMAT_NETCDF4 || fl_fmt == NC_FORMAT_NETCDF4_CLASSIC) && var->nbr_dim > 0)
+      {
+
+          int flg_cnk;
+	      if(dfl_lvl >= 0)
+            (void)nco_def_var_deflate(out_id,var_out_id,var->shuffle,(int)True,dfl_lvl);
+          else if(var->dfl_lvl >= 0)
+            (void)nco_def_var_deflate(out_id,var_out_id,var->shuffle,(int)True,var->dfl_lvl);
+
+          /* remember ncap_get_cnk_sz can set var->cnk_sz */
+          flg_cnk=ncap_get_cnk_sz(var);
+
+          for(idx=0;idx<var->nbr_dim;idx++)
+            if( var->dim[idx]->is_rec_dmn )
+              break;
+
+          // chunk if it contains a record dim, deeflated, or chunking inherited form Input
+          if( idx<var->nbr_dim || dfl_lvl >=0 || var->dfl_lvl >=0 || flg_cnk )
+            (void)nco_def_var_chunking(out_id,var_out_id,(int)NC_CHUNKED,var->cnk_sz);
+          else
+            (void)nco_def_var_chunking(out_id,var_out_id,(int)NC_CONTIGUOUS,var->cnk_sz);
+
+
+	  } /* endif netCDF4 */
+
     } // bdef
     /* Put missing value 
        if(var->has_mss_val) (void)nco_put_att(out_id,var_out_id,nco_mss_val_sng_get(),var->type,1,var->mss_val.vp);
@@ -539,76 +546,179 @@ prs_cls::ncap_var_write_omp(
   return True;
 }
 
-void prs_cls::ncap_def_ntl_scn(void)
-{
+void prs_cls::ncap_def_ntl_scn(void) {
   int idx;
   int jdx;
   int sz;
   int var_id;
-  size_t cnks[NC_MAX_VAR_DIMS]={0};
+  int rcd;
+  size_t cnks[NC_MAX_VAR_DIMS] = {0};
   NcapVar *Nvar;
   NcapVar *Cvar;
   var_sct *var1;
-  
-  const std::string fnc_nm("prs_cls::ncap_def_ntl_scn"); 
-  
-  if(nco_dbg_lvl_get() >= nco_dbg_scl) dbg_prn(fnc_nm, "Entered function");
-  
-  sz=int_vtr.size();
-  
-  for(idx=0;idx<sz;idx++){
+
+  int fl_fmt; /* [enm] Output file format */
+
+
+  const std::string fnc_nm("prs_cls::ncap_def_ntl_scn");
+
+  if (nco_dbg_lvl_get() >= nco_dbg_scl) dbg_prn(fnc_nm, "Entered function");
+
+  sz = int_vtr.size();
+
+  (void) nco_inq_format(out_id, &fl_fmt);
+
+  for (idx = 0; idx < sz; idx++) {
     // De-reference
-    Nvar=int_vtr[idx];
-    var1=Nvar->var;
-    if(!Nvar->flg_udf && Nvar->xpr_typ==ncap_var){
-      
-      if(nco_dbg_lvl_get() >= nco_dbg_scl) dbg_prn(fnc_nm, Nvar->getFll()+ (!Nvar->flg_mem ? " defined in output": " RAM variable"));
-      
+    Nvar = int_vtr[idx];
+    var1 = Nvar->var;
+    if (!Nvar->flg_udf && Nvar->xpr_typ == ncap_var) {
+
+      if (nco_dbg_lvl_get() >= nco_dbg_scl)
+        dbg_prn(fnc_nm, Nvar->getFll() + (!Nvar->flg_mem ? " defined in output" : " RAM variable"));
+
       // Define variable
-      if(!Nvar->flg_mem){
-	(void)nco_def_var(out_id,var1->nm,var1->type,var1->nbr_dim,var1->dmn_id,&var_id);
-	
-	Nvar->var->id=var_id;
-	Nvar->var->nc_id=out_id;
-	Nvar->flg_stt=1;
-	
-	/* Set HDF Lempel-Ziv compression level, if requested */
-	int fl_fmt; /* [enm] Output file format */
-	int rcd; /* [rcd] Return code */
-	(void)nco_inq_format(out_id,&fl_fmt);
-	if(fl_fmt == NC_FORMAT_NETCDF4 || fl_fmt == NC_FORMAT_NETCDF4_CLASSIC){
-	  if(var1->nbr_dim > 0){ 
-	    if(dfl_lvl >= 0) (void)nco_def_var_deflate(out_id,var_id,var1->shuffle,(int)True,dfl_lvl); else if(var1->dfl_lvl >= 0) (void)nco_def_var_deflate(out_id,var_id,var1->shuffle,(int)True,var1->dfl_lvl);    
-	    
-	    /* Set chunk sizes, if requested */
-	    // fxm: must first allow cnk_sz specification in ncap2.cc main()
-	    for(jdx=0;jdx<var1->nbr_dim;jdx++) 
-              if( var1->dim[jdx]->is_rec_dmn )
-		break; 
-
-            if( jdx==var1->nbr_dim)    
-               (void)nco_def_var_chunking(out_id,var_id,(int)NC_CONTIGUOUS,cnks);          
-
-	  } /* endif */
-	} /* endif netCDF4 */
-	
-      } else { 
-	//deal with RAM only var        
-	Nvar->var->id=-1;
-	Nvar->var->nc_id=-1;
-	Nvar->flg_stt=1;
+      if (!Nvar->flg_mem) {
+        (void) nco_def_var(out_id, var1->nm, var1->type, var1->nbr_dim, var1->dmn_id, &var_id);
+
+        Nvar->var->id = var_id;
+        Nvar->var->nc_id = out_id;
+        Nvar->flg_stt = 1;
+
+        // set cnk_sz to null
+        if (var1->cnk_sz)
+          var1->cnk_sz = (size_t *) nco_free(var1->cnk_sz);
+
+        /* Set HDF Lempel-Ziv compression level, if requested */
+
+        if ((fl_fmt == NC_FORMAT_NETCDF4 || fl_fmt == NC_FORMAT_NETCDF4_CLASSIC) && var1->nbr_dim)
+        {
+          int flg_cnk;
+          if (dfl_lvl >= 0)
+            (void) nco_def_var_deflate(out_id, var_id, var1->shuffle, (int) True, dfl_lvl);
+          else if (var1->dfl_lvl >= 0)
+            (void) nco_def_var_deflate(out_id, var_id, var1->shuffle, (int) True, var1->dfl_lvl);
+
+
+          for (jdx = 0; jdx < var1->nbr_dim; jdx++)
+            if (var1->dim[jdx]->is_rec_dmn)
+              break;
+
+          //  nb ncap_get_cnk_sz() checks the var->nm  in input. IF AND ONLY IF it is the same shape as var1
+          //  then the chunking is copied over
+          flg_cnk = ncap_get_cnk_sz(var1);
+          // chunk if var contains rec_dmn, deflated , or valid chunking from Input
+          if (jdx < var1->nbr_dim || dfl_lvl >= 0 || var1->dfl_lvl >= 0 || flg_cnk)
+            (void) nco_def_var_chunking(out_id, var_id, (int) NC_CHUNKED, var1->cnk_sz);
+          else
+            (void) nco_def_var_chunking(out_id, var_id, (int) NC_CONTIGUOUS, var1->cnk_sz);
+
+        }
+
+
+      } else {
+        //deal with RAM only var
+        Nvar->var->id = -1;
+        Nvar->var->nc_id = -1;
+        Nvar->flg_stt = 1;
       }
-      
+
       // Save newly defined variable in output vector
-      Cvar=new NcapVar(*Nvar);
+      Cvar = new NcapVar(*Nvar);
       var_vtr.push(Cvar);
-    } 
-    delete Nvar;  
+    }
+    delete Nvar;
+
   }
-  
   // Empty int_vtr n.b pointers have all been deleted
   int_vtr.clear();
 }
 
+int prs_cls::ncap_get_cnk_sz(var_sct *var){
+
+  nco_bool shp_chk=False;
+  int rcd;
+  int idx;
+  int jdx;
+  int sz;
+  int var_id=-1;
+  int dmn_var_nbr=0;
+  int *dim_id=NULL_CEWI;
+  int srg_typ=0; /* [enm] Storage type */
+  long *cnt=NULL_CEWI;
+  size_t *lcl_cnk_sz=NULL_CEWI;
+
+
+  if( nco_inq_varid_flg(in_id,var->nm,&var_id) !=NC_NOERR)
+    return shp_chk;
+
+
+  rcd=nco_inq_varndims(in_id,var_id,&dmn_var_nbr);
+  if(rcd != NC_NOERR || dmn_var_nbr==0 || var->nbr_dim != dmn_var_nbr )
+    return shp_chk;
+
+
+
+  (void)nco_inq_var_chunking(in_id,var_id,&srg_typ,(size_t *)NULL);
+  if(srg_typ == NC_CONTIGUOUS)
+    return shp_chk;
+
+
+
+  dim_id=(int *)nco_malloc(dmn_var_nbr*sizeof(int));
+  cnt=(long *)nco_malloc(dmn_var_nbr*sizeof(long));
+  lcl_cnk_sz=(size_t*)nco_calloc(dmn_var_nbr,sizeof(size_t));
+
+  nco_inq_vardimid(in_id,var_id,dim_id);
+
+
+ /* get shape of var in input - put in cnt */
+  sz=dmn_in_vtr.size();
+  for(idx=0;idx<dmn_var_nbr;idx++){
+    for(jdx=0;jdx< sz;jdx++  )
+      if (dmn_in_vtr[jdx]->id == dim_id[idx])
+        break;
+        cnt[idx]= ( jdx<sz ?   dmn_in_vtr[jdx]->cnt: 0);
+
+    }
+
+
+  // compare disc var cnt with var->cnt
+  for(idx=0;idx<dmn_var_nbr;idx++)
+    if( cnt[idx]==0 || var->dim[idx]->cnt != cnt[idx]   )
+      break;
+
+  /* var and disc var have the same shape so get chunking and put in var*/
+  if(idx==dmn_var_nbr)
+  {
+    srg_typ = NC_CHUNKED;
+    (void) nco_inq_var_chunking(in_id, var_id, &srg_typ, lcl_cnk_sz);
+
+    /* free up existing chunking */
+    if (var->cnk_sz)
+      var->cnk_sz = (size_t *) nco_free(var->cnk_sz);
+
+    var->cnk_sz = lcl_cnk_sz;
+
+    shp_chk=True;
+
+  }
+  else
+  {
+    lcl_cnk_sz=(size_t*)nco_free(lcl_cnk_sz);
+    shp_chk=False;
+  }
+
+
+  dim_id=(int *)nco_free(dim_id);
+  cnt=(long *)nco_free(cnt);
+
+
+
+  return shp_chk;
+
+
+}
+
 /********End prs_cls methods********************************************************/
 /***********************************************************************************/
diff --git a/src/nco++/prs_cls.hh b/src/nco++/prs_cls.hh
index a2d1302..aecb9b5 100644
--- a/src/nco++/prs_cls.hh
+++ b/src/nco++/prs_cls.hh
@@ -155,7 +155,13 @@ bool bram);
 
 void 
 ncap_def_ntl_scn           /* define variables captured on first parse */
-(void); 
+(void);
+
+int 
+ncap_get_cnk_sz(
+var_sct *var);
+
+
  };
 
 #endif // PRS_CLS_HH
diff --git a/src/nco/ncks.c b/src/nco/ncks.c
index 4c4e7c4..e08ba58 100644
--- a/src/nco/ncks.c
+++ b/src/nco/ncks.c
@@ -244,6 +244,7 @@ main(int argc,char **argv)
   nco_bool PRN_HDN=False; /* [flg] Print hidden attributes */
   nco_bool PRN_SRM=False; /* [flg] Print ncStream */
   nco_bool PRN_JSN=False; /* [flg] Print JSON */
+  nco_bool PRN_TRD=False; /* [flg] Print traditional */
   nco_bool PRN_XML=False; /* [flg] Print XML (NcML) */
   nco_bool PRN_XML_LOCATION=True; /* [flg] Print XML location tag */
   nco_bool PRN_DMN_IDX_CRD_VAL=True; /* [flg] Print leading dimension/coordinate indices/values Option Q */
@@ -362,6 +363,8 @@ main(int argc,char **argv)
     {"vrs",no_argument,0,0},
     {"jsn",no_argument,0,0}, /* [flg] Print JSON */
     {"json",no_argument,0,0}, /* [flg] Print JSON */
+    {"trd",no_argument,0,0}, /* [flg] Print traditional */
+    {"traditional",no_argument,0,0}, /* [flg] Print traditional */
     {"w10",no_argument,0,0}, /* [flg] Print JSON */
     {"w10n",no_argument,0,0}, /* [flg] Print JSON */
     {"xml",no_argument,0,0}, /* [flg] Print XML (NcML) */
@@ -370,6 +373,7 @@ main(int argc,char **argv)
     {"ncml_no_location",no_argument,0,0}, /* [flg] Omit XML location tag */
     /* Long options with argument, no short option counterpart */
     {"baa",required_argument,0,0}, /* [enm] Bit-Adjustment Algorithm */
+    {"bit_alg",required_argument,0,0}, /* [enm] Bit-Adjustment Algorithm */
     {"bfr_sz_hnt",required_argument,0,0}, /* [B] Buffer size hint */
     {"buffer_size_hint",required_argument,0,0}, /* [B] Buffer size hint */
     {"cnk_byt",required_argument,0,0}, /* [B] Chunk size in bytes */
@@ -595,6 +599,7 @@ main(int argc,char **argv)
         nco_exit(EXIT_SUCCESS);
       } /* endif "copyright" */
       if(!strcmp(opt_crr,"cdl")) PRN_CDL=True; /* [flg] Print CDL */
+      if(!strcmp(opt_crr,"trd") || !strcmp(opt_crr,"traditional")) PRN_TRD=True; /* [flg] Print traditional */
       if(!strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_mmr_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_mmr_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fix_rec_dmn") || !strcmp(opt_crr,"no_rec_dmn")){
@@ -679,7 +684,7 @@ main(int argc,char **argv)
 	rgr_var=(char *)strdup(optarg);
       } /* !rgr_var */
       if(!strcmp(opt_crr,"secret") || !strcmp(opt_crr,"scr") || !strcmp(opt_crr,"shh")){
-        (void)fprintf(stdout,"Hidden/unsupported NCO options:\nCompiler used\t\t--cmp, --compiler\nCopyright\t\t--cpy, --copyright, --license\nHidden functions\t--scr, --ssh, --secret\nLibrary used\t\t--lbr, --library\nMemory clean\t\t--mmr_cln, --cln, --clean\nMemory dirty\t\t--mmr_drt, --drt, --dirty\nMPI implementation\t--mpi_implementation\nNo-clobber files\t--no_clb, --no-clobber\nPseudonym\t\t--pseudonym, -Y (ncra only)\nSpinlock\t\t--spinlock\nStreams\t\t\t--srm\nSysconf\t\t\t--sy [...]
+        (void)fprintf(stdout,"Hidden/unsupported NCO options:\nBit-Adjustment Alg.\t--baa, --bit_alg\nCompiler used\t\t--cmp, --compiler\nCopyright\t\t--cpy, --copyright, --license\nHidden functions\t--scr, --ssh, --secret\nLibrary used\t\t--lbr, --library\nMemory clean\t\t--mmr_cln, --cln, --clean\nMemory dirty\t\t--mmr_drt, --drt, --dirty\nMPI implementation\t--mpi_implementation\nNo-clobber files\t--no_clb, --no-clobber\nPseudonym\t\t--pseudonym, -Y (ncra only)\nSpinlock\t\t--spinlock [...]
         nco_exit(EXIT_SUCCESS);
       } /* endif "shh" */
       if(!strcmp(opt_crr,"srm")) PRN_SRM=True; /* [flg] Print ncStream */
@@ -1036,7 +1041,7 @@ main(int argc,char **argv)
 
   if(fl_bnr && !fl_out){
     /* Native binary files depend on writing netCDF file to enter generic I/O logic */
-    (void)fprintf(stdout,"%s: ERROR Native binary files cannot be written unless netCDF output filename also specified. HINT: Repeat command with dummy netCDF file specified for output file (e.g., -o foo.nc)\n",nco_prg_nm_get());
+    (void)fprintf(stdout,"%s: ERROR Native binary files cannot be written unless netCDF output filename also specified.\nHINT: Repeat command with dummy netCDF file specified for output file (e.g., -o foo.nc)\n",nco_prg_nm_get());
     nco_exit(EXIT_FAILURE);
   } /* endif fl_bnr */
     
@@ -1183,7 +1188,7 @@ main(int argc,char **argv)
     prn_flg.jsn=PRN_JSN;
     prn_flg.srm=PRN_SRM;
     prn_flg.xml=PRN_XML;
-    prn_flg.trd=!(PRN_CDL || PRN_XML || PRN_JSN);
+    prn_flg.trd=PRN_TRD || !(PRN_CDL || PRN_XML || PRN_JSN); // 20170522
     if((prn_flg.cdl || prn_flg.xml) && nco_dbg_lvl >= nco_dbg_std) prn_flg.nfo_xtr=True; else prn_flg.nfo_xtr=False;
     prn_flg.new_fmt=(PRN_CDL || PRN_JSN || PRN_SRM || PRN_XML);
     prn_flg.hdn=PRN_HDN;
diff --git a/src/nco/nco.h b/src/nco/nco.h
index 67f568b..b170456 100644
--- a/src/nco/nco.h
+++ b/src/nco/nco.h
@@ -189,6 +189,9 @@ extern "C" {
   /* Linux default blocksize is 4096 B---a good chunk size for 1-D record dimension variables */
 #define NCO_CNK_SZ_BYT_R1D_DFL 4096
 
+  /* Maximum number of names to examine in CF "coordinates" attribute */
+#define NCO_MAX_CRD_PER_VAR 6
+
   /* netCDF provides no guidance on maximum nesting of groups */
 #define NCO_MAX_GRP_DEPTH 10
 
@@ -336,7 +339,7 @@ extern "C" {
 # define NCO_VERSION_MINOR 6
 #endif /* !NCO_VERSION_MINOR */
 #ifndef NCO_VERSION_PATCH
-# define NCO_VERSION_PATCH 6
+# define NCO_VERSION_PATCH 7
 #endif /* !NCO_VERSION_PATCH */
 #ifndef NCO_VERSION_NOTE
 # define NCO_VERSION_NOTE "" /* Blank for final versions, non-blank (e.g., "beta37") for pre-release versions */
@@ -346,7 +349,7 @@ extern "C" {
 # define NCO_LIB_VERSION ( NCO_VERSION_MAJOR * 100 + NCO_VERSION_MINOR * 10 + NCO_VERSION_PATCH )
 #endif /* !NCO_LIB_VERSION */
 #ifndef NCO_VERSION
-# define NCO_VERSION "4.6.6"
+# define NCO_VERSION "4.6.7"
 #endif /* !NCO_VERSION */
 
 /* Compatibility tokens new to netCDF4 netcdf.h: */
@@ -1100,6 +1103,8 @@ extern "C" {
     char *bnd_tm_nm; /* [sng] Name of dimension to employ for temporal bounds */
     char *col_nm_in; /* [sng] Name to recognize as input horizontal spatial dimension on unstructured grid */
     char *col_nm_out; /* [sng] Name of horizontal spatial output dimension on unstructured grid */
+    char *fl_hnt_dst; /* [sng] ERWG hint destination */
+    char *fl_hnt_src; /* [sng] ERWG hint source */
     char *frc_nm; /* [sng] Name of variable containing gridcell fraction */
     char *lat_bnd_nm; /* [sng] Name of rectangular boundary variable for latitude */
     char *lat_dmn_nm; /* [sng] Name of latitude dimension in inferred grid */
@@ -1112,12 +1117,14 @@ extern "C" {
     char *lon_nm_in; /* [sng] Name of dimension to recognize as longitude */
     char *lon_nm_out; /* [sng] Name of output dimension for longitude */
     char *lon_vrt_nm; /* [sng] Name of non-rectangular boundary variable for longitude */
+    char *msk_nm; /* [sng] Name of variable containing destination mask */
     char *vrt_nm; /* [sng] Name of dimension to employ for vertices */
     // User-specified grid properties
     char *fl_grd; /* [sng] Name of SCRIP grid file to create */
     char *fl_ugrid; /* [sng] Name of UGRID grid file to create */
     char *fl_skl; /* [sng] Name of skeleton data file to create */
     char *grd_ttl; /* [sng] Grid title */
+    char *msk_var; /* [sng] Mask-template variable */
     double lat_crv; /* [dgr] Latitudinal  curvilinearity */
     double lon_crv; /* [dgr] Longitudinal curvilinearity */
     double lat_sth; /* [dgr] Latitude of southern edge of grid */
@@ -1144,10 +1151,13 @@ extern "C" {
     nco_bool flg_area_out; /* [flg] Add area to output */
     nco_bool flg_cll_msr; /* [flg] Add cell_measures attribute */
     nco_bool flg_crv; /* [flg] Use curvilinear coordinates */
+    nco_bool flg_dgn_area; /* [flg] Diagnose rather than copy inferred area */
+    nco_bool flg_dgn_bnd; /* [flg] Diagnose rather than copy inferred bounds */
     nco_bool flg_grd; /* [flg] Create SCRIP-format grid file */
     nco_bool flg_grd_dst; /* [flg] User-specified destination grid */
     nco_bool flg_grd_src; /* [flg] User-specified input grid */
     nco_bool flg_map; /* [flg] User-specified mapping weights */
+    nco_bool flg_msk_out; /* [flg] Add mask to output */
     nco_bool flg_nfr; /* [flg] Infer SCRIP-format grid file */
     nco_bool flg_rnr; /* [flg] Renormalize destination values by valid area */
     nco_bool flg_stg; /* [flg] Write staggered grid with FV output */
diff --git a/src/nco/nco_att_utl.c b/src/nco/nco_att_utl.c
index cb15772..91a2f52 100644
--- a/src/nco/nco_att_utl.c
+++ b/src/nco/nco_att_utl.c
@@ -287,6 +287,7 @@ nco_aed_prc /* [fnc] Process single attribute edit for single variable */
     mss_val_crr.vp=(void *)nco_malloc(att_sz*nco_typ_lng(var->type));
     mss_val_new.vp=(void *)nco_malloc(aed.sz*nco_typ_lng(var->type));
 
+    /* 20170505: Does nco_val_cnf_typ() work as expected on NaNs? */
     (void)nco_val_cnf_typ(var->type,var->mss_val,var->type,mss_val_crr); 
     (void)nco_val_cnf_typ(aed.type,aed.val,var->type,mss_val_new);
 
@@ -358,9 +359,10 @@ nco_aed_prc /* [fnc] Process single attribute edit for single variable */
   /* According to netCDF4 C Reference Manual:
      "Fill values must be written while the file is still in initial define mode, that
      is, after the file is created, but before it leaves define mode for the first time.
-     NC EFILLVALUE is returned when the user attempts to set the fill value after
+     NC_EFILLVALUE is returned when the user attempts to set the fill value after
      it is too late." 
-     The netCDF4/_FillValue code (and rename trick) works around that limitation. */
+     (netcdf.h replaced NC_EFILLVALUE by NC_ELATEFILL after about netCDF ~4.2.1)
+     The NCO netCDF4/_FillValue code (and rename trick) works around that limitation */
 
   /* Bold hack which gets around problem of modifying netCDF4 "_FillValue" attributes
      netCDF4 does not allow this by default, though netCDF3 does
@@ -380,11 +382,13 @@ nco_aed_prc /* [fnc] Process single attribute edit for single variable */
      aed.att_nm && /* 20130419: Verify att_nm exists before using it in strcmp() below. att_nm does not exist when user leaves field blank. Fix provided by Etienne Tourigny. */
      !strcmp(aed.att_nm,nco_mss_val_sng_get()) && /* ... attribute is missing value and ... */
      aed.mode != aed_delete &&  /* ... we are not deleting attribute */
-     NC_LIB_VERSION <= 440){ /* netCDF library does not contain fix to NCF-187 */
+     // 20170523: Remove this condition as it did not seem to help anymore
+     //     NC_LIB_VERSION <= 440 && /* netCDF library does not contain fix to NCF-187 */
+     True){
     /* Rename existing attribute to netCDF4-safe name 
        After modifying missing value attribute with netCDF4-safe name below, 
        we will rename attribute to original missing value name. */
-    if(nco_dbg_lvl_get() >= nco_dbg_var && nco_dbg_lvl_get() != nco_dbg_dev) (void)fprintf(stdout,"%s: INFO %s reports creating, modifying, or overwriting %s attribute %s in netCDF4 file requires re-name trick\n",nco_prg_nm_get(),fnc_nm,var_nm,aed.att_nm);
+    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO %s reports attempt to create, modify, or overwrite %s attribute %s in netCDF4 file violates netCDF4 capabilities (and would result in NC_ELATEFILL error) so will invoke NCO hocus-pocus rename trick...\n",nco_prg_nm_get(),fnc_nm,var_nm,aed.att_nm);
     if(rcd_inq_att == NC_NOERR) (void)nco_rename_att(nc_id,var_id,aed.att_nm,att_nm_tmp);
     flg_netCDF4_rename_trick=True; /* [flg] Re-name _FillValue in order to create/modify/overwrite it */
     strcpy(aed.att_nm,att_nm_tmp); 
@@ -743,7 +747,12 @@ nco_att_cpy  /* [fnc] Copy attributes from input netCDF file to output netCDF fi
     } /* !flg_autoconvert */
 
     if(strcmp(att_nm,nco_mss_val_sng_get())){
-      if(flg_autoconvert){
+      /* Normal (non-_FillValue) attributes */
+      if(!flg_autoconvert){
+	/* Copy all attributes except _FillValue with fast library routine
+	   20170516: library routine does not copy empty NC_CHAR attributes? */
+	(void)nco_copy_att(in_id,var_in_id,att_nm,out_id,var_out_id);
+      }else{ /* autoconvert */
 	var_sct att_var; /* [sct] Variable structure */
 	var_sct *att_var_ptr=NULL; /* [sct] Variable structure */
 
@@ -767,11 +776,8 @@ nco_att_cpy  /* [fnc] Copy attributes from input netCDF file to output netCDF fi
 	  rcd=nco_put_att(out_id,var_out_id,att_nm,att_typ_out,att_sz,att_var_ptr->val.vp);
 	  if(att_var_ptr->val.vp) att_var_ptr->val.vp=nco_free(att_var_ptr->val.vp);
 	} /* !NC_STRING */
-      }else{
-	/* Copy all attributes except _FillValue with fast library routine */
-	(void)nco_copy_att(in_id,var_in_id,att_nm,out_id,var_out_id);
-      } /* !Autoconvert */
-    }else{
+      } /* !autoconvert */
+    }else{ /* !_FillValue */
       /* Convert "_FillValue" attribute to unpacked type then copy 
 	 Impose NCO convention that _FillValue is same type as variable,
 	 whether variable is packed or not */
@@ -1190,8 +1196,14 @@ nco_prs_aed_lst /* [fnc] Parse user-specified attribute edits into structure lis
     }else if(arg_lst[3] == NULL && *(arg_lst[2]) != 'd' && *(arg_lst[2]) != 'm'){
       msg_sng=strdup("Type must be explicitly specified for all modes except delete and modify");
       NCO_SYNTAX_ERROR=True;
-    }else if(arg_lst[idx_att_val_arg] == NULL && *(arg_lst[2]) != 'd' && *(arg_lst[3]) == 'c'){
-      /* ... value is not specified except that att_val = "" is valid for character type */
+    }else if(arg_lst[idx_att_val_arg] == NULL && *(arg_lst[2]) != 'd' && *(arg_lst[3]) != 'c' && strcmp(arg_lst[3],"sng")){
+      /* 20170515: 
+	 ncks --cdl -v one ~/nco/data/in.nc
+	 ncatted -O -a long_name,one,o,c,'' ~/nco/data/in.nc ~/foo.nc
+	 ncatted -O -a long_name,one,o,sng,'' ~/nco/data/in_4.nc ~/foo.nc
+	 ncks --cdl -v one ~/foo.nc
+      */
+      /* ... value is not specified except that att_val = "" is valid for character and string types */
       msg_sng=strdup("Value must be explicitly specified for all modes except delete (although an empty string value is permissible for attributes of type NC_CHAR and NC_STRING)");
       NCO_SYNTAX_ERROR=True;
     } /* end else */
@@ -1313,12 +1325,12 @@ nco_prs_aed_lst /* [fnc] Parse user-specified attribute edits into structure lis
         /* strdup() attaches a trailing NUL to the user-specified string 
 	   Retaining is obliquely discussed in netCDF Best Practices document:
 	   http://www.unidata.ucar.edu/software/netcdf/docs/BestPractices.html#Strings%20and%20Variables%20of%20type%20char */
-        aed_lst[idx].val.cp=(nco_char *)strdup(arg_lst[idx_att_val_arg]);
+	aed_lst[idx].val.cp= (aed_lst[idx].sz > 0L) ? (nco_char *)strdup(arg_lst[idx_att_val_arg]) : NULL; 
       }else if(aed_lst[idx].type == NC_STRING){
         aed_lst[idx].val.vp=(void *)nco_malloc(aed_lst[idx].sz*nco_typ_lng(aed_lst[idx].type));
         for(lmn=0L;lmn<aed_lst[idx].sz;lmn++){
-          aed_lst[idx].val.sngp[lmn]=(nco_string)strdup(arg_lst[idx_att_val_arg+lmn]);
-        } /* end loop over elements */
+	  if(arg_lst[idx_att_val_arg+lmn] != NULL) aed_lst[idx].val.sngp[lmn]=(nco_string)strdup(arg_lst[idx_att_val_arg+lmn]); else aed_lst[idx].val.sngp[lmn]=(nco_string)NULL;
+	} /* !lmn */
       }else{
         char *sng_cnv_rcd=NULL_CEWI; /* [sng] strtol()/strtoul() return code */
         double *val_arg_dbl=NULL_CEWI;
@@ -1976,7 +1988,11 @@ nco_glb_att_add /* [fnc] Add global attributes */
     gaa_aed.type=NC_CHAR;
     /* Insert value into attribute structure */
     gaa_aed.val=att_val;
-    gaa_aed.sz=strlen(gaa_aed.val.cp);
+    /* 20170428 jm: Update for flag parsing*/
+    if(gaa_aed.val.cp)
+      gaa_aed.sz=strlen(gaa_aed.val.cp);
+    else
+      gaa_aed.sz=0;
     /* 20160324: which is better mode for gaa---overwrite or append? 
        20160330: answer is overwrite. otherwise, climo_nco.sh produces ANN file with, e.g.,
        :climo_script = "climo_nco.shclimo_nco.shclimo_nco.sh" ;
diff --git a/src/nco/nco_cnk.c b/src/nco/nco_cnk.c
index 06e144f..6c972a6 100644
--- a/src/nco/nco_cnk.c
+++ b/src/nco/nco_cnk.c
@@ -461,6 +461,7 @@ nco_cnk_plc_get /* [fnc] Convert user-specified chunking policy to key */
   if(!strcmp(nco_cnk_plc_sng,"uck")) return nco_cnk_plc_uck;
   if(!strcmp(nco_cnk_plc_sng,"cnk_uck")) return nco_cnk_plc_uck;
   if(!strcmp(nco_cnk_plc_sng,"plc_uck")) return nco_cnk_plc_uck;
+  if(!strcmp(nco_cnk_plc_sng,"none")) return nco_cnk_plc_uck;
   if(!strcmp(nco_cnk_plc_sng,"unchunk")) return nco_cnk_plc_uck;
 
   (void)fprintf(stderr,"%s: ERROR %s reports unknown user-specified chunking policy %s\n",nco_prg_nm_get(),fnc_nm,nco_cnk_plc_sng);
diff --git a/src/nco/nco_cnv_csm.c b/src/nco/nco_cnv_csm.c
index 9a22af5..29fd2dd 100644
--- a/src/nco/nco_cnv_csm.c
+++ b/src/nco/nco_cnv_csm.c
@@ -414,13 +414,13 @@ nco_cnv_cf_cll_mth_add               /* [fnc] Add cell_methods attributes */
     (void)strcat(aed.val.cp,": ");
     (void)strcat(aed.val.cp,att_op_sng);
 
-    /* 20150625: Older versions of CAM, e.g., CAM3, used "cell_method" instead of "cell_methods" 
+    /* 20150625: Older versions of CAM, e.g., CAM3 and CLM3, used "cell_method" instead of "cell_methods" 
        If old attribute is not deleted then the output file will contain both attributes
        Does variable already have "cell_method" attribute? */
     strcpy(aed.att_nm,"cell_method");
     rcd=nco_inq_att_flg(grp_out_id,var_out_id,aed.att_nm,&att_typ,&att_lng);
     if(rcd == NC_NOERR){
-      if(FIRST_WARNING) (void)fprintf(stderr,"%s: WARNING: Variable \"%s\" uses the non-standard attribute name \"cell_method\" instead of \"cell_methods\", the correct attribute name. The CAM3 model (and others?) have this problem. Expect \"double attributes\" in output. This message is printed only once per invocation, although the problem likely occurs in multiple variables.\n",nco_prg_nm_get(),aed.var_nm);
+      if(FIRST_WARNING) (void)fprintf(stderr,"%s: WARNING: Variable \"%s\" uses the non-standard attribute name \"cell_method\" instead of \"cell_methods\", the correct attribute name. The CAM3 and CLM3 models (and others?) have this problem. Expect \"double attributes\" in output. This message is printed only once per invocation, although the problem likely occurs in multiple variables.\n",nco_prg_nm_get(),aed.var_nm);
       FIRST_WARNING=False;
     } /* endif attribute exists */
 
diff --git a/src/nco/nco_ctl.c b/src/nco/nco_ctl.c
index 8857715..b1c6eb2 100644
--- a/src/nco/nco_ctl.c
+++ b/src/nco/nco_ctl.c
@@ -844,7 +844,7 @@ nco_nmn_get(void) /* [fnc] Return mnemonic that describes current NCO version */
 { 
   /* Purpose: Return mnemonic describing current NCO version
      Always include terminal \n so mnemonic does not dangle */
-  return "Step-Half-Brother-in-Law\n";
+  return "Shots and power tools\n";
 } /* end nco_nmn_get() */
 
 char * /* O [sng] nm_in stripped of any path (i.e., program name stub) */ 
@@ -862,8 +862,8 @@ nco_prg_prs /* [fnc] Strip program name to stub and set program ID */
 #ifdef _MSC_VER
   int len;
   if(strrchr(nm_out_tmp,'\\')) nm_out_tmp=strrchr(nm_out_tmp,'\\')+1;
-  char *s=strstr(nm_out_tmp,".exe");
-  if(s!=NULL && !strcmp(s,".exe")){
+  char *sfx=strstr(nm_out_tmp,".exe");
+  if(sfx && !strcmp(sfx,".exe")){
     len=strlen(nm_out_tmp); /* cut any '.exe' from name */ 
     nm_out_tmp[len-4]='\0';   
   } /* endif */
@@ -955,41 +955,41 @@ nco_usg_prn(void)
 
   switch(prg_lcl){
   case ncap:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl lmn] [-D nco_dbg_lvl] [-F] [-f] [--fl_fmt fmt] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [-R] [-r] [--ram_all] [-s algebra] [-S fl.nco] [-t thr_nbr] [-v] in.nc [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl lmn] [-D nco_dbg_lvl] [-F] [-f] [--fl_fmt fmt] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [-R] [-r] [--ram_all] [-s algebra] [-S fl.nco] [-t thr_nbr] [-v] in.nc [out.nc]\n");
     break;
   case ncatted:
     opt_sng=(char *)strdup("[-a ...] [--bfr byt] [-D nco_dbg_lvl] [--glb ...] [-h] [--hdr_pad nbr] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] [-t] in.nc [[out.nc]]\n");
     break;
   case ncbo:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] [-y op_typ] in_1.nc i [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] [-y op_typ] in_1 [...]
     break;
   case ncflint:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fix_rec_crd] [--fl_fmt fmt] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-i var,val] [-L lvl] [-l path] [--msa] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-v ...] [-X box] [-x] [-w wgt_1[,wgt_2]]  [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fix_rec_crd] [--fl_fmt fmt] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-i var,val] [-L lvl] [-l path] [--msa] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-v ...] [-X box] [-x] [-w wgt_1[,wgt [...]
     break;
   case ncks:
     opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [-a] [-b fl_bnr] [--bfr byt] [-C] [-c] [--cal] [--cdl] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fix_rec_dmn dim] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [--grp_xtr_var_xcl] [-H] [-h] [--hdn] [--hdr_pad nbr] [--jsn] [--jsn_fmt lvl] [-L lvl] [-l path] [-M] [-m] [--map map.nc] [--md5_dgs] [--md5_wrt] [--mk_rec_dmn dim]  [...]
     break;
   case ncpdq:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [-a ...] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [-M pck_map] [--mrd] [--msa] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-P pck_plc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [-a ...] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [-M pck_map] [--mrd] [--msa] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-P pck_plc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [ [...]
     break;
   case ncra:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cb] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--mro] [--msa] [-N] [-n ...] [--no_cll_msr] [--no_cll_mth] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all]  [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cb] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--mro] [--msa] [-N] [-n ...] [--no_cll_msr] [--no_cll_mth] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_ [...]
     break;
   case ncfe:
   case ncge:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [--nsm_fl] [--nsm_grp] [--nsm_sfx] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all]  [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [--nsm_fl] [--nsm_grp] [--nsm_sfx] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_ [...]
     break;
   case ncrcat:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [--md5_digest] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-v ...] [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [--md5_digest] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-v [...]
     break;
   case ncecat:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--gag] [--glb ...] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [-M] [--md5_digest] [--mrd] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-u ulm_nm] [--unn] [-v [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--gag] [--glb ...] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [-M] [--md5_digest] [--mrd] [--msa] [-n ...] [--no_cll_msr] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-u ulm_nm] [--unn [...]
     break;
   case ncrename:
     opt_sng=(char *)strdup("[-a ...] [--bfr byt] [-D nco_dbg_lvl] [-d ...] [-g ...] [--glb ...] [-h] [--hdr_pad nbr] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] [-v ...] in.nc [[out.nc]]\n");
     break;
   case ncwa:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [-a ...] [-B mask_cond] [-b] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-I] [-L lvl] [-l path] [-m mask] [-M mask_val] [-N] [--no_cll_msr] [--no_cll_mth] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [- [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [-a ...] [-B mask_cond] [-b] [--bfr byt] [-C] [-c] [--cnk_byt byt] [--cnk_csh byt] [--cnk_dmn nm,lmn] [--cnk_map map] [--cnk_min byt] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--glb ...] [-h] [--hdf] [--hdr_pad nbr] [-I] [-L lvl] [-l path] [-m mask] [-M mask_val] [-N] [--no_cll_msr] [--no_cll_mth] [--no_frm_trm] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc .. [...]
     break;
   default: nco_dfl_case_prg_id_err(); break;
   } /* end switch */
@@ -1002,9 +1002,13 @@ nco_usg_prn(void)
 #ifdef ENABLE_NETCDF4
   if(strstr(opt_sng,"[-4]")) (void)fprintf(stdout,"-4, --4, --netcdf4\t\tOutput file in netCDF4 (HDF5) storage format\n");
 #endif /* !ENABLE_NETCDF4 */
-  if(strstr(opt_sng,"[-5]")) (void)fprintf(stdout,"-5, --5, --fl_fmt=64bit_data\tOutput file in netCDF3 64-bit data (i.e., CDF5) storage format\n");
+  if(NC_LIB_VERSION >= 440){
+    if(strstr(opt_sng,"[-5]")) (void)fprintf(stdout,"-5, --5, --fl_fmt=64bit_data\tOutput file in netCDF3 64-bit data (i.e., CDF5, PnetCDF) storage format\n");
+  } /* !NC_LIB_VERSION */
   if(strstr(opt_sng,"[-6]")) (void)fprintf(stdout,"-6, --6, --64, --fl_fmt=64bit_offset\tOutput file in netCDF3 64-bit offset storage format\n");
+#ifdef ENABLE_NETCDF4
   if(strstr(opt_sng,"[-7]")) (void)fprintf(stdout,"-7, --7, --fl_fmt=netcdf4_classic\tOutput file in netCDF4 CLASSIC format (3+4=7)\n");
+#endif /* !ENABLE_NETCDF4 */
   if(strstr(opt_sng,"[-A]")) (void)fprintf(stdout,"-A, --apn, --append\tAppend to existing output file, if any\n");
   if(strstr(opt_sng,"[-a")){
     if(prg_lcl == ncatted) (void)fprintf(stdout,"-a, --attribute att_nm,var_nm,mode,att_typ,att_val Attribute specification:\n\t\t\tmode = a,c,d,m,o (append, create, delete, modify, overwrite)\n\t\t\tatt_typ = f,d,l/i,s,c,b (float, double, long/int, short, char, byte)\n");
diff --git a/src/nco/nco_fl_utl.c b/src/nco/nco_fl_utl.c
index 1bd5255..1dc31a4 100644
--- a/src/nco/nco_fl_utl.c
+++ b/src/nco/nco_fl_utl.c
@@ -991,7 +991,7 @@ nco_fl_mk_lcl /* [fnc] Retrieve input file and return local filename */
         } /* end if */
 
         if(!rmt_cmd){
-          (void)fprintf(stderr,"%s: ERROR file %s not found. It does not exist on the local filesystem, nor does it match remote filename patterns (e.g., http://foo or foo.bar.edu:file), nor did NCO detect a High Performance Storage System (HPSS) to retrieve it from remote storage.\n",nco_prg_nm_get(),fl_nm_rmt);
+          (void)fprintf(stderr,"%s: ERROR file %s not found. It does not exist on the local filesystem, nor does it match remote filename patterns (e.g., http://foo or foo.bar.edu:file), nor did NCO detect a remote High Performance Storage System (HPSS) accessible via the 'hsi' command.\n",nco_prg_nm_get(),fl_nm_rmt);
 	  (void)fprintf(stderr,"%s: HINT file-not-found errors usually arise from filename typos, incorrect paths, missing files, or capricious gods. Please verify spelling and location of requested file.\n",nco_prg_nm_get());
           nco_exit(EXIT_FAILURE);
         } /* end if */
diff --git a/src/nco/nco_grp_utl.c b/src/nco/nco_grp_utl.c
index 07823d5..448a2ba 100644
--- a/src/nco/nco_grp_utl.c
+++ b/src/nco/nco_grp_utl.c
@@ -1195,7 +1195,7 @@ nco_xtr_cf_var_add /* [fnc] Add variables associated (via CF) with specified var
           *(cf_lst[nbr_cf]+var_lng)='\0';
           strncpy(cf_lst[nbr_cf],cln_ptr+2L,var_lng);
 	  cln_ptr+=var_lng;
-	  if(nco_dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stderr,"%s: DEBUG %s reports variable %s %s variable #%d is %s\n",nco_prg_nm_get(),fnc_nm,var_trv->nm_fll,att_nm,nbr_cf,cf_lst[nbr_cf]);
+	  if(nco_dbg_lvl_get() >= nco_dbg_io) (void)fprintf(stderr,"%s: DEBUG %s reports variable %s %s variable #%d is %s\n",nco_prg_nm_get(),fnc_nm,var_trv->nm_fll,att_nm,nbr_cf,cf_lst[nbr_cf]);
 	  nbr_cf++;
 	} /* !att_val */
       }else{
@@ -1701,6 +1701,9 @@ nco_xtr_dfn                          /* [fnc] Define extracted groups, variables
 
   char *grp_out_fll;                   /* [sng] Group name */
 
+  dmn_cmn_sct *dmn_cmn_out;            /* [sct] List of all dimensions in output file (used for RETAIN_ALL_DIMS) */
+  gpe_nm_sct *gpe_nm;                  /* [sct] GPE name duplicate check array */
+
   int fl_fmt;                          /* [enm] netCDF file format */
   int grp_id;                          /* [ID] Group ID in input file */
   int grp_out_id;                      /* [ID] Group ID in output file */ 
@@ -1711,10 +1714,6 @@ nco_xtr_dfn                          /* [fnc] Define extracted groups, variables
 
   nco_bool PCK_ATT_CPY;                /* [flg] Copy attributes "scale_factor", "add_offset" */
 
-  gpe_nm_sct *gpe_nm;                  /* [sct] GPE name duplicate check array */
-
-  dmn_cmn_sct *dmn_cmn_out;            /* [sct] List of all dimensions in output file (used for RETAIN_ALL_DIMS) */
-
   nco_prg_id=nco_prg_id_get(); 
   nbr_gpe_nm=0;
   gpe_nm=NULL;
diff --git a/src/nco/nco_mss_val.c b/src/nco/nco_mss_val.c
index fb0fb46..5524507 100644
--- a/src/nco/nco_mss_val.c
+++ b/src/nco/nco_mss_val.c
@@ -51,7 +51,7 @@ nco_mss_val_mk /* [fnc] Return default missing value for type type */
 nco_bool /* O [flg] One or both operands have missing value */
 nco_mss_val_cnf /* [fnc] Change missing_value of var2 to missing_value of var1 */
 (var_sct * const var1, /* I [sct] Variable with template missing value to copy */
- var_sct * const var2) /* I/O [sct] Variable with missing value to fill in/overwrite */
+ var_sct * const var2) /* I/O [sct] Variable with missing value to fill-in/overwrite */
 {
   /* Purpose: 
      1. Change missing_value of var2 to missing_value of var1 when both exist 
@@ -90,7 +90,6 @@ nco_mss_val_cnf /* [fnc] Change missing_value of var2 to missing_value of var1 *
     default: nco_dfl_case_nc_type_err(); break;
     } /* end switch */
     if(!MSS_VAL_EQL){
-      /* World's most anally formatted warning message... */
       char mss_val_1_sng[NCO_MAX_LEN_FMT_SNG];
       char mss_val_2_sng[NCO_MAX_LEN_FMT_SNG];
       const char *fmt_sng;
@@ -126,7 +125,8 @@ nco_mss_val_cnf /* [fnc] Change missing_value of var2 to missing_value of var1 *
       case NC_STRING: (void)sprintf(mss_val_2_sng,fmt_sng,var2->mss_val.sngp[0]); break;
       default: nco_dfl_case_nc_type_err(); break;
       } /* end switch */
-      (void)fprintf(stderr,"%s: WARNING Input variables have different NCO_MSS_VAL_SNG's:\nFile 1 variable %s has NCO_MSS_VAL_SNG type = %s, value = %s\nFile 2 variable %s has NCO_MSS_VAL_SNG type = %s, value = %s\nFile 3 variable %s will have NCO_MSS_VAL_SNG type = %s, value = %s\nWill translate values of var2 equaling mss_val2 to mss_val1 before arithmetic operation\n",nco_prg_nm_get(),var1->nm,nco_typ_sng(var1->type),mss_val_1_sng,var2->nm,nco_typ_sng(var2->type),mss_val_2_sng,var1->n [...]
+      /* World's most anally formatted warning message... */
+      (void)fprintf(stderr,"%s: WARNING Input variables have different NCO_MSS_VAL_SNG's:\nVariable #1 = %s has NCO_MSS_VAL_SNG type = %s, value = %s\nVariable #2 = %s has NCO_MSS_VAL_SNG type = %s, value = %s\nVariable #3 = output = %s will have NCO_MSS_VAL_SNG type = %s, value = %s\nWill translate values of var2 equaling mss_val2 to mss_val1 before evaluating arithmetic operation to compute var3\n",nco_prg_nm_get(),var1->nm,nco_typ_sng(var1->type),mss_val_1_sng,var2->nm,nco_typ_sng(var [...]
     } /* MSS_VAL_EQL */
     (void)cast_nctype_void(var_typ,&var1->mss_val);
     (void)cast_nctype_void(var_typ,&var2->mss_val);
diff --git a/src/nco/nco_mta.c b/src/nco/nco_mta.c
index 1d1ba66..58662f7 100644
--- a/src/nco/nco_mta.c
+++ b/src/nco/nco_mta.c
@@ -28,6 +28,14 @@ nco_sng2kvm /* [fnc] Convert string to key-value pair */
   char *args_copy=strdup(args);
   char *ptr_for_free=args_copy;
   kvm_sct kvm;
+
+  if(!strstr(args_copy, "="))
+  {
+    kvm.key=strdup(args_copy);
+    kvm.val=NULL;
+    nco_free(ptr_for_free);
+    return kvm;
+  }
   
   kvm.key=strdup(strsep(&args_copy,"="));
   kvm.val=strdup(args_copy);
@@ -81,7 +89,9 @@ nco_kvm_prn(kvm_sct kvm)
   if(kvm.key) (void)fprintf(stdout,"%s = %s\n",kvm.key,kvm.val); else return;
 } /* end nco_kvm_prn() */
 
-char *nco_remove_backslash(char *args)
+char * /* O/I [sng] string that has backslash(es) */
+nco_remove_backslash
+(char *args) /* O/I [sng] string that had already been got rid of backslash(es) */
 { /* Purpose: recursively remove backslash from string */
   char *backslash_pos=strstr(args,"\\"); 
   if(backslash_pos){
@@ -89,6 +99,20 @@ char *nco_remove_backslash(char *args)
     memmove(&args[absolute_pos],&args[absolute_pos+1L],strlen(args)-absolute_pos);
     return nco_remove_backslash(args);
   }else return args;
+} /* !nco_remove_backslash() */
+
+char * /* O [sng] the flag that has no hyphens */
+nco_remove_hyphens /* [fnc] Remove the hyphens come before the flag */
+(char* args) /* I [sng] the flag that has hyphens in it*/
+{
+  char *hyphen_pos=strstr(args,"-"); 
+  if(hyphen_pos){
+    int absolute_pos=hyphen_pos-args;/* Get memory address offset */
+    memmove(&args[absolute_pos],&args[absolute_pos+1L],strlen(args)-absolute_pos);
+    return nco_remove_hyphens(args);
+  }
+  else
+    return args;
 }
 
 char ** /* O [sng] Group of split strings */
@@ -146,6 +170,84 @@ nco_sng_split /* [fnc] Split string by delimiter */
   return sng_fnl;
 } /* end nco_sng_split() */
 
+int /* O [flg] Is flag */
+nco_is_flag /* [fnc] Check whether input is a flag */
+(const char* flag) /* I [sng] Input string */
+{
+  const char fnc_nm[]="nco_is_flag()"; /* [sng] Function name */
+  const char *rgr_flags[]={
+    "no_area",
+    "no_area_out",
+    "cell_measures",
+    "cll_msr",
+    "no_cell_measures",
+    "no_cll_msr",
+    "curvilinear",
+    "crv",
+    "dgn_area",
+    "diagnose_area",
+    "dgn_bnd",
+    "diagnose_bounds",
+    "infer",
+    "nfr",
+    "no_stagger",
+    "no_stg"};
+  const char *gaa_flags[]={""};
+  const char *trr_flags[]={""};
+  const char *ppc_flags[]={""};
+  
+  for(unsigned int index=0;index<sizeof(rgr_flags)/sizeof(char *);index++)
+    {
+      if(!strcmp(flag,rgr_flags[index])){
+        return NCO_NOERR;
+      }
+    }
+  for(unsigned int index=0;index<sizeof(gaa_flags)/sizeof(char *);index++)
+    {
+      if(!strcmp(flag, gaa_flags[index])) 
+        return NCO_NOERR;
+    }
+  for(unsigned int index=0;index<sizeof(trr_flags)/sizeof(char *);index++)
+    {
+      if(!strcmp(flag, trr_flags[index])) 
+        return NCO_NOERR;
+    }
+  for(unsigned int index=0;index<sizeof(ppc_flags)/sizeof(char *);index++)
+    {
+      if(!strcmp(flag, ppc_flags[index])) 
+        return NCO_NOERR;
+    }
+  
+  (void)fprintf(stderr, "%s: ERROR %s Multi-Argument (MTA) parser reports unrecognized option \"%s\"\n%s: HINT Lack of equals sign indicates this may be a mis-typed flag rather than an erroneous key-value pair specification. Valid MTA flags are listed below. Synonyms for each flag are listed on the same line. A leading \"--\" is optional. MTA documentation is at http://nco.sf.net/nco.html#mta\n",nco_prg_nm_get(),fnc_nm,flag,nco_prg_nm_get());
+
+  (void)fprintf(stderr, "Regridder flags (\"rgr\" indicator):\n");
+  for(unsigned int index=0;index<sizeof(rgr_flags)/sizeof(char *);index++)
+    {
+      (void)fprintf(stderr, "  %2d. %s\n",index+1,rgr_flags[index]);
+    }
+  /*
+    (void)fprintf(stderr, "ncks gaa (Global Attribute Adding) flags:\n");
+    for(unsigned int index=0;index<sizeof(gaa_flags)/sizeof(char *);index++)
+    {
+      (void)fprintf(stderr, "%s\n",gaa_flags[index]);
+    }
+  
+  (void)fprintf(stderr, "ncks trr (Terraref) flags:\n");
+  for(unsigned int index=0;index<sizeof(trr_flags)/sizeof(char *);index++)
+    {
+      (void)fprintf(stderr, "%s\n",trr_flags[index]);
+    }
+  (void)fprintf(stderr, "ncks ppc (Precision-Preserving Compression) flags:\n");
+  for(unsigned int index=0;index<sizeof(ppc_flags)/sizeof(char *);index++)
+    {
+      (void)fprintf(stderr, "%s\n",ppc_flags[index]);
+    }
+  */
+  
+  return NCO_ERR;
+}
+
+
 int /* O [flg] Input has valid syntax */
 nco_input_check /* [fnc] Check whether input has valid syntax */
 (const char *args) /* O [sng] Input arguments */
@@ -153,17 +255,22 @@ nco_input_check /* [fnc] Check whether input has valid syntax */
   /* Check argument syntax
    * If return value is false the parser will terminate the program */
   const char fnc_nm[]="nco_input_check()"; /* [sng] Function name */
-
+  
   if(!strstr(args,"=")){ // If no equal sign in arguments
-    (void)fprintf(stderr,"%s: ERROR %s did not detect equal sign between key and value for argument \"%s\".\n%s HINT This can occur when the designated or default key-value delimiter \"%s\" is mixed into the literal text of the value. Try changing the delimiter to a string guaranteed not to appear in the value string with, e.g., --dlm=\"##\".\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get(),nco_mta_dlm_get());
-    return NCO_ERR;
+    char *arg_copy=strdup(args);
+    if(!nco_is_flag(nco_remove_hyphens(arg_copy))){
+      (void)fprintf(stderr,"%s: ERROR %s did not detect equal sign between key and value for argument \"%s\".\n%s: HINT This can occur when the designated or default key-value delimiter string \"%s\" is mixed into the literal text of the value. Try changing delimiter to a string guaranteed not to appear in the value string with, e.g., --dlm=\"##\".\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get(),nco_mta_dlm_get());
+      nco_free(arg_copy);
+      return NCO_ERR;
+    }
+    nco_free(arg_copy);
   }
   if(strstr(args,"=") == args){ // Equal sign is at argument start (no key)
-    (void)fprintf(stderr,"%s: ERROR %s reports no key in key-value pair for argument \"%s\".\n%s HINT It appears that an equal sign is the first character of the argument, meaning that a value was specified with a corresponding key.\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get()); 
+    (void)fprintf(stderr,"%s: ERROR %s reports no key in key-value pair for argument \"%s\".\n%s: HINT It appears that an equal sign is the first character of the argument, meaning that a value was specified with a corresponding key.\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get()); 
     return NCO_ERR;
   }
   if(strstr(args,"=") == args+strlen(args)-1L){ // Equal sign is at argument end
-    (void)fprintf(stderr,"%s: ERROR %s reports no value in key-value pair for argument \"%s\".\n%s HINT This usually occurs when the value of a key is unintentionally omitted, e.g., --gaa foo= , --ppc foo= , --rgr foo= , or --trr foo= . Each equal sign must immediatte precede a value for the specified key(s).\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get());
+    (void)fprintf(stderr,"%s: ERROR %s reports no value in key-value pair for argument \"%s\".\n%s: HINT This usually occurs when the value of a key is unintentionally omitted, e.g., --gaa foo= , --ppc foo= , --rgr foo= , or --trr foo= . Each equal sign must immediatte precede a value for the specified key(s).\n",nco_prg_nm_get(),fnc_nm,args,nco_prg_nm_get());
     return NCO_ERR;
   }
   return NCO_NOERR;
@@ -195,7 +302,7 @@ nco_arg_mlt_prs /* [fnc] main parser, split the string and assign to kvm structu
   char **separate_args=nco_sng_split(args,(const char *)nco_mta_dlm);
   size_t counter=nco_count_blocks(args,nco_mta_dlm)*nco_count_blocks(args,nco_mta_sub_dlm); /* [nbr] Maximum number of kvm structures in this argument */
 
-  for(int index=0;index<nco_count_blocks(args,nco_mta_dlm);index++){
+   for(int index=0;index<nco_count_blocks(args,nco_mta_dlm);index++){
     if(!nco_input_check(separate_args[index])) nco_exit(EXIT_FAILURE);
   } /* !index */
   
@@ -204,14 +311,24 @@ nco_arg_mlt_prs /* [fnc] main parser, split the string and assign to kvm structu
   size_t kvm_idx=0;
   
   for(int sng_idx=0;sng_idx<nco_count_blocks(args,nco_mta_dlm);sng_idx++){
-    char *value=strdup(strstr(separate_args[sng_idx],"="));
-    char *set_of_keys=strdup(strtok(separate_args[sng_idx],"=")); 
+    char *value=NULL, *set_of_keys=NULL;
+    if(strstr(separate_args[sng_idx],"="))
+    { /*key-value pair case*/
+      value=strdup(strstr(separate_args[sng_idx],"="));
+      set_of_keys=strdup(strtok(separate_args[sng_idx],"="));
+    }
+    else
+    { /*Pure key case (flags) */
+      set_of_keys=strdup(nco_remove_hyphens(separate_args[sng_idx]));
+      value=NULL;
+    }
     char **individual_args=nco_sng_split(set_of_keys,nco_mta_sub_dlm);
     
     for(int sub_idx=0;sub_idx<nco_count_blocks(set_of_keys,nco_mta_sub_dlm);sub_idx++){
       char *temp_value=strdup(individual_args[sub_idx]);
-      temp_value=(char *)nco_realloc(temp_value,strlen(temp_value)+strlen(value)+1L);
-      temp_value=strcat(temp_value,value);
+      temp_value=(char *)nco_realloc(temp_value,strlen(temp_value)+(value ? strlen(value) : 0)+1L);
+      if(value)
+        temp_value= strcat(temp_value,value);
       kvm_set[kvm_idx++]=nco_sng2kvm(nco_remove_backslash(temp_value));
       nco_free(temp_value);
     } /* !sub_idx */
diff --git a/src/nco/nco_mta.h b/src/nco/nco_mta.h
index 485d234..8810270 100644
--- a/src/nco/nco_mta.h
+++ b/src/nco/nco_mta.h
@@ -49,9 +49,13 @@ extern "C" {
   nco_kvm_prn /* [fnc] Print kvm contents */
   (kvm_sct kvm); /* [fnc] kvm to print */
 
-  char *
+  char * /* O/I [sng] string that has backslash(es) */
   nco_remove_backslash
-  (char* args);
+  (char *args); /* O/I [sng] string that had already been got rid of backslash(es) */
+
+  char * /* O [sng] the flag that has no hyphens */
+  nco_remove_hyphens /* [fnc] Remove the hyphens come before the flag */
+  (char* args); /* I [sng] the flag that has hyphens in it*/
 
   char ** /* O [sng] Group of split strings */
   nco_sng_split /* [fnc] Split string by delimiter */
diff --git a/src/nco/nco_netcdf.c b/src/nco/nco_netcdf.c
index c9256fc..988ef06 100644
--- a/src/nco/nco_netcdf.c
+++ b/src/nco/nco_netcdf.c
@@ -80,11 +80,11 @@ nco_err_exit /* [fnc] Print netCDF error message, routine name, then exit */
     (void)fprintf(stdout,"ERROR NC_EACCESS Access failure\nHINT: NC_EACCESS errors signify a problem receiving data from a DAP server. This can occur, e.g., when NCO requests (with nco_var_get()) more data than the server is configured to dispense at one time. A workaround might be to request smaller chunks of data at one time. This can be accomplished by accessing hyperslabs or multi-slabs of data as described at http://nco.sf.net/nco.html#mlt\n"); break; /* NB: NC_EACCESS added to netc [...]
   case NC_EBADTYPE: (void)fprintf(stdout,"ERROR NC_BADTYPE Not a netCDF data type\nHINT: NC_EBADTYPE errors can occur when NCO tries to write netCDF4 features to a netCDF3 file. Features that cannot be defined in a netCDF3 file, and that thus will trigger this error, include groups and netCDF4 atomic types (e.g., NC_STRING, NC_UBYTE). The workaround is to remove all netCDF4 features before attempting the conversion, or to just give up and write a netCDF4 output file instead of a netCDF3  [...]
   case NC_ECANTWRITE: (void)fprintf(stdout,"ERROR NC_ECANTWRITE Can't write file\nHINT: NC_ECANTWRITE errors can occur when NCO tries to write to an HDF5 file that is not netCDF4-compliant. One workaround is translate the file to a netCDF4-compliant file first, e.g., with \'ncks in.h5 out.nc\'.\n"); break;
-  case NC_EINVAL: (void)fprintf(stdout,"ERROR NC_EINVAL Invalid argument\nHINT: NC_EINVAL errors can occur for many reasons. Three common ones are described here. 1. When NCO operators attempt to open netCDF4 files using the diskless option, usually invoked with --diskless_all, --ram_all, or --open_ram.  Is your input file netCDF4 format?  (http://nco.sf.net/nco.html#fmt_inq shows how to tell.) If so then omitting the diskless option may solve this problem. 2. When HDF4-enabled NCO attem [...]
+  case NC_EINVAL: (void)fprintf(stdout,"ERROR NC_EINVAL Invalid argument\nHINT: NC_EINVAL errors can occur for many reasons. Three common ones are described here. 1. When invalid chunking directives are given, e.g., to unchunk a record variable or to chunk a variable with an invalid size (such as zero or larger than a fixed dimension). This is the most frequent/likely cause in our experience. 2. When HDF4-enabled NCO attempts to directly write to an HDF4 (not HDF5) file. Not all HDF5 cal [...]
   case NC_EIO: /* netcdf.h added NC_EIO in ~2012 */
     (void)fprintf(stdout,"ERROR NC_EIO Generic IO error\nHINT: NC_EIO errors can occur when NCO tries to read a file through a non-existant DAP location. Then NCO automatically tries to retrieve the file through another method, e.g., searching for a file of the same name in the current directory. This can trigger a subsequent error. When debugging the problem, first address the originating error (from NC_EIO).\n"); break;
   case NC_ELATEFILL: /* netcdf.h replaced NC_EFILLVALUE by NC_ELATEFILL after about netCDF ~4.2.1 */ 
-     (void)fprintf(stdout,"ERROR NC_ELATEFILL (formerly NC_EFILLVALUE) Attempt to define fill value when data already exists\nHINT: NC_ELATEFILL errors can occur when ncap2 attempts to define a variable with a _FillValue attribute in a netCDF4 file.  We believe this is an NCO bug (fxm TODO nco1089) and are working to fix it. Does your output file need to be netCDF4 or netCDF4_classic format? If so, then wait for us to fix the bug. If not, change the output format to netCDF3 (e.g., with - [...]
+     (void)fprintf(stdout,"ERROR NC_ELATEFILL (formerly NC_EFILLVALUE) Attempt to define fill value when data already exists\nHINT: NC_ELATEFILL errors can occur when NCO attempts to create, modify, or overwrite  a _FillValue attribute for an existing variable in a netCDF4 file. The netCDF4 format (unlike netCDF3) does not permit this. Does your output file need to be netCDF4 or netCDF4_classic format? One workaround is to change the output format to netCDF3 (e.g., ncks -3 in.nc out.nc), [...]
 #ifdef ENABLE_NETCDF4 
   case NC_ENOTBUILT: (void)fprintf(stdout,"ERROR NC_ENOTBUILT Attempt to use feature that was not turned on when netCDF was built\nHINT: NC_ENOTBUILT errors occur only, in our experience, when NCO attempts to access an HDF4 (including HDF-EOS2) file. It is only possible to access HDF4 files from NCO if NCO is first re-linked to a version of netCDF configured with the --enable-hdf4 option, which itself must be linked to a version of HDF4 configured with the --disable-netcdf option. These  [...]
 #endif /* !ENABLE_NETCDF4 */
diff --git a/src/nco/nco_prn.c b/src/nco/nco_prn.c
index 719b15e..b1a6a81 100644
--- a/src/nco/nco_prn.c
+++ b/src/nco/nco_prn.c
@@ -100,8 +100,6 @@ nco_prn_att /* [fnc] Print all attributes of single variable or group */
   const nco_bool CDL_OR_TRD=prn_flg->cdl || prn_flg->trd; /* [flg] CDL or Traditional output */
   const nco_bool CDL_OR_JSN_OR_XML=prn_flg->cdl || prn_flg->jsn || prn_flg->xml; /* [flg] CDL or JSON or XML output */
 
-  //nco_bool has_fll_val=False; /* [flg] Has _FillValue attribute */
-
   nco_string sng_val; /* [sng] Current string */
 
   prn_ndn=prn_flg->ndn;
@@ -332,9 +330,17 @@ nco_prn_att /* [fnc] Print all attributes of single variable or group */
       att[idx].nm=(char *)nco_malloc(NC_MAX_NAME*sizeof(char));
       (void)nco_inq_attname(grp_id,var_id,idx,att[idx].nm);
       (void)nco_inq_att(grp_id,var_id,att[idx].nm,&att[idx].type,&att[idx].sz);
+
       /* Allocate enough space to hold attribute */
-      att[idx].val.vp=(void *)nco_malloc(att[idx].sz*nco_typ_lng(att[idx].type));
-      (void)nco_get_att(grp_id,var_id,att[idx].nm,att[idx].val.vp,att[idx].type);
+      att[idx].val.vp = (void *) nco_malloc(att[idx].sz * nco_typ_lng(att[idx].type));
+      (void) nco_get_att(grp_id, var_id, att[idx].nm, att[idx].val.vp, att[idx].type);
+
+      /* an NC_CHAR can have zero length size maybe others ? -create with a single FILL value */
+      if(att[idx].sz==0){
+        att[idx].val=nco_mss_val_mk(att[idx].type);
+        att[idx].sz=1;
+      }
+
     } /* idx == att_nbr */
     
     /* Copy value to avoid indirection in loop over att_sz */
@@ -396,7 +402,7 @@ nco_prn_att /* [fnc] Print all attributes of single variable or group */
 	  if(strstr(att[idx].val.cp,spr_sng)) spr_sng=spr_xml_chr_bck;
 	if(att[idx].type == NC_STRING){
 	  for(lmn=0;lmn<att_sz;lmn++){
-	    if(strstr(att[idx].val.sngp[lmn],spr_sng)){
+	    if(att[idx].val.sngp[lmn] && strstr(att[idx].val.sngp[lmn],spr_sng)){
 	      spr_sng=spr_xml_chr_bck;
 	      break;
 	    } /* endif */
@@ -462,6 +468,7 @@ nco_prn_att /* [fnc] Print all attributes of single variable or group */
 	    sng_lngm1=sng_lng-1UL;
 	    /* Worst case is printable strings are six or four times longer than unformatted, i.e., '\"' == """ or '\\' == "\\\\" */
 	    sng_val_sng_cpy=sng_val_sng=(char *)nco_malloc(6*sng_lng+1UL);
+
 	  } /* endif first element of string array */
 	  /* New string begins each element where penultimate dimension changes */
 	  if(lmn%sng_lng == 0L){
@@ -503,6 +510,8 @@ nco_prn_att /* [fnc] Print all attributes of single variable or group */
     case NC_STRING:
       for(lmn=0;lmn<att_sz;lmn++){
 	sng_val=att[idx].val.sngp[lmn];
+    /* In strict CDL an NC_STRING null is indictaed by NIL, for now we output an empty string */
+    if(!sng_val) sng_val="";
 	sng_lng=strlen(sng_val);
 	sng_lngm1=sng_lng-1UL;
 	if(CDL||XML||JSN){
@@ -862,7 +871,7 @@ nco_prn_var_val_cmt /* 0 print to stdout var values as CDL comment (delimited by
   #endif /* !NCO_HAVE_REGEX_FUNCTIONALITY */
 
   /* Print type in English in prefix text */
-  if(var->type == NC_STRING) (void)fprintf(stdout,"calendar format: "); else (void)fprintf(stdout,"%s value%s : ",cdl_typ_nm(var->type),(var->sz > 1 ? "s":""));
+  if(var->type == NC_STRING) (void)fprintf(stdout,"calendar format: "); else (void)fprintf(stdout,"%s value%s: ",cdl_typ_nm(var->type),(var->sz > 1 ? "s":""));
 
   for(lmn=0;lmn<sz;lmn++){
 
@@ -895,8 +904,8 @@ nco_prn_var_val_cmt /* 0 print to stdout var values as CDL comment (delimited by
        } /* end switch */
 
     } /* !is_mss_val */
-    if(lmn<sz-1)
-      (void)fprintf(stdout,", ");
+
+    if(lmn<sz-1L) (void)fprintf(stdout,", ");
 
   } /* end loop over element */
 
@@ -904,13 +913,8 @@ nco_prn_var_val_cmt /* 0 print to stdout var values as CDL comment (delimited by
 
   if(fmt_sng_mss_val) fmt_sng_mss_val=(char *)nco_free(fmt_sng_mss_val);
 
-
-
 }/* end nco_prn_var_val_cmt() */
 
-
-
-
 void
 nco_prn_var_val_lmt /* [fnc] Print variable data */
 (const int in_id, /* I [id] netCDF input file ID */
@@ -1620,7 +1624,7 @@ nco_prn_var_val_trv /* [fnc] Print variable data (GTT version) */
   nco_bool flg_malloc_unit_crd=False; /* [flg] Allocated memory for coordinate units string */
   nco_bool flg_malloc_unit_var=False; /* [flg] Allocated memory for variable units string */
   nco_bool unit_cln_crd=False; /* [flg] Coordinate has calendar units */
-  nco_bool unit_cln_var=False; /* [flg] Variable has calendar units */
+  //nco_bool unit_cln_var=False; /* [flg] Variable has calendar units */
 
   nco_string sng_val; /* [sng] Current string */
 
@@ -1695,7 +1699,7 @@ nco_prn_var_val_trv /* [fnc] Print variable data (GTT version) */
     if (unit_sng_var && strlen(unit_sng_var)) {
 
       flg_malloc_unit_var = True;
-      unit_cln_var = nco_cln_chk_tm(unit_sng_var);
+      //unit_cln_var = nco_cln_chk_tm(unit_sng_var);
 
       cln_sng = nco_lmt_get_udu_att(grp_id, cf_var_id, "calendar");
       if (cln_sng)
diff --git a/src/nco/nco_rgr.c b/src/nco/nco_rgr.c
index eb660fe..0f24264 100644
--- a/src/nco/nco_rgr.c
+++ b/src/nco/nco_rgr.c
@@ -84,6 +84,10 @@ nco_rgr_free /* [fnc] Deallocate regridding structure */
 
   /* free() strings associated with grid properties */
   if(rgr->fl_grd) rgr->fl_grd=(char *)nco_free(rgr->fl_grd);
+  if(rgr->fl_hnt_dst) rgr->fl_hnt_dst=(char *)nco_free(rgr->fl_hnt_dst);
+  if(rgr->fl_hnt_src) rgr->fl_hnt_src=(char *)nco_free(rgr->fl_hnt_src);
+  if(rgr->fl_skl) rgr->fl_skl=(char *)nco_free(rgr->fl_skl);
+  if(rgr->fl_ugrid) rgr->fl_ugrid=(char *)nco_free(rgr->fl_ugrid);
 
   /* Tempest */
   if(rgr->drc_tps) rgr->drc_tps=(char *)nco_free(rgr->drc_tps);
@@ -107,6 +111,7 @@ nco_rgr_free /* [fnc] Deallocate regridding structure */
   if(rgr->lon_nm_in) rgr->lon_nm_in=(char *)nco_free(rgr->lon_nm_in);
   if(rgr->lon_nm_out) rgr->lon_nm_out=(char *)nco_free(rgr->lon_nm_out);
   if(rgr->lon_vrt_nm) rgr->lon_vrt_nm=(char *)nco_free(rgr->lon_vrt_nm);
+  if(rgr->msk_nm) rgr->msk_nm=(char *)nco_free(rgr->msk_nm);
   if(rgr->vrt_nm) rgr->vrt_nm=(char *)nco_free(rgr->vrt_nm);
 
   /* Lastly, free() regrid structure itself */
@@ -239,16 +244,22 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
   rgr->lon_nm_in=NULL; /* [sng] Name of dimension to recognize as longitude */
   rgr->lon_nm_out=NULL; /* [sng] Name of output dimension for longitude */
   rgr->lon_vrt_nm=NULL; /* [sng] Name of non-rectangular boundary variable for longitude */
+  rgr->msk_nm=NULL; /* [sng] Name of variable containing destination mask */
   rgr->vrt_nm=NULL; /* [sng] Name of dimension to employ for vertices */
 
   /* Initialize key-value properties used in grid generation */
   rgr->fl_grd=NULL; /* [sng] Name of SCRIP grid file to create */
+  rgr->fl_hnt_dst=NULL; /* [sng] ERWG hint destination */
+  rgr->fl_hnt_src=NULL; /* [sng] ERWG hint source */
   rgr->fl_skl=NULL; /* [sng] Name of skeleton data file to create */
   rgr->fl_ugrid=NULL; /* [sng] Name of UGRID grid file to create */
   rgr->flg_area_out=True; /* [flg] Add area to output */
   rgr->flg_cll_msr=True; /* [flg] Add cell_measures attribute */
+  rgr->flg_dgn_area=False; /* [flg] Diagnose rather than copy inferred area */
+  rgr->flg_dgn_bnd=False; /* [flg] Diagnose rather than copy inferred bounds */
   rgr->flg_crv=False; /* [flg] Use curvilinear coordinates */
   rgr->flg_grd=False; /* [flg] Create SCRIP-format grid file */
+  rgr->flg_msk_out=False; /* [flg] Add mask to output */
   rgr->flg_nfr=False; /* [flg] Infer SCRIP-format grid file */
   rgr->flg_stg=True; /* [flg] Write staggered grid with FV output */
   rgr->grd_ttl=strdup("None given (supply with --rgr grd_ttl=\"Grid Title\")"); /* [enm] Grid title */
@@ -264,17 +275,31 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
   rgr->lon_wst=NC_MAX_DOUBLE; /* [dgr] Longitude of western edge of grid */
   rgr->lat_nrt=NC_MAX_DOUBLE; /* [dgr] Latitude of northern edge of grid */
   rgr->lon_est=NC_MAX_DOUBLE; /* [dgr] Longitude of eastern edge of grid */
+  rgr->msk_var=NULL; /* [sng] Mask-template variable */
   rgr->tst=0L; /* [enm] Generic key for testing (undocumented) */
   
   /* Parse key-value properties */
   char *sng_cnv_rcd=NULL_CEWI; /* [sng] strtol()/strtoul() return code */
   for(rgr_var_idx=0;rgr_var_idx<rgr_var_nbr;rgr_var_idx++){
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"grid")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"grid") || !strcasecmp(rgr_lst[rgr_var_idx].key,"scrip")){
       rgr->fl_grd=(char *)strdup(rgr_lst[rgr_var_idx].val);
       rgr->flg_grd=True;
       continue;
     } /* !grid */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"skl")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"hnt_dst") || !strcmp(rgr_lst[rgr_var_idx].key,"fl_hnt_dst")){
+      rgr->fl_hnt_dst=(char *)strdup(rgr_lst[rgr_var_idx].val);
+      continue;
+    } /* !hnt_dst */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"hnt_src") || !strcmp(rgr_lst[rgr_var_idx].key,"fl_hnt_src")){
+      rgr->fl_hnt_src=(char *)strdup(rgr_lst[rgr_var_idx].val);
+      continue;
+    } /* !hnt_src */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"msk_var") || !strcmp(rgr_lst[rgr_var_idx].key,"mask_var") || !strcmp(rgr_lst[rgr_var_idx].key,"mask") || !strcmp(rgr_lst[rgr_var_idx].key,"mask_variable")){
+      rgr->msk_var=(char *)strdup(rgr_lst[rgr_var_idx].val);
+      rgr->flg_msk_out=True;
+      continue;
+    } /* !msk_var */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"skl")){
       rgr->fl_skl=(char *)strdup(rgr_lst[rgr_var_idx].val);
       rgr->flg_grd=True;
       continue;
@@ -284,106 +309,123 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
       rgr->flg_nfr=True;
       continue;
     } /* !ugrid */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"no_area") || !strcasecmp(rgr_lst[rgr_var_idx].key,"no_area_out")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"no_area") || !strcmp(rgr_lst[rgr_var_idx].key,"no_area_out")){
       rgr->flg_area_out=False;
       continue;
     } /* !area */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"cell_measures") || !strcasecmp(rgr_lst[rgr_var_idx].key,"cll_msr")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"no_msk") || !strcmp(rgr_lst[rgr_var_idx].key,"no_msk_out") || !strcmp(rgr_lst[rgr_var_idx].key,"no_mask") || !strcmp(rgr_lst[rgr_var_idx].key,"no_mask_out")){
+      rgr->flg_msk_out=False;
+      continue;
+    } /* !msk */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"msk_out") || !strcmp(rgr_lst[rgr_var_idx].key,"mask_out")){
+      rgr->flg_msk_out=True;
+      continue;
+    } /* !mask */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"cell_measures") || !strcmp(rgr_lst[rgr_var_idx].key,"cll_msr")){
       rgr->flg_cll_msr=True;
       continue;
     } /* !cell_measures */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"no_cell_measures") || !strcasecmp(rgr_lst[rgr_var_idx].key,"no_cll_msr")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"no_cell_measures") || !strcmp(rgr_lst[rgr_var_idx].key,"no_cll_msr")){
       rgr->flg_cll_msr=False;
       continue;
     } /* !cell_measures */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"curvilinear") || !strcasecmp(rgr_lst[rgr_var_idx].key,"crv")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"curvilinear") || !strcmp(rgr_lst[rgr_var_idx].key,"crv")){
       rgr->flg_crv=True;
       continue;
     } /* !curvilinear */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"infer") || !strcasecmp(rgr_lst[rgr_var_idx].key,"nfr")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"infer") || !strcmp(rgr_lst[rgr_var_idx].key,"nfr")){
       rgr->flg_nfr=True;
       continue;
     } /* !infer */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"no_stagger") || !strcasecmp(rgr_lst[rgr_var_idx].key,"no_stg")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"diagnose_area") || !strcmp(rgr_lst[rgr_var_idx].key,"dgn_area")){
+      rgr->flg_dgn_area=True;
+      continue;
+    } /* !diagnose_area */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"diagnose_bounds") || !strcmp(rgr_lst[rgr_var_idx].key,"dgn_bnd")){
+      rgr->flg_dgn_bnd=True;
+      continue;
+    } /* !diagnose_bounds */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"no_stagger") || !strcmp(rgr_lst[rgr_var_idx].key,"no_stg")){
       rgr->flg_stg=False;
       continue;
     } /* !stagger */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"grd_ttl")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"grd_ttl")){
       if(rgr->grd_ttl) rgr->grd_ttl=(char *)nco_free(rgr->grd_ttl);
       rgr->grd_ttl=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !grd_ttl */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"idx_dbg")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"idx_dbg")){
       rgr->idx_dbg=strtol(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtol",sng_cnv_rcd);
       continue;
     } /* !idx_dbg */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"latlon")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"latlon")){
       cnv_nbr=sscanf(rgr_lst[rgr_var_idx].val,"%ld,%ld",&rgr->lat_nbr,&rgr->lon_nbr);
       assert(cnv_nbr == 2);
       continue;
     } /* !latlon */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lonlat")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lonlat")){
       cnv_nbr=sscanf(rgr_lst[rgr_var_idx].val,"%ld,%ld",&rgr->lon_nbr,&rgr->lat_nbr);
       assert(cnv_nbr == 2);
       continue;
     } /* !lonlat */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_nbr")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_nbr")){
       rgr->lat_nbr=strtol(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtol",sng_cnv_rcd);
       continue;
     } /* !lat_nbr */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_nbr")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_nbr")){
       rgr->lon_nbr=strtol(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtol",sng_cnv_rcd);
       continue;
     } /* !lon_nbr */
     if(!strcasecmp(rgr_lst[rgr_var_idx].key,"snwe")){
       cnv_nbr=sscanf(rgr_lst[rgr_var_idx].val,"%lf,%lf,%lf,%lf",&rgr->lat_sth,&rgr->lat_nrt,&rgr->lon_wst,&rgr->lon_est);
+      if(cnv_nbr != 4) (void)fprintf(stderr,"%s: ERROR %s unable to parse \"%s\" option value \"%s\" (possible typo in value?), aborting...\n",nco_prg_nm_get(),fnc_nm,rgr_lst[rgr_var_idx].key,rgr_lst[rgr_var_idx].val);
       assert(cnv_nbr == 4);
       if(cnv_nbr != 4) abort(); /* CEWI Use cnv_nbr at least once outside of assert() to avoid gcc 4.8.2 set-but-not-used warning */
       continue;
     } /* !snwe */
     if(!strcasecmp(rgr_lst[rgr_var_idx].key,"wesn")){
-      cnv_nbr=sscanf(rgr_lst[rgr_var_idx].val,"%lf,%lf,%lf,%lf",&rgr->lon_wst,&rgr->lon_est,&rgr->lat_sth,&rgr->lat_nrt);
+      if(cnv_nbr != 4) cnv_nbr=sscanf(rgr_lst[rgr_var_idx].val,"%lf,%lf,%lf,%lf",&rgr->lon_wst,&rgr->lon_est,&rgr->lat_sth,&rgr->lat_nrt);
       assert(cnv_nbr == 4);
       continue;
     } /* !wesn */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_crv")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_crv")){
       rgr->lat_crv=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       continue;
     } /* !lat_crv */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_crv")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_crv")){
       rgr->lon_crv=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       continue;
     } /* !lon_crv */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_sth")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_sth")){
       rgr->lat_sth=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       //      rgr->lat_typ=nco_grd_lat_bb;
       continue;
     } /* !lat_sth */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_wst")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_wst")){
       rgr->lon_wst=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       rgr->lon_typ=nco_grd_lon_bb;
       continue;
     } /* !lon_wst */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_nrt")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_nrt")){
       rgr->lat_nrt=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       //rgr->lat_typ=nco_grd_lat_bb;
       continue;
     } /* !lat_nrt */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_est")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_est")){
       rgr->lon_est=strtod(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtod",sng_cnv_rcd);
       rgr->lon_typ=nco_grd_lon_bb;
       continue;
     } /* !lon_est */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_typ")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_typ")){
       if(!strcasecmp(rgr_lst[rgr_var_idx].val,"cap") || !strcasecmp(rgr_lst[rgr_var_idx].val,"fv") || !strcasecmp(rgr_lst[rgr_var_idx].val,"fix") || !strcasecmp(rgr_lst[rgr_var_idx].val,"yarmulke")){
 	rgr->lat_typ=nco_grd_lat_fv;
 	rgr->grd_typ=nco_grd_2D_fv;
@@ -393,10 +435,13 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
       }else if(!strcasecmp(rgr_lst[rgr_var_idx].val,"gss")){
 	rgr->lat_typ=nco_grd_lat_gss;
 	rgr->grd_typ=nco_grd_2D_gss;
-      }else abort();
+      }else{
+	(void)fprintf(stderr,"%s: ERROR %s unable to parse \"%s\" option value \"%s\" (possible typo in value?), aborting...\n",nco_prg_nm_get(),fnc_nm,rgr_lst[rgr_var_idx].key,rgr_lst[rgr_var_idx].val);
+	abort();
+      } /* !val */
       continue;
     } /* !lat_typ */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_typ")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_typ")){
       if(!strcasecmp(rgr_lst[rgr_var_idx].val,"180_wst"))
 	rgr->lon_typ=nco_grd_lon_180_wst;
       else if(!strcasecmp(rgr_lst[rgr_var_idx].val,"180_ctr"))
@@ -405,83 +450,91 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
 	rgr->lon_typ=nco_grd_lon_Grn_wst;
       else if(!strcasecmp(rgr_lst[rgr_var_idx].val,"Grn_ctr"))
 	rgr->lon_typ=nco_grd_lon_Grn_ctr;
-      else abort();
+      else{
+	(void)fprintf(stderr,"%s: ERROR %s unable to parse \"%s\" option value \"%s\" (possible typo in value?), aborting...\n",nco_prg_nm_get(),fnc_nm,rgr_lst[rgr_var_idx].key,rgr_lst[rgr_var_idx].val);
+	abort();
+      } /* !val */
       continue;
     } /* !lon_typ */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"area_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"area_nm")){
       rgr->area_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !area_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"bnd_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"bnd_nm")){
       rgr->bnd_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !bnd_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"bnd_tm_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"bnd_tm_nm")){
       rgr->bnd_tm_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !bnd_tm_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"col_nm_in") || !strcasecmp(rgr_lst[rgr_var_idx].key,"col_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"col_nm_in") || !strcmp(rgr_lst[rgr_var_idx].key,"col_nm")){
       rgr->col_nm_in=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !col_nm_in */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"col_nm_out")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"col_nm_out")){
       rgr->col_nm_out=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !col_nm_out */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"frc_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"frc_nm")){
       rgr->frc_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !frc_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_bnd_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_bnd_nm")){
       rgr->lat_bnd_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_bnd_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_dmn_nm") || !strcasecmp(rgr_lst[rgr_var_idx].key,"lat_dmn")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_dmn_nm") || !strcmp(rgr_lst[rgr_var_idx].key,"lat_dmn")){
       rgr->lat_dmn_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_dmn_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_nm_in") || !strcasecmp(rgr_lst[rgr_var_idx].key,"lat_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_nm_in") || !strcmp(rgr_lst[rgr_var_idx].key,"lat_nm")){
       rgr->lat_nm_in=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_nm_in */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_nm_out")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_nm_out")){
       rgr->lat_nm_out=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_nm_out */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_vrt_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_vrt_nm")){
       rgr->lat_vrt_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_vrt_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lat_wgt_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lat_wgt_nm")){
       rgr->lat_wgt_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lat_wgt_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_bnd_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_bnd_nm")){
       rgr->lon_bnd_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lon_bnd_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_dmn_nm") || !strcasecmp(rgr_lst[rgr_var_idx].key,"lon_dmn")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_dmn_nm") || !strcmp(rgr_lst[rgr_var_idx].key,"lon_dmn")){
       rgr->lon_dmn_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lon_dmn_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_nm_in") || !strcasecmp(rgr_lst[rgr_var_idx].key,"lon_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_nm_in") || !strcmp(rgr_lst[rgr_var_idx].key,"lon_nm")){
       rgr->lon_nm_in=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lon_nm_in */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_nm_out")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_nm_out")){
       rgr->lon_nm_out=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lon_nm_out */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"lon_vrt_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"lon_vrt_nm")){
       rgr->lon_vrt_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !lon_vrt_nm */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"tst")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"tst")){
       rgr->tst=strtol(rgr_lst[rgr_var_idx].val,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
       if(*sng_cnv_rcd) nco_sng_cnv_err(rgr_lst[rgr_var_idx].val,"strtol",sng_cnv_rcd);
       continue;
     } /* !tst */
-    if(!strcasecmp(rgr_lst[rgr_var_idx].key,"vrt_nm")){
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"msk_nm") || !strcmp(rgr_lst[rgr_var_idx].key,"mask_nm")){
+      rgr->msk_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
+      rgr->flg_msk_out=True;
+      continue;
+    } /* !msk_nm */
+    if(!strcmp(rgr_lst[rgr_var_idx].key,"vrt_nm")){
       rgr->vrt_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
     } /* !vrt_nm */
@@ -506,6 +559,7 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
   if(!rgr->lon_bnd_nm) rgr->lon_bnd_nm=(char *)strdup("lon_bnds"); /* [sng] Name of rectangular boundary variable for longitude */
   if(!rgr->lon_nm_in) rgr->lon_nm_in=(char *)strdup("lon"); /* [sng] Name of dimension to recognize as longitude */
   if(!rgr->lon_vrt_nm) rgr->lon_vrt_nm=(char *)strdup("lon_vertices"); /* [sng] Name of non-rectangular boundary variable for longitude */
+  if(!rgr->msk_nm) rgr->msk_nm=(char *)strdup("mask"); /* [sng] Name of variable containing destination mask */
   if(!rgr->vrt_nm) rgr->vrt_nm=(char *)strdup("nv"); /* [sng] Name of dimension to employ for vertices */
 
   /* Derived from defaults and command-line arguments */
@@ -546,7 +600,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
      grid_size: Number of gridcells (product of lat*lon)
      address: Source and destination index for each link pair
      num_links: Number of unique address pairs in remapping, i.e., size of sparse matrix
-     num_wgts: Number of weights per vertice for given remapping
+     num_wgts: Number of weights per vertice for given remapping (we only handle num_wgts == 1 below)
      = 1 Bilinear
          Destination grid value determined by weights times known source grid values 
          at vertices of source quadrilateral that bounds destination point P
@@ -821,7 +875,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   int dst_grd_ctr_lat_id; /* [id] Destination grid center latitudes  variable ID */
   int dst_grd_ctr_lon_id; /* [id] Destination grid center longitudes variable ID */
   int frc_dst_id; /* [id] Fraction variable ID */
-  int msk_dst_id; /* [id] Mask variable ID */
+  int msk_dst_id=NC_MIN_INT; /* [id] Mask variable ID */
   int row_dst_adr_id; /* [id] Destination address (row) variable ID */
   int wgt_raw_id; /* [id] Remap matrix variable ID */
 
@@ -860,21 +914,25 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     break;
   } /* end switch */
   /* Obtain fields whose presence depends on mapfile type */
-  if(nco_rgr_mpf_typ == nco_rgr_mpf_ESMF){
-    rcd+=nco_inq_varid(in_id,"mask_b",&msk_dst_id); /* SCRIP: dst_grid_imask */
-  }else if(nco_rgr_mpf_typ == nco_rgr_mpf_SCRIP){
-    rcd+=nco_inq_varid(in_id,"dst_grid_imask",&msk_dst_id); /* ESMF: mask_b */
-  }else{ /* !SCRIP */
-    msk_dst_id=NC_MIN_INT;
-  } /* !Tempest */
+  nco_bool flg_msk_out=rgr->flg_msk_out; /* [flg] Add mask to output */
+  if(flg_msk_out){
+    if(nco_rgr_mpf_typ == nco_rgr_mpf_ESMF){
+      rcd+=nco_inq_varid(in_id,"mask_b",&msk_dst_id); /* SCRIP: dst_grid_imask */
+    }else if(nco_rgr_mpf_typ == nco_rgr_mpf_SCRIP){
+      rcd+=nco_inq_varid(in_id,"dst_grid_imask",&msk_dst_id); /* ESMF: mask_b */
+    }else{ /* !SCRIP */
+      msk_dst_id=NC_MIN_INT;
+      flg_msk_out=False;
+    } /* !Tempest */
+  } /* !flg_msk_out */
   /* Obtain fields whose names are independent of mapfile type */
   rcd+=nco_inq_varid(in_id,"src_grid_dims",&dmn_sz_in_int_id);
   rcd+=nco_inq_varid(in_id,"dst_grid_dims",&dmn_sz_out_int_id);
 
-  int lon_psn_src; /* [idx] Ordinal position of longitude size in rectangular source grid */
-  int lat_psn_src; /* [idx] Ordinal position of latitude  size in rectangular source grid */
-  int lon_psn_dst=int_CEWI; /* [idx] Ordinal position of longitude size in rectangular destination grid */
-  int lat_psn_dst=int_CEWI; /* [idx] Ordinal position of latitude  size in rectangular destination grid */
+  int lon_psn_src; /* [idx] Ordinal position of longitude in rectangular source grid dimension-size array */
+  int lat_psn_src; /* [idx] Ordinal position of latitude  in rectangular source grid dimension-size array */
+  int lon_psn_dst=int_CEWI; /* [idx] Ordinal position of longitude in rectangular destination grid dimension-size array */
+  int lat_psn_dst=int_CEWI; /* [idx] Ordinal position of latitude  in rectangular destination grid dimension-size array */
   if(flg_grd_in_2D){
     lon_psn_src=0; /* SCRIP introduced [lon,lat] convention because more natural for Fortran */
     lat_psn_src=1;
@@ -937,7 +995,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   double *wgt_raw; /* [frc] Remapping weights */
   int *col_src_adr; /* [idx] Source address (col) */
   int *row_dst_adr; /* [idx] Destination address (row) */
-  int *msk_out=NULL; /* [flg] Mask of destination grid */
+  int *msk_out=NULL; /* [flg] Mask on destination grid */
   int *dmn_sz_in_int; /* [nbr] Array of dimension sizes of source grid */
   int *dmn_sz_out_int; /* [nbr] Array of dimension sizes of destination grid */
   long *dmn_cnt_in=NULL;
@@ -1046,7 +1104,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     rcd=nco_get_vara(in_id,dst_grd_crn_lon_id,dmn_srt,dmn_cnt,lon_crn_out,crd_typ_out);
     rcd=nco_get_vara(in_id,dst_grd_crn_lat_id,dmn_srt,dmn_cnt,lat_crn_out,crd_typ_out);
 
-    /* User may specify curvilinear grid (with --rgr crv='y'). If not specified, manually test output grid for curvilinearity... */
+    /* User may specify curvilinear grid (with --rgr crv). If not specified, manually test output grid for curvilinearity... */
     flg_grd_out_crv=rgr->flg_crv; /* [flg] Curvilinear coordinates */
     if(flg_grd_out_crv){
       if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO Output grid specified to be %s\n",nco_prg_nm_get(),flg_grd_out_crv ? "Curvilinear" : "Rectangular");
@@ -1262,10 +1320,12 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     const double lat_ctr_tst_eqa=lat_ntf_out[0]+lat_spn*1.5/lat_nbr_out;
     const double lat_ctr_tst_fv=lat_ntf_out[0]+lat_spn/(lat_nbr_out-1);
     double lat_ctr_tst_gss;
-    /* In diagnosing grids, agreement with input to single-precision is "good enough for government work"
+    /* In diagnosing grids, agreement to slightly worse than single-precision is "good enough for government work"
        Hence some comparisons cast from double to float before comparison
        20150526: T42 grid from SCRIP and related maps, and NCL-generated Gaussian grids for CESM, are accurate to at most ~eight digits
-       20150611: map_ne120np4_to_fv801x1600_bilin.150418.nc has yc_b[1600]=-89.775000006 not expected exact value lat_ctr[1]=-89.775000000000006 */
+       20150611: map_ne120np4_to_fv801x1600_bilin.150418.nc has yc_b[1600]=-89.775000006 not expected exact value lat_ctr[1]=-89.775000000000006
+       20170521: T62 grid from NCEP-NCAR Reanalysis 1 worse than single precision, has yc_[192]=-86.6531 not expected exact value lat_ctr[1]=-86.6532 */
+
     if((float)lat_ctr_out[1] == (float)lat_ctr_tst_eqa) nco_grd_lat_typ=nco_grd_lat_eqa;
     if((float)lat_ctr_out[1] == (float)lat_ctr_tst_fv) nco_grd_lat_typ=nco_grd_lat_fv;
     double *wgt_Gss_out=NULL; // [frc] Gaussian weights double precision
@@ -1503,9 +1563,9 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   if(nco_rgr_mpf_typ != nco_rgr_mpf_SCRIP){
     rcd=nco_get_vara(in_id,wgt_raw_id,dmn_srt,dmn_cnt,wgt_raw,NC_DOUBLE);
   }else if(nco_rgr_mpf_typ == nco_rgr_mpf_SCRIP){
-    /* SCRIP mapfiles stored 2D weight array remap_matrix[num_links,num_wgts]
+    /* SCRIP mapfiles store 2D weight array remap_matrix[num_links,num_wgts]
        Apply only first weight for first-order conservative accuracy (i.e., area overlap)
-       Applying all three weights for second-order conservative accuracy (by including gradients from centroid to vertices) */
+       Apply all three weights for second-order conservative accuracy (by including gradients from centroid to vertices) */
     dmn_srd[0]=1L;
     dmn_srt[1]=0L;
     dmn_cnt[1]=1L;
@@ -1563,7 +1623,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
        ncks --cdl -m ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc | grep coordinates
        4LFTX_221_SPDY_S113:coordinates = "gridlat_221 gridlon_221" ;
        Usage:
-       ncks -O -D 3 --rgr nfr=y --rgr_var=ALBDO_221_SFC_S113 --rgr grid=~/grd_narr.nc ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc ~/foo.nc */
+       ncks -O -D 3 --rgr infer --rgr_var=ALBDO_221_SFC_S113 --rgr grid=~/grd_narr.nc ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc ~/foo.nc */
     char crd_sng[]="coordinates"; /* CF-standard coordinates attribute name */
     
     cf=(cf_crd_sct *)nco_malloc(sizeof(cf_crd_sct));
@@ -1601,40 +1661,81 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     } /* !rcd && att_typ */
       
     /* Valid coordinates attribute requires two coordinate names separated by space character */
-    char *sbs_srt; /* [sng] Coordinate name start position */
-    char *sbs_end; /* [sng] Coordinate name   end position */
-    cf->crd_nm[0]=(char *)strdup(cf->crd_sng);
-    sbs_end=strchr(cf->crd_nm[0],' ');
-    /* NUL-terminate first coordinate name */
-    *sbs_end='\0'; 
-    sbs_srt=sbs_end+1; 
-    cf->crd_nm[1]=(char *)strdup(sbs_srt);
-
-    if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[0],&cf->crd_id[0])) != NC_NOERR){
-      (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0]);
+    char *crd_nm[NCO_MAX_CRD_PER_VAR]; /* [sng] Coordinate name start position */
+    char *crd_dpl; /* [sng] Modifiable duplicate of coordinates string */
+    char *spc_ptr; /* [sng] Pointer to space character (' ') */
+    int crd_nbr=0; /* [nbr] Number of names in coordinates attribute */
+    int crd_spt=0; /* [nbr] Number of "spatial-like" (that include "degree" in units) coordinates */
+    int crd_idx=0; /* [idx] Counter for coordinate names */
+    for(crd_idx=0;crd_idx<NCO_MAX_CRD_PER_VAR;crd_idx++) crd_nm[crd_idx]=NULL;
+    crd_dpl=(char *)strdup(cf->crd_sng);
+    /* Search for spaces starting from end of string */
+    while((spc_ptr=strrchr(crd_dpl,' '))){
+      crd_nm[crd_nbr]=spc_ptr+1L;
+      crd_nbr++;
+      /* NUL-terminate so next search ends here */
+      *spc_ptr='\0'; 
+    } /* !sbs_ptr */
+    /* Final coordinate name begins where coordinate string starts */
+    crd_nm[crd_nbr]=crd_dpl;
+    if(crd_nbr < 2){
+      (void)fprintf(stderr,"%s: WARNING %s found only %d coordinates in coordinates attribute \"%s\", at least two are required. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,crd_nbr,cf->crd_sng);
       goto skp_cf;
-    } /* !rcd */ 
-    if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[1],&cf->crd_id[1])) != NC_NOERR){
-      (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1]);
-      goto skp_cf;
-    } /* !rcd */ 
-
-    rcd=nco_inq_att_flg(in_id,cf->crd_id[0],unt_sng,&att_typ,&att_sz);
-    if(rcd == NC_NOERR && att_typ == NC_CHAR){
-      cf->unt_sng[0]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
-      rcd=nco_get_att(in_id,cf->crd_id[0],unt_sng,cf->unt_sng[0],att_typ);
-      /* NUL-terminate attribute before using strstr() */
-      *(cf->unt_sng[0]+att_sz)='\0';
-      if(!strcasestr(cf->unt_sng[0],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->unt_sng[0]);
-    } /* !rcd && att_typ */
-    rcd=nco_inq_att_flg(in_id,cf->crd_id[1],unt_sng,&att_typ,&att_sz);
-    if(rcd == NC_NOERR && att_typ == NC_CHAR){
-      cf->unt_sng[1]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
-      rcd=nco_get_att(in_id,cf->crd_id[1],unt_sng,cf->unt_sng[1],att_typ);
-      /* NUL-terminate attribute before using strstr() */
-      *(cf->unt_sng[1]+att_sz)='\0';
-      if(!strcasestr(cf->unt_sng[1],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1],cf->unt_sng[1]);
-    } /* !rcd && att_typ */
+    } /* !crd_nbr */
+    /* If more than two coordinate names are present, choose first two (searching backwards from end) with "degree" in units attributes, otherwise just choose first two */
+    crd_idx=crd_spt=0;
+    while(crd_spt < 2 && crd_idx < crd_nbr){
+      cf->crd_nm[crd_spt]=crd_nm[crd_idx];
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[crd_spt],&cf->crd_id[crd_spt])) == NC_NOERR){
+	rcd=nco_inq_att_flg(in_id,cf->crd_id[crd_spt],unt_sng,&att_typ,&att_sz);
+	if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	  cf->unt_sng[crd_spt]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	  rcd=nco_get_att(in_id,cf->crd_id[crd_spt],unt_sng,cf->unt_sng[crd_spt],att_typ);
+	  /* NUL-terminate attribute before using strstr() */
+	  *(cf->unt_sng[crd_spt]+att_sz)='\0';
+	  if(strcasestr(cf->unt_sng[crd_spt],"degree")){
+	    /* Increment count of spatial-like coordinates... */
+	    crd_spt++;
+	  }else{
+	    /* ...or free() memory allocated during search */
+	    cf->unt_sng[crd_spt]=(char *)nco_free(cf->unt_sng[crd_spt]);
+	  } /* !strcasestr() */
+	  crd_idx++;
+	} /* !rcd && att_typ */
+      } /* !rcd */ 
+    } /* !crd_spt */
+
+    /* If while()-loop above was successful, our search is over
+       Otherwise, use first two coordinate names regardless of units, and print more diagnostics */
+    if(crd_spt < 2){
+      cf->crd_nm[0]=crd_nm[0];
+      cf->crd_nm[1]=crd_nm[1];
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[0],&cf->crd_id[0])) != NC_NOERR){
+	(void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s not found. Turning-off CF coordinates search for this file.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0]);
+	goto skp_cf;
+      } /* !rcd */ 
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[1],&cf->crd_id[1])) != NC_NOERR){
+	(void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s not found. Turning-off CF coordinates search for this file.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1]);
+	goto skp_cf;
+      } /* !rcd */ 
+      
+      rcd=nco_inq_att_flg(in_id,cf->crd_id[0],unt_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	cf->unt_sng[0]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd=nco_get_att(in_id,cf->crd_id[0],unt_sng,cf->unt_sng[0],att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	*(cf->unt_sng[0]+att_sz)='\0';
+	if(!strcasestr(cf->unt_sng[0],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->unt_sng[0]);
+      } /* !rcd && att_typ */
+      rcd=nco_inq_att_flg(in_id,cf->crd_id[1],unt_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	cf->unt_sng[1]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd=nco_get_att(in_id,cf->crd_id[1],unt_sng,cf->unt_sng[1],att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	*(cf->unt_sng[1]+att_sz)='\0';
+	if(!strcasestr(cf->unt_sng[1],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1],cf->unt_sng[1]);
+      } /* !rcd && att_typ */
+    } /* !crd_spt */
       
     int crd_rnk; /* [nbr] Coordinate rank */
     rcd=nco_inq_varndims(in_id,cf->crd_id[0],&crd_rnk);
@@ -1695,8 +1796,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s Coordinates %s and %s \"units\" values are \"%s\" and \"%s\", respectively.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->crd_nm[1],cf->unt_sng[0] ? cf->unt_sng[0] : "(non-existent)",cf->unt_sng[1] ? cf->unt_sng[1] : "(non-existent)");
 
     /* Clean-up CF coordinates memory */
-    if(cf->crd_nm[0]) cf->crd_nm[0]=(char *)nco_free(cf->crd_nm[0]);
-    if(cf->crd_nm[1]) cf->crd_nm[1]=(char *)nco_free(cf->crd_nm[1]);
+    if(crd_dpl) crd_dpl=(char *)nco_free(crd_dpl);
     if(cf->crd_sng) cf->crd_sng=(char *)nco_free(cf->crd_sng);
     if(cf->dmn_nm[0]) cf->dmn_nm[0]=(char *)nco_free(cf->dmn_nm[0]);
     if(cf->dmn_nm[1]) cf->dmn_nm[1]=(char *)nco_free(cf->dmn_nm[1]);
@@ -1752,7 +1852,8 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     else if((rcd=nco_inq_dimid_flg(in_id,"Cell_Along_Swath:mod04",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("Cell_Along_Swath:mod04"); /* MODIS MOD04 L2 */
     else if((rcd=nco_inq_dimid_flg(in_id,"Cell_Along_Swath_mod04",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("Cell_Along_Swath_mod04"); /* MODIS MOD04 L2 (ncl_convert2nc changes colon to underscore) */
     else if((rcd=nco_inq_dimid_flg(in_id,"CO_Latitude",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("CO_Latitude");
-    else if((rcd=nco_inq_dimid_flg(in_id,"x",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("x"); /* NSIDC polar stereographic */
+    else if((rcd=nco_inq_dimid_flg(in_id,"y",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("y"); /* NEMO */
+    else if((rcd=nco_inq_dimid_flg(in_id,"x",&dmn_id_lat)) == NC_NOERR) lat_nm_in=strdup("x"); /* NSIDC polar stereographic (NB: unfortunate incompatible conflict between NEMO & NSIDC names) */
     else{
       (void)fprintf(stdout,"%s: ERROR %s reports unable to find latitude dimension in input file. Tried the usual suspects. HINT: Inform regridder of latitude dimension name with --rgr lat_nm=name\n",nco_prg_nm_get(),fnc_nm);
       nco_exit(EXIT_FAILURE);
@@ -1782,7 +1883,8 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     else if((rcd=nco_inq_dimid_flg(in_id,"GeoXTrack:L2_Standard_atmospheric&surface_product",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("GeoXTrack:L2_Standard_atmospheric&surface_product"); /* AIRS L2 HDF */
     else if((rcd=nco_inq_dimid_flg(in_id,"Cell_Across_Swath:mod04",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("Cell_Across_Swath:mod04"); /* MODIS MOD04 L2 */
     else if((rcd=nco_inq_dimid_flg(in_id,"Cell_Across_Swath_mod04",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("Cell_Across_Swath_mod04"); /* MODIS MOD04 L2 (ncl_convert2nc changes colon to underscore) */
-    else if((rcd=nco_inq_dimid_flg(in_id,"y",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("y"); /* NSIDC polar stereographic */
+    else if((rcd=nco_inq_dimid_flg(in_id,"x",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("x"); /* NEMO */
+    else if((rcd=nco_inq_dimid_flg(in_id,"y",&dmn_id_lon)) == NC_NOERR) lon_nm_in=strdup("y"); /* NSIDC polar stereographic (NB: unfortunate incompatible conflict between NEMO & NSIDC names) */
     else{
       (void)fprintf(stdout,"%s: ERROR %s reports unable to find longitude dimension in input file. Tried the usual suspects. HINT: Inform regridder of longitude dimension name with --rgr lon_nm=name\n",nco_prg_nm_get(),fnc_nm);
       nco_exit(EXIT_FAILURE);
@@ -1794,24 +1896,25 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     } /* !err */
   } /* !2D */
     
-  /* Do not extract grid variables (that are also extensive variables) like lon, lat, and area
+  /* Do not extract grid variables (that are also extensive variables) like lon, lat, area, and masks
      If necessary, use remap data to diagnose them from scratch
      Other extensive variables (like counts, population) will be extracted and summed not averaged */
-  const int var_xcl_lst_nbr=44; /* [nbr] Number of objects on exclusion list */
   /* Exception list source:
+     ALM/CLM: landmask (20170504: Debatable, including erroneous mask may be better than completely excluding an expected mask) (20170504: must keep landfrac since regridded by ncremap for SGS option)
      AMSR: Latitude, Longitude
      CAM, CERES, CMIP5: lat, lon
      CAM, CMIP5: gw, lat_bnds, lon_bnds
      CAM-FV: slon, slat, w_stag (w_stag is weights for slat grid, analagous to gw for lat grid)
      CAM-SE: area
-     CICE: latt_bounds, lont_bounds, latu_bounds, lonu_bounds, TLAT, TLON, ULAT, ULON (NB: CICE uses ?LON and POP uses ?LONG)
+     CICE: latt_bounds, lont_bounds, latu_bounds, lonu_bounds, TLAT, TLON, ULAT, ULON (NB: CICE uses ?LON and POP uses ?LONG) (aice is ice area, tmask is state-variable mask, both not currently excluded, although all binary masks like tmask should be recomputed on new grid)
      ESMF: gridcell_area
      GPM: S1_Latitude, S1_Longitude
      HIRDLS: Latitude
-     MAR: LAT, LON
+     MAR/RACMO: LAT, LON
      MLS: CO_Latitude
      MPAS-O/I: areaCell, latCell, lonCell
      NCO: lat_vertices, lon_vertices
+     NEMO: nav_lat, nav_lon
      OCO2: latitude_bnds, longitude_bnds
      OMI DOMINO: Latitude, LatitudeCornerpoints, Longitude, LongitudeCornerpoints
      POP: TLAT, TLONG, ULAT, ULONG  (NB: CICE uses ?LON and POP uses ?LONG) (POP does not archive spatial bounds)
@@ -1819,7 +1922,8 @@ nco_rgr_map /* [fnc] Regrid with external weights */
      UV-CDAT regridder: bounds_lat, bounds_lon
      Unknown: XLAT_M, XLONG_M
      WRF: XLAT, XLONG */
-  const char *var_xcl_lst[]={"/area","/areaCell","/gridcell_area","/gw","/LAT","/lat","/latCell","/Latitude","/latitude","/CO_Latitude","/slat","/S1_Latitude","/TLAT","/ULAT","/XLAT","/XLAT_M","/lat_bnds","/lat_vertices","/latt_bounds","/latu_bounds","/latitude_bnds","/LatitudeCornerpoints","/bounds_lat","/LON","/lon","/lonCell","/Longitude","/longitude","/slon","/S1_Longitude","/TLON","/TLONG","/ULON","/ULONG","/XLONG","/XLONG_M","/lon_bnds","/lon_vertices","/lont_bounds","/lonu_bounds" [...]
+  const int var_xcl_lst_nbr=46; /* [nbr] Number of objects on exclusion list */
+  const char *var_xcl_lst[]={"/area","/areaCell","/gridcell_area","/gw","/LAT","/lat","/latCell","/Latitude","/latitude","/nav_lat","/slat","/TLAT","/ULAT","/XLAT","/XLAT_M","/CO_Latitude","/S1_Latitude","/lat_bnds","/lat_vertices","/latt_bounds","/latu_bounds","/latitude_bnds","/LatitudeCornerpoints","/bounds_lat","/LON","/lon","/lonCell","/Longitude","/longitude","/nav_lon","/slon","/TLON","/TLONG","/ULON","/ULONG","/XLONG","/XLONG_M","/CO_Longitude","/S1_Longitude","/lon_bnds","/lon_v [...]
   int var_cpy_nbr=0; /* [nbr] Number of copied variables */
   int var_rgr_nbr=0; /* [nbr] Number of regridded variables */
   int var_xcl_nbr=0; /* [nbr] Number of deleted variables */
@@ -1848,7 +1952,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
 	if(!strcmp(trv_tbl->lst[idx_tbl].nm_fll,mpas_xcl_lst[idx])) break;
       if(idx_tbl < trv_nbr){
 	if(trv_tbl->lst[idx_tbl].flg_xtr){
-	  if(nco_dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stdout,"%s: INFO automatically omitting (not copying or regridding from input) pre-defined exclusion-list variable %s\n",nco_prg_nm_get(),trv_tbl->lst[idx_tbl].nm_fll);
+	  if(nco_dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stdout,"%s: INFO automatically omitting (not copying or regridding from input) pre-defined MPAS exclusion-list variable %s\n",nco_prg_nm_get(),trv_tbl->lst[idx_tbl].nm_fll);
 	  var_xcl_nbr++;
 	} /* endif */
 	trv_tbl->lst[idx_tbl].flg_xtr=False;
@@ -1943,6 +2047,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   char *lat_wgt_nm;
   char *lon_bnd_nm_out;
   char *lon_nm_out;
+  char *msk_nm_out;
   char *slat_nm_out=NULL;
   char *slat_wgt_nm_out=NULL;
   char *slon_nm_out=NULL;
@@ -1957,6 +2062,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   int lat_wgt_id; /* [id] Variable ID for latitude weight */
   int lon_bnd_id; /* [id] Variable ID for lon_bnds/lon_vertices */
   int lat_bnd_id; /* [id] Variable ID for lat_bnds/lat_vertices */
+  int msk_out_id; /* [id] Variable ID for mask */
   int slat_out_id; /* [id] Variable ID for staggered latitude */
   int slat_wgt_id; /* [id] Variable ID for staggered latitude weight */
   int slon_out_id; /* [id] Variable ID for staggered longitude */
@@ -1971,6 +2077,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   lat_bnd_nm_out=rgr->lat_bnd_nm;
   lat_wgt_nm=rgr->lat_wgt_nm;
   lon_bnd_nm_out=rgr->lon_bnd_nm;
+  msk_nm_out=rgr->msk_nm;
   /* Use explicitly specified output names, if any, otherwise use input names (either explicitly specified or discovered by fuzzing) */
   if(rgr->col_nm_out) col_nm_out=rgr->col_nm_out; else col_nm_out=col_nm_in;
   if(rgr->lat_nm_out) lat_nm_out=rgr->lat_nm_out; else lat_nm_out=lat_nm_in;
@@ -2016,8 +2123,8 @@ nco_rgr_map /* [fnc] Regrid with external weights */
   aed_mtd_crd.val.cp=att_val_crd;
 
   /* Reminder: 
-     Regridder area_out options, e.g., --rgr area_out=Y, set flg_area_out to control adding "area" variable to regridded output
-     Regridder cll_msr options, --rgr cll_msr=Y, set flg_cll_msr to control adding "cell_measures" attribute to regridded output
+     Regridder area_out options, e.g., --rgr area_out, set flg_area_out to control adding "area" variable to regridded output
+     Regridder cll_msr options, --rgr cll_msr, set flg_cll_msr to control adding "cell_measures" attribute to regridded output
      ncks & ncra cll_msr options, --cll_msr, set EXTRACT_CLL_MSR to control adding "cell_measures" variables (e.g., area) to extraction list of input file
      EXTRACT_CLL_MSR supercedes --rgr area_out in determining whether to add "area" to regridded output */
   nco_bool flg_area_out=rgr->flg_area_out; /* [flg] Add area to output */
@@ -2100,6 +2207,11 @@ nco_rgr_map /* [fnc] Regrid with external weights */
       if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,frc_out_id,shuffle,deflate,dfl_lvl);
       var_crt_nbr++;
     } /* !flg_frc_out_wrt */
+    if(flg_msk_out){
+      rcd+=nco_def_var(out_id,msk_nm_out,(nc_type)NC_INT,dmn_nbr_1D,&dmn_id_col,&msk_out_id);
+      if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,msk_out_id,shuffle,deflate,dfl_lvl);
+      var_crt_nbr++;
+    } /* !flg_msk_out */
   } /* !flg_grd_out_1D */
   if(flg_grd_out_crv){
     dmn_ids_out[0]=dmn_id_lat;
@@ -2120,6 +2232,11 @@ nco_rgr_map /* [fnc] Regrid with external weights */
       if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,frc_out_id,shuffle,deflate,dfl_lvl);
       var_crt_nbr++;
     } /* !flg_frc_out_wrt */
+    if(flg_msk_out){
+      rcd+=nco_def_var(out_id,msk_nm_out,crd_typ_out,dmn_nbr_2D,dmn_ids_out,&msk_out_id);
+      if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,msk_out_id,shuffle,deflate,dfl_lvl);
+      var_crt_nbr++;
+    } /* !flg_msk_out */
     dmn_ids_out[0]=dmn_id_lat;
     dmn_ids_out[1]=dmn_id_lon;
     dmn_ids_out[2]=dmn_id_bnd;
@@ -2173,6 +2290,11 @@ nco_rgr_map /* [fnc] Regrid with external weights */
       if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,frc_out_id,shuffle,deflate,dfl_lvl);
       var_crt_nbr++;
     } /* !flg_frc_out_wrt */
+    if(flg_msk_out){
+      rcd+=nco_def_var(out_id,msk_nm_out,crd_typ_out,dmn_nbr_2D,dmn_ids_out,&msk_out_id);
+      if(dfl_lvl > 0) (void)nco_def_var_deflate(out_id,msk_out_id,shuffle,deflate,dfl_lvl);
+      var_crt_nbr++;
+    } /* !flg_msk_out */
   } /* !flg_grd_out_rct */
 
   /* Pre-allocate dimension ID and cnt/srt space */
@@ -2439,6 +2561,21 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     if(att_val) att_val=(char *)nco_free(att_val);
   } /* !flg_frc_out_wrt */
   
+  if(flg_msk_out){
+    att_nm=strdup("long_name");
+    att_val=strdup("Mask (0 = invalid destination, 1 = valid destination)");
+    aed_mtd.att_nm=att_nm;
+    aed_mtd.var_nm=msk_nm_out;
+    aed_mtd.id=msk_out_id;
+    aed_mtd.sz=strlen(att_val);
+    aed_mtd.type=NC_CHAR;
+    aed_mtd.val.cp=att_val;
+    aed_mtd.mode=aed_create;
+    (void)nco_aed_prc(out_id,msk_out_id,aed_mtd);
+    if(att_nm) att_nm=(char *)nco_free(att_nm);
+    if(att_val) att_val=(char *)nco_free(att_val);
+  } /* !flg_msk_out */
+
   att_nm=strdup("long_name");
   att_val=strdup("Latitude");
   aed_mtd.att_nm=att_nm;
@@ -2796,6 +2933,12 @@ nco_rgr_map /* [fnc] Regrid with external weights */
       (void)nco_aed_prc(out_id,frc_out_id,aed_mtd_crd);
     } /* !flg_frc_out_wrt */
 
+    if(flg_msk_out){
+      aed_mtd_crd.var_nm=msk_nm_out;
+      aed_mtd_crd.id=msk_out_id;
+      (void)nco_aed_prc(out_id,msk_out_id,aed_mtd_crd);
+    } /* !flg_msk_out */
+
     aed_mtd_crd.var_nm=lat_nm_out;
     aed_mtd_crd.id=lat_out_id;
     (void)nco_aed_prc(out_id,lat_out_id,aed_mtd_crd);
@@ -2846,6 +2989,11 @@ nco_rgr_map /* [fnc] Regrid with external weights */
       dmn_cnt_tuo[0]=col_nbr_out;
       (void)nco_put_vara(out_id,area_out_id,dmn_srt_out,dmn_cnt_tuo,area_out,crd_typ_out);
     } /* !flg_area_out */
+    if(flg_msk_out){
+      dmn_srt_out[0]=0L;
+      dmn_cnt_tuo[0]=col_nbr_out;
+      (void)nco_put_vara(out_id,msk_out_id,dmn_srt_out,dmn_cnt_tuo,msk_out,crd_typ_out);
+    } /* !flg_msk_out */
   } /* !flg_grd_out_1D */
   if(flg_grd_out_crv){
     dmn_srt_out[0]=dmn_srt_out[1]=0L;
@@ -2859,6 +3007,9 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     if(flg_frc_out_wrt){
       (void)nco_put_vara(out_id,frc_out_id,dmn_srt_out,dmn_cnt_tuo,frc_out,crd_typ_out);
     } /* !flg_frc_out_wrt */
+    if(flg_msk_out){
+      (void)nco_put_vara(out_id,msk_out_id,dmn_srt_out,dmn_cnt_tuo,msk_out,crd_typ_out);
+    } /* !flg_msk_out */
     dmn_srt_out[0]=dmn_srt_out[1]=dmn_srt_out[2]=0L;
     dmn_cnt_tuo[0]=lat_nbr_out;
     dmn_cnt_tuo[1]=lon_nbr_out;
@@ -2906,6 +3057,9 @@ nco_rgr_map /* [fnc] Regrid with external weights */
     if(flg_frc_out_wrt){
       (void)nco_put_vara(out_id,frc_out_id,dmn_srt_out,dmn_cnt_tuo,frc_out,crd_typ_out);
     } /* !flg_frc_out_wrt */
+    if(flg_msk_out){
+      (void)nco_put_vara(out_id,msk_out_id,dmn_srt_out,dmn_cnt_tuo,msk_out,crd_typ_out);
+    } /* !flg_msk_out */
   } /* !flg_grd_out_rct */
 
   /* Regrid or copy variable values */
@@ -3321,7 +3475,7 @@ nco_rgr_map /* [fnc] Regrid with external weights */
        ncks -C -m -v XLAT,XLONG ${DATA}/hdf/wrfout_v2_Lambert.nc # Interrogate file
        ncwa -O -a Time ${DATA}/hdf/wrfout_v2_Lambert.nc ${DATA}/hdf/wrfout_v2_Lambert_notime.nc # Create simpler input
        ncks -C -d south_north,0 -d west_east,0 -v XLAT,XLONG ${DATA}/hdf/wrfout_v2_Lambert_notime.nc # Interrogate file
-       ncks -O -D 1 -t 1 -v T --rgr nfr=y --rgr idx_dbg=0 --rgr grid=${DATA}/sld/rgr/grd_wrf.nc ${DATA}/hdf/wrfout_v2_Lambert_notime.nc ~/foo.nc # Infer grid
+       ncks -O -D 1 -t 1 -v T --rgr infer --rgr idx_dbg=0 --rgr grid=${DATA}/sld/rgr/grd_wrf.nc ${DATA}/hdf/wrfout_v2_Lambert_notime.nc ~/foo.nc # Infer grid
        ESMF_RegridWeightGen -s ${DATA}/sld/rgr/grd_wrf.nc -d ${DATA}/grids/180x360_SCRIP.20150901.nc -w ${DATA}/sld/rgr/map_wrf_to_dst_aave.nc --method conserve --src_regional --ignore_unmapped # Template map
        ncks -O -D 1 -t 1 -v T --map=${DATA}/sld/rgr/map_wrf_to_dst_aave.nc ${DATA}/hdf/wrfout_v2_Lambert_notime.nc ~/foo.nc # Regrid manually
        ncremap -v T -i ${DATA}/hdf/wrfout_v2_Lambert_notime.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -o ${DATA}/sld/rgr # Regrid automatically
@@ -3880,8 +4034,6 @@ nco_rgr_tps /* [fnc] Regrid using TempestRemap library */
   /* Allow for whitespace characters in fl_grd_dst
      Assume CDL translation results in acceptable name for shell commands */
   fl_grd_dst_cdl=nm2sng_fl(fl_grd_dst);
-  //drc_tps=strcat(drc_tps,"/");
-  //drc_tps=strcat(drc_tps,fl_grd_dst);
 
   /* Construct and execute regridding command */
   nco_rgr_cmd=nco_rgr_GenerateRLLMesh;
@@ -4133,7 +4285,7 @@ nco_grd_mk /* [fnc] Create SCRIP-format grid file */
      https://acme-svn2.ornl.gov/acme-repo/acme/inputdata/cpl/gridmaps
 
      NCAR:
-     /glade/p/cesm/cseg/mapping/grids
+     yellowstone.ucar.edu:/glade/p/cesm/cseg/mapping/grids
 
      Global RLL grids:
      ncks -O -D 1 --rgr grd_ttl='Equiangular grid 180x360' --rgr grid=${DATA}/grids/180x360_SCRIP.20150901.nc --rgr latlon=180,360 --rgr lat_typ=eqa --rgr lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
@@ -4188,7 +4340,7 @@ nco_grd_mk /* [fnc] Create SCRIP-format grid file */
      ncks -O -D 1 --rgr grd_ttl='Equiangular grid 180x360' --rgr skl=${DATA}/sld/rgr/skl_180x360.nc --rgr grid=${DATA}/grids/180x360_SCRIP.20150901.nc --rgr latlon=180,360#lat_typ=eqa#lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
 
      Curvilinear grids:
-     ncks -O -D 1 --rgr grd_ttl='Curvilinear grid 10x20. Degenerate case.' --rgr crv=Y --rgr lon_crv=0.0 --rgr skl=${DATA}/sld/rgr/skl_crv.nc --rgr grid=${DATA}/sld/rgr/grd_crv.nc --rgr latlon=10,20 --rgr snwe=-5.0,5.0,-10.0,10.0 ~/nco/data/in.nc ~/foo.nc
+     ncks -O -D 1 --rgr grd_ttl='Curvilinear grid 10x20. Degenerate case.' --rgr crv --rgr lon_crv=0.0 --rgr skl=${DATA}/sld/rgr/skl_crv.nc --rgr grid=${DATA}/sld/rgr/grd_crv.nc --rgr latlon=10,20 --rgr snwe=-5.0,5.0,-10.0,10.0 ~/nco/data/in.nc ~/foo.nc
      ncks -O -D 1 --rgr grd_ttl='Curvilinear grid 10x20. Curvilinearity = 1.0 lon' --rgr lon_crv=1.0 --rgr skl=${DATA}/sld/rgr/skl_crv.nc --rgr grid=${DATA}/sld/rgr/grd_crv.nc --rgr latlon=10,20 --rgr snwe=-5.0,5.0,-10.0,10.0 ~/nco/data/in.nc ~/foo.nc
 
      1-D Latitude (no longitude) grids:
@@ -4358,8 +4510,8 @@ nco_grd_mk /* [fnc] Create SCRIP-format grid file */
   grd_crn_lon=(double *)nco_malloc(grd_crn_nbr*grd_sz_nbr*nco_typ_lng(crd_typ));
   
   /* Define variable values */
-  int lon_psn=int_CEWI; /* [idx] Ordinal position of longitude size in rectangular grid */
-  int lat_psn=int_CEWI; /* [idx] Ordinal position of latitude  size in rectangular grid */
+  int lon_psn=int_CEWI; /* [idx] Ordinal position of longitude in rectangular grid dimension-size array */
+  int lat_psn=int_CEWI; /* [idx] Ordinal position of latitude  in rectangular grid dimension-size array */
   if(grd_rnk_nbr == dmn_nbr_2D){
     lon_psn=0; /* SCRIP introduced [lon,lat] convention because more natural for Fortran */
     lat_psn=1;
@@ -5344,8 +5496,8 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   /* Purpose: Use grid information and guesswork to create SCRIP-format grid file from input data file
      
      Test curvilinear grids:
-     ncks -O -D 1 --rgr nfr=y --rgr grid=${DATA}/sld/rgr/grd_airs.nc ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.nc ~/foo.nc
-     ncks -O -D 1 --rgr nfr=y --rgr grid=${DATA}/sld/rgr/grd_airs.nc ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc ~/foo.nc */
+     ncks -O -D 1 --rgr infer --rgr grid=${DATA}/sld/rgr/grd_airs.nc ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.nc ~/foo.nc
+     ncks -O -D 1 --rgr infer --rgr grid=${DATA}/sld/rgr/grd_airs.nc ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc ~/foo.nc */
 
   const char fnc_nm[]="nco_grd_nfr()"; /* [sng] Function name */
 
@@ -5355,8 +5507,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   const int dmn_nbr_0D=0; /* [nbr] Rank of 0-D grid variables */
   const int dmn_nbr_1D=1; /* [nbr] Rank of 1-D grid variables */
   const int dmn_nbr_2D=2; /* [nbr] Rank of 2-D grid variables */
-  const int dmn_nbr_3D=3; /* [nbr] Rank of 3-D grid variables */
-  const int dmn_nbr_grd_max=dmn_nbr_3D; /* [nbr] Maximum rank of grid variables */
+  const int dmn_nbr_grd_max=4; /* [nbr] Maximum rank of grid variables (msk_[src/dst] could be rank 4) */
   const int itr_nbr_max=20; // [nbr] Maximum number of iterations
   const int idx_ccw=0; /* [idx] Index of starting vertice for CCW check (Point A = tail side AB) */
   const int rcr_lvl=1; /* [nbr] Recursion level (1 is top level, 2 and greater are recursed */
@@ -5401,15 +5552,16 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
   double area_ttl=0.0; /* [frc] Exact sum of area */
   double lat_nrt; /* [dgr] Latitude of northern edge of grid */
-  //double lat_sth; /* [dgr] Latitude of southern edge of grid */
+  double lat_sth; /* [dgr] Latitude of southern edge of grid */
   double lat_wgt_ttl=0.0; /* [frc] Actual sum of quadrature weights */
   double lat_wgt_gss; /* [frc] Latitude weight estimated from interface latitudes */
   //  double lon_est; /* [dgr] Longitude of eastern edge of grid */
-  //  double lon_wst; /* [dgr] Longitude of western edge of grid */
-  //  double lon_ncr; /* [dgr] Longitude increment */
+  double lon_wst; /* [dgr] Longitude of western edge of grid */
+  double lon_ncr; /* [dgr] Longitude increment */
   double lat_ncr; /* [dgr] Latitude increment */
   double lon_spn; /* [dgr] Longitude span */
   double lat_spn; /* [dgr] Latitude span */
+  double mss_val_area_dbl;
   double mss_val_ctr_dbl;
   double mss_val_msk_dbl;
   
@@ -5443,6 +5595,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   int lat_bnd_id=NC_MIN_INT; /* [id] Latitude centers of rectangular grid variable ID */
   int lon_bnd_id=NC_MIN_INT; /* [id] Longitude centers of rectangular grid variable ID */
   int msk_id=NC_MIN_INT; /* [id] Mask variable ID */
+  int msk_rnk_nbr; /* [id] Mask rank */
   int mss_val_int_out=NC_MIN_INT; /* [nbr] Value that can be non-erroneously pointed to */
   int val_two=2; /* [nbr] Value that can be non-erroneously pointed to */
   int val_zero=0; /* [nbr] Value that can be non-erroneously pointed to */
@@ -5453,7 +5606,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
   long att_sz;
   long bnd_idx;
-  long bnd_nbr; /* [nbr] Number of bounds in gridcell */
+  long bnd_nbr=NC_MIN_INT; /* [nbr] Number of bounds in gridcell */
   long col_idx;
   long col_nbr; /* [nbr] Number of columns in grid */
   long crn_idx; /* [idx] Counting index for corners */
@@ -5463,6 +5616,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   long grd_sz_nbr; /* [nbr] Number of gridcells in grid */
   long idx2; /* [idx] Counting index for unrolled grids */
   long idx; /* [idx] Counting index for unrolled grids */
+  long idx_crn;
   long idx_ctr;
   long lat_idx2; /* [idx] Counting index for unrolled latitude */
   long lat_idx;
@@ -5491,12 +5645,16 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   nco_bool flg_grd_crv=False;
   nco_bool flg_wrt_crn=True;
   nco_bool flg_crn_grd_lat_lon=False; /* [flg] Curvilinear corner array ordered non-canonically as grd_nbr,lat_nbr,lon_nbr */
+  nco_bool use_mss_val_area=False;
+  nco_bool has_mss_val_area=False;
+  nco_bool has_mss_val_bnd=False;
   nco_bool has_mss_val_ctr=False;
-  nco_bool has_mss_val_msk;
+  nco_bool has_mss_val_msk=False;
 
   nco_grd_2D_typ_enm grd_typ; /* [enm] Grid-type enum */
   nco_grd_lat_typ_enm lat_typ; /* [enm] Latitude grid-type enum */
   nco_grd_lon_typ_enm lon_typ; /* [enm] Longitude grid-type enum */
+  nco_grd_xtn_enm nco_grd_xtn=nco_grd_xtn_nil; /* [enm] Grid-extent enum */
 
   nc_type msk_typ;
 
@@ -5543,7 +5701,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
        ncks --cdl -m ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc | grep coordinates
        4LFTX_221_SPDY_S113:coordinates = "gridlat_221 gridlon_221" ;
        Usage:
-       ncks -O -D 3 --rgr nfr=y --rgr_var=4LFTX_221_SPDY_S113 --rgr grid=~/grd_narr.nc ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc ~/foo.nc */
+       ncks -O -D 3 --rgr infer --rgr_var=4LFTX_221_SPDY_S113 --rgr grid=~/grd_narr.nc ${DATA}/hdf/narrmon-a_221_20100101_0000_000.nc ~/foo.nc */
     char crd_sng[]="coordinates"; /* CF-standard coordinates attribute name */
     
     cf=(cf_crd_sct *)nco_malloc(sizeof(cf_crd_sct));
@@ -5581,40 +5739,81 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     } /* !rcd && att_typ */
       
     /* Valid coordinates attribute requires two coordinate names separated by space character */
-    char *sbs_srt; /* [sng] Coordinate name start position */
-    char *sbs_end; /* [sng] Coordinate name   end position */
-    cf->crd_nm[0]=(char *)strdup(cf->crd_sng);
-    sbs_end=strchr(cf->crd_nm[0],' ');
-    /* NUL-terminate first coordinate name */
-    *sbs_end='\0'; 
-    sbs_srt=sbs_end+1; 
-    cf->crd_nm[1]=(char *)strdup(sbs_srt);
-
-    if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[0],&cf->crd_id[0])) != NC_NOERR){
-      (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0]);
+    char *crd_nm[NCO_MAX_CRD_PER_VAR]; /* [sng] Coordinate name start position */
+    char *crd_dpl; /* [sng] Modifiable duplicate of coordinates string */
+    char *spc_ptr; /* [sng] Pointer to space character (' ') */
+    int crd_nbr=0; /* [nbr] Number of names in coordinates attribute */
+    int crd_spt=0; /* [nbr] Number of "spatial-like" (that include "degree" in units) coordinates */
+    int crd_idx=0; /* [idx] Counter for coordinate names */
+    for(crd_idx=0;crd_idx<NCO_MAX_CRD_PER_VAR;crd_idx++) crd_nm[crd_idx]=NULL;
+    crd_dpl=(char *)strdup(cf->crd_sng);
+    /* Search for spaces starting from end of string */
+    while((spc_ptr=strrchr(crd_dpl,' '))){
+      crd_nm[crd_nbr]=spc_ptr+1L;
+      crd_nbr++;
+      /* NUL-terminate so next search ends here */
+      *spc_ptr='\0'; 
+    } /* !sbs_ptr */
+    /* Final coordinate name begins where coordinate string starts */
+    crd_nm[crd_nbr]=crd_dpl;
+    if(crd_nbr < 2){
+      (void)fprintf(stderr,"%s: WARNING %s found only %d coordinates in coordinates attribute \"%s\", at least two are required. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,crd_nbr,cf->crd_sng);
       goto skp_cf;
-    } /* !rcd */ 
-    if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[1],&cf->crd_id[1])) != NC_NOERR){
-      (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1]);
-      goto skp_cf;
-    } /* !rcd */ 
-
-    rcd=nco_inq_att_flg(in_id,cf->crd_id[0],unt_sng,&att_typ,&att_sz);
-    if(rcd == NC_NOERR && att_typ == NC_CHAR){
-      cf->unt_sng[0]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
-      rcd=nco_get_att(in_id,cf->crd_id[0],unt_sng,cf->unt_sng[0],att_typ);
-      /* NUL-terminate attribute before using strstr() */
-      *(cf->unt_sng[0]+att_sz)='\0';
-      if(!strcasestr(cf->unt_sng[0],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->unt_sng[0]);
-    } /* !rcd && att_typ */
-    rcd=nco_inq_att_flg(in_id,cf->crd_id[1],unt_sng,&att_typ,&att_sz);
-    if(rcd == NC_NOERR && att_typ == NC_CHAR){
-      cf->unt_sng[1]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
-      rcd=nco_get_att(in_id,cf->crd_id[1],unt_sng,cf->unt_sng[1],att_typ);
-      /* NUL-terminate attribute before using strstr() */
-      *(cf->unt_sng[1]+att_sz)='\0';
-      if(!strcasestr(cf->unt_sng[1],"degrees_")) (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1],cf->unt_sng[1]);
-    } /* !rcd && att_typ */
+    } /* !crd_nbr */
+    /* If more than two coordinate names are present, choose first two (searching backwards from end) with "degree" in units attributes, otherwise just choose first two */
+    crd_idx=crd_spt=0;
+    while(crd_spt < 2 && crd_idx < crd_nbr){
+      cf->crd_nm[crd_spt]=crd_nm[crd_idx];
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[crd_spt],&cf->crd_id[crd_spt])) == NC_NOERR){
+	rcd=nco_inq_att_flg(in_id,cf->crd_id[crd_spt],unt_sng,&att_typ,&att_sz);
+	if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	  cf->unt_sng[crd_spt]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	  rcd=nco_get_att(in_id,cf->crd_id[crd_spt],unt_sng,cf->unt_sng[crd_spt],att_typ);
+	  /* NUL-terminate attribute before using strstr() */
+	  *(cf->unt_sng[crd_spt]+att_sz)='\0';
+	  if(strcasestr(cf->unt_sng[crd_spt],"degree")){
+	    /* Increment count of spatial-like coordinates... */
+	    crd_spt++;
+	  }else{
+	    /* ...or free() memory allocated during search */
+	    cf->unt_sng[crd_spt]=(char *)nco_free(cf->unt_sng[crd_spt]);
+	  } /* !strcasestr() */
+	  crd_idx++;
+	} /* !rcd && att_typ */
+      } /* !rcd */ 
+    } /* !crd_spt */
+
+    /* If while()-loop above was successful, our search is over
+       Otherwise, use first two coordinate names regardless of units, and print more diagnostics */
+    if(crd_spt < 2){
+      cf->crd_nm[0]=crd_nm[0];
+      cf->crd_nm[1]=crd_nm[1];
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[0],&cf->crd_id[0])) != NC_NOERR){
+	(void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0]);
+	goto skp_cf;
+      } /* !rcd */ 
+      if((rcd=nco_inq_varid_flg(in_id,cf->crd_nm[1],&cf->crd_id[1])) != NC_NOERR){
+	(void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s not found. Turning-off CF coordinates search.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1]);
+	goto skp_cf;
+      } /* !rcd */ 
+
+      rcd=nco_inq_att_flg(in_id,cf->crd_id[0],unt_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	cf->unt_sng[0]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd=nco_get_att(in_id,cf->crd_id[0],unt_sng,cf->unt_sng[0],att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	*(cf->unt_sng[0]+att_sz)='\0';
+	if(!strcasestr(cf->unt_sng[0],"degree")) (void)fprintf(stderr,"%s: WARNING %s reports first coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->unt_sng[0]);
+      } /* !rcd && att_typ */
+      rcd=nco_inq_att_flg(in_id,cf->crd_id[1],unt_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	cf->unt_sng[1]=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd=nco_get_att(in_id,cf->crd_id[1],unt_sng,cf->unt_sng[1],att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	*(cf->unt_sng[1]+att_sz)='\0';
+	if(!strcasestr(cf->unt_sng[1],"degree")) (void)fprintf(stderr,"%s: WARNING %s reports second coordinates variable %s has weird units attribute = %s. May not detect correct ordering of latitude and longitude coordinates\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[1],cf->unt_sng[1]);
+      } /* !rcd && att_typ */
+    } /* !crd_spt */
       
     int crd_rnk; /* [nbr] Coordinate rank */
     rcd=nco_inq_varndims(in_id,cf->crd_id[0],&crd_rnk);
@@ -5675,8 +5874,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s Coordinates %s and %s \"units\" values are \"%s\" and \"%s\", respectively.\n",nco_prg_nm_get(),fnc_nm,cf->crd_nm[0],cf->crd_nm[1],cf->unt_sng[0] ? cf->unt_sng[0] : "(non-existent)",cf->unt_sng[1] ? cf->unt_sng[1] : "(non-existent)");
 
     /* Clean-up CF coordinates memory */
-    if(cf->crd_nm[0]) cf->crd_nm[0]=(char *)nco_free(cf->crd_nm[0]);
-    if(cf->crd_nm[1]) cf->crd_nm[1]=(char *)nco_free(cf->crd_nm[1]);
+    if(crd_dpl) crd_dpl=(char *)nco_free(crd_dpl);
     if(cf->crd_sng) cf->crd_sng=(char *)nco_free(cf->crd_sng);
     if(cf->dmn_nm[0]) cf->dmn_nm[0]=(char *)nco_free(cf->dmn_nm[0]);
     if(cf->dmn_nm[1]) cf->dmn_nm[1]=(char *)nco_free(cf->dmn_nm[1]);
@@ -5706,12 +5904,13 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     else if((rcd=nco_inq_varid_flg(in_id,"Lat",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("Lat");
     else if((rcd=nco_inq_varid_flg(in_id,"XLAT",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("XLAT"); /* WRF */
     else if((rcd=nco_inq_varid_flg(in_id,"XLAT_M",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("XLAT_M"); /* Unknown */
-    else if((rcd=nco_inq_varid_flg(in_id,"LAT",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("LAT"); /* MAR */
+    else if((rcd=nco_inq_varid_flg(in_id,"LAT",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("LAT"); /* MAR/RACMO */
     else if((rcd=nco_inq_varid_flg(in_id,"TLAT",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("TLAT"); /* CICE, POP */
-    else if((rcd=nco_inq_varid_flg(in_id,"CO_Latitude",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("CO_Latitude"); /* MLS */
-    else if((rcd=nco_inq_varid_flg(in_id,"S1_Latitude",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("S1_Latitude"); /* GPM */
     else if((rcd=nco_inq_varid_flg(in_id,"ULAT",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("ULAT"); /* CICE, POP */
     else if((rcd=nco_inq_varid_flg(in_id,"latCell",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("latCell"); /* MPAS-O/I */
+    else if((rcd=nco_inq_varid_flg(in_id,"nav_lat",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("nav_lat"); /* NEMO */
+    else if((rcd=nco_inq_varid_flg(in_id,"CO_Latitude",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("CO_Latitude"); /* MLS */
+    else if((rcd=nco_inq_varid_flg(in_id,"S1_Latitude",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("S1_Latitude"); /* GPM */
     else if((rcd=nco_inq_varid_flg(in_id,"yc",&lat_ctr_id)) == NC_NOERR) lat_nm_in=strdup("yc"); /* RTM */
   } /* !lat_ctr_id */
   
@@ -5723,13 +5922,15 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     else if((rcd=nco_inq_varid_flg(in_id,"Lon",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("Lon");
     else if((rcd=nco_inq_varid_flg(in_id,"XLONG",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("XLONG"); /* WRF */
     else if((rcd=nco_inq_varid_flg(in_id,"XLONG_M",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("XLONG_M"); /* Unknown */
-    else if((rcd=nco_inq_varid_flg(in_id,"LON",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("LON"); /* MAR */
-    else if((rcd=nco_inq_varid_flg(in_id,"S1_Longitude",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("S1_Longitude"); /* GPM */
+    else if((rcd=nco_inq_varid_flg(in_id,"LON",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("LON"); /* MAR/RACMO */
     else if((rcd=nco_inq_varid_flg(in_id,"TLON",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("TLON"); /* CICE */
     else if((rcd=nco_inq_varid_flg(in_id,"TLONG",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("TLONG"); /* POP */
     else if((rcd=nco_inq_varid_flg(in_id,"ULON",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("ULON"); /* CICE */
     else if((rcd=nco_inq_varid_flg(in_id,"ULONG",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("ULONG"); /* POP */
     else if((rcd=nco_inq_varid_flg(in_id,"lonCell",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("lonCell"); /* MPAS-O/I */
+    else if((rcd=nco_inq_varid_flg(in_id,"nav_lon",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("nav_lon"); /* NEMO */
+    else if((rcd=nco_inq_varid_flg(in_id,"CO_Longitude",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("CO_Longitude"); /* MLS */
+    else if((rcd=nco_inq_varid_flg(in_id,"S1_Longitude",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("S1_Longitude"); /* GPM */
     else if((rcd=nco_inq_varid_flg(in_id,"xc",&lon_ctr_id)) == NC_NOERR) lon_nm_in=strdup("xc"); /* RTM */
   } /* !lon_ctr_id */
   
@@ -5822,6 +6023,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     /* 1D grids without their own boundaries are at the mercy of the weight generator */
     if(dmn_id_bnd == NC_MIN_INT){
       (void)fprintf(stdout,"%s: WARNING %s reports an unstructured grid without spatial boundary information. NCO can copy but not infer spatial boundaries from unstructured grids. Thus NCO will not write spatial bounds to the gridfile inferred from this input file. Instead, the weight generator that ingests this gridfile must generate weights for gridcells with unknown spatial extent. This is feasible for grids and mappings where weights masquerade as areas and are determined by underly [...]
+      (void)fprintf(stdout,"%s: HINT Re-run the regridder, this time adding the \"-s src_grd\" option to specify the source grid file in SCRIP format. That SCRIP file will have the spatial bounds information required by the ESMF_RegridWeightGen (ERWG) program, so that the regridder will circumvent inferring the underlying grid through its black but fragile magic.\n",nco_prg_nm_get());
       flg_wrt_crn=False;
       /* Input could actually be from grid with no polygonal definition, e.g., CAM-SE 
 	 Corner number is non-deterministic since, e.g., CAM-SE dual grid can be fit to quadrilaterals, pentagons, chevrons, etc.
@@ -5876,12 +6078,12 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   msk=(int *)nco_malloc(grd_sz_nbr*nco_typ_lng((nc_type)NC_INT));
   
   if(flg_grd_1D){
-    lat_bnd=(double *)nco_malloc(grd_sz_nbr*bnd_nbr*nco_typ_lng(crd_typ));
+    if(bnd_nbr != NC_MIN_INT) lat_bnd=(double *)nco_malloc(grd_sz_nbr*bnd_nbr*nco_typ_lng(crd_typ));
     lat_crn=(double *)nco_malloc(grd_sz_nbr*grd_crn_nbr*nco_typ_lng(crd_typ));
     lat_ctr=(double *)nco_malloc(grd_sz_nbr*nco_typ_lng(crd_typ));
     lat_ntf=(double *)nco_malloc((lat_nbr+1L)*nco_typ_lng(crd_typ));
     lat_wgt=(double *)nco_malloc(lat_nbr*nco_typ_lng(crd_typ));
-    lon_bnd=(double *)nco_malloc(grd_sz_nbr*bnd_nbr*nco_typ_lng(crd_typ));
+    if(bnd_nbr != NC_MIN_INT) lon_bnd=(double *)nco_malloc(grd_sz_nbr*bnd_nbr*nco_typ_lng(crd_typ));
     lon_crn=(double *)nco_malloc(grd_sz_nbr*grd_crn_nbr*nco_typ_lng(crd_typ));
     lon_ctr=(double *)nco_malloc(grd_sz_nbr*nco_typ_lng(crd_typ));
     lon_ntf=(double *)nco_malloc((lon_nbr+1L)*nco_typ_lng(crd_typ));
@@ -5932,27 +6134,39 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   else if((rcd=nco_inq_varid_flg(in_id,"Area",&area_id)) == NC_NOERR) area_nm_in=strdup("Area");
   else if((rcd=nco_inq_varid_flg(in_id,"areaCell",&area_id)) == NC_NOERR) area_nm_in=strdup("areaCell"); /* MPAS-O/I */
   else if((rcd=nco_inq_varid_flg(in_id,"grid_area",&area_id)) == NC_NOERR) area_nm_in=strdup("grid_area");
-  else if((rcd=nco_inq_varid_flg(in_id,"tarea",&area_id)) == NC_NOERR) area_nm_in=strdup("tarea"); /* CICE */
-  else if((rcd=nco_inq_varid_flg(in_id,"uarea",&area_id)) == NC_NOERR) area_nm_in=strdup("uarea"); /* CICE */
-
-  if((rcd=nco_inq_varid_flg(in_id,"mask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("mask");
-  else if((rcd=nco_inq_varid_flg(in_id,"Mask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("Mask");
-  else if((rcd=nco_inq_varid_flg(in_id,"grid_imask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("grid_imask");
-  else if((rcd=nco_inq_varid_flg(in_id,"tmask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("tmask"); /* CICE */
-
+  // else if((rcd=nco_inq_varid_flg(in_id,"aice",&area_id)) == NC_NOERR) area_nm_in=strdup("aice"); /* CICE time-dependent ice area (3D), not total gridcell area */
+  else if((rcd=nco_inq_varid_flg(in_id,"tarea",&area_id)) == NC_NOERR) area_nm_in=strdup("tarea"); /* CICE time-invariant state-variable gridcell area (2D) */
+  else if((rcd=nco_inq_varid_flg(in_id,"uarea",&area_id)) == NC_NOERR) area_nm_in=strdup("uarea"); /* CICE time-invariant dynamics variables (2D) */
+
+  msk_nm_in=rgr->msk_var;
+  if(msk_nm_in){
+    /* User-supplied name overrides database */
+    rcd=nco_inq_varid(in_id,msk_nm_in,&msk_id);
+  }else{
+    /* Otherwise search database */
+    if((rcd=nco_inq_varid_flg(in_id,"mask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("mask");
+    else if((rcd=nco_inq_varid_flg(in_id,"Mask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("Mask");
+    else if((rcd=nco_inq_varid_flg(in_id,"grid_imask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("grid_imask");
+    else if((rcd=nco_inq_varid_flg(in_id,"landmask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("landmask"); /* ALM/CLM */
+    else if((rcd=nco_inq_varid_flg(in_id,"tmask",&msk_id)) == NC_NOERR) msk_nm_in=strdup("tmask"); /* CICE */
+  } /* !msk_nm_in */
+  
   /* Mask field requires special handling for non-conformant models */
   if(msk_id != NC_MIN_INT){
     /* 20151201: All models tested define mask as NC_INT except CICE which uses NC_FLOAT
        20160111: No observations tested define mask except AMSR which uses NC_SHORT to store bitmasks. Bitmask is 1 for missing data, and up to 128 for various quality levels of valid data. Hence, almost better to ignore AMSR mask variable. */
+    rcd=nco_inq_varndims(in_id,msk_id,&msk_rnk_nbr);
+    if(msk_rnk_nbr != grd_rnk_nbr && nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO %s reports input mask variable \"%s\" is rank %d while grid is rank %ld so will use first timestep/layer to determine output mask\n",nco_prg_nm_get(),fnc_nm,msk_nm_in,msk_rnk_nbr,grd_rnk_nbr);
     rcd=nco_inq_vartype(in_id,msk_id,&msk_typ);
     msk_unn.vp=(void *)nco_malloc(grd_sz_nbr*nco_typ_lng(msk_typ));
   } /* !msk */
 
   /* All grids: 
      Some real-world datasets violate convention that coordinates ought never have missing values 
-     CICE lists missing value for lat/lon_ctr arrays (TLAT, TLONG) and re-uses that for bounds arrays */
-  has_mss_val_ctr=nco_mss_val_get_dbl(in_id,lat_ctr_id,&mss_val_ctr_dbl);
-
+     CICE lists missing value for lat/lon_ctr arrays (TLAT, TLONG) and re-uses that for bounds arrays (latt_bounds, lont_bounds) that do not bother to have their own missing value attributes
+     Without counter-example, assume has_mss_val_bnd=has_mss_val_ctr and mss_val_bnd_dbl=mss_val_ctr_dbl */
+  has_mss_val_bnd=has_mss_val_ctr=nco_mss_val_get_dbl(in_id,lat_ctr_id,&mss_val_ctr_dbl);
+  
   if(flg_grd_1D){
     /* Obtain fields that must be present in unstructured input file */
     dmn_srt[0]=0L;
@@ -5962,7 +6176,18 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
     /* Obtain fields that may be present in unstructured input file */
     if(area_id != NC_MIN_INT) rcd=nco_get_vara(in_id,area_id,dmn_srt,dmn_cnt,area,crd_typ);
-    if(msk_id != NC_MIN_INT) rcd=nco_get_vara(in_id,msk_id,dmn_srt,dmn_cnt,msk_unn.vp,msk_typ);
+    if(msk_id != NC_MIN_INT){
+      if(msk_rnk_nbr > grd_rnk_nbr){
+	/* Retrieve mask elements only from first horizontal grid, e.g., first timestep, first layer... */
+	for(dmn_idx=0;dmn_idx<msk_rnk_nbr-grd_rnk_nbr;dmn_idx++){
+	  dmn_srt[dmn_idx]=0L;
+	  dmn_cnt[dmn_idx]=1L;
+	} /* !dmn_idx */
+	dmn_srt[dmn_idx]=0L;
+	dmn_cnt[dmn_idx]=col_nbr;
+      } /* !msk_rnk_nbr */
+      rcd=nco_get_vara(in_id,msk_id,dmn_srt,dmn_cnt,msk_unn.vp,msk_typ);
+    } /* !msk_id */
     dmn_srt[0]=dmn_srt[1]=0L;
     dmn_cnt[0]=col_nbr;
     if(flg_1D_psd_rct_bnd){
@@ -5988,9 +6213,19 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
        area and mask are same size as lat and lon */
     if(area_id != NC_MIN_INT) rcd=nco_get_vara(in_id,area_id,dmn_srt,dmn_cnt,area,crd_typ);
     if(msk_id != NC_MIN_INT){
+      if(msk_rnk_nbr > grd_rnk_nbr){
+	/* Retrieve mask elements only from first horizontal grid, e.g., first timestep, first layer... */
+	for(dmn_idx=0;dmn_idx<msk_rnk_nbr-grd_rnk_nbr;dmn_idx++){
+	  dmn_srt[dmn_idx]=0L;
+	  dmn_cnt[dmn_idx]=1L;
+	} /* !dmn_idx */
+	dmn_srt[dmn_idx]=dmn_srt[dmn_idx+1]=0L;
+	dmn_cnt[dmn_idx]=lat_nbr;
+	dmn_cnt[dmn_idx+1]=lon_nbr;
+      } /* !msk_rnk_nbr */
       rcd=nco_get_vara(in_id,msk_id,dmn_srt,dmn_cnt,msk_unn.vp,msk_typ);
-      has_mss_val_msk=nco_mss_val_get_dbl(in_id,msk_id,&mss_val_msk_dbl);
-    } /* !msk */
+    } /* !msk_id */
+
     /* Corners are on curvilinear corner grid
        Rectangular boundaries (i.e., lat_bnd=[lat_nbr,2]) DNE for curvilinear grids 
        Read-in *_crn arrays in curvilinear grids, and *_bnd arrays for rectilinear grids
@@ -6030,7 +6265,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 	  for(idx=0;idx<grd_sz_nbr;idx++){
 	    lat_idx=idx/lon_nbr;
 	    lon_idx=idx%lon_nbr;
-	    /* NB: Variables differ (lat vs. lon) but indexes are identical in next to lines */
+	    /* NB: Variables differ (lat vs. lon) but indexes are identical in next two lines */
 	    lat_crn[lat_idx*lon_nbr*grd_crn_nbr+lon_idx*grd_crn_nbr+crn_idx]=lat_crn_tmp[crn_idx*grd_sz_nbr+idx];
 	    lon_crn[lat_idx*lon_nbr*grd_crn_nbr+lon_idx*grd_crn_nbr+crn_idx]=lon_crn_tmp[crn_idx*grd_sz_nbr+idx];
 	  } /* !idx */
@@ -6049,9 +6284,9 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   } /* !flg_grd_crv */
 
   if(flg_grd_2D){
-    int lon_psn_in=0L; /* [idx] Ordinal position of longitude size in rectangular grid */
-    int lat_psn_in=1L; /* [idx] Ordinal position of latitude  size in rectangular grid */
-    int tpl_id=NC_MIN_INT; /* [idx] Ordinal position of latitude  size in rectangular grid */
+    int lon_psn_in=1L; /* [idx] Ordinal position of longitude dimension in rectangular grid variables like area */
+    int lat_psn_in=0L; /* [idx] Ordinal position of latitude  dimension in rectangular grid variables like area */
+    int tpl_id=NC_MIN_INT; /* [id] ID of template field */
 
     /* Obtain fields that must be present in input file */
     dmn_srt[0]=0L;
@@ -6063,14 +6298,17 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
     /* Use fields that may be present in input file to override, if necessary, default lon/lat order
        area and mask are both suitable templates for determining input lat/lon ordering
-       NB: Algorithm assumes area and mask do not have time dimension */
+       NB: Algorithm assumes area is same rank as grid, and falls-back to mask if that has same rank as grid */
     if(area_id != NC_MIN_INT) tpl_id=area_id;
-    else if(msk_id != NC_MIN_INT) tpl_id=msk_id;
+    else if(msk_id != NC_MIN_INT && msk_rnk_nbr == grd_rnk_nbr) tpl_id=msk_id;
 
     if(tpl_id != NC_MIN_INT){
+      int tpl_rnk_nbr;
       var_id=tpl_id;
+      /* NB: Template variable rank may exceed two with --msk_[src/dst] (e.g., SST(time,lat,lon)) */
+      rcd=nco_inq_varndims(in_id,var_id,&tpl_rnk_nbr);
       rcd=nco_inq_vardimid(in_id,var_id,dmn_ids);
-      /* fxm: optimize discovery of lat/lon ordering */
+      /* fxm: Optimize discovery of lat/lon ordering */
       for(dmn_idx=0;dmn_idx<grd_rnk_nbr;dmn_idx++){
 	rcd=nco_inq_dimname(in_id,dmn_ids[dmn_idx],dmn_nm);
 	rcd+=nco_inq_dimlen(in_id,dmn_ids[dmn_idx],&dmn_sz);
@@ -6105,6 +6343,16 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
       dmn_cnt[lat_psn_in]=lat_nbr;
       dmn_srt[lon_psn_in]=0L;
       dmn_cnt[lon_psn_in]=lon_nbr;
+      if(msk_rnk_nbr != grd_rnk_nbr){
+	/* Retrieve mask elements only from first horizontal grid, e.g., first timestep, first layer... */
+	for(dmn_idx=0;dmn_idx<msk_rnk_nbr-grd_rnk_nbr;dmn_idx++){
+	  dmn_srt[dmn_idx]=0L;
+	  dmn_cnt[dmn_idx]=1L;
+	} /* !dmn_idx */
+	dmn_srt[dmn_idx]=dmn_srt[dmn_idx+1]=0L;
+	dmn_cnt[dmn_idx+lat_psn_in]=lat_nbr;
+	dmn_cnt[dmn_idx+lon_psn_in]=lon_nbr;
+      } /* !msk_rnk_nbr */
       rcd=nco_get_vara(in_id,msk_id,dmn_srt,dmn_cnt,msk_unn.vp,msk_typ);
     } /* !msk */
 
@@ -6120,6 +6368,10 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     if(lon_bnd_id != NC_MIN_INT) rcd=nco_get_vara(in_id,lon_bnd_id,dmn_srt,dmn_cnt,lon_bnd,crd_typ);
   } /* !flg_grd_2D */
 
+  /* Additional information that may be required for any input grid */
+  if(area_id != NC_MIN_INT) has_mss_val_area=nco_mss_val_get_dbl(in_id,area_id,&mss_val_area_dbl);
+  if(msk_id != NC_MIN_INT) has_mss_val_msk=nco_mss_val_get_dbl(in_id,msk_id,&mss_val_msk_dbl);
+
   /* 20160115: AMSR coordinates are packed as NC_SHORT with scale_value=0.01f. What to do? Is it worth unpacking everything? */
   int flg_pck; /* [flg] Variable is packed on disk  */
   rcd=nco_inq_var_packing(in_id,lat_ctr_id,&flg_pck);
@@ -6138,16 +6390,22 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   dfl_lvl=rgr->dfl_lvl;
   fl_out=rgr->fl_grd;
   fl_out_fmt=rgr->fl_out_fmt;
-
+  if(!fl_out){
+    (void)fprintf(stdout,"%s: ERROR %s filename for inferred SCRIP grid-file is uninitialized, supply it with --rgr grid=filename.nc\n",nco_prg_nm_get(),fnc_nm);
+    (void)fprintf(stdout,"%s: HINT ncremap supplies an automatically generated default name for any output SCRIP grid-file. Users of the standalone regridder (ncks) must explicitly specify a name for the inferred SCRIP grid-file.\n",nco_prg_nm_get());
+    nco_exit(EXIT_FAILURE);
+  } /* !fl_out */
+  
   /* Define output variable values */
-  int lon_psn; /* [idx] Ordinal position of longitude size in rectangular grid */
-  int lat_psn; /* [idx] Ordinal position of latitude  size in rectangular grid */
+  int lon_psn; /* [idx] Ordinal position of longitude dimension in rectangular grid dimension-size array */
+  int lat_psn; /* [idx] Ordinal position of latitude  dimension in rectangular grid dimension-size array */
   if(grd_rnk_nbr == dmn_nbr_1D){
     dmn_sz_int[0]=col_nbr;
   }else if(grd_rnk_nbr == dmn_nbr_2D){ /* !dmn_nbr_1D */
     /* SCRIP introduced [lon,lat] convention because more natural for Fortran 
-       NB: I think this [lon,lat] convention applies only to grid_dims variable 
-       All other SCRIP variables seem to be written as [lat,lon] (fxm: verify) */
+       NB: This [lon,lat] convention applies ONLY to grid_dims variable 
+       Write all other SCRIP variables as [lat,lon]
+       Nonsensical? Yes, but backwards compatibility is priceless */
     lon_psn=0;
     lat_psn=1;
     dmn_sz_int[lon_psn]=lon_nbr;
@@ -6158,6 +6416,135 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     /* For curvilinear grids first, if necessary, infer corner boundaries
        Then perform sanity check using same code on inferred and copied grids */
     
+    if(False && has_mss_val_bnd && grd_crn_nbr == 4 && !strcmp(lat_bnd_nm,"latt_bounds") && !strcmp(lon_bnd_nm,"lont_bounds") && lat_bnd_id != NC_MIN_INT && lon_bnd_id != NC_MIN_INT){
+      /* Only CESM CICE is known to fit these constraints
+	 Cell center locations are (misleadingly) reported in a regular, rectangular, regional grid
+	 Cell corners/boundaries are regular only in SH, curvilinear in NH, i.e., displaced or tripole grid
+	 Grid is from southernmost Antarctic Ocean latitude and longitude near 79S,320E to North Pole
+	 Nominal centers do not agree with true centers computed from corners
+	 CICE may run in decomposed/unstructured mode, each column writes separately to output buffer?
+	 This could explain missing coordinates in non-ocean gridcells
+	 However, land points are completely masked (grid centers and corners are missing)
+	 Oversight? Why not write coordinates for land-masked cells?
+	 Regridder needs corners so we fill-in missing boundaries with derived grid
+	 Gave up on inferring 20170521 once tri-pole grid complexity became apparent */
+      const long idx_dbg=rgr->idx_dbg;
+      double lat_ctr_drv; /* [dgr] Latitude center, derived */
+      double lon_ctr_drv; /* [dgr] Longitude center, derived */
+      double lat_crn_drv; /* [dgr] Latitude corner, derived */
+      double lon_crn_drv; /* [dgr] Longitude corner, derived */
+      long idx_ctr_sth; /* [idx] Index of southern neighbor */
+      long idx_ctr_nrt; /* [idx] Index of northern neighbor */
+      long idx_crn_sth; /* [idx] Index of southern neighbor */
+      long idx_crn_nrt; /* [idx] Index of northern neighbor */
+      long lon_idx_crr; /* [idx] Current longitude index */
+      long lon_vld_frs; /* [idx] First valid longitude in latitude row */
+      long *lon_vld_prv=NULL; /* [idx] Previous valid longitude in latitude row */
+      long *lon_vld_nxt=NULL; /* [idx] Next valid longitude in latitude row */
+
+      lon_vld_prv=(long *)nco_malloc(lon_nbr*sizeof(long));
+      lon_vld_nxt=(long *)nco_malloc(lon_nbr*sizeof(long));
+
+      /* First valid gridcell sets west and south bounds of entire grid */
+      for(idx_ctr=0;idx_ctr<grd_sz_nbr;idx_ctr++){
+	if(lat_ctr[idx_ctr] != mss_val_ctr_dbl) break;
+      } /* !grd_sz_nbr */
+      assert(idx_ctr != grd_sz_nbr);
+      idx_crn=idx_ctr*grd_crn_nbr;
+      lat_sth=lat_crn[idx_crn];
+      lat_ncr=lat_crn[idx_crn+3]-lat_crn[idx_crn]; /* ul-ll */
+      lon_wst=lon_crn[idx_crn];
+      lon_ncr=lon_crn[idx_crn+1]-lon_crn[idx_crn]; /* lr-ll */
+      if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO %s will assume grid is regional CICE in curvilinear format with masked land. Will diagnose missing cell boundaries and centers from present boundaries and centers in grid of size lat_nbr=%ld, lon_nbr=%ld.\n",nco_prg_nm_get(),fnc_nm,lat_nbr,lon_nbr);
+      for(lat_idx=0;lat_idx<lat_nbr;lat_idx++){
+	idx_ctr=lat_idx*lon_nbr;
+	/* Find first valid longitude at this latitude */
+	for(lon_idx=0;lon_idx<lon_nbr;lon_idx++)
+	  if(lat_ctr[idx_ctr+lon_idx] != mss_val_ctr_dbl) break;
+	lon_vld_frs=lon_idx;
+	/* 20170519: Verified all tri-pole grid latitudes have at least one valid point */
+	if(lon_vld_frs == -1L) abort();
+	for(lon_idx_crr=0;lon_idx_crr<lon_nbr;lon_idx++){
+	  /* Find previous and next valid longitude for all longitudes at this latitude
+	     Cells can be their own previous/next valid longitude */
+	  lon_vld_prv[lon_idx_crr]=-1L;
+	  lon_vld_nxt[lon_idx_crr]=-1L;
+	  /* Start from current longitude and move left (west)... */
+	  for(lon_idx=lon_idx_crr;lon_idx>=0;lon_idx--)
+	    if(lat_ctr[idx_ctr+lon_idx] != mss_val_ctr_dbl) break;
+	  if(lon_idx >= 0) lon_vld_prv[lon_idx_crr]=lon_idx;
+	  /* Start from current longitude and move right (east)... */
+	  for(lon_idx=lon_idx_crr;lon_idx<lon_nbr;lon_idx++)
+	    if(lat_ctr[idx_ctr+lon_idx] != mss_val_ctr_dbl) break;
+	  if(lon_idx < lon_nbr) lon_vld_nxt[lon_idx_crr]=lon_idx;
+	  /* Wrap west if previous valid cell not found */
+	  lon_vld_prv[lon_idx_crr]=lon_vld_prv[lon_nbr-1L];
+	  /* Wrap east if next valid cell not found */
+	  lon_vld_nxt[lon_idx_crr]=lon_vld_nxt[0];
+	} /* !lon_idx_crr */
+	/* Derive centers and corners for each missing point */
+	for(lon_idx=0;lon_idx<lon_nbr;lon_idx++){
+	  idx_ctr=lat_idx*lon_nbr+lon_idx;
+	  idx_crn=idx_ctr*grd_crn_nbr;
+	  if(lat_ctr[idx_ctr] != mss_val_ctr_dbl){
+	    lat_sth=lat_crn[idx_crn];
+	    lat_ncr=lat_crn[idx_crn+3]-lat_crn[idx_crn]; /* ul-ll */
+	    lat_ctr_drv=lat_sth+0.5*lat_ncr;
+	    lat_crn_drv=lat_sth;
+	    lon_wst=lon_crn[idx_crn];
+	    lon_ncr=lon_crn[idx_crn+1]-lon_crn[idx_crn]; /* lr-ll */
+	    lon_ctr_drv=lon_wst+lon_ncr*(lon_idx+0.5);
+	    if(nco_dbg_lvl_get() >= nco_dbg_std && idx_ctr == idx_dbg) (void)fprintf(stdout,"%s: DEBUG %s idx=%ld lat_idx=%ld, lon_idx=%ld, lat_sth=%g, lat_ncr=%g, lon_wst=%g, lon_ncr=%g\n",nco_prg_nm_get(),fnc_nm,idx_ctr,lat_idx,lon_idx,lat_sth,lat_ncr,lon_wst,lon_ncr);
+	  } /* !idx_ctr */
+	  if(lat_ctr[idx_ctr] == mss_val_ctr_dbl){
+	    if(lat_idx != 0L){
+	      /* Not bottom row */
+	      idx_ctr_sth=idx_ctr-lon_nbr;
+	      if(lat_ctr[idx_ctr_sth] != mss_val_ctr_dbl){
+		/* Copy southern corners from northern corners of southern neighbor */
+		idx_crn_sth=idx_ctr_sth*grd_crn_nbr;
+		lat_crn[idx_crn+0L]=lat_crn[idx_crn_sth+3L];
+		lat_crn[idx_crn+1L]=lat_crn[idx_crn_sth+2L];
+		lon_crn[idx_crn+0L]=lon_crn[idx_crn_sth+3L];
+		lon_crn[idx_crn+1L]=lon_crn[idx_crn_sth+2L];
+	      } /* !mss_val */
+	    } /* !lat_idx */
+	    if(lat_idx != lat_nbr-1L){
+	      /* Not top row */
+	      idx_ctr_nrt=idx_ctr+lon_nbr;
+	      if(lat_ctr[idx_ctr_nrt] != mss_val_ctr_dbl){
+		/* Copy northern corners from southern corners of northern neighbor */
+		idx_crn_nrt=idx_ctr_nrt*grd_crn_nbr;
+		lat_crn[idx_crn+2L]=lat_crn[idx_crn_nrt+1L];
+		lat_crn[idx_crn+3L]=lat_crn[idx_crn_nrt+0L];
+		lon_crn[idx_crn+2L]=lon_crn[idx_crn_nrt+1L];
+		lon_crn[idx_crn+3L]=lon_crn[idx_crn_nrt+0L];
+	      } /* !mss_val */
+	    } /* !lat_idx */
+	    /* Got to here before giving up
+	       Idea was to interpolate missing cell corners between previous and next valid cell */
+	    /* Algorithm assumes lon_wst never changes (too simple for displaced/tri_pole) */
+	    lon_ctr_drv=lon_wst+lon_ncr*(lon_idx+0.5);
+	    lon_crn_drv=lon_wst+lon_ncr*lon_idx;
+	    if(lon_ctr_drv >= 360.0) lon_ctr_drv-=360.0;
+	    lat_ctr[idx_ctr]=lat_ctr_drv;
+	    lon_ctr[idx_ctr]=lon_ctr_drv;
+	    lat_crn[idx_crn+0L]=lat_crn[idx_crn+1L]=lat_crn_drv;
+	    lat_crn[idx_crn+2L]=lat_crn[idx_crn+3L]=lat_crn_drv+lat_ncr;
+	    lon_crn[idx_crn+0L]=lon_crn[idx_crn+3L]=lon_crn_drv;
+	    lon_crn[idx_crn+1L]=lon_crn[idx_crn+2L]=lon_crn_drv+lon_ncr;
+	    /* Branch-cut rule */
+	    if(lon_crn_drv+lon_ncr >= 360.0){
+	      lon_crn[idx_crn+0L]=lon_crn[idx_crn+3L]=lon_crn_drv-360.0;
+	      lon_crn[idx_crn+1L]=lon_crn[idx_crn+2L]=lon_crn_drv+lon_ncr-360.0;
+	    } /* !brnch */
+	  } /* !mss_val */
+	} /* !lon_idx */
+      } /* !lat_idx */
+      if(lon_vld_nxt) lon_vld_nxt=(long *)nco_free(lon_vld_nxt);
+      if(lon_vld_prv) lon_vld_prv=(long *)nco_free(lon_vld_prv);
+    } /* !CICE */
+
     if(lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT){
       /* Interfaces (ntf) and boundaries (bnd) for curvilinear grids are ill-defined since sides need not follow latitudes nor meridians 
 	 Simplest representation that contains equivalent information to interfaces/boundaries is grid corners array
@@ -6472,8 +6859,14 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     } /* !idx */
   } /* !flg_grd_crv */
 
+  /* 20150512 Many 2D datasets have bad bounds
+     Primary example is Gaussian grids archived by CESM models that use midpoint rule rather than iterate to compute interfaces from quadrature points
+     Such files have correct gw arrays and incorrect cell bounds
+     flg_dgn_bnd allows nco_grd_nfr() to override faulty boundaries in file with correct bounds */
+  const nco_bool flg_dgn_bnd=rgr->flg_dgn_bnd; /* [flg] Diagnose rather than copy inferred bounds */
   if(flg_grd_2D){
-    if(lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT){
+    if(flg_dgn_bnd || (lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT)){
+      if(nco_dbg_lvl_get() >= nco_dbg_std && flg_dgn_bnd) (void)fprintf(stdout,"%s: INFO %s will diagnose cell boundaries from cell centers...\n",nco_prg_nm_get(),fnc_nm);
       /* Derive interfaces (ntf) and bounds (bnd) from midpoints approximation applied to center data
 	 NB: Simplistically derived interfaces (ntf) only valid on some rectangular grids (not on Gaussian grids)
 	 These inferred-from-midpoint interfaces/bounds are overwritten in next block once lat grid is known */
@@ -6509,17 +6902,18 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
       lon_spn=lon_ntf[lon_nbr]-lon_ntf[0];
     } /* !(lat_bnd_id && lon_bnd_id) */
   } /* !flg_grd_2D */
-  
+
   if(flg_grd_2D){
     /* Diagnose type of two-dimensional input grid by testing second latitude center against formulae */
-    nco_grd_xtn_enm nco_grd_xtn=nco_grd_xtn_glb; /* [enm] Extent of grid */
     const double lat_ctr_tst_eqa=lat_ntf[0]+lat_spn*1.5/lat_nbr;
     const double lat_ctr_tst_fv=lat_ntf[0]+lat_spn/(lat_nbr-1);
     double lat_ctr_tst_gss;
     /* In diagnosing grids, agreement with input to single-precision is "good enough for government work"
        Hence some comparisons cast from double to float before comparison
        20150526: T42 grid from SCRIP and related maps are only accurate to ~eight digits
-       20150611: map_ne120np4_to_fv801x1600_bilin.150418.nc has yc_b[1600]=-89.775000006 not expected exact value lat_ctr[1]=-89.775000000000006 */
+       20150611: map_ne120np4_to_fv801x1600_bilin.150418.nc has yc_b[1600]=-89.775000006 not expected exact value lat_ctr[1]=-89.775000000000006
+       20170521: T62 grid from NCEP-NCAR Reanalysis 1 worse than single precision, has yc_[192]=-86.6531 not expected exact value lat_ctr[1]=-86.6532 */
+    if(lat_ctr[0] > 0.0) (void)fprintf(stderr,"%s: WARNING %s reports lat_ctr[0] = %g is positive and lat_ctr[%ld] = %g is negative. Grid inferral currently assumes 2D global grids run from south-to-north, not north-to-south. Global N-to-S grids may not be correctly recognized. Please contact us if full support for inferring N-to-S grids is important to you.\nHINT: Re-try inferring grid after reversing input dataset's latitude coordinate (with, e.g., ncpdq -a time,-lat,lon in.nc out.nc)\ [...]
     if((float)lat_ctr[1] == (float)lat_ctr_tst_eqa) lat_typ=nco_grd_lat_eqa;
     if((float)lat_ctr[1] == (float)lat_ctr_tst_fv) lat_typ=nco_grd_lat_fv;
     double *lat_sin=NULL_CEWI; // [frc] Sine of Gaussian latitudes double precision
@@ -6533,7 +6927,8 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
       /* Gaussian weights on output grid will be double-precision accurate
 	 Grid itself is kept as user-specified so area diagnosed by ESMF_RegridWeightGen may be slightly inconsistent with weights */
       if(nco_dbg_lvl_get() >= nco_dbg_sbr) (void)fprintf(stderr,"%s: INFO %s reports lat_ctr[1] = %g, lat_ctr_tst_gss = %g\n",nco_prg_nm_get(),fnc_nm,lat_ctr[1],lat_ctr_tst_gss);
-      if((float)lat_ctr[1] == (float)lat_ctr_tst_gss) lat_typ=nco_grd_lat_gss;
+      const double eps_rlt_cnv_gss=1.0e-7; // Convergence criterion (1.0e-7 fails for NCEP NCAR Reanalysis 1
+      if(fabs(1.0-fabs(lat_ctr[1])/lat_ctr_tst_gss) < eps_rlt_cnv_gss) lat_typ=nco_grd_lat_gss;
     } /* !Gaussian */
     if(lat_typ == nco_grd_lat_nil){
       /* If still of unknown type, this 2D grid may be weird
@@ -6550,7 +6945,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     else assert(False);
 
     /* Diagnose latitude interfaces from gridcell centers (if boundaries not provided) */
-    if(lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT){
+    if(flg_dgn_bnd || (lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT)){
       lat_nrt=lat_ntf[lat_nbr];
       lat_spn=lat_ntf[lat_nbr]-lat_ntf[0];
       switch(lat_typ){
@@ -6605,6 +7000,16 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
       } /* !lat_typ */
       /* Ensure rounding errors do not produce unphysical grid */
       lat_ntf[lat_nbr]=lat_nrt;
+
+      if(lat_typ == nco_grd_lat_gss){
+	/* 20170510: First approximation above to exterior interfaces for Gaussian grid are ~ +/-89 degrees
+	   Loops below recompute interior interfaces only 
+	   Southern- and northern-most interfaces must be explicitly assigned 
+	   Inferral test for Gaussian grid _assumes_ global grid 
+	   Hence WLOG can assign [-90.0, 90.0] to Gaussian grid exterior boundaries */
+	lat_ntf[0]=-90.0;
+	lat_ntf[lat_nbr]=90.0;
+      } /* !nco_grd_lat_gss */
     } /* !(lat_bnd_id && lon_bnd_id) */
     
     /* Use centers and boundaries to diagnose latitude weights */
@@ -6627,7 +7032,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     /* Diagnose type of longitude grid by testing second longitude center against formulae */
     lon_spn=lon_ntf[lon_nbr]-lon_ntf[0];
     lat_spn=lat_ntf[lat_nbr]-lat_ntf[0];
-    if((float)lon_spn != 360.0f || (float)lat_spn != 180.0f) nco_grd_xtn=nco_grd_xtn_rgn;
+    if((float)lon_spn == 360.0f && (float)lat_spn == 180.0f) nco_grd_xtn=nco_grd_xtn_glb; else nco_grd_xtn=nco_grd_xtn_rgn;
     if(lon_typ == nco_grd_lon_nil){
       if(     (float)lon_ctr[0] ==    0.0f && (float)lon_ctr[1] == (float)(lon_ctr[0]+lon_spn/lon_nbr)) lon_typ=nco_grd_lon_Grn_ctr;
       else if((float)lon_ctr[0] == -180.0f && (float)lon_ctr[1] == (float)(lon_ctr[0]+lon_spn/lon_nbr)) lon_typ=nco_grd_lon_180_ctr;
@@ -6640,7 +7045,6 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed input 2D grid-type: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_2D_sng(grd_typ));
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed input latitude grid-type: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_lat_sng(lat_typ));
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed input longitude grid-type: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_lon_sng(lon_typ));
-    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed input grid-extent: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_xtn_sng(nco_grd_xtn));
 
   } /* !flg_grd_2D */
 
@@ -6672,7 +7076,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
   if(flg_grd_2D){
     assert(grd_crn_nbr == 4);
-    if(lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT){
+    if(flg_dgn_bnd || (lat_bnd_id == NC_MIN_INT && lon_bnd_id == NC_MIN_INT)){
       /* If interfaces were diagnosed from centers, copy corners from interfaces */
       for(lon_idx=0;lon_idx<lon_nbr;lon_idx++){
 	idx=grd_crn_nbr*lon_idx;
@@ -6745,40 +7149,114 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     } /* !lat */
   } /* !flg_grd_2D */
   
-  /* Find span of any grid that has boundaries */
+  /* Find span of all grids */
+  double lat_max; /* [dgr] Maximum latitude */
+  double lat_min; /* [dgr] Minimum latitude */
+  double lon_max; /* [dgr] Maximum longitude */
+  double lon_min; /* [dgr] Minimum longitude */
+  idx_ctr=0;
+  if(has_mss_val_ctr){
+    /* Find first non-missing value center and thus corners */
+    for(idx_ctr=0;idx_ctr<grd_sz_nbr;idx_ctr++){
+      if(grd_ctr_lat[idx_ctr] != mss_val_ctr_dbl) break;
+    } /* !grd_sz_nbr */
+    assert(idx_ctr != grd_sz_nbr);
+  } /* !has_mss_val_ctr */
   if(flg_wrt_crn){
-    double lat_max; /* [dgr] Maximum latitude */
-    double lat_min; /* [dgr] Minimum latitude */
-    double lon_max; /* [dgr] Maximum longitude */
-    double lon_min; /* [dgr] Minimum longitude */
-    idx_ctr=0;
-    if(has_mss_val_ctr){
-      /* Find first non-missing value center and thus corners */
-      for(idx_ctr=0;idx_ctr<grd_sz_nbr;idx_ctr++){
-	if(grd_ctr_lat[idx_ctr] != mss_val_ctr_dbl) break;
-      } /* !grd_sz_nbr */
-      assert(idx_ctr != grd_sz_nbr);
-    } /* !has_mss_val_ctr */
+    /* Grids with corner boundaries supplied or inferred */
     lon_max=grd_crn_lon[idx_ctr*grd_crn_nbr];
     lat_max=grd_crn_lat[idx_ctr*grd_crn_nbr];
     lon_min=grd_crn_lon[idx_ctr*grd_crn_nbr];
     lat_min=grd_crn_lat[idx_ctr*grd_crn_nbr];
     for(idx=1;idx<grd_sz_nbr*grd_crn_nbr;idx++){
       idx_ctr=idx/grd_crn_nbr;
-      if(grd_ctr_lat[idx_ctr] == mss_val_ctr_dbl) continue;
+      if(has_mss_val_ctr)
+	if(grd_ctr_lat[idx_ctr] == mss_val_ctr_dbl)
+	  continue;
       lat_max=(grd_crn_lat[idx] > lat_max) ? grd_crn_lat[idx] : lat_max;
       lon_max=(grd_crn_lon[idx] > lon_max) ? grd_crn_lon[idx] : lon_max;
       lat_min=(grd_crn_lat[idx] < lat_min) ? grd_crn_lat[idx] : lat_min;
       lon_min=(grd_crn_lon[idx] < lon_min) ? grd_crn_lon[idx] : lon_min;
     } /* !idx */
-    lat_spn=lat_max-lat_min;
-    lon_spn=lon_max-lon_min;
-    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s reports grid resolution %li x %li, spans %g x %g degrees: [%g <= lat <= %g], [%g <= lon <= %g]\n",nco_prg_nm_get(),fnc_nm,lat_nbr,lon_nbr,lat_spn,lon_spn,lat_min,lat_max,lon_min,lon_max);
-  } /* !flg_wrt_crn */
-
-  /* Diagnose area if necessary */
-  if(area_id == NC_MIN_INT && flg_wrt_crn){
-    /* Not absolutely necessary to diagnose area because ERWG will diagnose and output area itself */
+  }else{ /* !flg_wrt_crn */
+    /* 20170424: Diagnose grid-extent when corners were not provided or inferred
+       This is usually (always?) for 1d unstructured grids with only centers provided */
+    lon_max=grd_ctr_lon[idx_ctr];
+    lat_max=grd_ctr_lat[idx_ctr];
+    lon_min=grd_ctr_lon[idx_ctr];
+    lat_min=grd_ctr_lat[idx_ctr];
+    for(idx_ctr=1;idx_ctr<grd_sz_nbr;idx_ctr++){
+      if(has_mss_val_ctr)
+	if(grd_ctr_lat[idx_ctr] == mss_val_ctr_dbl)
+	  continue;
+      lat_max=(grd_ctr_lat[idx_ctr] > lat_max) ? grd_ctr_lat[idx_ctr] : lat_max;
+      lon_max=(grd_ctr_lon[idx_ctr] > lon_max) ? grd_ctr_lon[idx_ctr] : lon_max;
+      lat_min=(grd_ctr_lat[idx_ctr] < lat_min) ? grd_ctr_lat[idx_ctr] : lat_min;
+      lon_min=(grd_ctr_lon[idx_ctr] < lon_min) ? grd_ctr_lon[idx_ctr] : lon_min;
+    } /* !idx_ctr */
+  } /* flg_wrt_crn */
+  lat_spn=lat_max-lat_min;
+  lon_spn=lon_max-lon_min;
+  /* Use strict rules for rectangular grids, looser for spans that are inferred, or center-to-center not corner-to-corner */
+  if(flg_grd_2D){
+    if((float)lon_spn == 360.0f && (float)lat_spn == 180.0f) nco_grd_xtn=nco_grd_xtn_glb; else nco_grd_xtn=nco_grd_xtn_rgn;
+  }else{ /* !flg_grd_2D */
+    if((float)lon_spn >= 340.0f && (float)lat_spn >= 170.0f) nco_grd_xtn=nco_grd_xtn_glb; else nco_grd_xtn=nco_grd_xtn_rgn;
+  } /* flg_wrt_crn */
+  if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s reports grid resolution %li x %li, spans %g x %g degrees: [%g <= lat <= %g], [%g <= lon <= %g]\n",nco_prg_nm_get(),fnc_nm,lat_nbr,lon_nbr,lat_spn,lon_spn,lat_min,lat_max,lon_min,lon_max);
+  if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed input grid-extent: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_xtn_sng(nco_grd_xtn));
+
+  /* Write ERWG hints if filenames provided and grid is regional */
+  char *fl_hnt=NULL;
+  char *fl_hnt_dst=NULL;
+  char *fl_hnt_src=NULL;
+  if(rgr->fl_hnt_dst) fl_hnt=fl_hnt_dst=rgr->fl_hnt_dst;
+  if(rgr->fl_hnt_src) fl_hnt=fl_hnt_src=rgr->fl_hnt_src;
+  if(nco_grd_xtn == nco_grd_xtn_rgn && fl_hnt){
+    const char *fl_mode="w";
+    FILE *fp_hnt; /* [fl] Hint file (for ERWG switches) file handle */
+    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s writing ERWG weight-generation regional hint to file %s\n",nco_prg_nm_get(),fnc_nm,fl_hnt);
+    /* Open output file */
+    if((fp_hnt=fopen(fl_hnt,fl_mode)) == NULL){
+      (void)fprintf(stderr,"%s: ERROR unable to open hint output file %s\n",nco_prg_nm_get(),fl_hnt);
+      nco_exit(EXIT_FAILURE);
+    } /* end if */
+    if(nco_dbg_lvl_get() >= nco_dbg_fl) (void)fprintf(stdout,"%s: Opened hint file %s\n",nco_prg_nm_get(),fl_hnt);
+    if(fl_hnt_src) (void)fprintf(fp_hnt,"--src_regional");
+    if(fl_hnt_dst) (void)fprintf(fp_hnt,"--dst_regional");
+    rcd=fclose(fp_hnt);
+    if(rcd != 0){
+      (void)fprintf(stderr,"%s: ERROR unable to close hint output file %s\n",nco_prg_nm_get(),fl_hnt);
+      nco_exit(EXIT_FAILURE);
+    } /* end if */
+    if(nco_dbg_lvl_get() >= nco_dbg_fl) (void)fprintf(stdout,"%s: Closed hint file %s\n",nco_prg_nm_get(),fl_hnt);
+  } /* !nco_grd_xtn */
+  
+  /* Diagnose area if necessary
+     20170510: ALM/CLM "area" is _FillValue=1.0e36f over ocean and total gridcell area in km2 (not multiplied by landfrac) elsewhere
+     Writing this ALM/CLM "area" variable to gridfile, then using with ERWG --user_areas could be disastrous (depending on mask array and interpolation type)
+     On the other hand CAM "area" variable is exactly what we want for gridfile
+     Input areas are considered "untrustworthy" iff they have _and use_ missing value attribute
+     Re-diagnose areas considered untrustworthy so output area array does not contain missing values */
+  if(flg_wrt_crn && has_mss_val_area){
+    const double mss_val_dbl=mss_val_area_dbl;
+    for(idx=0;idx<grd_sz_nbr;idx++)
+      if(area[idx] == mss_val_dbl) break;
+    if(idx < grd_sz_nbr) use_mss_val_area=True;
+    if(nco_dbg_lvl_get() >= nco_dbg_fl && use_mss_val_area) (void)fprintf(stdout,"%s: INFO %s reports input area field %s is considered untrustworthy because it uses missing values, will diagnose area from cell boundaries instead...\n",nco_prg_nm_get(),fnc_nm,area_nm_in);
+  } /* !has_mss_val_area */
+  /* 20170511: There remain a handful of cases when input area should be diagnosed not copied
+     These include using ncremap in SGS mode when inferred grids must use sensible area units
+     Otherwise an inferred grid with area [km2] from ALM/CLM might be combined with area [sr] from NCO
+     This would bias ERWG --user_areas produced values by ~10^10
+     Setting flg_dgn_area ensures inferred area uses [sr] */
+  const nco_bool flg_dgn_area=rgr->flg_dgn_area; /* [flg] Diagnose rather than copy inferred area */
+  if(flg_wrt_crn && /* If bounds are available to compute area and ... */
+     (area_id == NC_MIN_INT || /* Area is not in input file ... */
+      use_mss_val_area || /* Area is untrustworthy */
+      flg_dgn_area)){ /* User/application explicitly requests diagnostic area */
+    /* Not absolutely necessary to diagnose area because ERWG will diagnose and output area itself _unless_ --user_areas option is given */
+    if(nco_dbg_lvl_get() >= nco_dbg_std && flg_dgn_area) (void)fprintf(stdout,"%s: INFO %s reports diagnosing area from cell boundaries...\n",nco_prg_nm_get(),fnc_nm);
     if(flg_grd_crv || flg_grd_1D){
       /* Area of arbitrary unstructured or curvilinear grids requires spherical trigonometry */
       nco_sph_plg_area(grd_crn_lat,grd_crn_lon,grd_sz_nbr,grd_crn_nbr,area);
@@ -6789,52 +7267,58 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
     } /* !flg_grd_2D */
   } /* !area_id */
 
-  /* Input mask can be any type and output mask will always be NC_INT */
-  if(msk_id == NC_MIN_INT){
-    /* ERWG will fail unless the grid file has a mask variable
-       The nul-mask (all points included) will be used whenever a true mask variable is not detected
-       fxm: Optionally construct mask from missing values of var_rgr? */
-    for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=1;
-  }else{
-    /* Change missing value mask points to 0 integer mask for SCRIP grids, which have no missing value convention
+  /* ERWG will fail unless grid file has mask variable
+     Use nul-mask (all points included) whenever input mask variable not supplied/detected 
+     Define nul-mask true everywhere and overwrite with false below
+     Input mask can be any type and output mask will always be NC_INT */
+  for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=1;
+  if(msk_id != NC_MIN_INT){
+    /* Change missing-value-masked points to 0 integer mask for SCRIP grids (SCRIP has no missing value convention)
+       Input mask can be any type and output mask will always be NC_INT
        Applications: 
-       CICE mask is NC_FLOAT and uses NC_FLOAT missing value
+       ALM/CLM mask (landmask) is NC_FLOAT and defines but does not use NC_FLOAT missing value
+       CICE mask (tmask/umask) is NC_FLOAT and defines and uses NC_FLOAT missing value
        AMSR mask is NC_SHORT and has no missing value */
-    switch(msk_typ){
+  switch(msk_typ){
     case NC_FLOAT:
       if(has_mss_val_msk){
 	const float mss_val_flt=mss_val_msk_dbl;
 	for(idx=0;idx<grd_sz_nbr;idx++)
-	  if(msk_unn.fp[idx] == mss_val_flt) msk[idx]=0; else msk[idx]=msk_unn.fp[idx];
+	  if(msk_unn.fp[idx] == mss_val_flt || msk_unn.fp[idx] == 0.0f) msk[idx]=0;
       }else{
-	for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=msk_unn.fp[idx];
+	for(idx=0;idx<grd_sz_nbr;idx++)
+	  if(msk_unn.fp[idx] == 0.0f) msk[idx]=0;
       } /* !mss_val */
       break;
     case NC_DOUBLE:
       if(has_mss_val_msk){
 	const double mss_val_dbl=mss_val_msk_dbl;
 	for(idx=0;idx<grd_sz_nbr;idx++)
-	  if(msk_unn.dp[idx] == mss_val_dbl) msk[idx]=0; else msk[idx]=msk_unn.dp[idx];
+	  if(msk_unn.dp[idx] == mss_val_dbl || msk_unn.dp[idx] == 0.0) msk[idx]=0;
       }else{
-	for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=msk_unn.dp[idx];
+	for(idx=0;idx<grd_sz_nbr;idx++)
+	  if(msk_unn.dp[idx] == 0.0) msk[idx]=0;
       } /* !mss_val */
       break;
     case NC_INT:
       if(has_mss_val_msk){
 	const int mss_val_int=mss_val_msk_dbl;
 	for(idx=0;idx<grd_sz_nbr;idx++)
-	  if(msk_unn.ip[idx] == mss_val_int) msk[idx]=0; else msk[idx]=msk_unn.ip[idx];
+	  if(msk_unn.ip[idx] == mss_val_int || msk_unn.ip[idx] == 0) msk[idx]=0;
       }else{
-	for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=msk_unn.ip[idx];
+	for(idx=0;idx<grd_sz_nbr;idx++)
+	  if(msk_unn.ip[idx] == 0) msk[idx]=0;
       } /* !mss_val */
       break;
     case NC_SHORT:
+      /* http://stackoverflow.com/questions/208433/how-do-i-write-a-short-literal-in-c */
       if(has_mss_val_msk){
 	const short mss_val_sht=mss_val_msk_dbl;
 	for(idx=0;idx<grd_sz_nbr;idx++)
-	  if(msk_unn.sp[idx] == mss_val_sht) msk[idx]=0; else msk[idx]=msk_unn.sp[idx];
+	  if(msk_unn.sp[idx] == mss_val_sht || msk_unn.sp[idx] == ((short)0)) msk[idx]=0;
       }else{
-	for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=msk_unn.sp[idx];
+	for(idx=0;idx<grd_sz_nbr;idx++)
+	  if(msk_unn.sp[idx] == ((short)0)) msk[idx]=0;
 	/* 20160111: AMSR kludge fxm */
 	//	for(idx=0;idx<grd_sz_nbr;idx++) if(msk[idx] == 1) msk[idx]=0;
       } /* !mss_val */
@@ -6906,7 +7390,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
   
   att_nm=strdup("title");
   if(strstr(rgr->grd_ttl,"None given")){
-    const char att_fmt[]="Grid inferred by NCO from input file %s";
+    const char att_fmt[]="NCO inferred this grid from input file %s";
     att_val=(char *)nco_malloc((strlen(att_fmt)+strlen(rgr->fl_in)+1L)*sizeof(char));
     sprintf(att_val,att_fmt,rgr->fl_in);
   }else{
@@ -7056,7 +7540,7 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
        Documentation: https://github.com/ugrid-conventions/ugrid-conventions
        Procedure: Create 1x1 skeleton file, infer UGRID and SCRIP grids from it
        ncks -O -D 1 --rgr grd_ttl='Equiangular grid 180x360' --rgr skl=${HOME}/skl_180x360.nc --rgr grid=${HOME}/grd_180x360_SCRIP.nc --rgr latlon=180,360#lat_typ=eqa#lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
-       ncks -O -D 1 --rgr nfr=y --rgr ugrid=${HOME}/grd_ugrid.nc --rgr grid=${HOME}/grd_scrip.nc ~/skl_180x360.nc ~/foo.nc
+       ncks -O -D 1 --rgr infer --rgr ugrid=${HOME}/grd_ugrid.nc --rgr grid=${HOME}/grd_scrip.nc ~/skl_180x360.nc ~/foo.nc
        ncks --cdl -v mesh_node_y ~/grd_ugrid.nc
        ncks --cdl -v mesh_face_nodes,mesh_face_x,mesh_face_y -d nFaces,0 ~/grd_ugrid.nc
        ncks --cdl -v mesh_edge_nodes,mesh_edge_x,mesh_edge_y -d nEdges,0 ~/grd_ugrid.nc
@@ -7806,7 +8290,6 @@ nco_grd_nfr /* [fnc] Infer SCRIP-format grid file from input data file */
 
     /* Close output file and move it from temporary to permanent location */
     (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id);
-    (void)fprintf(stdout,"%s: DBG %s ending UGRID section\n",nco_prg_nm_get(),fnc_nm);
 
     /* Free memory associated with output file */
     if(dgx) dgx=(double *)nco_free(dgx);
diff --git a/src/nco/nco_var_utl.c b/src/nco/nco_var_utl.c
index 8e06318..0e8774e 100644
--- a/src/nco/nco_var_utl.c
+++ b/src/nco/nco_var_utl.c
@@ -1474,11 +1474,11 @@ nco_is_spc_in_cf_att /* [fnc] Variable is listed in this CF attribute, thereby a
 } /* end nco_is_spc_in_cf_att() */
 
 
-char ***  /* [0] [ptr]  list of lists - each ragged array terminated with empty string    */
+char *** /* O [ptr]  list of lists - each ragged array terminated with empty string    */
 nco_lst_cf_att /* [fnc] look in all vars for att cf_nm  */
-(const int nc_id,    /* I [id] netCDF file ID */
- const char *const cf_nm,  /* I [sng] cf att name */
- int *nbr_lst) /* 0 [nbr] number of ragged arrays returned */
+(const int nc_id, /* I [id] netCDF file ID */
+ const char *const cf_nm, /* I [sng] CF att name */
+ int *nbr_lst) /* O [nbr] number of ragged arrays returned */
 {
   /* Purpose: Is variable specified in an associated attribute?
      Associated attributes include "ancillary_variables", "bounds", "climatology", "coordinates", "grid_mapping"
@@ -1512,7 +1512,7 @@ nco_lst_cf_att /* [fnc] look in all vars for att cf_nm  */
   rcd+=nco_inq_nvars(nc_id,&nbr_var);
 
   /* This assumption, praise the Lord, is valid in netCDF2, netCDF3, and netCDF4 */
-  for(var_id=0; var_id<nbr_var;var_id++){
+  for(var_id=0;var_id<nbr_var;var_id++){
 
     nco_inq_varname(nc_id,var_id,var_nm);
 
@@ -1531,11 +1531,10 @@ nco_lst_cf_att /* [fnc] look in all vars for att cf_nm  */
         /* NUL-terminate attribute */
         att_val[att_sz]='\0';
         /* Split list into separate variable names
-	     Use nco_lst_prs_sgl_2D() not nco_lst_prs_2D() to avert TODO nco944 */
+	   Use nco_lst_prs_sgl_2D() not nco_lst_prs_2D() to avert TODO nco944 */
         cf_lst=nco_lst_prs_sgl_2D(att_val,dlm_sng,&nbr_cf);
 
-
-        int_lst=(char**)nco_malloc( (nbr_cf+3) * sizeof(char*)  );
+        int_lst=(char **)nco_malloc((nbr_cf+3)*sizeof(char *));
         int_lst[0]=strdup(var_nm);
         int_lst[1]=strdup(cf_nm);
 
@@ -1546,20 +1545,18 @@ nco_lst_cf_att /* [fnc] look in all vars for att cf_nm  */
         int_lst[nbr_cf+2]=strdup("");
 
         /* add ragged array to list */
-        ra_lst=(char***)nco_realloc( ra_lst, sizeof(char**)*(*nbr_lst+1) );
+        ra_lst=(char ***)nco_realloc(ra_lst,sizeof(char**)*(*nbr_lst+1));
         ra_lst[*nbr_lst]=int_lst;
         ++*nbr_lst;
 
         att_val=(char *)nco_free(att_val);
         cf_lst=nco_sng_lst_free(cf_lst,nbr_cf);
         // cf_lst=nco_free(cf_lst);
-        int_lst=(char**)NULL_CEWI;
-
+        int_lst=(char **)NULL_CEWI;
       }
     } /* end loop over attributes */
   } /* end loop over var_id */
 
-
   return ra_lst;
 } /* end nco_lst_cf_att() */
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/nco.git



More information about the Pkg-grass-devel mailing list