[nco] 01/06: Imported Upstream version 4.5.2

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri Sep 11 11:11:14 UTC 2015


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

sebastic pushed a commit to branch master
in repository nco.

commit 6a3507a5e1c7db5594393509be30bbd718b5e9cd
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Sep 11 12:22:59 2015 +0200

    Imported Upstream version 4.5.2
---
 bld/Makefile           |   22 +-
 bld/nco.spec           |    4 +-
 bm/NCO_rgr.pm          |  136 ++++-
 configure              |   20 +-
 configure.ac           |    2 +-
 configure.eg           |   78 ++-
 doc/ANNOUNCE           |  142 ++---
 doc/ChangeLog          |  228 +++++++-
 doc/TODO               |    3 +-
 doc/VERSION            |    2 +-
 doc/index.shtml        |   76 ++-
 doc/nco.texi           |  429 ++++++++++++--
 man/ncap.1             |    3 +
 man/ncap2.1            |    3 +
 man/ncatted.1          |    3 +
 man/ncbo.1             |    3 +
 man/ncdiff.1           |    3 +
 man/ncea.1             |    5 +-
 man/ncecat.1           |    3 +
 man/nces.1             |    2 +-
 man/ncflint.1          |    3 +
 man/ncks.1             |   15 +-
 man/ncpdq.1            |    3 +
 man/ncra.1             |    5 +-
 man/ncrcat.1           |    3 +
 man/ncrename.1         |    6 +-
 man/ncwa.1             |    3 +
 src/nco++/ncap2.cc     |  260 +++++----
 src/nco++/ncoGrammer.g |    5 +
 src/nco++/ncoTree.cpp  |  207 +++----
 src/nco/mpncbo.c       |  217 +++----
 src/nco/mpncecat.c     |  221 +++----
 src/nco/mpncflint.c    |  217 +++----
 src/nco/mpncpdq.c      |  214 +++----
 src/nco/mpncra.c       |   50 +-
 src/nco/mpncwa.c       |  278 ++++-----
 src/nco/ncap.c         |  214 +++----
 src/nco/ncatted.c      |   31 +-
 src/nco/ncbo.c         |  202 +++----
 src/nco/ncecat.c       |  221 +++----
 src/nco/ncflint.c      |  210 +++----
 src/nco/ncks.c         |  487 ++++++++--------
 src/nco/nco.h          |   50 +-
 src/nco/nco_att_utl.c  |   62 ++
 src/nco/nco_att_utl.h  |    6 +
 src/nco/nco_cnf_typ.c  |    2 +-
 src/nco/nco_cnv_csm.c  |    2 +-
 src/nco/nco_ctl.c      |   36 +-
 src/nco/nco_fl_utl.c   |   54 +-
 src/nco/nco_grp_utl.c  |   10 +-
 src/nco/nco_mmr.c      |    6 +-
 src/nco/nco_rgr.c      | 1506 ++++++++++++++++++++++++++++++++++++++++++------
 src/nco/nco_rgr.h      |   36 +-
 src/nco/nco_rth_utl.c  |   10 +-
 src/nco/nco_scm.c      |    2 +-
 src/nco/nco_sld.c      |  453 ++++++++++++++-
 src/nco/nco_sld.h      |    8 +
 src/nco/nco_var_rth.c  |  113 +++-
 src/nco/nco_var_rth.h  |   12 +
 src/nco/nco_var_utl.c  |    7 +
 src/nco/ncpdq.c        |   55 +-
 src/nco/ncra.c         |  306 +++++-----
 src/nco/ncrename.c     |   28 +-
 src/nco/ncwa.c         |   74 +--
 64 files changed, 4979 insertions(+), 2098 deletions(-)

diff --git a/bld/Makefile b/bld/Makefile
index 054626f..e73f905 100644
--- a/bld/Makefile
+++ b/bld/Makefile
@@ -150,28 +150,28 @@ NCOXX_SRC_DIR := ${MY_SRC_DIR}/../nco++
 
 # Primary tokens which determine build options
 # Specify non-default when invoking make, e.g. make OMP=Y
-ifndef ${ABI}
+ifndef ABI
 # 32- vs. 64-bit ABI: 32=32-bit mode, 64=64-bit mode (default) if available
  ABI := 64
 endif # endif ABI
-ifndef ${CCACHE}
+ifndef CCACHE
  CCACHE := N
 endif # CCACHE
 ifndef CNK
 # Use newer netCDF4.1 chunking API
  CNK := Y
 endif # endif CNK
-ifndef ${CUDA}
+ifndef CUDA
  CUDA := N
 endif # CUDA
 ifndef DAP
  DAP := Y
 endif # DAP
-ifndef ${DBG}
+ifndef DBG
 # Debugging token N=No (default) Y=Yes
  DBG := N
 endif # endif DBG
-ifndef ${DPKG}
+ifndef DPKG
 # Debian hardening tokens
  DPKG := N
 endif # endif DPKG
@@ -201,17 +201,17 @@ ifndef MK_DPN
  MK_DPN = ${CPP} -M # NB: Recursive expansion required
  MK_DPN_CXX = ${CXX} -M # NB: Recursive expansion required
 endif # endif MK_DPN
-ifndef ${MPI} # MPI
+ifndef MPI # MPI
  MPI := N
 endif # endif MPI
-ifndef ${MPI_FAKE} # MPI
+ifndef MPI_FAKE # MPI
  MPI_FAKE := N
 endif # endif MPI_FAKE
 ifndef NCO_VRS
 # Used for RPM building
  NCO_VRS := $(shell cat ${MY_DOC_DIR}/VERSION)
 endif
-ifndef ${NETCDF4} # netCDF4 support
+ifndef NETCDF4 # netCDF4 support
  NETCDF4 := Y
 endif # endif NETCDF4
 ifndef NETCDF_ROOT
@@ -243,7 +243,7 @@ endif
 ifndef PGI_RCH_ARG
  PGI_RCH_ARG :=
 endif # endif PGI_RCH_ARG
-ifndef ${PNETCDF} # pnetCDF support
+ifndef PNETCDF # pnetCDF support
  PNETCDF := N
 endif # endif PNETCDF
 ifndef PSC_RCH_ARG
@@ -260,7 +260,7 @@ ifndef SZ
 # Link to Szip library
  SZ := N
 endif
-ifndef ${UDUNITS}
+ifndef UDUNITS
 # Use UDUnits functionality
  UDUNITS := Y
 endif
@@ -275,7 +275,7 @@ ifndef VRS_SNG
 # 20150622
  VRS_SNG := $(shell git describe --abbrev=7 --dirty --always --tags)
 endif # endif VRS_SNG
-ifndef ${ZNETCDF} # znetcdf support
+ifndef ZNETCDF # znetcdf support
  ZNETCDF := N
 endif # endif ZNETCDF
 # Derived-tokens based on primary tokens
diff --git a/bld/nco.spec b/bld/nco.spec
index 8274fe7..10bd83e 100644
--- a/bld/nco.spec
+++ b/bld/nco.spec
@@ -108,8 +108,8 @@ fi
 # %{_libdir}/libnco++.so
 
 %changelog
-* Fri Jul 24 2015 Charlie Zender <zender at uci.edu> - 4.5.1-1
-- new upstream 4.5.1
+* Fri Jul 24 2015 Charlie Zender <zender at uci.edu> - 4.5.-1
+- new upstream 4.5.2
 
 * Fri Jul 10 2015 Charlie Zender <zender at uci.edu> - 4.5.1-1
 - new upstream 4.5.1
diff --git a/bm/NCO_rgr.pm b/bm/NCO_rgr.pm
index 7b66025..b1ee6fd 100644
--- a/bm/NCO_rgr.pm
+++ b/bm/NCO_rgr.pm
@@ -137,7 +137,9 @@ print "\n";
     $#tst_cmd=0; # Reset array
 # printf("paused @ [%s:%d] - hit return to continue\n", __FILE__, __LINE__); my $wait = <STDIN>;
     } # endif false
-    
+
+# ncap2 -O -v -s 'tpt_mod=tpt%273.0f' ~/nco/data/in.nc ~/foo.nc
+# ncks -C -H -v tpt_mod -s '%.1f' ~/foo.nc
     $dsc_sng="Testing float modulo float";
     $tst_cmd[0]="ncap2 -h -O $fl_fmt $nco_D_flg -C -v -s 'tpt_mod=tpt%273.0f' $in_pth_arg in.nc %tmp_fl_00%";
     $tst_cmd[1]="ncks -C -H -v tpt_mod -s '%.1f ' %tmp_fl_00%";
@@ -264,7 +266,7 @@ print "\n";
 	NCO_bm::tst_run(\@tst_cmd);
 	$#tst_cmd=0; # Reset array
 
-	$dsc_sng="Regridding area 1D->2D to test grid normalization";
+	$dsc_sng="Regridding area 1D->2D to test grid area integral/normalization";
 	$tst_cmd[0]="ncks -O $fl_fmt $nco_D_flg --map=${drc_dat}/map_ne30np4_to_fv129x256_aave.150418.nc $drc_dat/ne30_tst.nc %tmp_fl_00%";
 	$tst_cmd[1]="ncwa -O $fl_fmt $nco_D_flg -y ttl -v area %tmp_fl_00% %tmp_fl_02%";
 	$tst_cmd[2]="ncks -O $fl_fmt $nco_D_flg -H -u -C -v area %tmp_fl_02%";
@@ -273,17 +275,27 @@ print "\n";
 	NCO_bm::tst_run(\@tst_cmd);
 	$#tst_cmd=0; # Reset array
 
-	$dsc_sng="Regridding FSNT 2D->1D to test conservation (uses SSH/scp to givre.ess.uci.edu)";
-	$tst_cmd[0]="scp givre.ess.uci.edu:/data/zender/maps/map_fv129x256_to_ne30np4_aave.20150602.nc .";
+	$dsc_sng="Regridding FSNT 1D->2D to test bilinear remapping (uses SSH/scp to givre.ess.uci.edu)";
+	$tst_cmd[0]="scp givre.ess.uci.edu:/data/zender/maps/map_ne30np4_to_fv257x512_bilin.150418.nc .";
 	$tst_cmd[1]="scp givre.ess.uci.edu:/data/zender/ne30/rgr/ne30_tst.nc .";
-	$tst_cmd[2]="ncks -O $fl_fmt $nco_D_flg --map=map_fv129x256_to_ne30np4_aave.20150602.nc ne30_2D.nc %tmp_fl_00%";
-	$tst_cmd[3]="ncwa -O $fl_fmt $nco_D_flg -w area %tmp_fl_00% %tmp_fl_01%";
+	$tst_cmd[2]="ncks -O $fl_fmt $nco_D_flg --map=map_ne30np4_to_fv257x512_bilin.150418.nc ne30_tst.nc %tmp_fl_00%";
+	$tst_cmd[3]="ncwa -O $fl_fmt $nco_D_flg -w gw %tmp_fl_00% %tmp_fl_01%";
 	$tst_cmd[4]="ncks -O $fl_fmt $nco_D_flg -H -u -C -v FSNT %tmp_fl_01%";
-	$tst_cmd[5]="FSNT = 244.124 W/m2";
+	$tst_cmd[5]="FSNT = 244.237 W/m2";
 	$tst_cmd[6]="SS_OK";
 	NCO_bm::tst_run(\@tst_cmd);
 	$#tst_cmd=0; # Reset array
 
+	$dsc_sng="Regridding FSNT 2D->1D to test conservation (uses SSH/scp to givre.ess.uci.edu)";
+	$tst_cmd[0]="scp givre.ess.uci.edu:/data/zender/maps/map_fv129x256_to_ne30np4_aave.20150602.nc .";
+	$tst_cmd[1]="ncks -O $fl_fmt $nco_D_flg --map=map_fv129x256_to_ne30np4_aave.20150602.nc ne30_2D.nc %tmp_fl_00%";
+	$tst_cmd[2]="ncwa -O $fl_fmt $nco_D_flg -w area %tmp_fl_00% %tmp_fl_01%";
+	$tst_cmd[3]="ncks -O $fl_fmt $nco_D_flg -H -u -C -v FSNT %tmp_fl_01%";
+	$tst_cmd[4]="FSNT = 244.124 W/m2";
+	$tst_cmd[5]="SS_OK";
+	NCO_bm::tst_run(\@tst_cmd);
+	$#tst_cmd=0; # Reset array
+
 	$dsc_sng="Regridding FSNT 2D->2D to test conservation (uses SSH/scp to givre.ess.uci.edu)";
 	$tst_cmd[0]="scp givre.ess.uci.edu:/data/zender/maps/map_fv129x256_to_fv257x512_aave.20150529.nc .";
 	$tst_cmd[1]="scp givre.ess.uci.edu:/data/zender/ne30/rgr/ne30_tst.nc .";
@@ -2620,6 +2632,40 @@ if($RUN_NETCDF4_TESTS_VERSION_GE_431){
     NCO_bm::tst_run(\@tst_cmd);
     $#tst_cmd=0; # Reset array
 
+# ncks #108
+# ncks -h -O --gaa script=nco_climo.sh ~/nco/data/in.nc ~/foo.nc
+# ncks -M ~/foo.nc | grep script | cut -d ' ' -f 11    
+    $dsc_sng="Add single global attribute";
+    $tst_cmd[0]="ncks -h -O $nco_D_flg --gaa script=nco_climo.sh $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -M %tmp_fl_00% | grep 'script' | cut -d ' ' -f 11";
+    $tst_cmd[2]="nco_climo.sh";
+    $tst_cmd[3]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array
+
+# ncks #109
+# ncks -h -O --gaa foo=bar --gaa foo2,foo3=bar2 --gaa script='created by nco_climo.sh' ~/nco/data/in.nc ~/foo.nc
+# ncks -M ~/foo.nc | grep script | cut -d ' ' -f 11-13    
+    $dsc_sng="Add multiple global attributes";
+    $tst_cmd[0]="ncks -h -O $nco_D_flg --gaa foo=bar --gaa foo2,foo3=bar2 --gaa script='created by nco_climo.sh' $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -M %tmp_fl_00% | grep 'script' | cut -d ' ' -f 11-13";
+    $tst_cmd[2]="created by nco_climo.sh";
+    $tst_cmd[3]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array
+
+# ncks #110
+# NB: This tests whether the output file has global metadata, and that provides (circumstantial) evidence that there were no major problems in the intervening routines of grid generation
+# ncks -O -v one -D 5 -t 1 --rgr grd_ttl='FV-scalar grid' --rgr grid=~/65x128_SCRIP.nc --rgr lat_nbr=65 --rgr lon_nbr=128 --rgr lat_typ=FV --rgr lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
+# ncks -M ~/foo.nc | grep "julian" | cut -d ' ' -f 4
+    $dsc_sng="Generate RLL grid";
+    $tst_cmd[0]="ncks -h -O $nco_D_flg -v one --rgr grd_ttl='FV-scalar grid' --rgr grid=65x128_SCRIP.nc --rgr lat_nbr=65 --rgr lon_nbr=128 --rgr lat_typ=FV --rgr lon_typ=Grn_ctr $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -M %tmp_fl_00% | grep 'julian' | cut -d ' ' -f 4";
+    $tst_cmd[2]="julian_day,";
+    $tst_cmd[3]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array
+
 } # RUN_NETCDF4_TESTS_VERSION_GE_431
 	
 #####################
@@ -4075,12 +4121,88 @@ if(0){
     $dsc_sng="Test per-record weighting with --wgt=one_dmn_rec_wgt";
     $tst_cmd[0]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,,1 -v one_dmn_rec_wgt,one_dmn_rec_var_flt $in_pth_arg in.nc %tmp_fl_00%";
     $tst_cmd[1]="ncra -h -O $fl_fmt $nco_D_flg -w one_dmn_rec_wgt -v one_dmn_rec_var_flt %tmp_fl_00% %tmp_fl_01%";
+#    NB: verify test fails with missing values TODO nco1124
+#    $tst_cmd[0]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,,1 $in_pth_arg in.nc %tmp_fl_00%";
+#    $tst_cmd[1]="ncra -h -O $fl_fmt $nco_D_flg -w one_dmn_rec_wgt %tmp_fl_00% %tmp_fl_01%";
     $tst_cmd[2]="ncks -C -H -s '%g' -v one_dmn_rec_var_flt %tmp_fl_01%";
     $tst_cmd[3]="1.33333";
     $tst_cmd[4]="SS_OK";   
     NCO_bm::tst_run(\@tst_cmd);
     $#tst_cmd=0; # Reset array 	
 
+# ncra #36
+# Test per-file weighting without missing values
+# Correct answer: 2.33333=(1*1+2*2+3*3)/(1+2+3)
+# Actual answer until 20150801: 2.33333 Yay!
+# ncks -O -C -d time,0 -v one_dmn_rec_var_flt ~/nco/data/in.nc ~/foo1.nc
+# ncks -O -C -d time,1 -v one_dmn_rec_var_flt ~/nco/data/in.nc ~/foo2.nc
+# ncks -O -C -d time,2 -v one_dmn_rec_var_flt ~/nco/data/in.nc ~/foo3.nc
+# ncra -O -D 6 -w 1,2,3 ~/foo1.nc ~/foo2.nc ~/foo3.nc ~/foo.nc
+# ncks -C -H -s '%g' -v one_dmn_rec_var_flt ~/foo.nc
+    $dsc_sng="Test per-file weighting without missing values";
+    $tst_cmd[0]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,0 -v one_dmn_rec_var_flt $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,1 -v one_dmn_rec_var_flt $in_pth_arg in.nc %tmp_fl_01%";
+    $tst_cmd[2]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,2 -v one_dmn_rec_var_flt $in_pth_arg in.nc %tmp_fl_02%";
+    $tst_cmd[3]="ncra -h -O $fl_fmt $nco_D_flg -w 1,2,3 %tmp_fl_00% %tmp_fl_01% %tmp_fl_02% %tmp_fl_03%";
+    $tst_cmd[4]="ncks -C -H -s '%g' -v one_dmn_rec_var_flt %tmp_fl_03%";
+    $tst_cmd[5]="2.33333";
+    $tst_cmd[6]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array 	
+
+# ncra #37
+# Test per-file weighting with missing values
+# Correct answer: 2.6=(0*1+2*2+3*3)/(2+3) = (6/5)*(0*1+2*2+3*3)/(1+2+3) = ((0*1+2*2+3*3)/(1+2+3))/(5/6)
+# Actual (and incorrect) answer until 20150801: 3.25=3*(0*1+2*2+3*3)/(2*(1+2+3))
+# Actual (and incorrect) answer on 20150802: 1.3=3*(0*1+2*2+3*3)/(2*(1+2+3))
+# Theoretical (and incorrect) answer I thought algorithm produced on 20150731: 2.1666=(0*1+2*2+3*3)/(1+2+3)
+# IOW: To obtain the correct answer for the missing value case, 
+# divide the answer obtained by original method (which is correct only for non-missing values) 
+# by the sum of the valid (non-missing), normalized weights.
+# New algorithm: 
+# If no missing value exists, use existing algorithm and change nothing
+# If missing value exists, declare and compute new double-precision, spatially conforming (i.e., all dimensions except record/time), normalized (to unity) weight structure member for each variable
+# Divide final answer by this (unity if no missing values encountered)
+# NB: This implies that wgt_nm option wgt_avg field must be full (non-scalar) variable
+# Current implementation as "crippled" scalar value is incorrect for missing values    
+# ncks -O -C -d time,0 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo1.nc
+# ncks -O -C -d time,1 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo2.nc
+# ncks -O -C -d time,2 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo3.nc
+# ncra -O -D 6 -w 1,2,3 ~/foo1.nc ~/foo2.nc ~/foo3.nc ~/foo.nc
+# ncks -C -H -s '%g' -v one_dmn_rec_var_flt_mss ~/foo.nc
+    $dsc_sng="Test per-file weighting with missing values with --wgt 1,2,3";
+    $tst_cmd[0]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,0 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,1 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_01%";
+    $tst_cmd[2]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,2 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_02%";
+    $tst_cmd[3]="ncra -h -O $fl_fmt $nco_D_flg -w 1,2,3 %tmp_fl_00% %tmp_fl_01% %tmp_fl_02% %tmp_fl_03%";
+    $tst_cmd[4]="ncks -C -H -s '%g' -v one_dmn_rec_var_flt_mss %tmp_fl_03%";
+    $tst_cmd[5]="2.6";
+    $tst_cmd[6]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array 	
+
+# ncra #38
+# Test per-file weighting with missing values
+# Correct answer: 1.0=(3*1+2*0+1*0)/3 = (6/3)*(3*1+2*0+1*0)/(1+2+3) = ((3*1+2*0+1*0)/(1+2+3))/(3/6)
+# Actual answer on 20150802: 1.0
+# ncks -O -C -d time,1 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo1.nc
+# ncap2 -O -h -s 'one_dmn_rec_var_flt_mss/=2' ~/foo1.nc ~/foo1.nc
+# ncks -O -C -d time,0 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo2.nc
+# ncks -O -C -d time,0 -v one_dmn_rec_var_flt_mss ~/nco/data/in.nc ~/foo3.nc
+# ncra -O -D 6 -w 3,2,1 ~/foo1.nc ~/foo2.nc ~/foo3.nc ~/foo.nc
+# ncks -C -H -s '%g' -v one_dmn_rec_var_flt_mss ~/foo.nc
+    $dsc_sng="Test per-file weighting with missing values with --wgt 3,2,1";
+    $tst_cmd[0]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,1 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_00%";
+    $tst_cmd[1]="ncap2 -h -O $nco_D_flg -s 'one_dmn_rec_var_flt_mss/=2' %tmp_fl_00% %tmp_fl_00%";
+    $tst_cmd[2]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,0 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_01%";
+    $tst_cmd[3]="ncks -h -O $fl_fmt $nco_D_flg -C -d time,0 -v one_dmn_rec_var_flt_mss $in_pth_arg in.nc %tmp_fl_02%";
+    $tst_cmd[4]="ncra -h -O $fl_fmt $nco_D_flg -w 3,2,1 %tmp_fl_00% %tmp_fl_01% %tmp_fl_02% %tmp_fl_03%";
+    $tst_cmd[5]="ncks -C -H -s '%g' -v one_dmn_rec_var_flt_mss %tmp_fl_03%";
+    $tst_cmd[6]="1.0";
+    $tst_cmd[7]="SS_OK";   
+    NCO_bm::tst_run(\@tst_cmd);
+    $#tst_cmd=0; # Reset array 	
+
 ####################
 #### ncwa tests #### OK!
 ####################
diff --git a/configure b/configure
index d6eb03a..54b9378 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.5.1.
+# Generated by GNU Autoconf 2.69 for NCO netCDF Operators 4.5.2.
 #
 # 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.5.1'
-PACKAGE_STRING='NCO netCDF Operators 4.5.1'
+PACKAGE_VERSION='4.5.2'
+PACKAGE_STRING='NCO netCDF Operators 4.5.2'
 PACKAGE_BUGREPORT='nco-bugs at lists.sourceforge.net'
 PACKAGE_URL=''
 
@@ -1392,7 +1392,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.5.1 to adapt to many kinds of systems.
+\`configure' configures NCO netCDF Operators 4.5.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1463,7 +1463,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of NCO netCDF Operators 4.5.1:";;
+     short | recursive ) echo "Configuration of NCO netCDF Operators 4.5.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1626,7 +1626,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-NCO netCDF Operators configure 4.5.1
+NCO netCDF Operators configure 4.5.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2492,7 +2492,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.5.1, which was
+It was created by NCO netCDF Operators $as_me 4.5.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3741,7 +3741,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='nco'
- VERSION='4.5.1'
+ VERSION='4.5.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21426,7 +21426,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.5.1, which was
+This file was extended by NCO netCDF Operators $as_me 4.5.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21492,7 +21492,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.5.1
+NCO netCDF Operators config.status 4.5.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index e773e9a..20a5b0d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,7 +51,7 @@
 
 # Process configure input with autoconf to produce configure script
 # (package name,version,bug-report-address,tarball name)
-AC_INIT([NCO netCDF Operators],[4.5.1],[nco-bugs at lists.sourceforge.net],[nco])
+AC_INIT([NCO netCDF Operators],[4.5.2],[nco-bugs at lists.sourceforge.net],[nco])
 
 # Print GNU copyright in configure script
 AC_COPYRIGHT
diff --git a/configure.eg b/configure.eg
index 05c97bc..a3eb3c1 100644
--- a/configure.eg
+++ b/configure.eg
@@ -268,6 +268,68 @@ make check >> nco.make.${GNU_TRP}.foo 2>&1
 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:/var/www/html/nco/rgr
 
+# gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on edison:
+# Used 20150825-
+module load szip
+module load gsl
+module load udunits
+module load cray-netcdf
+export GNU_TRP=`~/nco/autobld/config.guess`
+cd ~/nco;/bin/rm -f *.${GNU_TRP}.foo;make distclean
+ANTLR_ROOT='/usr' CC='icc' CXX='icpc' GSL_ROOT='/usr/common/usg/gsl/1.16/intel' NETCDF_INC='/opt/cray/netcdf/4.3.2/INTEL/140/include' NETCDF_LIB='/opt/cray/netcdf/4.3.2/INTEL/140/lib' NETCDF_ROOT='/opt/cray/netcdf/4.3.2' UDUNITS2_PATH='/usr/common/usg/udunits/2.1.24/intel' ./configure --prefix=${HOME} --bindir=${HOME}/bin --datadir=${HOME}/nco/data --libdir=${HOME}/lib --mandir=${HOME}/man > nco.configure.${GNU_TRP}.foo 2>&1
+/bin/cp -f config.log nco.config.log.${GNU_TRP}.foo
+/bin/cp -f libtool nco.libtool.${GNU_TRP}.foo
+make clean;make > nco.make.${GNU_TRP}.foo 2>&1
+make check >> nco.make.${GNU_TRP}.foo 2>&1
+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:/var/www/html/nco/rgr
+
+# gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on hopper:
+# Used 20150824-
+module load szip
+module load gsl
+module load udunits
+module load cray-netcdf
+export GNU_TRP=`~/nco/autobld/config.guess`
+cd ~/nco;/bin/rm -f *.${GNU_TRP}.foo;make distclean
+ANTLR_ROOT='/usr' CC='gcc' CXX='g++' GSL_ROOT='/usr/common/usg/gsl/1.16/pgi' NETCDF_INC='/opt/cray/netcdf/4.3.2/PGI/141/include' NETCDF_LIB='/opt/cray/netcdf/4.3.2/PGI/141/lib' NETCDF_ROOT='/opt/cray/netcdf/4.3.2' UDUNITS2_PATH='/usr/common/usg/udunits/2.2.18/pgi' ./configure --prefix=${HOME} --bindir=${HOME}/bin --datadir=${HOME}/nco/data --libdir=${HOME}/lib --mandir=${HOME}/man > nco.configure.${GNU_TRP}.foo 2>&1
+/bin/cp -f config.log nco.config.log.${GNU_TRP}.foo
+/bin/cp -f libtool nco.libtool.${GNU_TRP}.foo
+make clean;make > nco.make.${GNU_TRP}.foo 2>&1
+make check >> nco.make.${GNU_TRP}.foo 2>&1
+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:/var/www/html/nco/rgr
+
+# gcc/g++ Zender used this to develop/install/update netCDF4-enabled NCO in personal directories on hopper:
+# Used 20150818-20150824
+module load netcdf
+module load szip
+module load gsl
+module load udunits
+export GNU_TRP=`~/nco/autobld/config.guess`
+cd ~/nco;/bin/rm -f *.${GNU_TRP}.foo;make distclean
+ANTLR_ROOT='/usr' CC='gcc' CXX='g++' GSL_ROOT='/usr/common/usg/gsl/1.16/pgi' NETCDF_ROOT='/opt/cray/netcdf/4.3.2/GNU/49' UDUNITS2_PATH='/usr/common/usg/udunits/2.2.18/pgi' ./configure --prefix=${HOME} --bindir=${HOME}/bin --datadir=${HOME}/nco/data --libdir=${HOME}/lib --mandir=${HOME}/man > nco.configure.${GNU_TRP}.foo 2>&1
+/bin/cp -f config.log nco.config.log.${GNU_TRP}.foo
+/bin/cp -f libtool nco.libtool.${GNU_TRP}.foo
+make clean;make > nco.make.${GNU_TRP}.foo 2>&1
+make check >> nco.make.${GNU_TRP}.foo 2>&1
+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:/var/www/html/nco/rgr
+
+# gcc/g++ Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on pileus:
+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='/opt/ACME/uvcdat-2.2-build/install/Externals' UDUNITS2_PATH='/opt/ACME/uvcdat-2.2-build/install/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
+/bin/cp -f config.log nco.config.log.${GNU_TRP}.foo
+/bin/cp -f libtool nco.libtool.${GNU_TRP}.foo
+make clean;make > nco.make.${GNU_TRP}.foo 2>&1
+make check >> nco.make.${GNU_TRP}.foo 2>&1
+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:/var/www/html/nco/rgr
+
+# Commands used for Configure builds with gcc/++ on rhea
+fxm
+
 # icc/icpc Zender uses this to develop/install/update netCDF4-enabled NCO in personal directories on rhea:
 export GNU_TRP=`~/nco/autobld/config.guess`
 # Commands used for Makefile builds
@@ -275,16 +337,18 @@ module avail
 . ~/.bashrc
 # module add intel gsl netcdf # No! netcdf/hdf from modules causes unresolved linker error
 module add intel gsl
-export LD_LIBRARY_PATH='/sw/redhat6/netcdf/4.1.3/rhel6.4_intel13.1.3/lib:/sw/redhat6/szip/2.1/rhel6.6_gnu4.8.2/lib':${LD_LIBRARY_PATH}
-export NETCDF_ROOT='/sw/redhat6/netcdf/4.1.3/rhel6.4_intel13.1.3' 
-cd ~/nco/bld;make ANTLR_ROOT=${HOME} NETCDF_ROOT='/sw/redhat6/netcdf/4.1.3/rhel6.4_intel13.1.3' SZ=Y SZ_LIB='/sw/redhat6/szip/2.1/rhel6.6_gnu4.8.2/lib' UDUNITS_INC='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/include' UDUNITS_LIB='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/lib' OPTS=D OMP=Y allinone;cd -
-
-# Commands used for Configure builds
-module add intel gsl netcdf
+module add climate/netcdf/4.3.3.1
+export LD_LIBRARY_PATH='/ccs/proj/cli900/sw/redhat/netcdf/4.3.3.1/rhel6.6_intel-14.0.4--with-dap+hdf4/lib':${LD_LIBRARY_PATH}
+export NETCDF_ROOT='/ccs/proj/cli900/sw/redhat/netcdf/4.3.3.1/rhel6.6_intel-14.0.4--with-dap+hdf4' 
+cd ~/nco/bld;make ANTLR_ROOT=${HOME} NETCDF_ROOT='/ccs/proj/cli900/sw/redhat/netcdf/4.3.3.1/rhel6.6_intel-14.0.4--with-dap+hdf4' UDUNITS_INC='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/include' UDUNITS_LIB='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/lib' OPTS=D OMP=Y allinone;cd -
+cd ~/nco/bld;make ANTLR_ROOT=${HOME} NETCDF_ROOT='/ccs/proj/cli900/sw/redhat/netcdf/4.3.3.1/rhel6.6_intel-14.0.4--with-dap+hdf4' SZ=Y SZ_LIB='/sw/redhat6/szip/2.1/rhel6.6_gnu4.8.2/lib' UDUNITS_INC='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/include' UDUNITS_LIB='/sw/redhat6/udunits/2.1.24/rhel6.4_intel13.1.3/lib' OPTS=D OMP=Y allinone;cd -
+
+# Commands used for Configure builds with icc/icpc on rhea
+module add intel gsl udunits climate/netcdf/4.3.3.1
 export LDFLAGS="${NETCDF_CLIB} ${GSL_LIB} ${SZIP_POST_LINK_OPTS}"
 export CPPFLAGS="-I${NETCDF_DIR}/include ${GSL_INCLUDE_OPTS} ${SZIP_INCLUDE_OPTS}"
 cd ~/nco;/bin/rm -f *.${GNU_TRP}.foo;make distclean
-CC='icc' CXX='icpc' ./configure --disable-shared --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
+CC='icc' CXX='icpc' NETCDF_ROOT='/ccs/proj/cli900/sw/redhat/netcdf/4.3.3.1/rhel6.6_intel-14.0.4--with-dap+hdf4' UDUNITS2_PATH='/sw/rhea/udunits/2.1.24/rhel6.6_gnu4.4.7' ./configure --disable-shared --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
 /bin/cp -f config.log nco.config.log.${GNU_TRP}.foo
 /bin/cp -f libtool nco.libtool.${GNU_TRP}.foo
 make clean;make > nco.make.${GNU_TRP}.foo 2>&1
diff --git a/doc/ANNOUNCE b/doc/ANNOUNCE
index d2571ef..4749c96 100644
--- a/doc/ANNOUNCE
+++ b/doc/ANNOUNCE
@@ -1,20 +1,26 @@
 $Header$ -*-text-*-
 
-The netCDF Operators NCO version 4.5.1 are ready. 
+The netCDF Operators NCO version 4.5.2 are ready. 
 
-http://nco.sf.net (Homepage)
-http://dust.ess.uci.edu/nco (Homepage "mirror")
+http://nco.sf.net (Homepage, Mailing lists)
+http://github.com/nco (Source Code, Releases, Developers)
 
-This release improves regridding features, ncra weighting, and
+First, NCO now resides at http://github.com/nco, i.e., it is a
+GitHub organization. We are pleased to co-habit with the pyNCO
+project of Joe Hamman who has produced NCO Python bindings.
+Please check 'em out. All GitHub paths with "czender" instead of
+"nco" as the username will still work, but should be updated.
+Change your local copy of the repository with:
+git remote set-url origin https://github.com/nco/nco.git
+
+This NCO release improves regridding features, ncra weighting, and
 ncatted flexibility, and contains a raft of minor fixes and tunings.
-Notably, most implementation-specific dimension/variable names
-involved in regridding can be specified at the command line, and
-the regridder understands mapfiles generated by TempestRemap.
-ncra can now weight records by a 1-D record variable in the file.
-And ncatted supports regular expressions in both the variable name
-AND the attribute name (simultaneously, too).
-
-Work on NCO 4.5.2 has commenced and will better support regional
+Also, in case you need updated NCO versions at US computing centers,
+know that we now maintain up-to-date NCO in ~zender/[bin,lib] at
+ANL/ALCF (cooley), NCAR/NWSC (yellowstone), LBNL/NERSC (edison), and 
+ORNL/OLCF (rhea).
+
+Work on NCO 4.5.3 has commenced and will better support regional
 regridding, masks, threading, CF-checking and easier builds on
 computer systems that use modules.  
 
@@ -23,71 +29,73 @@ Charlie
 
 NEW FEATURES (full details always in ChangeLog):
 
-A. Regrid global datasets with TempestRemap mapfiles (in addition to
-   ESMF and SCRIP, which were already supported). Tempest mapfiles
-   use slightly different conventions than the other two, and this
-   release accounts for those differences. This capability makes
-   NCO's regridder a drop-in replacement for the Tempest program
-   ApplyOfflineMap with global (source and destination) maps.
-   The two produce the same results, modulo metadata.
-   Please give it a try and send us feedback!
-   # Regrid entire file, same output format as input:
-   ncks --map=map.nc in.nc out.nc
-   # Deflated netCDF4 output, threading, selected variables:
-   ncks -4 -L 1 -t 8 -v FS.?,T --map=map.nc in.nc out.nc
+A. All operators can now add user-specified global attributes to
+   output files using the --glb switch. The switch takes mandatory
+   arguments --glb att_nm=att_val where att_nm is the desired name of
+   the global attriute to add, and att_val is its value.
+   Currently only text attributes are supported (recorded as type
+   NC_CHAR, and regular expressions are not allowed (unlike ncatted). 
+   Multiple invocations simplify the annotation of output file at
+   creation (or modification) time, and incur no performance penalty.
+   Should users emit a loud hue and cry, we will consider ading the
+   the functionality of ncatted to the front-end of all operators,
+   i.e., accepting valid arguments to modify attributes of any type
+   and to apply regular expressions. 
+   ncra --glb machine=${HOSTNAME} --glb created_by=${USER} in*.nc out.nc
+   http://nco.sf.net/nco.html#glb
+
+B. Grid generation: ncks generates SCRIP-format gridfiles for
+   select grid types, in cluding uniform/equi-angular, cap/FV, and 
+   Gaussian. Options pertinent to the grid geometry and metadata are
+   passed to NCO via key-value pairs prefixed by "--rgr". Pass at
+   least six key-value pair arguments to create a fully explicitly
+   specified, well-annotated grid. The six arguments, and their
+   corresponding keys in parentheses, are: grid title (grd_ttl),
+   filename to write the grid to (grid), number of latitudes
+   (lat_nbr), number of longitudes (lon_nbr), latitude grid type
+   (lat_typ), and longitude grid type (lon_typ). Four other arguments
+   (the NSEW bounding box) are necessary to construct regular regional
+   (non-global) grids.
+   ncks -grid=FV129x256.nc \
+   --rgr lat_nbr=129 --rgr lon_nbr=256 --rgr lat_typ=cap
+   --rgr lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
+   ncks -grid=T42.nc \
+   --rgr lat_nbr=64 --rgr lon_nbr=128 --rgr lat_typ=gss
+   --rgr lon_typ=grn_ctr ~zender/nco/data/in.nc ~/foo.nc
+   http://nco.sf.net/nco.html#grid
+
+C. Regrid regional datasets with ESMF, SCRIP, and TempestRemap
+   mapfiles. Please give it a try and send us feedback!
+   # Regrid global file to regional domain
+   ncks --map map_conusx4v1_to_fv0.1x0.1_US_bilin.nc in.nc out.nc
    http://nco.sf.net/nco.html#regrid
 
-B. ncatted now supports regular expressions in both the variable name 
-   AND the attribute name (simultaneously, too). Previously, ncatted
-   accepted regular expressions only in the variable name. The new
-   functionality simplifies sculpting metadata topiary from files with
-   baroque metadata annotations, since whole groups of attributes may
-   now be added/modified/deleted with a single command. For example,
-   delete all attributes whose names end in "_iso19115" from all
-   variables whose names contain "H2O".
-   ncatted -a '.?_iso19115$','^H2O*',d,, in.nc
-   http://nco.sf.net/nco.html#ncatted
-
-C. Add mibs/mabs/mebs methods and operators to ncap2. These are the
-   absolute-value analogues of min/max/mean, so that, e.g., mibs()
-   returns the minimum absolute-value of the operand.
-   tpt_max=temperature.max();
-   tpt_max=max(temperature);
-   tpt_mabs=temperature.mabs();
-   tpt_mabs=mabs(temperature);
-   http://nco.sf.net/nco.html#mibs
-   http://nco.sf.net/nco.html#ppc
-   http://nco.sf.net/nco.html#ncap2
-
-D. Prevent operators from repeating existing cell_methods attribute.
-   Previously NCO would append new operations, e.g., "time: mean" to
-   the existing cell_methods attribute, if any. Now it first checks
-   to see whether that method has been applied and, if so, declines
-   to write a duplicate operation.
-   http://nco.sf.net/nco.html#cll_mth
+D. Multi-file operators support a new extension to the -n option
+   that understands calendar month counting. It is now possibly to
+   automatically generate series of filenames whose right-most two
+   digits increment from a specified minimum (e.g., 03) by a specified
+   amount (e.g., 1) until a specified maximum (e.g., 05) is reached
+   and then the leftmost digits (i.e., the year) increments by one,
+   and the whole process is reapeated until the total specified number
+   of filenames is generated.
+   ncrcat -n 3,6,1,12,1,yyyymm 198512.nc 198512_198602.nc
+   http://nco.sf.net/nco.html#input
 
 BUG FIXES:
 
-A. Fix formatting of history_of_appended_files attribute when appended 
-   file had no history attribute.
-   http://nco.sf.net/nco.html#history
-
-B. Round-up to one rather than round-down to zero in chunking maps lfp
-   and rew. This fixes a bug that only appears on datasets with
-   certain shapes. 
-   http://nco.sf.net/nco.html#cnk
-
-C. Fix bug using min/max on coordinate variables in ncap2
-
-D. Initialize memory that appeared to cause zeros to be written
-   by regridder compiled by clang on MacOSX.
+A. The ncra --wgt option, introduced in 4.4.9, works fine except,
+   it turns out, for variables with missing values. The normalization
+   for these values was incorrect and produced errors whose size was
+   roughly inversely proportional to the size of the weights.
+   The solution is to upgrade to 4.5.2. Thanks to Jeff Painter for
+   reporting this problem.
 
 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.5.1 built/tested with netCDF
-   4.4.0-development (20150710) on top of HDF5 hdf5-1.8.13 with:
+   These problems occur with NCO 4.5.2-alpha7 built/tested with netCDF
+   4.4.0-development (20150818) on top of HDF5 hdf5-1.8.13 with:
 
    cd ~/nco;./configure # Configure mechanism -or-
    cd ~/nco/bld;make dir;make allinone # Old Makefile mechanism
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 0ed1c0b..75a166d 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,8 +1,234 @@
+2015-09-06  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2 release procedure:
+ 	Changes since nco-4.5.0: ncra --wgt nrm, --grid, --glb, Newton Gaussian
+	cd ~/nco;git commit -a -m 'Version 4.5.2 release final changes';git push
+	git tag -d 4.5.2;git push origin :refs/tags/4.5.2
+	git tag -a 4.5.2 -m 'Version 4.5.2: Parenthood';git push --tags
+
+	* Change grid descriptions to match final 4.5.2 nomenclature
+
+2015-09-05  Charlie Zender  <zender at uci.edu>
+
+	* Remove constraint that FV grids must have odd-number of latitudes
+
+2015-09-03  Charlie Zender  <zender at uci.edu>
+
+	* Add hackish sixth argument 'yyyymm' to -n option to generate filenames in YYYYMM format
+
+2015-08-31  Charlie Zender  <zender at uci.edu>
+
+	* Change from spherical law of cosines to haversine formula for	great circle arc length
+
+2015-08-30  Charlie Zender  <zender at uci.edu>
+
+	* Change output grid area name from "area" to "grid_area" for ESMF_RegridWeightGen
+
+2015-08-27  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2-beta2 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-beta2 final changes';git push
+	git tag -a 4.5.2-beta2 -m 'Version 4.5.2-beta2 tag: New metadata names for climo, new typenames for grid generation, Gaussian fix, GitHub relocation';git push --tags
+
+	* Add regional grid-generation capability (lon_wst,lon_est,lat_sth,lat_nrt)
+
+2015-08-25  Charlie Zender  <zender at uci.edu>
+
+	* Fix ncdiff typo in manual thanks to Dave Allured
+
+	* Allow user input of lon_srt, lon_end, lat_srt, lat_end
+
+	* Fix off-by-one error in nco_bsl_zro() that broke spectral grids when lat_nbr > 100
+
+	* Change rgr metadata mapping_file -> map_file and source_file -> input_file
+
+2015-08-24  Charlie Zender  <zender at uci.edu>
+
+	* Transfer ownership to new NCO GitHub Organization http://github.com/nco/nco.git
+
+	* NCO 4.5.2-beta1 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-beta1 final changes';git push
+	git tag -a 4.5.2-beta1 -m 'Version 4.5.2-beta1 tag: Diagnose area on bilinearly-interpolated 1D grids with LHuillier's formula';git push --tags
+
+	* Areas of random gridcell (ncol=0) from NCO diagnosis and raw native grid output are
+        4.396773732788860e-05 and 4.396773732840130e-05, respectively.
+	Relative agreement is 0.99999999998833917706 within tolerance of 1.0e-10.
+
+	* NCO-diagnosed ne30 global area exactly equals original (native grid) ne30 global area = 12.5663706144 sr
+	These global areas equal 4*pi within fractional tolerance of 1.0e-13.
+
+	* Optimize area calculation to recycle information from previous triangles
+
+2015-08-23  Charlie Zender  <zender at uci.edu>
+
+	* Diagnose area on bilinearly-interpolated 1D grids with L'Huillier's formula
+
+2015-08-21  Charlie Zender  <zender at uci.edu>
+
+	* Start infrastructure to diagnose area on bilinearly-interpolated 1D grids
+
+	* Fix interface latitudes for offset grids
+
+	* Change polar offset grid latitude weights from continuum formula
+	(cos(lat)) to exact discretized formula, same as polar centered grid
+
+	* NULL-initialize lat_sin in nco_grd_mk() to prevent invalid free()
+
+2015-08-18  Charlie Zender  <zender at uci.edu>
+
+	* Install on hopper.nersc.gov
+
+	* Replace #ifndef ${FOO} with #ifndef FOO in bld/Makefile so make data works on hopper
+
+	* NCO 4.5.2-alpha9 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha9 final changes';git push
+	git tag -a 4.5.2-alpha9 -m 'Version 4.5.2-alpha9 tag: Work with 2D grids in either lon/lat or lat/lon (old Tempest) src/dst_grid_dims order';git push --tags
+
+	* nco_rgr_map() determines Tempest 2D grid ordering with [src/dst]_grid_dims "name0" attribute
+
+2015-08-03  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2-alpha8 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha8 final changes';git push
+	git tag -a 4.5.2-alpha8 -m 'Version 4.5.2-alpha8 tag: fix missing value normalizaion with ncra -w wgt';git push --tags
+
+	* Re-tag 4.5.2-alpha8
+
+	* Normalize wgt_sum by tally
+
+	* Add new normalization test case
+
+	* Test against actual ne30 data found that wgt_avg_scl normalization not needed
+
+2015-08-02  Charlie Zender  <zender at uci.edu>
+
+	* Add var->wgt infrastructure for running sum of per-file valid weights in ncra
+
+2015-07-25  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2-alpha7 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha7 final changes';git push
+	git tag -a 4.5.2-alpha7 -m 'Version 4.5.2-alpha7 tag: Generate exact Gaussian grids';git push --tags
+
+	* Gaussian grids now have lat_ctr=Legendre zeros, and lat_ntf that define spherical zones that reproduce Gaussian weights
+
+	* Newton-Raphson iterate latitude interface location to agree with spherical zone area
+
+	* Use Gaussian angles as latitude centers rather than bisecting interfaces
+
+	* Show that SCRIP and NCAR T42 grid/map files accurate to 8 decimal places (NCO to 16)
+
+	* Verify NCO Gaussian weights/angles accuracy to 16 decimal places
+
+2015-07-24  Charlie Zender  <zender at uci.edu>
+
+	* "mask" _is_ the mask for each point, not "whether to mask" each point. Change default from 0 to 1.
+
+	* NCO 4.5.2-alpha6 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha6 final changes';git push
+	git tag -a 4.5.2-alpha6 -m 'Version 4.5.2-alpha6 tag: create 2D rectangular SCRIP grids';git push --tags
+
+	* Incorporate self-diagnostics (lat_wgt) in nco_grd_mk()
+
+	* Verify ACME FV-scalar SCRIP grids are missing meridional strip next to Greenwich
+
+	* Eliminate GSC gridtype (obscure name for FV-scalar), treat FV	and ngl_eqi_pol identically, leave names distinct
+
+ 	* nco_grd_mk() has fancy metadata annotations and generates correct FV-scalar grids
+
+2015-07-23  Charlie Zender  <zender at uci.edu>
+
+	* Hook-up nco_grd_mk() to rgr front-end
+
+2015-07-22  Charlie Zender  <zender at uci.edu>
+
+	* Implement nco_grd_mk() to generate SCRIP grid files
+
+	* NCO 4.5.2-alpha5 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha5 final changes';git push
+	git tag -a 4.5.2-alpha5 -m 'Version 4.5.2-alpha5 tag: ncra -N, diagnose area if possible when area_out == 0.0 (bilinear interpolation)';git push --tags
+
+	* Diagnose (possibly approximate) area_out when area_out == 0.0	due to bilinear remapping
+
+	* Decriminalize mapfiles with area_out == 0.0, e.g., ESMF bilinear remapping (broken since 4.5.2-alpha1)
+
+	* Add bilinear remapping to regression test
+
+2015-07-21  Charlie Zender  <zender at uci.edu>
+
+	* Change meaning of NORMALIZE_BY_WEIGHT to NORMALIZE_WEIGHTS
+
+	* NCO 4.5.2-alpha4 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha4 final changes';git push
+	git tag -a 4.5.2-alpha4 -m 'Version 4.5.2-alpha4 tag: ncra -N';git push --tags
+
+	* Document -N in man pages, nco.texi
+
+2015-07-20  Charlie Zender  <zender at uci.edu>
+
+	* Add -N = --no-normalize-by-weight = --no_nrm_by_wgt to ncra
+
+2015-07-18  Charlie Zender  <zender at uci.edu>
+
+	* Migrate nco_rgr_esmf2() to user-specified destination grid
+
+	* Add structures for user-specified destination grid
+
+2015-07-16  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2-alpha3 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha3 final changes';git push
+	git tag -a 4.5.2-alpha3 -m 'Version 4.5.2-alpha3 tag: --glb_att_add';git push --tags
+
+	* Implement glb_att_add (gaa) in all remaining operators
+
+	* Document --glb_att_add
+
+2015-07-15  Charlie Zender  <zender at uci.edu>
+
+	* Change --glb_mtd_spp to --no_glb_mtd so --glb can refer to --gaa
+
+	* Implement glb_att_add (gaa) in ncra
+
+	* Eliminate small leak in kvm loop in nco_glb_att_add(), nco_rgr_ini()
+
+2015-07-14  Charlie Zender  <zender at uci.edu>
+
+	* Implement glb_att_add (gaa) in ncks
+
+2015-07-13  Charlie Zender  <zender at uci.edu>
+
+	* NCO 4.5.2-alpha2 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha2 final changes';git push
+	git tag -a 4.5.2-alpha2 -m 'Version 4.5.2-alpha2 tag: Displaced-pole support, fracarea/destarea';git push --tags
+
+	* Completed (though did not verify) first regridding to/from POP displaced-pole grid with SCRIP mapfile
+
+	* Valgrind emits "uninitialized value" warnings at first cosine cos() function in nco_lat_wgt_gss()---why?
+
+	* Implement true "destarea" normalization, support more aspects of dst_frac and dst_mask
+
+	* Ensure double normalization (with --rnr and "none" = imask) does not occur
+
+	* Convert input coordinates from radians to degrees if necessary, handle POP grids
+
+	* Allow SCRIP "fracarea" normalization which is, in my terminology, no normalization just weights
+	"fracarea" is what NCO actually did before, although technically all ESMF fields tested were "destarea"
+	But their dst_frac = frac_b was uniformly 1.0, so no difference	from "destarea"
+
+2015-07-12  Charlie Zender  <zender at uci.edu>
+
+	* Add sanity checks to ensure mapfile grid matches input data file grid
+
 2015-07-11  Charlie Zender  <zender at uci.edu>
 
+	* NCO 4.5.2-alpha1 release procedure:
+	cd ~/nco;git commit -a -m 'Version 4.5.2-alpha1 final changes';git push
+	git tag -a 4.5.2-alpha1 -m 'Version 4.5.2-alpha1 tag: bump to alpha1';git push --tags
+
 	* NCO 4.5.1 release procedure:
  	Changes since nco-4.5.0: ncra --wgt=wgt_nm, ncap2 mibs/mabs/mebs, Tempest
-	cd ~/nco;git commit -a -m 'Version 4.5.1 release final changes'
+	cd ~/nco;git commit -a -m 'Version 4.5.1 release final changes';git push
 	git tag -d 4.5.1;git push origin :refs/tags/4.5.1
 	git tag -a 4.5.1 -m 'Version 4.5.1: Maxine';git push --tags
 
diff --git a/doc/TODO b/doc/TODO
index 3297144..84cd87c 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -674,7 +674,8 @@ nco1122. cnk slowdown Barry McInnes 3/9
       ncks -O -v huss --cnk_plc=r1d --fl_fmt=netcdf4_classic -L 5 ${DATA}/hdf/huss_Amon_ACCESS1-0_historical_r1i1p1_185001-200512.nc ~/foo.nc # works
 nco1123. ESGF access
       ncks -M http://esgf-data2.ceda.ac.uk/thredds/dodsC/cmip5.output1.MOHC.HadGEM2-ES.rcp85.mon.ocean.Omon.r1i1p1.uo.20111014.aggregation.1
-nco1124. 
+nco1124. ncra fix ncra --wgt_nm to work (i.e., correctly normalize) with missing values
+nco1125. 
 qrk
 ************************************************************************
 End ncoXXX TODOs
diff --git a/doc/VERSION b/doc/VERSION
index 4404a17..6cedcff 100644
--- a/doc/VERSION
+++ b/doc/VERSION
@@ -1 +1 @@
-4.5.1
+4.5.2
diff --git a/doc/index.shtml b/doc/index.shtml
index fa4290e..6450a45 100644
--- a/doc/index.shtml
+++ b/doc/index.shtml
@@ -51,7 +51,7 @@ Try to disable Spammers' machines:
 <a href="http://sf.net/p/nco/discussion/9830">Help</a> /
 <a href="#RTFM">Manual</a> /
 <a href="http://sf.net/projects/nco">Project</a> /
-<a href="https://github.com/czender/nco/tree/master/src/nco">Source</a> /
+<a href="https://github.com/nco/nco/tree/master/src/nco">Source</a> /
 </td>
 
 <td align="right" valign="top">
@@ -149,7 +149,8 @@ and
 <h2>Recent Releases & Milestones</h2>
 
 <ul>
-<li>2015 Jul ??: 4.5.2 (<i>In progress</i>)
+<li>2015 Oct ??: 4.5.3 (<i>In progress</i>)
+<li>2015 Sep 06: 4.5.2 (Generate SCRIP grids)
 <li>2015 Jul 10: 4.5.1 (Stability)
 <li>2015 Jun 11: 4.5.0 (Regridding)
 <li>2015 May 21: 4.4.9 (<tt>ncra</tt> weights)
@@ -658,18 +659,29 @@ San Francisco, CA, December 5–9, 2006.
 <h2>Release Highlights</h2>
 Stable releases receive unique tags and their tarballs are stored  
 <a href="http://nco.sf.net/src">here</a> on SourceForge and
-<a href="https://github.com/czender/nco/releases">here</a> at GitHub.
+<a href="https://github.com/nco/nco/releases">here</a> at GitHub.
 You may also retrieve the source of tagged versions directly
-<a name="#Source">with <tt>git clone -b 4.5.1 http://github.com/czender/nco.git nco-4.5.1</tt></a>.
+<a name="#Source">with <tt>git clone -b 4.5.1 http://github.com/nco/nco.git nco-4.5.1</tt></a>.
 <ul>
-<li><b>NCO 4.5.3</b>: (<i>Future</i>) 
+<li><b>NCO 4.5.4</b>: (<i>Future</i>) 
 <tt>ncks</tt> prints human-legible ISO8601 dates;
 <a href="http://nco.sf.net/nco.html#cnk">Chunking</a> bytes not elements, caching;
 extensive hashing?;
 netCDF4 compound types?;
 Optimize diskless files?;</li>
-<li><b>NCO 4.5.2</b>: (<i>In Progress, features completed or being worked on include</i>)
-<li><b>NCO 4.5.1</b>: (<i>Current Stable Release</i>)
+<li><b>NCO 4.5.3</b>: (<i>In Progress, features in-progress or completed include</i>)
+<tt>ncks</tt> better support regional grids;</li>
+<li><b>NCO 4.5.2</b>: (<i>Current Stable Release</i>)
+All operators support <tt>--glb_att_add</tt>;
+<tt>ncks</tt> better support for <tt>fracarea</tt>, <tt>mask</tt>, and displaced-pole grids;
+<tt>ncks</tt> diagnoses <tt>area</tt> for bilinear remapping and when area_b equals 0.0;
+<tt>ncks</tt> <i>generates</i> exact Gaussian and equi-angular, rectangular, and regional gridfiles;
+<tt>ncks</tt> regrid with old, new, and regional TempestRemap mapfiles;
+<tt>ncra -n NINTAP</tt> option understands calendar month counting;
+<tt>ncra -N</tt> avoids normalizing by weights;
+<tt>ncra -w</tt> bugfix with missing value normalization;
+<tt>ncwa</tt> bugfix when weights were not found;</li>
+<li><b>NCO 4.5.1</b>: 
 <tt>cell_method</tt> improvments;
 <tt>ncap2</tt> gets </tt>mibs()/mabs()/mebs()</tt> methods;
 <tt>ncatted</tt> regular expressions in </tt>att_nm</tt>;
@@ -832,7 +844,7 @@ the directory index <a href="src">here</a>.
 <h3><a href="http://www.ibm.com/servers/aix">AIX</a> on IBM mainframes</h3>
 <ul> <!-- http://nco.sf.net/src/nco-4.2.5.aix53.tar.gz -->
 <li><a href="src/nco-4.2.5.aix53.tar.gz">nco-4.2.5.aix53.tar.gz</a> (<!--#fsize file="src/nco-4.2.5.aix53.tar.gz"-->): Executables AIX 5.3-compatible (last updated <!--#flastmod file="src/nco-4.2.5.aix53.tar.gz"-->). Maintained by NCO Project.</li>
-Newer (beta- or pre-release) packages are sometimes available for AIX users as described <a href="https://github.com/czender/nco/tree/master/doc/beta.txt">here</a>.
+Newer (beta- or pre-release) packages are sometimes available for AIX users as described <a href="https://github.com/nco/nco/tree/master/doc/beta.txt">here</a>.
 Thanks to NSF for supporting AIX machines at NCAR over the years. 
 </ul>
 
@@ -848,7 +860,7 @@ Thanks to NSF for supporting AIX machines at NCAR over the years.
 ‘<tt>aptitude install nco</tt>’ installs the standard NCO for your Debian-compatible OS.
 NCO packages in the Debian/Ubuntu repositories (i.e., 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/czender/nco/tree/master/doc/beta.txt">here</a>.
+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.5.1-1_i386.deb</tt>’):</dt>
 <li><a href="src/nco_4.5.1-1_amd64.deb">nco_4.5.1-1_amd64.deb</a> (<!--#fsize file="src/nco_4.5.1-1_amd64.deb"-->): Executables AMD64-compatible (last updated <!--#flastmod file="src/nco_4.5.1-1_amd64.deb"-->)</li>
 <li><a href="src/nco_4.5.1-1.dsc">nco_4.5.1-1.dsc</a> (<!--#fsize file="src/nco_4.5.1-1.dsc"-->): Description (last updated <!--#flastmod file="src/nco_4.5.1-1.dsc"-->)</li>
@@ -945,7 +957,9 @@ Thanks to Cygnus Solutions and RedHat Inc. for developing and supporting Cygwin
 <a name="python"></a> <!-- http://nco.sf.net#python -->
 <a name="NCOpy"></a> <!-- http://nco.sf.net#NCOpy -->
 <a name="pyt"></a> <!-- http://nco.sf.net#pyt -->
-<h3><a href="http://www.python.org">Python</a> Bindings <a href="https://github.com/jhamman/nco-bindings">Source</a> and <a href="http://www.hydro.washington.edu/~jhamman/hydro-logic/blog/2014/01/29/NCOpy">Documentation</a>
+<a name="pynco"></a> <!-- http://nco.sf.net#pynco -->
+<a name="PyNCO"></a> <!-- http://nco.sf.net#PyNCO -->
+<h3><a href="http://www.python.org">Python</a> Bindings <a href="https://github.com/nco/pynco">Source</a> and <a href="http://pynco.readthedocs.org">Documentation</a>
 
 <hr></p>
 <!-- End http://nco.sf.net#bnr -->
@@ -1106,7 +1120,7 @@ The simplest way to acquire the source is to download the compressed tarball:
      http://svn.unidata.ucar.edu/repos/netcdf/trunk/ncdump/nccopy.c -->
 <p>The best way to acquire the source and occasionally update to the
 latest features is with <a href="http://git-scm.com/book/en/v2">Git</a>. 
-The browsable <a href="https://github.com/czender/nco/tree/master">Repository</a> 
+The browsable <a href="https://github.com/nco/nco/tree/master">Repository</a> 
 contains up-to-the-minute sources and is the easiest way to stay
 synchronized with NCO features.
 Updating NCO source requires some familiarity with development tools,
@@ -1118,10 +1132,10 @@ You may retrieve any NCO distribution you wish from
 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.5.1</tt>:
-<p><tt>git clone https://github.com/czender/nco.git;cd nco;git checkout -b 4.5.1</tt></p>
+<p><tt>git clone https://github.com/nco/nco.git;cd nco;git checkout -b 4.5.1</tt></p>
 This command retrieves the current (“bleeding edge”)
 development version of NCO into a local directory named <tt>nco</tt>:
-<p><tt>git clone https://github.com/czender/nco.git ~/nco</tt></p>
+<p><tt>git clone https://github.com/nco/nco.git ~/nco</tt></p>
 Track changes to the development version using
 <p><tt>cd ~/nco;git pull</tt></p>
 One difference between running a "tagged" release 
@@ -1259,7 +1273,7 @@ Users should instead first download and install the Antlr found <a href="http://
   then build the latest stable NCO and install it in,
   e.g., <tt>/usr/local</tt> with: 
 <tt>
-<dt>wget https://github.com/czender/nco/archive/4.5.1.tar.gz</dt>
+<dt>wget https://github.com/nco/nco/archive/4.5.1.tar.gz</dt>
 <dt>tar xvzf 4.5.1.tar.gz</dt>
 <dt>cd nco-4.5.1</dt>
 <dt>./configure --prefix=/usr/local</dt>
@@ -1294,21 +1308,25 @@ Still having trouble building NCO from source? Read these
 <!-- http://nco.sf.net#NCAR -->
 <dt><a name="NCAR"></a></dt>
 <h2>Using NCO at UCI, NCAR, and other High Performance Computing Centers (HPCCs)</h2>
-<p>UC Irvine, NCAR, and DOE ORNL/OLCF users <i>may</i> find pre-built,
-<i>almost</i> up-to-date NCO executables in the following locations.
-Users at NCAR/NWSC and ORNL/OLCF should first try the institution-<i>supported</i>
-executables with <tt>module load nco</tt>.
-These stable releases are usually a few versions and up to two years old.
-The unsatisfied or adventurous may try my personal executables which
-are built from the “master branch” of NCO, not a tagged
-version, and therefore may behave slightly differently.
+HPCCs unfortunately do not utilize modern package systems like RPMs or
+.debs, or do so on old OSs with no access to newer RPMs and .debs.
+Institution-<i>supported</i> executables are usually available with <tt>module load nco</tt>.
+These stable releases are often many versions (up to two years) old.
+Thanks to funding from external grants, <p>DOE, NCAR, and UCI HPCC
+users <i>may</i> find more recent pre-built NCO executableses the
+personal directories shown below. 
+These are usually built from a recent tagged-version of NCO (e.g.,
+4.5.X-alphaY) not from the “bleeding-edge” of master which
+is usually untagged.
+
 <ul>
-<li>ANL Cooley <tt></tt> (Linux 2.6.x): <tt>~zender/bin</tt></li>
-<li>NCAR CISL <tt>yellowstone.ucar.edu</tt> (Linux 2.6.x): <tt>~zender/bin</tt></li>
-<li>NCAR CISL <tt>mirage0.ucar.edu</tt> (Linux 2.6.x): <tt>~zender/bin</tt></li>
-<li>ORNL Rhea <tt></tt> (Linux 2.6.x): <tt>~zender/bin</tt></li>
-<li>UCI ESS <tt>greenplanet.ps.uci.edu</tt> (Linux 2.6.x): <tt>~zender/bin</tt></li>
-<li>UCI ESS <tt>dust.ess.uci.edu</tt> (Linux 3.2.x): <tt>~zender/bin</tt></li>
+<li>ANL ALCF Cooley <tt></tt>: <tt>~zender/bin</tt></li>
+<li>NCAR CISL <tt>yellowstone.ucar.edu</tt>: <tt>~zender/bin</tt></li>
+<li>NCAR CISL <tt>mirage0.ucar.edu</tt>: <tt>~zender/bin</tt></li>
+<li>NERSC Hopper <tt></tt>: <tt>~zender/bin</tt></li>
+<li>ORNL OLCF Pileus <tt></tt>: <tt>~zender/bin</tt></li>
+<li>ORNL OLCF Rhea <tt></tt>: <tt>~zender/bin</tt></li>
+<li>UCI ESS <tt>greenplanet.ps.uci.edu</tt>: <tt>~zender/bin</tt></li>
 </ul>
 <hr></p>
 <!-- End http://nco.sf.net#NCAR -->
@@ -1651,7 +1669,7 @@ community.
 <a href="http://sf.net/p/nco/discussion/9830">Help</a> /
 <a href="#RTFM">Manual</a> /
 <a href="http://sf.net/projects/nco">Project</a> /
-<a href="https://github.com/czender/nco/tree/master/src/nco/">Source</a> /
+<a href="https://github.com/nco/nco/tree/master/src/nco/">Source</a> /
 </td>
 
 <td align="right" valign="top">
diff --git a/doc/nco.texi b/doc/nco.texi
index 1f1ad8c..386520d 100644
--- a/doc/nco.texi
+++ b/doc/nco.texi
@@ -117,12 +117,12 @@ Octave TeXInfo manual shows clean TeXInfo structure
 @setfilename nco.info
 
 @c Define edition, date, ...
- at set nco-edition 4.5.1
- at set doc-edition 4.5.1
+ at set nco-edition 4.5.2
+ at set doc-edition 4.5.2
 @set copyright-years 1995--2015
 @set update-year 2015
- at set update-date 10 July 2015
- at set update-month July 2015
+ at set update-date 5 September 2015
+ at set update-month September 2015
 
 @settitle @acronym{NCO} @value{nco-edition} User Guide
 
@@ -1052,7 +1052,7 @@ We implement the symbolic links and synonyms by the executing the
 following @acronym{UNIX} commands in the directory where the
 @acronym{NCO} executables are installed.
 @example
-ln -s -f ncbo ncdiff    # ncbo --op_typ='+'
+ln -s -f ncbo ncdiff    # ncbo --op_typ='-'
 ln -s -f ncra nces      # ncra --pseudonym='nces'
 ln -s -f ncra ncrcat    # ncra --pseudonym='ncrcat'
 ln -s -f ncbo ncadd     # ncbo --op_typ='+'
@@ -2552,6 +2552,7 @@ feature is automatic and cannot be controlled by the user.
 * Multislabs::
 * Wrapped Coordinates::
 * Auxiliary Coordinates::
+* Grid Generation::
 * Regridding::
 * UDUnits Support::
 * Rebasing Time Coordinate::
@@ -2567,6 +2568,7 @@ feature is automatic and cannot be controlled by the user.
 * Operation Types::
 * Type Conversion::
 * Batch Mode::
+* Global Attribute Addition::
 * History Attribute::
 * File List Attributes::
 * CF Conventions::
@@ -2932,7 +2934,7 @@ The @acronym{CCM} Processor was custom-written Fortran code maintained
 for many years by Lawrence Buja at @acronym{NCAR}, and phased-out in 
 the late 1990s.
 @acronym{NCO} stole some ideas, like @code{NINTAP}-functionality,
-from the @acronym{CCM} Processor capabilities.}.
+from @acronym{CCM} Processor capabilities.}.
 @cindex multi-file operators
 @cindex files, multiple
 This option is only available with the @dfn{multi-file operators}:
@@ -2951,7 +2953,7 @@ For example, in the file @file{ccm3_h0001.nc}, we have
 
 @acronym{NCO} decodes lists of such filenames encoded using the
 @samp{-n} syntax. 
-The simpler (3-argument) @samp{-n} usage takes the form 
+The simpler (three-argument) @samp{-n} usage takes the form 
 @code{-n @var{file_number}, at var{digit_number}, at var{numeric_increment}}
 where @var{file_number} is the number of files, @var{digit_number} is
 the fixed number of numeric digits comprising the @var{numeric_suffix},
@@ -2964,8 +2966,8 @@ file name @file{85.nc} tells @acronym{NCO} to
 construct five (5) filenames identical to the template @file{85.nc}
 except that the final two (2) digits are a numeric suffix to be
 incremented by one (1) for each successive file.
-Currently @var{filetype} may be either be empty, @file{nc},
- at file{cdf}, @file{hdf}, or @file{hd5}. 
+Currently @var{filetype} may be either be empty, @file{nc}, @file{h5},
+ at file{cdf}, @file{hdf}, @file{hd5}, or @file{he5}.
 If present, these @var{filetype} suffixes (and the preceding @file{.})
 are ignored by @acronym{NCO} as it uses the @samp{-n} arguments to
 locate, evaluate, and compute the @var{numeric_suffix} component of
@@ -3012,6 +3014,38 @@ Thus the second and third examples have the same effect, that is, they
 automatically generate, in order, the filenames @file{85_12.nc},
 @file{85_01.nc}, and @file{85_02.nc} as input to @acronym{NCO}.
 
+As of @acronym{NCO} version 4.5.2 (September, 2015), @acronym{NCO}
+supports an optional sixth argument to @samp{-n}, the month-indicator. 
+The month-indicator affirms to @acronym{NCO} that the right-most digits
+being manipulated in the generated filenames correspond to month numbers 
+(with January formatted as @file{01} and December as @file{12}). 
+Moreover, it assumes digits to the left of the month are the year.
+The full (six-argument) @samp{-n} usage takes the form 
+ at code{-n @var{file_number}, at var{digit_number}, at var{month_increment}, at var{max_month}, at var{min_month}, at samp{yyyymm}}.
+The @samp{yyyymm} string is a clunky way (can you think of a clearer
+way?) to tell @acronym{NCO} to enumerate files in year-month mode.
+When present, @samp{yyyymm} string causes @acronym{NCO} to automatically
+generate series of filenames whose right-most two digits increment from
+ at var{min_month} by @var{month_increment} up to @var{max_month} and then
+the leftmost digits (i.e., the year) increment by one, and the whole
+process is reapeated until the @var{file_number} filenames are
+generated. 
+ at example
+ncrcat -n 3,6,1,12,1         198512.nc 198512_198502.nc
+ncrcat -n 3,6,1,12,1,yyyymm  198512.nc 198512_198602.nc
+ncrcat -n 3,6,1,12,12,yyyymm 198512.nc 198512_198712.nc
+ at end example
+The first command concatenates three files (@file{198512.nc},
+ at file{198501.nc}, @file{198502.nc}) into the output file.
+The second command concatenates three files (@file{198512.nc},
+ at file{198601.nc}, @file{198602.nc}).
+The @samp{yyyymm}-indicator causes the left-most digits to
+increment each time the right-most two digits reach their
+maximum and then wrap.
+The first command does not have the indicator so it is always 1985.  
+The third command concatenates three files (@file{198512.nc},
+ at file{198612.nc}, @file{198712.nc}).
+
 @html
 <a name="fl_out"></a> <!-- http://nco.sf.net/nco.html#fl_out -->
 <a name="out"></a> <!-- http://nco.sf.net/nco.html#out -->
@@ -5664,7 +5698,7 @@ eastern hemisphere, although they are stored in the opposite order in
 the input file. 
 
 With this background, one sees that the following commands suffice to
-rotate the input file by 180 degrees longitude:
+rotate the input file by @w{180 degrees} longitude:
 @example
 % ncks -O -v LatLon --msa -d Lon,0.,180. -d Lon,-180.,-1.0 in.nc out.nc
 % ncap2 -O -s 'where(Lon < 0) Lon=Lon+360' out.nc out.nc
@@ -5776,7 +5810,7 @@ values (@pxref{Hyperslabs}).
 <a name="std_nm"></a> <!-- http://nco.sf.net/nco.html#std_nm -->
 <a name="standard_name"></a> <!-- http://nco.sf.net/nco.html#standard_name -->
 @end html
- at node Auxiliary Coordinates, Regridding, Wrapped Coordinates, Shared features
+ at node Auxiliary Coordinates, Grid Generation, Wrapped Coordinates, Shared features
 @section Auxiliary Coordinates
 @cindex @code{-X}
 @cindex @code{--auxiliary}
@@ -5918,6 +5952,225 @@ We recommend always using decimal points with @samp{-X} arguments
 to avoid confusion.
 
 @html
+<a name="scrip"></a> <!-- http://nco.sf.net/nco.html#scrip -->
+<a name="grid"></a> <!-- http://nco.sf.net/nco.html#grid -->
+<a name="grd"></a> <!-- http://nco.sf.net/nco.html#grd -->
+ at end html
+ at node Grid Generation, Regridding, Auxiliary Coordinates, Shared features
+ at section Grid Generation
+ at cindex Gaussian grid
+ at cindex Equi-Angular grid
+ at cindex FV grid
+ at cindex grid, Fixed
+ at cindex grid, Offset
+ at cindex grid, FV
+ at cindex grid, Equi-Angular
+ at cindex grid, Gaussian
+ at cindex gridfile
+ at cindex @code{--map}
+ at cindex @acronym{ESMF}
+ at cindex @acronym{SCRIP}
+ at cindex @code{--rgr @var{key}=@var{val}}
+ at cartouche
+Availability: @command{ncks}@* 
+Short options: None@*
+Long options: 
+ at samp{--rgr @var{key}=@var{val}} (multiple invocations allowed)@*
+ at end cartouche
+
+As of @acronym{NCO} version 4.5.2 (August, 2015), @command{ncks}
+generates accurate and complete SCRIP-format gridfiles for select grid 
+types, including uniform, capped and Gaussian rectangular
+latitude/longitude grids.  
+The grids are stored in an external @var{grid-file}.
+
+All options pertinent to the grid geometry and metadata are passed to
+ at acronym{NCO} via key-value pairs prefixed by the @samp{--rgr} option.
+Pass at least six key-value pair arguments to create a fully
+explicitly specified, well-annotated grid.
+The six arguments, and their corresponding keys, are: grid title
+(@var{grd_ttl}), grid filename (@var{grid}), number of latitudes
+(@var{lat_nbr}), number of longitudes (@var{lon_nbr}), latitude
+grid-type (@var{lat_typ}), and longitude grid-type (@var{lon_typ}). 
+Four other arguments (the North/South/East/West bounding box) are
+necessary to construct equi-angular regional (non-global) grids, described
+later. 
+
+The six arguments, and their corresponding keys, are: 
+ at enumerate
+ at cindex @var{grd_ttl}
+ at cindex @samp{--rgr grd_ttl=@var{grd_ttl}}
+ at item It is surprisingly difficult to discern the geometric
+configuration of a grid from the coordinates of a @acronym{SCRIP}-format
+gridfile.  
+A human-readable grid description should be placed in @var{grd_ttl}.
+Examples include ``FV-scalar grid 129x256'' and ``T42 Gaussian grid''. 
+
+ at cindex @var{grid}
+ at cindex @samp{--rgr grid=@var{grid}}
+ at item 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}.
+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}). 
+It will not be altered. 
+The destination file (e.g., @file{foo.nc}) will be overwritten. 
+Its contents are immaterial. 
+
+ at cindex @var{lat_grd}
+ at cindex @var{lon_grd}
+ at cindex @samp{--rgr lon_grd=@var{lon_grd}}
+ at cindex @samp{--rgr lat_grd=@var{lat_grd}}
+ at item The keys that hold the longitude and latitude gridtypes (which
+are, by the way, independent of eachother) are @var{lon_grd} and
+ at var{lat_grd}. 
+The @var{lat_typ} options for global grids are @samp{uni} for
+Uniform, @samp{cap} (or @samp{fv}) for Capped (equivalent to
+ at acronym{FV}), and @samp{gss} for Gaussian.  
+These values are all case-independent, so @samp{Gss} and @samp{gss} both 
+work. 
+
+As its name suggests, the latitudes in a Uniform-latitude grid are
+uniformly spaced  
+ at footnote{
+A Uniform grid in latitude could be called ``equi-angular'' in
+latitude, but @acronym{NCO} reserves the term Equi-angular or ``eqa'' 
+for grids that have the same uniform spacing in both latitude and
+longitude, e.g., 1 at textdegree{}x1 at textdegree{} or
+2 at textdegree{}x2 at textdegree{}. 
+ at acronym{NCO} reserves the term Regular to refer to grids that are
+monotonic and rectangular grids. 
+Confusingly, the angular spacing in a Regular grid need not be uniform,  
+it could be irregular, such as in a Gaussian grid.
+The term Regular is not too useful in grid-generation, because so many
+other parameters (spacing, centering) are necessary to disambiuate it.}. 
+The Uniform-latitude grid may have any number of latitudes. 
+ at acronym{NCO} can only generate longitude grids (below) that are
+uniformly spaced, so the Uniform-latitude grids we describe are
+also uniform in the 2D sense.
+Uniform grids are intuitive, easy to visualize, and simple to program.
+Hence their popularity in data exchange, visualization, and archives.
+Moreover, regional grids (unless they include the poles), are free
+of polar singularities, and thus are well-suited to storage on Uniform 
+grids. 
+Theoretically, a Uniform-latitude grid could have non-uniform
+longitudes, but @acronym{NCO} currently does not implement non-uniform
+longitude grids.
+
+Their mathematical properties (convergence and excessive resolution at
+the poles, which can appear as singularities) make Uniform grids fraught
+for use in global models.  
+One purpose Uniform grids serve in modeling is as ``offset'' or
+``staggered'' grids, meaning grids whose centers are the interfaces of 
+another grid. 
+The Finite-Volume (@acronym{FV}) method is often used to represent 
+and solve the equations of motion in climate-related fields.
+Many @acronym{FV} solutions (including the popular Lin-Rood method as
+used in the @acronym{CESM} model) evaluate scalar (i.e., non-vector)
+fields (e.g., temperature, water vapor) at gridcell centers of what is 
+therefore called the scalar grid. 
+ at acronym{FV} methods (like Lin-Rood) that employ an Arakawa C-grid or
+D-grid formulation define velocities on the edges of the scalar grid.
+This @acronym{FV}-velocity grid is therefore ``staggered'' or ``offset'' 
+from the scalar grid by one-half gridcell. 
+The Lin-Rood @acronym{FV}-scalar latitude grid has gridpoints (the
+``caps'') centered on each pole to avoid singularities.
+The offset of a Cap-grid is a Uniform-grid, so the Uniform grid is 
+often called an @acronym{FV}-''offset'' or ``staggered'' grid.
+Hence an @acronym{NCO} Uniform grid is equivalent to an @acronym{NCL}  
+``Fixed Offset'' grid.
+For example, a 128x256 Uniform grid is the offset or staggered version
+of a 129x256 Cap grid (aka @acronym{FV}-grid).
+
+Owing the ``cap''-points at the poles, @acronym{NCO} uses the term Cap
+grid to describe the latitude portion of the @acronym{FV}-scalar grid as
+used by the @acronym{CESM} Lin-Rood dynamics formulation.
+ at acronym{NCO} treats the shorthand (and more memorable) @acronym{FV} as
+a synonym for Cap.   
+A Cap-latitude grid differs from a Uniform-latitude grid in many ways:
+Most importantly, Cap grids are 2D-representations of numerical grids
+with cap-midpoints instead of zonal-teeth convergence at the poles.  
+The rectangular 2D-representation of each cap contains gridcells shaped
+like sharp teeth that converge at the poles similar to the Uniform grid,  
+but the Cap gridcells are meant to be aggregated into a single cell
+centered at the pole in a dynamical transport algorithm.  
+In other words, the polar teeth are a convenient way to encode a
+non-rectangular grid in memory into a rectangular array on disk.  
+Hence Cap grids have the unusual property that the poles are labeled as
+being both the centers and the outer interfaces of all polar gridcells. 
+Second, Cap grids are uniform in angle except at the poles, where the
+latitudes span half the meridional range of the rest of the gridcells. 
+Even though in the host dynamical model the Cap grid polar points are
+melded into caps uniform (in angle) with the rest of the grid, the disk
+representation on disk is not uniform.
+Nevertheless, some call the Cap grid a uniform-angle grid because the
+information contained at the poles is aggregated in memory to span twice
+the range of a single polar gridcell (which has half the normal width). 
+The @acronym{NCL} uses the term ``Fixed grid'' for a Cap grid.
+The ``Fixed'' terminology seems broken.
+
+Finally, Gaussian grids are the Cartesian representation of global
+spectral transform models. 
+Gaussian grids do not have points at the poles, and must have an even
+number of latitudes. 
+All three latitude grid-type supported by @acronym{NCO} (Uniform, Cap, 
+and Gaussian) are Regular grids in that they are monotonic. 
+
+The @var{lon_typ} options for global grids are @samp{grn_ctr} and
+ at samp{180_ctr} for the first gridcell centered at Greenwich or 
+ at w{180 degrees}, respecitvely.   
+And @samp{grn_wst} and @samp{180_wst} for Greenwich or @w{180 degress}
+lying on the western edge of the first gridcell.
+Many global models use the @samp{grn_ctr} longitude grid as their
+``scalar grid'' (where, e.g., temperature, humidity, and other scalars
+are defined).
+The ``staggered'' or ``offset'' grid (where often the dynamics variables
+are defined) then must have the @samp{grn_wst} longitude convention.
+That way the centers of the scalar grid are the vertices of the offset
+grid, and visa versa.
+
+ at cindex @var{lat_nbr}
+ at cindex @var{lon_nbr}
+ at cindex @samp{--rgr lon_nbr=@var{lon_nbr}}
+ at cindex @samp{--rgr lat_nbr=@var{lat_nbr}}
+ at item The number of gridcells in the horizontal spatial dimensions
+are @var{lat_nbr} and @var{lon_nbr}, respectively.
+There are no restrictions on @var{lon_nbr} for any gridtype.
+Latitude grids do place some restrictions on @var{lat_nbr} (see above). 
+ at end enumerate
+
+Generating common grids:
+ at example
+ at 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 \
+     --rgr lat_nbr=180 --rgr lon_nbr=360 --rgr lat_typ=rgl --rgr lon_typ=grn_ctr \
+     ~zender/nco/data/in.nc ~/foo.nc
+
+# 129x256 FV grid, first longitude centered at Greenwich
+ncks --rgr grd_ttl='FV-scalar grid 129x256' --rgr grid=${DATA}/grids/129x256_SCRIP.20150901.nc \
+     --rgr lat_nbr=129 --rgr lon_nbr=256 --rgr lat_typ=fv --rgr lon_typ=grn_ctr \
+     ~zender/nco/data/in.nc ~/foo.nc
+
+# 128x256 Equi-Angular grid, Greenwich west edge of first longitude
+# This is the FV-offset grid for the 129x256 FV grid above
+ncks --rgr grd_ttl='Equi-Angular grid 128x256' --rgr grid=${DATA}/grids/128x256_SCRIP.20150901.nc \
+     --rgr lat_nbr=128 --rgr lon_nbr=256 --rgr lat_typ=rgl --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 \
+     --rgr lat_nbr=64 --rgr lon_nbr=128 --rgr lat_typ=gss --rgr lon_typ=Grn_ctr \
+     ~zender/nco/data/in.nc ~/foo.nc
+ at end verbatim
+ at end example
+
+ at html
 <a name="map"></a> <!-- http://nco.sf.net/nco.html#map -->
 <a name="esmf"></a> <!-- http://nco.sf.net/nco.html#esmf -->
 <a name="scrip"></a> <!-- http://nco.sf.net/nco.html#scrip -->
@@ -5925,7 +6178,7 @@ to avoid confusion.
 <a name="rgr_map"></a> <!-- http://nco.sf.net/nco.html#rgr_map -->
 <a name="regrid"></a> <!-- http://nco.sf.net/nco.html#regrid -->
 @end html
- at node Regridding, UDUnits Support, Auxiliary Coordinates, Shared features
+ at node Regridding, UDUnits Support, Grid Generation, Shared features
 @section Regridding
 @cindex map
 @cindex regridding
@@ -6001,9 +6254,10 @@ Options specific to regridding are described below.
 2D at result{}2D regridding for any unstructured 
 1D-grid and any rectangular 2D-grid.  
 This has been tested by converting among and between Gaussian,
-equiangular, @acronym{FV}, and unstructured cubed-sphere grids.
-Support for irregular 2D- and for regional grids (e.g., swath-like data)  
-is planned. 
+equiangular, @acronym{FV}, unstructured cubed-sphere grids, and
+regionally refined grids.
+Support for irregular 2D- and regional grids (e.g., swath-like data) is
+planned.  
 
 @cindex conservative regridding
 @cindex renormalized regridding
@@ -6238,19 +6492,20 @@ ncks --rgr bnd=vertices --rgr lat_bnd=lat_vrt --rgr lon_bnd=lon_vrt
 @end example
 The first command causes the regridder to associate the latitude and
 longitude dimensions with the dimension names @code{latitude} and
- at code{longitude} (instead of @code{lat} and @code{lon}).
+ at code{longitude} (instead of the defaults, @code{lat} and @code{lon}). 
 The second command causes the regridder to associate the independent
 columns in an unstructured grid with the dimension name @code{column}
-(instead of @code{ncol}) and the variable containing latitude weights
-to be named @code{lat_wgt} (instead of @code{gw}).
+(instead of the default, @code{ncol}) and the variable containing
+latitude weights to be named @code{lat_wgt} (instead of the default,
+ at code{gw}). 
 The third command associates the latitude and longitude bounds with the
-dimension @code{bounds} (instead of @code{nbnd}) and the variables
- at code{lat_bounds} and @code{lon_bounds} (instead of @code{lat_bnds} and 
- at code{lon_bnds}, respectively). 
+dimension @code{bounds} (instead of the default, @code{nbnd}) and the
+variables @code{lat_bounds} and @code{lon_bounds} (instead of the
+defaults, @code{lat_bnds} and  @code{lon_bnds}, respectively). 
 The fourth command associates the latitude and longitude bounds with the
-dimension @code{vertices} (instead of @code{nv}) and the variables
- at code{lat_vrt} and @code{lon_vrt} (instead of @code{lat_vertices} and 
- at code{lon_vertices}, respectively). 
+dimension @code{vertices} (instead of the default, @code{nv}) and the
+variables @code{lat_vrt} and @code{lon_vrt} (instead of the defaults,
+ at code{lat_vertices} and @code{lon_vertices}, respectively). 
 
 When used with an identity remapping files, regridding can signficantly
 enhance the metadata and therefore the dataset usability.
@@ -6363,6 +6618,19 @@ For example, statistics for regions that can be expressed as unions of
 rectangular regions can now be performed on the native (unstructured)
 grid. 
 
+Here are some quick examples of regridding from common models.
+All examples require @samp{in.nc out.nc} at the end.
+ at example
+ at verbatim
+# Identity re-map ACME CAM-SE Cubed-Sphere output (to improve metadata)
+ncks --map=${DATA}/maps/map_ne30np4_to_ne30np4_aave.20150603.nc
+# Convert ACME CAM-SE Cubed Sphere output to rectangular lat/lon
+ncks --map=${DATA}/maps/map_ne30np4_to_fv129x256_aave.150418.nc
+# Convert CAM3 T42 output to Cubed-Sphere grid
+ncks --map=${DATA}/maps/map_ne30np4_to_t42_aave.20150601.nc
+ at end verbatim
+ at end example
+
 @html
 <a name="UDUnits"></a> <!-- http://nco.sf.net/nco.html#UDUnits -->
 <a name="UDUnits2"></a> <!-- http://nco.sf.net/nco.html#UDUnits2 -->
@@ -9816,7 +10084,7 @@ ncap2 -s 'tpt=short(tpt);prs=double(prs)' in.nc out.nc
 <a name="ovr"></a> <!-- http://nco.sf.net/nco.html#ovr -->
 <a name="-O"></a> <!-- http://nco.sf.net/nco.html#-O -->
 @end html
- at node Batch Mode, History Attribute, Type Conversion, Shared features
+ at node Batch Mode, Global Attribute Addition, Type Conversion, Shared features
 @section Batch Mode
 @cindex batch mode
 @cindex overwriting files
@@ -9852,11 +10120,57 @@ NB: As of 20120515, @command{ncap2} is unable to append to files that
 already contain the appended dimensions. 
 
 @html
+<a name="gaa"></a> <!-- http://nco.sf.net/nco.html#gaa -->
+<a name="glb"></a> <!-- http://nco.sf.net/nco.html#glb -->
+<a name="glb_att_add"></a> <!-- http://nco.sf.net/nco.html#glb_att_add -->
+ at end html
+ at node Global Attribute Addition, History Attribute, Batch Mode, Shared features
+ at section Global Attribute Addition
+ at cindex global attributes
+ at cindex attributes, global
+ at cindex @code{--gaa}
+ at cindex @code{--glb @var{att_nm}=@var{att_val}}
+ at cindex @code{--glb}
+ at cindex @code{--glb_att_add}
+ at cindex @command{ncatted}
+ at cartouche
+Availability: All operators@*
+Short options: None@*
+Long options: @samp{--glb}, @samp{--gaa}, @samp{--glb_att_add}@*
+ at samp{--glb @var{att_nm}=@var{att_val}} (multiple invocations allowed)@*
+ at end cartouche
+All operators can add user-specified global attributes to output files.
+As of @acronym{NCO} version 4.5.2 (July, 2015), @acronym{NCO} supports
+multiple uses of the @samp{--glb} (or equivalent @samp{--gaa} or
+ at samp{--glb_att_add}) switch.
+The switch takes mandatory arguments 
+ at samp{--glb @var{att_nm}=@var{att_val}}   
+where @var{att_nm} is the desired name of the global attriute to add, 
+and @var{att_val} is its value.
+Currently only text attributes are supported (recorded as type
+ at code{NC_CHAR}), and regular expressions are not allowed (unlike
+ at pxref{ncatted netCDF Attribute Editor}).    
+ at example
+ at verbatim
+ncra --glb machine=${HOSTNAME} --glb created_by=${USER} in*.nc out.nc
+ at end verbatim
+ at end example
+Multiple invocations simplify the annotation of output file at creation
+(or modification) time.
+
+This feature helps to avoid the performance penalty incurred by having
+to use @command{ncatted} separately to annotate large files.
+Should users emit a loud hue and cry, we will consider ading the
+the functionality of @command{ncatted} to the front-end of all
+operators, i.e., accepting valid @command{ncatted} arguments to
+modify attributes of any type and to apply regular expressions.
+
+ at html
 <a name="hst"></a> <!-- http://nco.sf.net/nco.html#hst -->
 <a name="history"></a> <!-- http://nco.sf.net/nco.html#history -->
 <a name="-h"></a> <!-- http://nco.sf.net/nco.html#-h -->
 @end html
- at node History Attribute, File List Attributes, Batch Mode, Shared features
+ at node History Attribute, File List Attributes, Global Attribute Addition, Shared features
 @section History Attribute
 @cindex @code{history}
 @cindex timestamp
@@ -10439,7 +10753,7 @@ in-depth examples of @command{ncap2} solutions to complex problems.
 SYNTAX
 @example
 ncap2 [-3] [-4] [-6] [-7] [@uref{http://nco.sf.net/nco.html#-A,,-A}] [-C] [-c] 
-[-D @var{dbg}] [-F] [-f] [-h] [--hdf] [--hdr_pad @var{nbr}] [-L @var{dfl_lvl}] [-l @var{path}]
+[-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]
 @var{input-file} [@var{output-file}]  
@@ -12292,7 +12606,6 @@ ncap2 -O -v -S ~/ncap2_foo.nco ~/nco/data/in.nc ~/foo.nc
 @end example
 
 @html
-<a name="grd"></a> <!-- http://nco.sf.net/nco.html#grd -->
 <a name="rrg"></a> <!-- http://nco.sf.net/nco.html#rrg -->
 <a name="rct"></a> <!-- http://nco.sf.net/nco.html#rct -->
 @end html
@@ -12703,7 +13016,7 @@ The function/wrapper returns a status flag.
 Zero indicates success. 
 
 @noindent Consider another array function @* 
- at code{int gsl_sf_legendre_Pl_array( int lmax, double x, double *result_array);}
+ at code{int gsl_sf_legendre_Pl_array(int lmax, double x, double *result_array);}
 @cindex Legendre polynomial
 @findex gsl_sf_legendre_Pl
 @example
@@ -14727,7 +15040,7 @@ SYNTAX
 ncbo [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F] 
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdr_pad @var{nbr}]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdr_pad @var{nbr}]
 [-L @var{dfl_lvl}] [-l @var{path}] [--no_tmp_fl]
 [-O] [-o @var{file_3}] [-p @var{path}] [-R] [-r] [--ram_all]
 [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-X ...] [-x] [-y @var{op_typ}]
@@ -15154,7 +15467,7 @@ SYNTAX
 nces [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdf] [--hdr_pad @var{nbr}] 
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}] 
 [-L @var{dfl_lvl}] [-l @var{path}] [-n @var{loop}] [--no_tmp_fl] [--nsm_fl|grp] [--nsm_sfx sfx]
 [-O] [-o @var{output-file}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] [--rth_dbl|flt]
 [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-X ...] [-x] [-y @var{op_typ}]
@@ -15378,7 +15691,7 @@ SYNTAX
 ncecat [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--gag] [-h] [--hdf] [--hdr_pad @var{nbr}]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--gag] [--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}]
 [-L @var{dfl_lvl}] [-l @var{path}] [-M] [--md5_digest] [--mrd] [-n @var{loop}] [--no_tmp_fl] 
 [-O] [-o @var{output-file}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] 
 [-t @var{thr_nbr}] [-u @var{ulm_nm}] [--unn] [-v @var{var}[, at dots{}]] [-X ...] [-x] 
@@ -15501,7 +15814,8 @@ as positional arguments on the command line
 (@pxref{Large Numbers of Files}).
 
 @cindex @code{-M}
- at cindex @code{--glb_mtd_spp}
+ at cindex @code{--no_glb_mtd}
+ at cindex @code{--suppress_global_metadata}
 @cindex @code{history}
 @cindex provenance
 @cindex metadata, global 
@@ -15509,14 +15823,14 @@ Suppress global metadata copying.
 By default @acronym{NCO}'s multi-file operators copy the global metadata
 from the first input file into @var{output-file}.  
 This helps to preserve the provenance of the output data.
-However, the use of metadata is burgeoning and is not uncommon to
-encounter files with excessive amounts of extraneous metadata.
+However, the use of metadata is burgeoning and sometimes one
+encounters files with excessive amounts of extraneous metadata.
 Extracting small bits of data from such files leads to output files
 which are much larger than necessary due to the automatically copied
 metadata.
 @command{ncecat} supports turning off the default copying of global
 metadata via the @samp{-M} switch (or its long option equivalents,
- at samp{--glb_mtd_spp} and @samp{--global_metadata_suppress}). 
+ at samp{--no_glb_mtd} and @samp{--suppress_global_metadata}). 
 
 @cindex climate model
 Consider five realizations, @file{85a.nc}, @file{85b.nc}, 
@@ -15638,7 +15952,7 @@ SYNTAX
 ncflint [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]]
-[-F] [--fix_rec_crd] [-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdr_pad @var{nbr}]
+[-F] [--fix_rec_crd] [-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdr_pad @var{nbr}]
 [-i @var{var}, at var{val3}] [-L @var{dfl_lvl}] [-l @var{path}] [--no_tmp_fl] 
 [-O] [-o @var{file_3}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] 
 [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-w @var{wgt1}[, at var{wgt2}]] [-X ...] [-x]
@@ -15900,10 +16214,11 @@ SYNTAX
 ncks [-3] [-4] [-5] [-6] [-7] [-A] [-a] [-b @var{binary-file}] [-C] [-c] [--cdl]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F] [--fix_rec_dmn @var{dim}] 
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--grp_xtr_var_xcl] [-H] [-h] [--hdn] [--hdr_pad @var{nbr}]
-[-L @var{dfl_lvl}] [-l @var{path}] [-M] [-m] [--map @var{map-file}] [--md5_digest] [--mk_rec_dmn @var{dim}]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [--grp_xtr_var_xcl]
+[-H] [-h] [--hdn] [--hdr_pad @var{nbr}] [-L @var{dfl_lvl}] [-l @var{path}]
+[-M] [-m] [--map @var{map-file}] [--md5] [--mk_rec_dmn @var{dim}]
 [--no_blank] [--no_tmp_fl] [-O] [-o @var{output-file}] [-P] [-p @var{path}] [--ppc ...]
-[-Q] [-q] [-R] [-r] [--rad] [--ram_all] [--rnr=wgt] [-s @var{format}] 
+[-Q] [-q] [-R] [-r] [--rad] [--ram_all] [--rgr ...] [--rnr=wgt] [-s @var{format}] 
 [-u] [--unn] [-V] [-v @var{var}[, at dots{}]] [-X ...] [-x] [--xml]
 @var{input-file} [[@var{output-file}]]
 @end example
@@ -17102,7 +17417,7 @@ SYNTAX
 ncpdq [-3] [-4] [-6] [-7] [-A] [-a [-]@var{dim}[, at dots{}]] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]]
-[-F] [-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdf] [--hdr_pad @var{nbr}]
+[-F] [-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}]
 [-L @var{dfl_lvl}] [-l @var{path}] [-M @var{pck_map}] [--mrd] [--no_tmp_fl] 
 [-O] [-o @var{output-file}] [-P @var{pck_plc}] [-p @var{path}] [--ppc ...]
 [-R] [-r] [--ram_all] [-t @var{thr_nbr}] [-U] [--unn] [-v @var{var}[, at dots{}]] [-X ...] [-x]
@@ -17693,8 +18008,8 @@ SYNTAX
 ncra [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}][,[@var{subcycle}]]]] [-F]
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdf] [--hdr_pad @var{nbr}] 
-[-L @var{dfl_lvl}] [-l @var{path}] [--mro] [-n @var{loop}] [--no_tmp_fl]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}] 
+[-L @var{dfl_lvl}] [-l @var{path}] [--mro] [-N] [-n @var{loop}] [--no_tmp_fl]
 [-O] [-o @var{output-file}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [--rth_dbl|flt]
 [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-w wgt] [-X ...] [-x] [-y @var{op_typ}]
 [@var{input-files}] [@var{output-file}]
@@ -17758,6 +18073,28 @@ One-dimensional weights apply to each corresponding record (i.e.,
 per-record weights), and are suitable for dynamically changing
 timesteps. 
 
+By default, any weights specified (whether by value or by variable name)
+are normalized to unity by dividing each specified weight by the sum of
+all the weights.
+This means, for example, that, @samp{-w 0.25,0.75} is equivalent to 
+ at samp{-w 2.0,6.0} since both are equal when normalized.
+This behavior simplifies specifying weights based on countable items.
+For example, time-weighting monthly averages for March, April, and May
+to obtain a spring seasonal average can be done with 
+ at samp{-w 31,30,31} instead of 
+ at samp{-w 0.33695652173913043478,0.32608695652173913043,0.33695652173913043478}. 
+
+However, sometimes one wishes to use weights in ``dot-product mode'',
+i.e., multiply by the (non-normalized) weights.
+As of @acronym{NCO} @w{version 4.5.2}, released in July, 2015,
+ at command{ncra} accepts the @samp{-N} (or long-option equivalent
+ at samp{--no_nrm_by_wgt}) switch that prevents automatic weight
+normalization. 
+When this switch is used, the weights will not be normalized (unless the
+user provides them as normalized), and the numerator of the weighted
+average will not be divided by the sum of the weights (which is one for
+normalized weights).
+
 Bear these two exceptions in mind when weighting input:
 First, @command{ncra} only applies weights if the arithmetic operation
 type is averaging (@pxref{Operation Types}), i.e., for timeseries mean
@@ -17845,7 +18182,7 @@ SYNTAX
 ncrcat [-3] [-4] [-6] [-7] [-A] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}][,[@var{subcycle}]]]] [-F]
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdr_pad @var{nbr}]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdr_pad @var{nbr}]
 [-L @var{dfl_lvl}] [-l @var{path}] [--md5_digest] [-n @var{loop}] [--no_tmp_fl]
 [-O] [-o @var{output-file}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn]
 [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-X ...] [-x] 
@@ -17984,7 +18321,7 @@ SYNTAX
 @example
 ncrename [-a @var{old_name}, at var{new_name}] [-a @dots{}] [-D @var{dbg}] 
 [-d @var{old_name}, at var{new_name}] [-d @dots{}] [-g @var{old_name}, at var{new_name}] [-g @dots{}] 
-[-h] [--hdf] [--hdr_pad @var{nbr}] [-l @var{path}] [-O] [-o @var{output-file}] [-p @var{path}] [-R] [-r] 
+[--glb ...] [-h] [--hdf] [--hdr_pad @var{nbr}] [-l @var{path}] [-O] [-o @var{output-file}] [-p @var{path}] [-R] [-r] 
 [-v @var{old_name}, at var{new_name}] [-v @dots{}]
 @var{input-file} [[@var{output-file}]]
 @end example
@@ -18325,7 +18662,7 @@ SYNTAX
 ncwa [-3] [-4] [-6] [-7] [-A] [-a @var{dim}[, at dots{}]] [-B @var{mask_cond}] [-b] [-C] [-c]
 [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min sz] [--cnk_plc plc] [--cnk_scl sz]
 [-D @var{dbg}] [-d @var{dim},[@var{min}][,[@var{max}][,[@var{stride}]]] [-F]
-[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [-h] [--hdr_pad @var{nbr}] [-I]
+[-G @var{gpe_dsc}] [-g @var{grp}[, at dots{}]] [--glb ...] [-h] [--hdr_pad @var{nbr}] [-I]
 [-L @var{dfl_lvl}] [-l @var{path}] [-M @var{mask_val}] [-m @var{mask_var}] [-N] [--no_tmp_fl]
 [-O] [-o @var{output-file}] [-p @var{path}] [--ppc ...] [-R] [-r] [--ram_all] [--rth_dbl|flt]
 [-T @var{mask_comp}] [-t @var{thr_nbr}] [--unn] [-v @var{var}[, at dots{}]] [-w @var{weight}]
diff --git a/man/ncap.1 b/man/ncap.1
index a697032..46f082b 100644
--- a/man/ncap.1
+++ b/man/ncap.1
@@ -9,6 +9,9 @@ ncap \- netCDF Arithmetic Processor
 ncap [\-3] [\-4] [\-6] [\-7] [\-A] [\-C] [\-c] [\-D 
 .IR dbg_lvl ]
 [\-F] [\-f]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/ncap2.1 b/man/ncap2.1
index c49fe29..bf13033 100644
--- a/man/ncap2.1
+++ b/man/ncap2.1
@@ -14,6 +14,9 @@ ncap2 [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR min ][,[
 .IR max ]]]
 [\-F] [\-f]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-l 
diff --git a/man/ncatted.1 b/man/ncatted.1
index c0193aa..4678823 100644
--- a/man/ncatted.1
+++ b/man/ncatted.1
@@ -11,6 +11,9 @@ ncatted [\-a
 [\-a ...] [\-\-bfr
 .IR sz ] [\-D
 .IR dbg_lvl]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdr_pad
 .IR sz ]
 [\-l path] [\-O] [\-p path] [\-R] [\-r] [\-\-ram_all]
diff --git a/man/ncbo.1 b/man/ncbo.1
index 4ead63a..41c5d69 100644
--- a/man/ncbo.1
+++ b/man/ncbo.1
@@ -28,6 +28,9 @@ ncbo [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/ncdiff.1 b/man/ncdiff.1
index d6628f3..18bdfb4 100644
--- a/man/ncdiff.1
+++ b/man/ncdiff.1
@@ -9,6 +9,9 @@ dbg_lvl ]
 .IR min ][,[
 .IR max ]]]
 [\-F]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/ncea.1 b/man/ncea.1
index cd73208..8e3ac58 100644
--- a/man/ncea.1
+++ b/man/ncea.1
@@ -25,13 +25,16 @@ ncea [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-L 
 .IR dfl_lvl ] 
 [\-l 
 .IR path ]
-[\-\-msa] [\-n 
+[\-\-msa] [\-N] [\-n 
 .IR loop ]
 [\-\-no_tmp_fl] [\-\-nsm_sfx
 .IR grp_sfx ]
diff --git a/man/ncecat.1 b/man/ncecat.1
index d3c9fc1..0186266 100644
--- a/man/ncecat.1
+++ b/man/ncecat.1
@@ -28,6 +28,9 @@ ncecat [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 [\-g  
 .IR grp [,...]]
 [\--gag]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/nces.1 b/man/nces.1
index aa087a3..ae5f3cf 100644
--- a/man/nces.1
+++ b/man/nces.1
@@ -33,7 +33,7 @@ nces [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR dfl_lvl ] 
 [\-l 
 .IR path ]
-[\-\-msa] [\-n 
+[\-\-msa] [\-N] [\-n 
 .IR loop ]
 [\-\-no_tmp_fl] [\-\-nsm_sfx
 .IR grp_sfx ]
diff --git a/man/ncflint.1 b/man/ncflint.1
index 2c4a42d..9abf473 100644
--- a/man/ncflint.1
+++ b/man/ncflint.1
@@ -27,6 +27,9 @@ ncflint [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-i
diff --git a/man/ncks.1 b/man/ncks.1
index b4a580d..fee2e51 100644
--- a/man/ncks.1
+++ b/man/ncks.1
@@ -34,6 +34,9 @@ dbg_lvl]
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-\-grp_xtr_var_xcl]
 [\-H] [\-h] [\-\-hdn] 
 [\-\-hdr_pad
@@ -43,8 +46,10 @@ dbg_lvl]
 [\-l 
 .IR path ]
 [\-M] [\-m] [\-\-map
-.IR map-file ] [\-\-md5]  [\-\-mk_rec_dmn
-.IR dim ] [\-\-msa] [\-\-no_blank] [\-\-no_tmp_fl] [\-O] [\-o 
+.IR map-file ]
+[\-\-md5] [\-\-mk_rec_dmn
+.IR dim ]
+[\-\-msa] [\-\-no_blank] [\-\-no_tmp_fl] [\-O] [\-o 
 .IR output-file ] 
 [\-P] [\-p 
 .IR path ]
@@ -53,7 +58,11 @@ dbg_lvl]
 .IR var2 [,...]]=
 .IR prc ]]
 [\-Q] [\-q]
-[\-R] [\-r] [\-\-rad] [\-\-ram_all] [\--rnr
+[\-R] [\-r] [\-\-rad] [\-\-ram_all]
+[\-\-rgr
+.IR key=
+.IR val ]]
+[\--rnr
 .IR wgt ] [\-s 
 .IR format ] [\-t
 .IR thr_nbr ] [\-u] [\--unn] [\-V] [\-v 
diff --git a/man/ncpdq.1 b/man/ncpdq.1
index 5bfcd41..43516aa 100644
--- a/man/ncpdq.1
+++ b/man/ncpdq.1
@@ -29,6 +29,9 @@ ncpdq [\-3] [\-4] [\-6] [\-7] [\-A] [\-a
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/ncra.1 b/man/ncra.1
index 4140c7a..9095ef8 100644
--- a/man/ncra.1
+++ b/man/ncra.1
@@ -29,13 +29,16 @@ ncra [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-L 
 .IR dfl_lvl ] 
 [\-l 
 .IR path ]
-[\-\-mro] [\-\-msa] [\-n 
+[\-\-mro] [\-\-msa] [\-N] [\-n 
 .IR loop ]
 [\-\-no_cll_mth] [\-\-no_tmp_fl] [\-O] [\-p 
 .IR path ]
diff --git a/man/ncrcat.1 b/man/ncrcat.1
index 4b96d30..301918e 100644
--- a/man/ncrcat.1
+++ b/man/ncrcat.1
@@ -29,6 +29,9 @@ ncrcat [\-3] [\-4] [\-6] [\-7] [\-A] [\-\-bfr
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdr_pad
 .IR sz ]
 [\-L 
diff --git a/man/ncrename.1 b/man/ncrename.1
index bff5ea7..97f50fc 100644
--- a/man/ncrename.1
+++ b/man/ncrename.1
@@ -15,7 +15,11 @@ ncrename [\-a
 [\-d
 \ .\|.\|.\ ] [\-g 
 .IR old_name,new_name ] 
-[\-g \ .\|.\|.\ ] [\-h] [\-\-hdr_pad
+[\-g \ .\|.\|.\ ]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
+[\-h] [\-\-hdr_pad
 .IR sz ]
 [\-l path] [\-O] [\-p path]
 [\-R] [\-r] [\-\-ram_all] [\-v 
diff --git a/man/ncwa.1 b/man/ncwa.1
index 8712434..ac4b467 100644
--- a/man/ncwa.1
+++ b/man/ncwa.1
@@ -31,6 +31,9 @@ ncwa [\-3] [\-4] [\-6] [\-7] [\-A] [\-a
 .IR gpe_dsc ]
 [\-g  
 .IR grp [,...]]
+[\-\-glb
+.IR att_name=
+.IR att_val ]]
 [\-h] [\-\-hdf] [\-\-hdr_pad
 .IR sz ]
 [\-I] [\-L 
diff --git a/src/nco++/ncap2.cc b/src/nco++/ncap2.cc
index a8e1439..8583784 100644
--- a/src/nco++/ncap2.cc
+++ b/src/nco++/ncap2.cc
@@ -102,30 +102,11 @@ main(int argc,char **argv)
   /* fxm TODO nco652 */
   double rnd_nbr(double);
   
-  nco_bool ATT_INHERIT=True;          
-  nco_bool ATT_PROPAGATE=True;        
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool FL_OUT_NEW=False;
-  nco_bool PRN_FNC_TBL=False; /* Option f */  
-  nco_bool PROCESS_ALL_VARS=True; /* Option v */  
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
-  
   aed_sct att_item; // Used to convert atts in vector to normal form  
   
   char **fl_lst_abb=NULL_CEWI; /* Option n */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *cmd_ln;
   char *cnk_arg[NC_MAX_DIMS];
@@ -155,22 +136,6 @@ main(int argc,char **argv)
   dmn_sct *dmn_new;
   dmn_sct *dmn_item;
 
-  // Template lists
-  NcapVector<dmn_sct*> dmn_in_vtr;  
-  NcapVector<dmn_sct*> dmn_out_vtr;  
-  
-  // Holder for attributes and vectors
-  NcapVarVector var_vtr;
-  
-  // Holder for attributes and vectors in first parse
-  NcapVarVector int_vtr;
-  
-  // Method/function holder
-  std::vector<fmc_cls> fmc_vtr;
-  
-  // Holder for prs_cls, NB: used for OpenMP
-  std::vector<prs_cls> prs_vtr;
-  
   extern char *optarg;
   extern int optind;
   
@@ -183,6 +148,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int in_id;  
   int idx;
   int jdx;
@@ -204,6 +170,42 @@ main(int argc,char **argv)
   
   lmt_sct **lmt=NULL_CEWI;
   
+  // Template lists
+  NcapVector<dmn_sct*> dmn_in_vtr;  
+  NcapVector<dmn_sct*> dmn_out_vtr;  
+  
+  // Holder for attributes and vectors
+  NcapVarVector var_vtr;
+  
+  // Holder for attributes and vectors in first parse
+  NcapVarVector int_vtr;
+  
+  // Method/function holder
+  std::vector<fmc_cls> fmc_vtr;
+  
+  // Holder for prs_cls, NB: used for OpenMP
+  std::vector<prs_cls> prs_vtr;
+  
+  nco_bool ATT_INHERIT=True;          
+  nco_bool ATT_PROPAGATE=True;        
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool FL_OUT_NEW=False;
+  nco_bool PRN_FNC_TBL=False; /* Option f */  
+  nco_bool PROCESS_ALL_VARS=True; /* Option v */  
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
+  
   nm_id_sct *dmn_lst=NULL_CEWI;
   nm_id_sct *xtr_lst=NULL_CEWI; /* Non-processed variables to copy to OUTPUT */
   nm_id_sct *xtr_lst_a=NULL_CEWI; /* Initialize to ALL variables in OUTPUT file */
@@ -223,96 +225,97 @@ main(int argc,char **argv)
   var_sct **var_prc;
   var_sct **var_prc_out;
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"lbr",no_argument,0,0},
-      {"library",no_argument,0,0},
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fnc_tbl",no_argument,0,'f'},
-      {"prn_fnc_tbl",no_argument,0,'f'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"nintap",required_argument,0,'n'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"file",required_argument,0,'S'},
-      {"script-file",required_argument,0,'S'},
-      {"signal",no_argument,0,'z'},
-      {"fl_spt",required_argument,0,'S'},
-      {"spt",required_argument,0,'s'},
-      {"script",required_argument,0,'s'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"units",no_argument,0,'u'},
-      {"variable",no_argument,0,'v'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"lbr",no_argument,0,0},
+    {"library",no_argument,0,0},
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fnc_tbl",no_argument,0,'f'},
+    {"prn_fnc_tbl",no_argument,0,'f'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"nintap",required_argument,0,'n'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"file",required_argument,0,'S'},
+    {"script-file",required_argument,0,'S'},
+    {"signal",no_argument,0,'z'},
+    {"fl_spt",required_argument,0,'S'},
+    {"spt",required_argument,0,'s'},
+    {"script",required_argument,0,'s'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"units",no_argument,0,'u'},
+    {"variable",no_argument,0,'v'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
   /* Start clock and save command line */ 
@@ -365,6 +368,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
@@ -661,6 +668,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
diff --git a/src/nco++/ncoGrammer.g b/src/nco++/ncoGrammer.g
index 12a2847..b0c675f 100644
--- a/src/nco++/ncoGrammer.g
+++ b/src/nco++/ncoGrammer.g
@@ -1856,6 +1856,11 @@ end0:         if(lmt->getNextSibling() && lmt->getNextSibling()->getType()==NORE
             if(nco_dbg_lvl_get() >= nco_dbg_var) dbg_prn(fnc_nm,sa);
  
             var1=out(att2->getNextSibling());
+            // we dont need missing values in ATT right !!
+            if(var1->has_mss_val){
+              var1->has_mss_val=False;
+	          var1->mss_val.vp=(void*)nco_free(var1->mss_val.vp);
+            }   
 
             // if RHS is a non scalar variable then loose superfluous dimension data 
             if( var1->nbr_dim >0){
diff --git a/src/nco++/ncoTree.cpp b/src/nco++/ncoTree.cpp
index f7cd870..a5c2eec 100644
--- a/src/nco++/ncoTree.cpp
+++ b/src/nco++/ncoTree.cpp
@@ -829,7 +829,7 @@ int  ncoTree::statements(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 }
 
 var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
-#line 1886 "ncoGrammer.g"
+#line 1891 "ncoGrammer.g"
 	var_sct *var;
 #line 835 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST out_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
@@ -863,7 +863,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 	ANTLR_USE_NAMESPACE(antlr)RefAST val_uint = ANTLR_USE_NAMESPACE(antlr)nullAST;
 	ANTLR_USE_NAMESPACE(antlr)RefAST val_int64 = ANTLR_USE_NAMESPACE(antlr)nullAST;
 	ANTLR_USE_NAMESPACE(antlr)RefAST val_uint64 = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 1886 "ncoGrammer.g"
+#line 1891 "ncoGrammer.g"
 	
 	const std::string fnc_nm("out"); 
 		var_sct *var1;
@@ -889,7 +889,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t308;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1913 "ncoGrammer.g"
+#line 1918 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, TIMES );
 #line 895 "ncoTree.cpp"
 			}
@@ -908,7 +908,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t309;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1916 "ncoGrammer.g"
+#line 1921 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, DIVIDE );
 #line 914 "ncoTree.cpp"
 			}
@@ -927,7 +927,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t310;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1918 "ncoGrammer.g"
+#line 1923 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, MOD);
 #line 933 "ncoTree.cpp"
 			}
@@ -946,7 +946,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t311;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1920 "ncoGrammer.g"
+#line 1925 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, CARET);
 #line 952 "ncoTree.cpp"
 			}
@@ -963,7 +963,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t312;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1923 "ncoGrammer.g"
+#line 1928 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,NULL_CEWI, LNOT );
 #line 969 "ncoTree.cpp"
 			}
@@ -980,7 +980,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t315;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1929 "ncoGrammer.g"
+#line 1934 "ncoGrammer.g"
 				var=ncap_var_var_inc(var1,NULL_CEWI,INC,false,prs_arg);
 #line 986 "ncoTree.cpp"
 			}
@@ -997,7 +997,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t316;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1931 "ncoGrammer.g"
+#line 1936 "ncoGrammer.g"
 				var=ncap_var_var_inc(var1,NULL_CEWI, DEC,false,prs_arg );
 #line 1003 "ncoTree.cpp"
 			}
@@ -1014,7 +1014,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t317;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1933 "ncoGrammer.g"
+#line 1938 "ncoGrammer.g"
 				
 				var=ncap_var_var_inc(var1,NULL_CEWI,POST_INC,false,prs_arg);
 				
@@ -1033,7 +1033,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t318;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1936 "ncoGrammer.g"
+#line 1941 "ncoGrammer.g"
 				
 				var=ncap_var_var_inc(var1,NULL_CEWI,POST_DEC,false,prs_arg);
 				
@@ -1054,7 +1054,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t319;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1941 "ncoGrammer.g"
+#line 1946 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, LAND );
 #line 1060 "ncoTree.cpp"
 			}
@@ -1073,7 +1073,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t320;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1943 "ncoGrammer.g"
+#line 1948 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, LOR );
 #line 1079 "ncoTree.cpp"
 			}
@@ -1092,7 +1092,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t321;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1946 "ncoGrammer.g"
+#line 1951 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, LTHAN );
 #line 1098 "ncoTree.cpp"
 			}
@@ -1111,7 +1111,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t322;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1948 "ncoGrammer.g"
+#line 1953 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, GTHAN );
 #line 1117 "ncoTree.cpp"
 			}
@@ -1130,7 +1130,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t323;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1950 "ncoGrammer.g"
+#line 1955 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, GEQ );
 #line 1136 "ncoTree.cpp"
 			}
@@ -1149,7 +1149,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t324;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1952 "ncoGrammer.g"
+#line 1957 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, LEQ );
 #line 1155 "ncoTree.cpp"
 			}
@@ -1168,7 +1168,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t325;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1954 "ncoGrammer.g"
+#line 1959 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, EQ );
 #line 1174 "ncoTree.cpp"
 			}
@@ -1187,7 +1187,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t326;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1956 "ncoGrammer.g"
+#line 1961 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, NEQ );
 #line 1193 "ncoTree.cpp"
 			}
@@ -1206,7 +1206,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t327;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1959 "ncoGrammer.g"
+#line 1964 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, FLTHAN );
 #line 1212 "ncoTree.cpp"
 			}
@@ -1225,7 +1225,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t328;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1961 "ncoGrammer.g"
+#line 1966 "ncoGrammer.g"
 				var=ncap_var_var_op(var1,var2, FGTHAN );
 #line 1231 "ncoTree.cpp"
 			}
@@ -1245,7 +1245,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t329;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1963 "ncoGrammer.g"
+#line 1968 "ncoGrammer.g"
 				
 				var1=out_asn(pls_asn);
 				var=ncap_var_var_inc(var1,var2, PLUS_ASSIGN ,(pls_asn->getType()==UTIMES), prs_arg);
@@ -1268,7 +1268,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t330;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1967 "ncoGrammer.g"
+#line 1972 "ncoGrammer.g"
 				
 				var1=out_asn(min_asn);
 				var=ncap_var_var_inc(var1,var2, MINUS_ASSIGN ,(min_asn->getType()==UTIMES), prs_arg);
@@ -1291,7 +1291,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t331;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1971 "ncoGrammer.g"
+#line 1976 "ncoGrammer.g"
 				
 				var1=out_asn(tim_asn);
 				var=ncap_var_var_inc(var1,var2, TIMES_ASSIGN ,(tim_asn->getType()==UTIMES), prs_arg);
@@ -1314,7 +1314,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t332;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1975 "ncoGrammer.g"
+#line 1980 "ncoGrammer.g"
 					
 				var1=out_asn(div_asn);
 				var=ncap_var_var_inc(var1,var2, DIVIDE_ASSIGN ,(div_asn->getType()==UTIMES), prs_arg);
@@ -1335,7 +1335,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t333;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 1981 "ncoGrammer.g"
+#line 1986 "ncoGrammer.g"
 				
 				// Check for RAM variable - if present 
 				// change tree - for example from:
@@ -1386,7 +1386,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t334;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2015 "ncoGrammer.g"
+#line 2020 "ncoGrammer.g"
 				
 				
 				
@@ -1408,7 +1408,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t335;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2020 "ncoGrammer.g"
+#line 2025 "ncoGrammer.g"
 				
 				bool br;
 				
@@ -1441,7 +1441,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t336;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2038 "ncoGrammer.g"
+#line 2043 "ncoGrammer.g"
 				
 				// The lexer has appended the index of the function to the function name m - (name#index)
 				//  the index is into fmc_vtr  
@@ -1473,7 +1473,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t337;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2049 "ncoGrammer.g"
+#line 2054 "ncoGrammer.g"
 				
 				// The lexer has appended the index of the function to the function name m - (name#index)
 				//  the index is into fmc_vtr  
@@ -1492,7 +1492,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,DIM_ID_SIZE);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2059 "ncoGrammer.g"
+#line 2064 "ncoGrammer.g"
 				
 				string sDim=dval->getText();
 				dmn_sct *dmn_fd;
@@ -1542,7 +1542,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,ATT_ID);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2131 "ncoGrammer.g"
+#line 2136 "ncoGrammer.g"
 				
 				
 				NcapVar *Nvar=NULL;
@@ -1582,7 +1582,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,VALUE_LIST);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2162 "ncoGrammer.g"
+#line 2167 "ncoGrammer.g"
 				
 				var=value_list(vlst);
 				
@@ -1596,7 +1596,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,NSTRING);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2167 "ncoGrammer.g"
+#line 2172 "ncoGrammer.g"
 				
 				char *tsng;
 				
@@ -1628,7 +1628,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,N4STRING);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2190 "ncoGrammer.g"
+#line 2195 "ncoGrammer.g"
 				
 				char *tsng;
 				
@@ -1666,7 +1666,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,FLOAT);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2220 "ncoGrammer.g"
+#line 2225 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~float"),(nc_type)NC_FLOAT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~float"),static_cast<float>(std::strtod(val_float->getText().c_str(),(char **)NULL)));
 #line 1672 "ncoTree.cpp"
 			}
@@ -1678,7 +1678,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,DOUBLE);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2222 "ncoGrammer.g"
+#line 2227 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~double"),(nc_type)NC_DOUBLE,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~double"),strtod(val_double->getText().c_str(),(char **)NULL));
 #line 1684 "ncoTree.cpp"
 			}
@@ -1690,7 +1690,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,INT);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2224 "ncoGrammer.g"
+#line 2229 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~int"),(nc_type)NC_INT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~int"),static_cast<nco_int>(std::strtol(val_int->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1696 "ncoTree.cpp"
 			}
@@ -1702,7 +1702,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,SHORT);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2226 "ncoGrammer.g"
+#line 2231 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~short"),(nc_type)NC_SHORT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~short"),static_cast<nco_short>(std::strtol(val_short->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1708 "ncoTree.cpp"
 			}
@@ -1714,7 +1714,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,BYTE);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2228 "ncoGrammer.g"
+#line 2233 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~byte"),(nc_type)NC_BYTE,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~byte"),static_cast<nco_byte>(std::strtol(val_byte->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1720 "ncoTree.cpp"
 			}
@@ -1726,7 +1726,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,UBYTE);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2233 "ncoGrammer.g"
+#line 2238 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~ubyte"),(nc_type)NC_UBYTE,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~ubyte"),static_cast<nco_ubyte>(std::strtoul(val_ubyte->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1732 "ncoTree.cpp"
 			}
@@ -1738,7 +1738,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,USHORT);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2237 "ncoGrammer.g"
+#line 2242 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~ushort"),(nc_type)NC_USHORT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~ushort"),static_cast<nco_ushort>(std::strtoul(val_ushort->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1744 "ncoTree.cpp"
 			}
@@ -1750,7 +1750,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,UINT);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2239 "ncoGrammer.g"
+#line 2244 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~uint"),(nc_type)NC_UINT,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~uint"),static_cast<nco_uint>(std::strtoul(val_uint->getText().c_str(),(char **)NULL,NCO_SNG_CNV_BASE10)));
 #line 1756 "ncoTree.cpp"
 			}
@@ -1762,7 +1762,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,INT64);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2241 "ncoGrammer.g"
+#line 2246 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~int64"),(nc_type)NC_INT64,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~int64"),sng2nbr(val_int64->getText(),nco_int64_CEWI));
 #line 1768 "ncoTree.cpp"
 			}
@@ -1774,7 +1774,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,UINT64);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2245 "ncoGrammer.g"
+#line 2250 "ncoGrammer.g"
 				if(prs_arg->ntl_scn) var=ncap_sclr_var_mk(static_cast<std::string>("~uint64"),(nc_type)NC_UINT64,false); else var=ncap_sclr_var_mk(static_cast<std::string>("~uint64"),sng2nbr(val_uint64->getText(),nco_uint64_CEWI));
 #line 1780 "ncoTree.cpp"
 			}
@@ -1820,7 +1820,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 				_t = __t279;
 				_t = _t->getNextSibling();
 				if ( inputState->guessing==0 ) {
-#line 1896 "ncoGrammer.g"
+#line 1901 "ncoGrammer.g"
 					var=ncap_var_var_op(var1,var2, PLUS );
 #line 1826 "ncoTree.cpp"
 				}
@@ -1865,7 +1865,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 					_t = __t283;
 					_t = _t->getNextSibling();
 					if ( inputState->guessing==0 ) {
-#line 1898 "ncoGrammer.g"
+#line 1903 "ncoGrammer.g"
 						var=ncap_var_var_op(var1,var2, MINUS );
 #line 1871 "ncoTree.cpp"
 					}
@@ -1918,7 +1918,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 						_t = __t288;
 						_t = _t->getNextSibling();
 						if ( inputState->guessing==0 ) {
-#line 1899 "ncoGrammer.g"
+#line 1904 "ncoGrammer.g"
 							
 							var=ncap_var_var_inc(var1,NULL_CEWI,POST_INC,true,prs_arg);      
 							
@@ -1973,7 +1973,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 							_t = __t294;
 							_t = _t->getNextSibling();
 							if ( inputState->guessing==0 ) {
-#line 1902 "ncoGrammer.g"
+#line 1907 "ncoGrammer.g"
 								
 								var=ncap_var_var_inc(var1,NULL_CEWI,POST_DEC,true,prs_arg);      
 								
@@ -2028,7 +2028,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 								_t = __t300;
 								_t = _t->getNextSibling();
 								if ( inputState->guessing==0 ) {
-#line 1905 "ncoGrammer.g"
+#line 1910 "ncoGrammer.g"
 									
 									var=ncap_var_var_inc(var1,NULL_CEWI,INC,true,prs_arg);      
 									
@@ -2083,7 +2083,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 									_t = __t306;
 									_t = _t->getNextSibling();
 									if ( inputState->guessing==0 ) {
-#line 1908 "ncoGrammer.g"
+#line 1913 "ncoGrammer.g"
 										
 										var=ncap_var_var_inc(var1,NULL_CEWI,DEC,true,prs_arg);      
 										
@@ -2100,7 +2100,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 									_t = __t313;
 									_t = _t->getNextSibling();
 									if ( inputState->guessing==0 ) {
-#line 1925 "ncoGrammer.g"
+#line 1930 "ncoGrammer.g"
 										var=ncap_var_var_op(var1,NULL_CEWI, MINUS );
 #line 2106 "ncoTree.cpp"
 									}
@@ -2153,7 +2153,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 										_t = __t341;
 										_t = _t->getNextSibling();
 										if ( inputState->guessing==0 ) {
-#line 2100 "ncoGrammer.g"
+#line 2105 "ncoGrammer.g"
 											
 											// see if hyperslab limit is a single value
 											if(lmt->getNumberOfChildren()==1 && 
@@ -2173,7 +2173,7 @@ var_sct * ncoTree::out(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 										match(_t,VAR_ID);
 										_t = _t->getNextSibling();
 										if ( inputState->guessing==0 ) {
-#line 2114 "ncoGrammer.g"
+#line 2119 "ncoGrammer.g"
 											
 											
 											var=prs_arg->ncap_var_init(v->getText(),true);
@@ -3128,6 +3128,11 @@ var_sct * ncoTree::assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 							if(nco_dbg_lvl_get() >= nco_dbg_var) dbg_prn(fnc_nm,sa);
 							
 							var1=out(att2->getNextSibling());
+							// we dont need missing values in ATT right !!
+							if(var1->has_mss_val){
+							var1->has_mss_val=False;
+								          var1->mss_val.vp=(void*)nco_free(var1->mss_val.vp);
+							}   
 							
 							// if RHS is a non scalar variable then loose superfluous dimension data 
 							if( var1->nbr_dim >0){
@@ -3153,7 +3158,7 @@ var_sct * ncoTree::assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 							var=nco_var_dpl(var1);               ;
 							
 							
-#line 3157 "ncoTree.cpp"
+#line 3162 "ncoTree.cpp"
 						}
 					}
 		else {
@@ -3175,14 +3180,14 @@ var_sct * ncoTree::assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 }
 
 var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
-#line 2255 "ncoGrammer.g"
+#line 2260 "ncoGrammer.g"
 	var_sct *var;
-#line 3181 "ncoTree.cpp"
+#line 3186 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST out_asn_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid1 = ANTLR_USE_NAMESPACE(antlr)nullAST;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid = ANTLR_USE_NAMESPACE(antlr)nullAST;
 	ANTLR_USE_NAMESPACE(antlr)RefAST att = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2255 "ncoGrammer.g"
+#line 2260 "ncoGrammer.g"
 	
 	const std::string fnc_nm("assign_asn");
 	var=NULL_CEWI; 
@@ -3190,7 +3195,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 	NcapVar *Nvar;
 	
 	
-#line 3194 "ncoTree.cpp"
+#line 3199 "ncoTree.cpp"
 	
 	try {      // for error handling
 		if (_t == ANTLR_USE_NAMESPACE(antlr)nullAST )
@@ -3208,7 +3213,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			_t = __t343;
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2265 "ncoGrammer.g"
+#line 2270 "ncoGrammer.g"
 				
 				if(vid1->getFirstChild())
 				err_prn(fnc_nm,"Invalid Lvalue " +vid1->getText() );
@@ -3226,7 +3231,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 				}
 				
 				
-#line 3230 "ncoTree.cpp"
+#line 3235 "ncoTree.cpp"
 			}
 			break;
 		}
@@ -3236,7 +3241,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,VAR_ID);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2283 "ncoGrammer.g"
+#line 2288 "ncoGrammer.g"
 				
 				var_nm_s=vid->getText();  
 				if(vid->getFirstChild())
@@ -3255,7 +3260,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 				}
 				
 				
-#line 3259 "ncoTree.cpp"
+#line 3264 "ncoTree.cpp"
 			}
 			break;
 		}
@@ -3265,7 +3270,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			match(_t,ATT_ID);
 			_t = _t->getNextSibling();
 			if ( inputState->guessing==0 ) {
-#line 2302 "ncoGrammer.g"
+#line 2307 "ncoGrammer.g"
 				
 				// check "output"
 				NcapVar *Nvar=NULL;
@@ -3298,7 +3303,7 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 				var->val.vp=(void*)nco_free(var->val.vp);
 				
 				
-#line 3302 "ncoTree.cpp"
+#line 3307 "ncoTree.cpp"
 			}
 			break;
 		}
@@ -3322,17 +3327,17 @@ var_sct * ncoTree::out_asn(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 }
 
 var_sct * ncoTree::value_list(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
-#line 2336 "ncoGrammer.g"
+#line 2341 "ncoGrammer.g"
 	var_sct *var;
-#line 3328 "ncoTree.cpp"
+#line 3333 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST value_list_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vlst = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2336 "ncoGrammer.g"
+#line 2341 "ncoGrammer.g"
 	
 	const std::string fnc_nm("value_list");
 	var=NULL_CEWI; 
 	
-#line 3336 "ncoTree.cpp"
+#line 3341 "ncoTree.cpp"
 	
 	try {      // for error handling
 		{
@@ -3341,7 +3346,7 @@ var_sct * ncoTree::value_list(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 		_t = _t->getNextSibling();
 		}
 		if ( inputState->guessing==0 ) {
-#line 2341 "ncoGrammer.g"
+#line 2346 "ncoGrammer.g"
 			
 			
 			char *cp;
@@ -3429,7 +3434,7 @@ var_sct * ncoTree::value_list(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			var=var_ret;
 			
 			
-#line 3433 "ncoTree.cpp"
+#line 3438 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
@@ -3448,20 +3453,20 @@ var_sct * ncoTree::value_list(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 var_sct * ncoTree::value_list_string(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 	 std::vector<var_sct*> &exp_vtr
 ) {
-#line 2432 "ncoGrammer.g"
+#line 2437 "ncoGrammer.g"
 	var_sct *var;
-#line 3454 "ncoTree.cpp"
+#line 3459 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST value_list_string_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
-#line 2432 "ncoGrammer.g"
+#line 2437 "ncoGrammer.g"
 	
 	const std::string fnc_nm("value_list_string");
 	var=NULL_CEWI; 
 	
-#line 3461 "ncoTree.cpp"
+#line 3466 "ncoTree.cpp"
 	
 	try {      // for error handling
 		if ( inputState->guessing==0 ) {
-#line 2438 "ncoGrammer.g"
+#line 2443 "ncoGrammer.g"
 			
 			int idx;
 			int nbr_lst;
@@ -3510,7 +3515,7 @@ var_sct * ncoTree::value_list_string(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 			end_val: var=var_ret;
 			
 			
-#line 3514 "ncoTree.cpp"
+#line 3519 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
@@ -3529,18 +3534,18 @@ var_sct * ncoTree::value_list_string(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 bool  ncoTree::where_assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 	var_sct *var_msk
 ) {
-#line 2489 "ncoGrammer.g"
+#line 2494 "ncoGrammer.g"
 	bool bret=false;
-#line 3535 "ncoTree.cpp"
+#line 3540 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST where_assign_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2489 "ncoGrammer.g"
+#line 2494 "ncoGrammer.g"
 	
 	const std::string fnc_nm("where_assign");
 	var_sct *var_rhs;
 	
 	
-#line 3544 "ncoTree.cpp"
+#line 3549 "ncoTree.cpp"
 	
 	try {      // for error handling
 		ANTLR_USE_NAMESPACE(antlr)RefAST __t348 = _t;
@@ -3561,7 +3566,7 @@ bool  ncoTree::where_assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 		_t = __t348;
 		_t = _t->getNextSibling();
 		if ( inputState->guessing==0 ) {
-#line 2495 "ncoGrammer.g"
+#line 2500 "ncoGrammer.g"
 			
 			
 			bool bfr=false;
@@ -3693,7 +3698,7 @@ bool  ncoTree::where_assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 			prs_arg->ncap_var_write(var_lhs,false);
 			bret=true;
 			
-#line 3697 "ncoTree.cpp"
+#line 3702 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
@@ -3710,18 +3715,18 @@ bool  ncoTree::where_assign(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 }
 
 var_sct * ncoTree::var_lmt_one(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
-#line 2630 "ncoGrammer.g"
+#line 2635 "ncoGrammer.g"
 	var_sct *var;
-#line 3716 "ncoTree.cpp"
+#line 3721 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST var_lmt_one_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2630 "ncoGrammer.g"
+#line 2635 "ncoGrammer.g"
 	
 	const std::string fnc_nm("var_lmt_one");
 	var=NULL_CEWI; 
 	var_sct *var_nbr;
 	
-#line 3725 "ncoTree.cpp"
+#line 3730 "ncoTree.cpp"
 	
 	try {      // for error handling
 		ANTLR_USE_NAMESPACE(antlr)RefAST __t351 = _t;
@@ -3745,7 +3750,7 @@ var_sct * ncoTree::var_lmt_one(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 		_t = __t351;
 		_t = _t->getNextSibling();
 		if ( inputState->guessing==0 ) {
-#line 2636 "ncoGrammer.g"
+#line 2641 "ncoGrammer.g"
 			
 			
 			int idx;
@@ -3846,7 +3851,7 @@ var_sct * ncoTree::var_lmt_one(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			end0:       var_nbr=nco_var_free(var_nbr);
 			var_rhs=nco_var_free(var_rhs);   
 			
-#line 3850 "ncoTree.cpp"
+#line 3855 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
@@ -3865,18 +3870,18 @@ var_sct * ncoTree::var_lmt_one(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 var_sct * ncoTree::var_lmt_one_lhs(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 	bool bram
 ) {
-#line 2740 "ncoGrammer.g"
+#line 2745 "ncoGrammer.g"
 	var_sct *var;
-#line 3871 "ncoTree.cpp"
+#line 3876 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST var_lmt_one_lhs_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2740 "ncoGrammer.g"
+#line 2745 "ncoGrammer.g"
 	
 	const std::string fnc_nm("var_lmt_one_lhs");
 	var=NULL_CEWI; 
 	var_sct *var_nbr;
 	
-#line 3880 "ncoTree.cpp"
+#line 3885 "ncoTree.cpp"
 	
 	try {      // for error handling
 		ANTLR_USE_NAMESPACE(antlr)RefAST __t355 = _t;
@@ -3900,7 +3905,7 @@ var_sct * ncoTree::var_lmt_one_lhs(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 		_t = __t355;
 		_t = _t->getNextSibling();
 		if ( inputState->guessing==0 ) {
-#line 2746 "ncoGrammer.g"
+#line 2751 "ncoGrammer.g"
 			
 			int idx; 
 			int var_id; 
@@ -4045,7 +4050,7 @@ var_sct * ncoTree::var_lmt_one_lhs(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 			var_rhs=nco_var_free(var_rhs); 
 			var_nbr=nco_var_free(var_nbr); 
 			
-#line 4049 "ncoTree.cpp"
+#line 4054 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
@@ -4062,18 +4067,18 @@ var_sct * ncoTree::var_lmt_one_lhs(ANTLR_USE_NAMESPACE(antlr)RefAST _t,
 }
 
 var_sct * ncoTree::var_lmt(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
-#line 2893 "ncoGrammer.g"
+#line 2898 "ncoGrammer.g"
 	var_sct *var;
-#line 4068 "ncoTree.cpp"
+#line 4073 "ncoTree.cpp"
 	ANTLR_USE_NAMESPACE(antlr)RefAST var_lmt_AST_in = (_t == ANTLR_USE_NAMESPACE(antlr)RefAST(ASTNULL)) ? ANTLR_USE_NAMESPACE(antlr)nullAST : _t;
 	ANTLR_USE_NAMESPACE(antlr)RefAST vid = ANTLR_USE_NAMESPACE(antlr)nullAST;
 	ANTLR_USE_NAMESPACE(antlr)RefAST lmt = ANTLR_USE_NAMESPACE(antlr)nullAST;
-#line 2893 "ncoGrammer.g"
+#line 2898 "ncoGrammer.g"
 	
 	const std::string fnc_nm("var_lmt");
 	var=NULL_CEWI; 
 	
-#line 4077 "ncoTree.cpp"
+#line 4082 "ncoTree.cpp"
 	
 	try {      // for error handling
 		ANTLR_USE_NAMESPACE(antlr)RefAST __t359 = _t;
@@ -4086,7 +4091,7 @@ var_sct * ncoTree::var_lmt(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 		_t = __t359;
 		_t = _t->getNextSibling();
 		if ( inputState->guessing==0 ) {
-#line 2898 "ncoGrammer.g"
+#line 2903 "ncoGrammer.g"
 			
 			bool bram;   // Check for a RAM variable
 			bool bnrm;
@@ -4325,7 +4330,7 @@ var_sct * ncoTree::var_lmt(ANTLR_USE_NAMESPACE(antlr)RefAST _t) {
 			
 			end2: var_rhs=nco_var_free(var_rhs); 
 			
-#line 4329 "ncoTree.cpp"
+#line 4334 "ncoTree.cpp"
 		}
 	}
 	catch (ANTLR_USE_NAMESPACE(antlr)RecognitionException& ex) {
diff --git a/src/nco/mpncbo.c b/src/nco/mpncbo.c
index 075569e..a0fc110 100644
--- a/src/nco/mpncbo.c
+++ b/src/nco/mpncbo.c
@@ -85,27 +85,9 @@
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION;
-  nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
-  
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
   char *cmd_ln;
@@ -165,6 +147,7 @@ main(int argc,char **argv)
   int fl_in_fmt_2; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx;
   int jdx;
   int dmn_idx;
@@ -197,6 +180,25 @@ main(int argc,char **argv)
   lmt_sct **lmt=NULL_CEWI;
   lmt_all_sct **lmt_all_lst=NULL_CEWI; /* List of *lmt_all structures */
   
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION;
+  nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
+  
   nm_id_sct *dmn_lst_1;
   nm_id_sct *dmn_lst_2;
   nm_id_sct *xtr_lst_1=NULL; /* xtr_lst_1 may be alloc()'d from NULL with -c option */
@@ -235,90 +237,91 @@ main(int argc,char **argv)
   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */	  
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"suspend", no_argument,0,'S'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"operation",required_argument,0,'y'},
-      {"op_typ",required_argument,0,'y'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */	  
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"suspend", no_argument,0,'S'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"operation",required_argument,0,'y'},
+    {"op_typ",required_argument,0,'y'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
 #ifdef ENABLE_MPI 
@@ -344,7 +347,7 @@ main(int argc,char **argv)
     /* NB: access to opt_crr is only valid when long_opt is detected */
     if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */
     opt_crr=(char *)strdup(opt_lng[opt_idx].name);
-
+    
     /* Process long options without short option counterparts */
     if(opt == 0){
       if(!strcmp(opt_crr,"bfr_sz_hnt") || !strcmp(opt_crr,"buffer_size_hint")){
@@ -382,6 +385,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"ddra") || !strcmp(opt_crr,"mdl_cmp")) ddra_info.flg_ddra=flg_ddra=True; /* [flg] DDRA diagnostics */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -723,6 +730,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in_1,in_id_1,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
diff --git a/src/nco/mpncecat.c b/src/nco/mpncecat.c
index e3a77b5..f508470 100644
--- a/src/nco/mpncecat.c
+++ b/src/nco/mpncecat.c
@@ -62,26 +62,9 @@
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_APPEND=True; /* Option H */
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
   char *cmd_ln;
@@ -131,6 +114,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx;
   int jdx;
   int in_id;  
@@ -156,6 +140,24 @@ main(int argc,char **argv)
   
   long idx_rec_out=0L; /* idx_rec_out gets incremented */
   
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_APPEND=True; /* Option H */
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  
   nm_id_sct *dmn_lst;
   nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
   
@@ -191,93 +193,94 @@ main(int argc,char **argv)
   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"fl_lst_in",no_argument,0,'H'},
-      {"file_list",no_argument,0,'H'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"nintap",required_argument,0,'n'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"suspend", no_argument,0,'S'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"ulm_nm",required_argument,0,'u'},
-      {"rcd_nm",required_argument,0,'u'},
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"fl_lst_in",no_argument,0,'H'},
+    {"file_list",no_argument,0,'H'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"nintap",required_argument,0,'n'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"suspend", no_argument,0,'S'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"ulm_nm",required_argument,0,'u'},
+    {"rcd_nm",required_argument,0,'u'},
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
 #ifdef ENABLE_MPI
@@ -337,6 +340,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -403,7 +410,7 @@ main(int argc,char **argv)
       break;
     case 'n': /* NINTAP-style abbreviation of files to process */
       fl_lst_abb=nco_lst_prs_2D(optarg,",",&abb_arg_nbr);
-      if(abb_arg_nbr < 1 || abb_arg_nbr > 5){
+      if(abb_arg_nbr < 1 || abb_arg_nbr > 6){
 	(void)fprintf(stdout,"%s: ERROR Incorrect abbreviation for file list\n",nco_prg_nm);
 	(void)nco_usg_prn();
 	nco_exit(EXIT_FAILURE);
@@ -592,6 +599,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
diff --git a/src/nco/mpncflint.c b/src/nco/mpncflint.c
index 6fd27ef..de87607 100644
--- a/src/nco/mpncflint.c
+++ b/src/nco/mpncflint.c
@@ -68,30 +68,9 @@
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool CMD_LN_NTP_VAR=False; /* Option i */
-  nco_bool CMD_LN_NTP_WGT=True; /* Option w */
-  nco_bool DO_CONFORM=False; /* Did nco_var_cnf_dmn() find truly conforming variables? */
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION;
-  nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
-  nco_bool MUST_CONFORM=False; /* Must nco_var_cnf_dmn() find truly conforming variables? */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **ntp_lst_in;
   char **var_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
@@ -147,6 +126,7 @@ main(int argc,char **argv)
   int fl_in_fmt_2; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int has_mss_val=False;
   int idx;
   int jdx;
@@ -172,6 +152,28 @@ main(int argc,char **argv)
   lmt_sct **lmt;
   lmt_all_sct **lmt_all_lst; /* List of *lmt_all structures */
   
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool CMD_LN_NTP_VAR=False; /* Option i */
+  nco_bool CMD_LN_NTP_WGT=True; /* Option w */
+  nco_bool DO_CONFORM=False; /* Did nco_var_cnf_dmn() find truly conforming variables? */
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FILE_1_RETRIEVED_FROM_REMOTE_LOCATION;
+  nco_bool FILE_2_RETRIEVED_FROM_REMOTE_LOCATION;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
+  nco_bool MUST_CONFORM=False; /* Must nco_var_cnf_dmn() find truly conforming variables? */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  
   nm_id_sct *dmn_lst;
   nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
   
@@ -213,88 +215,89 @@ main(int argc,char **argv)
   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"interpolate",required_argument,0,'i'},
-      {"ntp",required_argument,0,'i'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"suspend", no_argument,0,'S'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"weight",required_argument,0,'w'},
-      {"wgt_var",no_argument,0,'w'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"interpolate",required_argument,0,'i'},
+    {"ntp",required_argument,0,'i'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"suspend", no_argument,0,'S'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"weight",required_argument,0,'w'},
+    {"wgt_var",no_argument,0,'w'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
 #ifdef ENABLE_MPI
@@ -354,6 +357,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -650,6 +657,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in_1,in_id_1,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
diff --git a/src/nco/mpncpdq.c b/src/nco/mpncpdq.c
index ff935ad..af00ccf 100644
--- a/src/nco/mpncpdq.c
+++ b/src/nco/mpncpdq.c
@@ -72,25 +72,6 @@ main(int argc,char **argv)
   aed_sct *aed_lst_add_fst=NULL_CEWI;
   aed_sct *aed_lst_scl_fct=NULL_CEWI;
   
-  nco_bool **dmn_rvr_in=NULL; /* [flg] Reverse dimension */
-  nco_bool *dmn_rvr_rdr=NULL; /* [flg] Reverse dimension */
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool REDEFINED_RECORD_DIMENSION=False; /* [flg] Re-defined record dimension */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  
   char **dmn_rdr_lst_in=NULL_CEWI; /* Option a */
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in=NULL_CEWI;
@@ -154,6 +135,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx=int_CEWI;
   int idx_rdr=int_CEWI;
   int in_id;  
@@ -180,6 +162,25 @@ main(int argc,char **argv)
   lmt_sct **lmt=NULL_CEWI;
   lmt_all_sct **lmt_all_lst=NULL_CEWI; /* List of *lmt_all structures */
   
+  nco_bool **dmn_rvr_in=NULL; /* [flg] Reverse dimension */
+  nco_bool *dmn_rvr_rdr=NULL; /* [flg] Reverse dimension */
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool REDEFINED_RECORD_DIMENSION=False; /* [flg] Re-defined record dimension */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  
   nm_id_sct *dmn_lst;
   nm_id_sct *dmn_rdr_lst;
   nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
@@ -218,90 +219,91 @@ main(int argc,char **argv)
   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"arrange",required_argument,0,'a'},
-      {"permute",required_argument,0,'a'},
-      {"reorder",required_argument,0,'a'},
-      {"rdr",required_argument,0,'a'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"pck_map",required_argument,0,'M'},
-      {"map",required_argument,0,'M'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"pack_policy",required_argument,0,'P'},
-      {"pck_plc",required_argument,0,'P'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"suspend", no_argument,0,'S'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"unpack",no_argument,0,'U'},
-      {"upk",no_argument,0,'U'},
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"arrange",required_argument,0,'a'},
+    {"permute",required_argument,0,'a'},
+    {"reorder",required_argument,0,'a'},
+    {"rdr",required_argument,0,'a'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"pck_map",required_argument,0,'M'},
+    {"map",required_argument,0,'M'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"pack_policy",required_argument,0,'P'},
+    {"pck_plc",required_argument,0,'P'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"suspend", no_argument,0,'S'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"unpack",no_argument,0,'U'},
+    {"upk",no_argument,0,'U'},
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
 #ifdef ENABLE_MPI
@@ -361,6 +363,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -692,6 +698,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
diff --git a/src/nco/mpncra.c b/src/nco/mpncra.c
index a8260cf..e9a9ab6 100644
--- a/src/nco/mpncra.c
+++ b/src/nco/mpncra.c
@@ -112,27 +112,9 @@ void checkpointMpi(int prc_rnk, int stage){
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_ARM;
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_APPEND=True; /* Option H */
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool LAST_RECORD=False;
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *cmd_ln;
   char *cnk_arg[NC_MAX_DIMS];
@@ -176,6 +158,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx=int_CEWI;
   int in_id;  
   int lmt_nbr=0; /* Option d. NB: lmt_nbr gets incremented */
@@ -204,6 +187,25 @@ main(int argc,char **argv)
   long idx_rec; /* [idx] Index of current record in current input file */
   long rec_usd_cml=0L; /* [idx] Index of current record in output file (0 is first, ...) */
   
+  nco_bool CNV_ARM;
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_APPEND=True; /* Option H */
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool LAST_RECORD=False;
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  
   nco_int base_time_srt=nco_int_CEWI;
   nco_int base_time_crr=nco_int_CEWI;
   
@@ -279,6 +281,8 @@ main(int argc,char **argv)
       {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
       {"fl_fmt",required_argument,0,0},
       {"file_format",required_argument,0,0},
+      {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+      {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
       {"hdr_pad",required_argument,0,0},
       {"header_pad",required_argument,0,0},
       /* Long options with short counterparts */
@@ -397,6 +401,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -462,7 +470,7 @@ main(int argc,char **argv)
       break;
     case 'n': /* NINTAP-style abbreviation of files to average */
       fl_lst_abb=nco_lst_prs_2D(optarg,",",&abb_arg_nbr);
-      if(abb_arg_nbr < 1 || abb_arg_nbr > 5){
+      if(abb_arg_nbr < 1 || abb_arg_nbr > 6){
 	(void)fprintf(stdout,gettext("%s: ERROR Incorrect abbreviation for file list\n"),nco_prg_nm_get());
 	(void)nco_usg_prn();
 	nco_exit(EXIT_FAILURE);
@@ -704,6 +712,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     /* Add input file list global attribute */
diff --git a/src/nco/mpncwa.c b/src/nco/mpncwa.c
index 3d0722b..204561a 100644
--- a/src/nco/mpncwa.c
+++ b/src/nco/mpncwa.c
@@ -77,33 +77,6 @@ char **ncap_fl_spt_glb; /* [fl] Script file */
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool DO_CONFORM_MSK=False; /* Did nco_var_cnf_dmn() find truly conforming mask? */
-  nco_bool DO_CONFORM_WGT=False; /* Did nco_var_cnf_dmn() find truly conforming weight? */
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool MULTIPLY_BY_TALLY=False; /* Not currently implemented */
-  nco_bool MUST_CONFORM=False; /* [flg] Must nco_var_cnf_dmn() find truly conforming variables? */
-  nco_bool NORMALIZE_BY_TALLY=True; /* Not currently implemented */
-  nco_bool NORMALIZE_BY_WEIGHT=True; /* Not currently implemented */
-  nco_bool NRM_BY_DNM=True; /* Option N Normalize by denominator */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WGT_MSK_CRD_VAR=True; /* [flg] Weight and/or mask coordinate variables */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
-  nco_bool flg_opt_a=False; /* Option a */
-  nco_bool flg_rdd=False; /* [flg] Retain degenerate dimensions */
-  
   char **dmn_avg_lst_in=NULL_CEWI; /* Option a */
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in=NULL_CEWI;
@@ -166,6 +139,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx=int_CEWI;
   int idx_avg;
   int in_id;
@@ -190,6 +164,33 @@ main(int argc,char **argv)
   
   lmt_sct **lmt;
   
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool DO_CONFORM_MSK=False; /* Did nco_var_cnf_dmn() find truly conforming mask? */
+  nco_bool DO_CONFORM_WGT=False; /* Did nco_var_cnf_dmn() find truly conforming weight? */
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool MULTIPLY_BY_TALLY=False; /* Not currently implemented */
+  nco_bool MUST_CONFORM=False; /* [flg] Must nco_var_cnf_dmn() find truly conforming variables? */
+  nco_bool NORMALIZE_BY_TALLY=True; /* Not currently implemented */
+  nco_bool NORMALIZE_BY_WEIGHT=True; /* Not currently implemented */
+  nco_bool NRM_BY_DNM=True; /* Option N Normalize by denominator */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WGT_MSK_CRD_VAR=True; /* [flg] Weight and/or mask coordinate variables */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
+  nco_bool flg_opt_a=False; /* Option a */
+  nco_bool flg_rdd=False; /* [flg] Retain degenerate dimensions */
+  
   nm_id_sct *dmn_lst;
   nm_id_sct *xtr_lst=NULL; /* xtr_lst may be alloc()'d from NULL with -c option */
   nm_id_sct *dmn_avg_lst;
@@ -231,114 +232,115 @@ main(int argc,char **argv)
   int wrk_id_bfr[wrk_id_bfr_lng]; /* [bfr] Buffer for rnk_wrk */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"average",required_argument,0,'a'},
-      {"avg",required_argument,0,'a'},
-      {"append",no_argument,0,'A'},
-      {"mask_condition",required_argument,0,'B'},
-      {"msk_cnd_sng",required_argument,0,'B'},
-      {"retain-degenerate-dimensions",no_argument,0,'b'}, /* [flg] Retain degenerate dimensions */
-      {"rdd",no_argument,0,'b'}, /* [flg] Retain degenerate dimensions */
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"wgt_msk_crd_var",no_argument,0,'I'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"mask-variable",required_argument,0,'m'},
-      {"mask_variable",required_argument,0,'m'},
-      {"mask",required_argument,0,'m'},
-      {"msk_var",required_argument,0,'m'},
-      {"msk_nm",required_argument,0,'m'},
-      {"mask-value",required_argument,0,'M'},
-      {"mask_value",required_argument,0,'M'},
-      {"msk_val",required_argument,0,'M'},
-      {"nintap",required_argument,0,'n'},
-      {"nmr",no_argument,0,'N'},
-      {"numerator",no_argument,0,'N'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"suspend", no_argument,0,'S'},
-      {"mask_comparator",required_argument,0,'T'},
-      {"msk_cmp_typ",required_argument,0,'T'},
-      {"op_rlt",required_argument,0,'T'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"normalize-by-tally",no_argument,0,'W',},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"weight",no_argument,0,'w'},
-      {"wgt",no_argument,0,'w'},
-      {"wgt_var",no_argument,0,'w'},
-      {"operation",required_argument,0,'y'},
-      {"op_typ",required_argument,0,'y'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"average",required_argument,0,'a'},
+    {"avg",required_argument,0,'a'},
+    {"append",no_argument,0,'A'},
+    {"mask_condition",required_argument,0,'B'},
+    {"msk_cnd_sng",required_argument,0,'B'},
+    {"retain-degenerate-dimensions",no_argument,0,'b'}, /* [flg] Retain degenerate dimensions */
+    {"rdd",no_argument,0,'b'}, /* [flg] Retain degenerate dimensions */
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"wgt_msk_crd_var",no_argument,0,'I'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"mask-variable",required_argument,0,'m'},
+    {"mask_variable",required_argument,0,'m'},
+    {"mask",required_argument,0,'m'},
+    {"msk_var",required_argument,0,'m'},
+    {"msk_nm",required_argument,0,'m'},
+    {"mask-value",required_argument,0,'M'},
+    {"mask_value",required_argument,0,'M'},
+    {"msk_val",required_argument,0,'M'},
+    {"nintap",required_argument,0,'n'},
+    {"nmr",no_argument,0,'N'},
+    {"numerator",no_argument,0,'N'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"suspend", no_argument,0,'S'},
+    {"mask_comparator",required_argument,0,'T'},
+    {"msk_cmp_typ",required_argument,0,'T'},
+    {"op_rlt",required_argument,0,'T'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"normalize-by-tally",no_argument,0,'W',},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"weight",no_argument,0,'w'},
+    {"wgt",no_argument,0,'w'},
+    {"wgt_var",no_argument,0,'w'},
+    {"operation",required_argument,0,'y'},
+    {"op_typ",required_argument,0,'y'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
 #ifdef ENABLE_MPI
@@ -405,6 +407,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"ddra") || !strcmp(opt_crr,"mdl_cmp")) ddra_info.flg_ddra=flg_ddra=True; /* [flg] DDRA diagnostics */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtoul",sng_cnv_rcd);
@@ -781,6 +787,8 @@ main(int argc,char **argv)
     
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+    if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     
     if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
diff --git a/src/nco/ncap.c b/src/nco/ncap.c
index 907f422..f1fd278 100644
--- a/src/nco/ncap.c
+++ b/src/nco/ncap.c
@@ -86,26 +86,9 @@ main(int argc,char **argv)
   /* fxm TODO nco652 */
   double rnd_nbr(double);
   
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool PRN_FNC_TBL=False; /* Option f */  
-  nco_bool PROCESS_ALL_VARS=True; /* Option v */  
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *cmd_ln;
   char *cnk_arg[NC_MAX_DIMS];
@@ -199,6 +182,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx;
   int in_id;  
   int jdx;
@@ -226,6 +210,24 @@ main(int argc,char **argv)
   
   lmt_sct **lmt=NULL_CEWI;
   
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool PRN_FNC_TBL=False; /* Option f */  
+  nco_bool PROCESS_ALL_VARS=True; /* Option v */  
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+
   nm_id_sct *dmn_lst=NULL;
   nm_id_sct *xtr_lst=NULL; /* Non-processed variables to copy to OUTPUT */
   nm_id_sct *xtr_lst_a=NULL; /* Initialize to ALL variables in OUTPUT file */
@@ -250,90 +252,91 @@ main(int argc,char **argv)
   
   prs_sct prs_arg; /* [sct] Global information required in parser routines */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"fnc_tbl",no_argument,0,'f'},
-      {"prn_fnc_tbl",no_argument,0,'f'},
-      {"ftn",no_argument,0,'F'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"nintap",required_argument,0,'n'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"file",required_argument,0,'S'},
-      {"script-file",required_argument,0,'S'},
-      {"fl_spt",required_argument,0,'S'},
-      {"spt",required_argument,0,'s'},
-      {"script",required_argument,0,'s'},
-      {"units",no_argument,0,'u'},
-      {"variable",no_argument,0,'v'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"fnc_tbl",no_argument,0,'f'},
+    {"prn_fnc_tbl",no_argument,0,'f'},
+    {"ftn",no_argument,0,'F'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"nintap",required_argument,0,'n'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"file",required_argument,0,'S'},
+    {"script-file",required_argument,0,'S'},
+    {"fl_spt",required_argument,0,'S'},
+    {"spt",required_argument,0,'s'},
+    {"script",required_argument,0,'s'},
+    {"units",no_argument,0,'u'},
+    {"variable",no_argument,0,'v'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
   /* Start timer and save command line */ 
@@ -352,7 +355,7 @@ main(int argc,char **argv)
     /* NB: access to opt_crr is only valid when long_opt is detected */
     if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */
     opt_crr=(char *)strdup(opt_lng[opt_idx].name);
-
+    
     /* Process long options without short option counterparts */
     if(opt == 0){
       if(!strcmp(opt_crr,"bfr_sz_hnt") || !strcmp(opt_crr,"buffer_size_hint")){
@@ -390,6 +393,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -659,6 +666,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   
   /* Take output file out of define mode */
diff --git a/src/nco/ncatted.c b/src/nco/ncatted.c
index b1fef31..d8031d7 100644
--- a/src/nco/ncatted.c
+++ b/src/nco/ncatted.c
@@ -152,18 +152,9 @@ main(int argc,char **argv)
 {
   aed_sct *aed_lst=NULL_CEWI;
 
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool FL_OUT_NEW=False;
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char *aed_arg[NC_MAX_ATTRS];
   char *cmd_ln;
   char *fl_in=NULL;
@@ -190,6 +181,7 @@ main(int argc,char **argv)
 
   int abb_arg_nbr=0;
   int fl_nbr=0;
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int nbr_aed=0; /* Option a. NB: nbr_var_aed gets incremented */
   int nbr_var_fl;
   int nc_id;  
@@ -197,6 +189,16 @@ main(int argc,char **argv)
   int opt;
   int rcd=NC_NOERR; /* [rcd] Return code */
 
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool FL_OUT_NEW=False;
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+
   size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
   size_t hdr_pad=0UL; /* [B] Pad at end of header section */
 
@@ -211,8 +213,7 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-  { /* Structure ordered by short option key if possible */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
     /* Long options with no argument, no short option counterpart */
     {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
     {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
@@ -230,6 +231,8 @@ main(int argc,char **argv)
     /* Long options with argument, no short option counterpart */
     {"bfr_sz_hnt",required_argument,0,0}, /* [B] Buffer size hint */
     {"buffer_size_hint",required_argument,0,0}, /* [B] Buffer size hint */
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
     {"hdr_pad",required_argument,0,0},
     {"header_pad",required_argument,0,0},
     /* Long options with short counterparts */
@@ -287,6 +290,10 @@ main(int argc,char **argv)
       } /* endif cnk */
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
diff --git a/src/nco/ncbo.c b/src/nco/ncbo.c
index f5ed20c..896e98a 100644
--- a/src/nco/ncbo.c
+++ b/src/nco/ncbo.c
@@ -123,6 +123,7 @@ main(int argc,char **argv)
 
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
   char *cmd_ln;
@@ -178,6 +179,7 @@ main(int argc,char **argv)
   int fl_in_fmt_2; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx;
   int in_id_1;  
   int in_id_2;  
@@ -238,104 +240,105 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */	  
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"7",no_argument,0,'7'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
-      {"grp",required_argument,0,'g'},
-      {"group",required_argument,0,'g'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"operation",required_argument,0,'y'},
-      {"op_typ",required_argument,0,'y'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"ddra",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"mdl_cmp",no_argument,0,0}, /* [flg] DDRA diagnostics */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */	  
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"7",no_argument,0,'7'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
+    {"grp",required_argument,0,'g'},
+    {"group",required_argument,0,'g'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"operation",required_argument,0,'y'},
+    {"op_typ",required_argument,0,'y'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
-
+  
   nbr_gpe_nm=0;
   
   /* Start timer and save command line */ 
@@ -400,6 +403,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"ddra") || !strcmp(opt_crr,"mdl_cmp")) ddra_info.flg_ddra=flg_ddra=True; /* [flg] DDRA diagnostics */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -633,6 +640,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in_1,in_id_1,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
 
   /* Turn off default filling behavior to enhance efficiency */
diff --git a/src/nco/ncecat.c b/src/nco/ncecat.c
index 46bb59b..e39bdb2 100644
--- a/src/nco/ncecat.c
+++ b/src/nco/ncecat.c
@@ -27,7 +27,7 @@
    University of California, Irvine
    Irvine, CA 92697-3100 */
 
-/* URL: https://github.com/czender/nco/tree/master/src/nco/ncecat.c
+/* URL: https://github.com/nco/nco/tree/master/src/nco/ncecat.c
 
    Usage:
    ncecat -O -D 1 -p ${HOME}/nco/data in_grp.nc in_grp.nc ~/foo.nc
@@ -115,6 +115,7 @@ main(int argc,char **argv)
 
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **grp_lst_in=NULL;
   char **var_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
@@ -177,6 +178,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int gpe_id; /* [id] Group ID of GPE path (diagnostic only) */
   int grp_lst_in_nbr=0; /* [nbr] Number of groups explicitly specified by user */
   int idx;
@@ -227,109 +229,110 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"gag",no_argument,0,0}, /* [flg] Group aggregation */
-      {"aggregate_group",no_argument,0,0}, /* [flg] Group aggregation */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"mrd",no_argument,0,0}, /* [enm] Multiple Record Dimension convention */
-      {"multiple_record_dimension",no_argument,0,0}, /* [enm] Multiple Record Dimension convention */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
-      {"group",required_argument,0,'g'},
-      {"grp",required_argument,0,'g'},
-      {"fl_lst_in",no_argument,0,'H'},
-      {"file_list",no_argument,0,'H'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"glb_mtd_spp",no_argument,0,'M'},
-      {"global_metadata_suppress",no_argument,0,'M'},
-      {"nintap",required_argument,0,'n'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"ulm_nm",required_argument,0,'u'},
-      {"rcd_nm",required_argument,0,'u'},
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"gag",no_argument,0,0}, /* [flg] Group aggregation */
+    {"aggregate_group",no_argument,0,0}, /* [flg] Group aggregation */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"mrd",no_argument,0,0}, /* [enm] Multiple Record Dimension convention */
+    {"multiple_record_dimension",no_argument,0,0}, /* [enm] Multiple Record Dimension convention */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
+    {"group",required_argument,0,'g'},
+    {"grp",required_argument,0,'g'},
+    {"fl_lst_in",no_argument,0,'H'},
+    {"file_list",no_argument,0,'H'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"no_glb_mtd",no_argument,0,'M'},
+    {"suppress_global_metadata",no_argument,0,'M'},
+    {"nintap",required_argument,0,'n'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"ulm_nm",required_argument,0,'u'},
+    {"rcd_nm",required_argument,0,'u'},
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
   }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
 
@@ -394,6 +397,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"gag") || !strcmp(opt_crr,"aggregate_group")) GROUP_AGGREGATE=True; /* [flg] Aggregate files into groups not records */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -494,7 +501,7 @@ main(int argc,char **argv)
       break;
     case 'n': /* NINTAP-style abbreviation of files to process */
       fl_lst_abb=nco_lst_prs_2D(optarg,",",&abb_arg_nbr);
-      if(abb_arg_nbr < 1 || abb_arg_nbr > 5){
+      if(abb_arg_nbr < 1 || abb_arg_nbr > 6){
         (void)fprintf(stdout,"%s: ERROR Incorrect abbreviation for file list\n",nco_prg_nm);
         (void)nco_usg_prn();
         nco_exit(EXIT_FAILURE);
@@ -668,6 +675,7 @@ main(int argc,char **argv)
     /* Catenate time-stamped command line to "history" global attribute */
     if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
     if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
     if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
     /* Add input file list global attribute */
     if(FL_LST_IN_APPEND && HISTORY_APPEND && FL_LST_IN_FROM_STDIN) (void)nco_fl_lst_att_cat(out_id,fl_lst_in,fl_nbr);
@@ -787,7 +795,8 @@ main(int argc,char **argv)
 
         /* Catenate time-stamped command line to "history" global attribute */
         if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
-    if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
+    if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
+  if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
 
         /* Add input file list global attribute */
         if(FL_LST_IN_APPEND && HISTORY_APPEND && FL_LST_IN_FROM_STDIN) (void)nco_fl_lst_att_cat(out_id,fl_lst_in,fl_nbr);
diff --git a/src/nco/ncflint.c b/src/nco/ncflint.c
index fa70628..00470ab 100644
--- a/src/nco/ncflint.c
+++ b/src/nco/ncflint.c
@@ -112,6 +112,7 @@ main(int argc,char **argv)
 
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **ntp_lst_in;
   char **grp_lst_in=NULL_CEWI;
   char **var_lst_in=NULL_CEWI;
@@ -176,6 +177,7 @@ main(int argc,char **argv)
   int fl_in_fmt_2; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int has_mss_val=False;
   int idx;
   int in_id_1;  
@@ -230,104 +232,105 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"fix_rec_crd",no_argument,0,0}, /* [flg] Do not interpolate/multiply record coordinate variables */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
-      {"grp",required_argument,0,'g'},
-      {"group",required_argument,0,'g'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"interpolate",required_argument,0,'i'},
-      {"ntp",required_argument,0,'i'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"weight",required_argument,0,'w'},
-      {"wgt_var",no_argument,0,'w'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"fix_rec_crd",no_argument,0,0}, /* [flg] Do not interpolate/multiply record coordinate variables */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
+    {"grp",required_argument,0,'g'},
+    {"group",required_argument,0,'g'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"interpolate",required_argument,0,'i'},
+    {"ntp",required_argument,0,'i'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"weight",required_argument,0,'w'},
+    {"wgt_var",no_argument,0,'w'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
   
   /* Start timer and save command line */ 
@@ -335,10 +338,10 @@ main(int argc,char **argv)
   rcd+=nco_ddra((char *)NULL,(char *)NULL,&ddra_info);
   ddra_info.tmr_flg=nco_tmr_mtd;
   cmd_ln=nco_cmd_ln_sng(argc,argv);
-
+  
   /* Get program name and set program enum (e.g., nco_prg_id=ncra) */
   nco_prg_nm=nco_prg_prs(argv[0],&nco_prg_id);
-
+  
 #ifdef ENABLE_MPI
   /* MPI Initialization */
   if(False) (void)fprintf(stdout,gettext("%s: WARNING Compiled with MPI\n"),nco_prg_nm);
@@ -354,7 +357,7 @@ main(int argc,char **argv)
     /* NB: access to opt_crr is only valid when long_opt is detected */
     if(opt == EOF) break; /* Parse positional arguments once getopt_long() returns EOF */
     opt_crr=(char *)strdup(opt_lng[opt_idx].name);
-
+    
     /* Process long options without short option counterparts */
     if(opt == 0){
       if(!strcmp(opt_crr,"bfr_sz_hnt") || !strcmp(opt_crr,"buffer_size_hint")){
@@ -392,6 +395,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fix_rec_crd")) FIX_REC_CRD=True; /* [flg] Do not interpolate/multiply record coordinate variables */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -656,6 +663,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in_1,in_id_1,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
diff --git a/src/nco/ncks.c b/src/nco/ncks.c
index 2d08cc1..f16d230 100644
--- a/src/nco/ncks.c
+++ b/src/nco/ncks.c
@@ -28,7 +28,7 @@
    University of California, Irvine
    Irvine, CA 92697-3100 */
 
-/* URL: https://github.com/czender/nco/tree/master/src/nco/ncks.c
+/* URL: https://github.com/nco/nco/tree/master/src/nco/ncks.c
 
    Usage:
    ncks ~/nco/data/in.nc 
@@ -110,55 +110,9 @@
 int 
 main(int argc,char **argv)
 {
-  nco_bool ALPHABETIZE_OUTPUT=True; /* Option a */
-  nco_bool CPY_GRP_METADATA; /* [flg] Copy group metadata (attributes) */
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option x */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_NOCLOBBER=False; /* Option no-clobber */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool GET_GRP_INFO=False; /* [flg] Iterate file, get group extended information */
-  nco_bool GET_FILE_INFO=False; /* [flg] Get file information (#groups, #dimensions, #attributes, #variables) */
-  nco_bool GET_LIST=False; /* [flg] Iterate file, print variables and exit */
-  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
-  nco_bool GRP_XTR_VAR_XCL=False; /* [flg] Extract matching groups, exclude matching variables */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool HAVE_LIMITS=False; /* [flg] Are there user limits? (-d) */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-  nco_bool PRN_CDL=False; /* [flg] Print CDL */
-  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_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 */
-  nco_bool PRN_DMN_UNITS=True; /* [flg] Print dimensional units Option u */
-  nco_bool PRN_DMN_VAR_NM=True; /* [flg] Print dimension/variable names */
-  nco_bool PRN_DMN_UNITS_TGL=False; /* [flg] Toggle print dimensional units Option u */
-  nco_bool PRN_GLB_METADATA=False; /* [flg] Print global metadata */
-  nco_bool PRN_GLB_METADATA_TGL=False; /* [flg] Toggle print global metadata Option M */
-  nco_bool PRN_MSS_VAL_BLANK=True; /* [flg] Print missing values as blanks */
-  nco_bool PRN_QUENCH=False; /* [flg] Quench (turn-off) all printing to screen */
-  nco_bool PRN_VAR_DATA=False; /* [flg] Print variable data */
-  nco_bool PRN_VAR_DATA_TGL=False; /* [flg] Toggle print variable data Option H */
-  nco_bool PRN_VAR_METADATA=False; /* [flg] Print variable metadata */
-  nco_bool PRN_VAR_METADATA_TGL=False; /* [flg] Toggle print variable metadata Option m */
-  nco_bool PRN_VRB=False; /* [flg] Print data and metadata by default */
-  nco_bool PRN_NEW_FMT=False; /* [flg] Print using new print format */
-  nco_bool RETAIN_ALL_DIMS=False; /* [flg] Retain all dimensions */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
-  nco_bool flg_rgr=False; /* [flg] Regrid */
-
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **grp_lst_in=NULL;
   char **rgr_arg=NULL; /* [sng] Regridding arguments */
   char **var_lst_in=NULL;
@@ -234,6 +188,7 @@ main(int argc,char **argv)
   int fl_nbr=0;
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int grp_dpt_fl; /* [nbr] Maximum group depth (root = 0) */
   int grp_lst_in_nbr=0; /* [nbr] Number of groups explicitly specified by user */
   int grp_nbr_fl;
@@ -256,6 +211,53 @@ main(int argc,char **argv)
 
   md5_sct *md5=NULL; /* [sct] MD5 configuration */
 
+  nco_bool ALPHABETIZE_OUTPUT=True; /* Option a */
+  nco_bool CPY_GRP_METADATA; /* [flg] Copy group metadata (attributes) */
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option x */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_NOCLOBBER=False; /* Option no-clobber */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool GET_GRP_INFO=False; /* [flg] Iterate file, get group extended information */
+  nco_bool GET_FILE_INFO=False; /* [flg] Get file information (#groups, #dimensions, #attributes, #variables) */
+  nco_bool GET_LIST=False; /* [flg] Iterate file, print variables and exit */
+  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
+  nco_bool GRP_XTR_VAR_XCL=False; /* [flg] Extract matching groups, exclude matching variables */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool HAVE_LIMITS=False; /* [flg] Are there user limits? (-d) */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+  nco_bool PRN_CDL=False; /* [flg] Print CDL */
+  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_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 */
+  nco_bool PRN_DMN_UNITS=True; /* [flg] Print dimensional units Option u */
+  nco_bool PRN_DMN_VAR_NM=True; /* [flg] Print dimension/variable names */
+  nco_bool PRN_DMN_UNITS_TGL=False; /* [flg] Toggle print dimensional units Option u */
+  nco_bool PRN_GLB_METADATA=False; /* [flg] Print global metadata */
+  nco_bool PRN_GLB_METADATA_TGL=False; /* [flg] Toggle print global metadata Option M */
+  nco_bool PRN_MSS_VAL_BLANK=True; /* [flg] Print missing values as blanks */
+  nco_bool PRN_QUENCH=False; /* [flg] Quench (turn-off) all printing to screen */
+  nco_bool PRN_VAR_DATA=False; /* [flg] Print variable data */
+  nco_bool PRN_VAR_DATA_TGL=False; /* [flg] Toggle print variable data Option H */
+  nco_bool PRN_VAR_METADATA=False; /* [flg] Print variable metadata */
+  nco_bool PRN_VAR_METADATA_TGL=False; /* [flg] Toggle print variable metadata Option m */
+  nco_bool PRN_VRB=False; /* [flg] Print data and metadata by default */
+  nco_bool PRN_NEW_FMT=False; /* [flg] Print using new print format */
+  nco_bool RETAIN_ALL_DIMS=False; /* [flg] Retain all dimensions */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
+  nco_bool flg_rgr=False; /* [flg] Regrid */
+
   size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
   size_t cnk_min_byt=NCO_CNK_SZ_MIN_BYT_DFL; /* [B] Minimize size of variable to chunk */
   size_t cnk_sz_byt=0UL; /* [B] Chunk size in bytes */
@@ -273,196 +275,197 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cdl",no_argument,0,0}, /* [flg] Print CDL */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"cmp",no_argument,0,0},
-      {"compiler",no_argument,0,0},
-      {"copyright",no_argument,0,0},
-      {"cpy",no_argument,0,0},
-      {"license",no_argument,0,0},
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdn",no_argument,0,0}, /* [flg] Print hidden attributes */
-      {"hidden",no_argument,0,0}, /* [flg] Print hidden attributes */
-      {"id",no_argument,0,0}, /* [flg] Print normally hidden information, like file, group, and variable IDs */
-      {"lbr",no_argument,0,0},
-      {"library",no_argument,0,0},
-      {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"md5_wrt_att",no_argument,0,0}, /* [flg] Write MD5 digests as attributes */
-      {"md5_write_attribute",no_argument,0,0}, /* [flg] Write MD5 digests as attributes */
-      {"mpi_implementation",no_argument,0,0},
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"no_blank",no_argument,0,0}, /* [flg] Print numeric missing values */
-      {"no-blank",no_argument,0,0}, /* [flg] Print numeric missing values */
-      {"noblank",no_argument,0,0}, /* [flg] Print numeric missing values */
-      {"no_clb",no_argument,0,0},
-      {"noclobber",no_argument,0,0},
-      {"no-clobber",no_argument,0,0},
-      {"no_clobber",no_argument,0,0},
-      {"no_dmn_var_nm",no_argument,0,0}, /* [flg] Omit variable and dimension names and indices but print all values */
-      {"no_nm_prn",no_argument,0,0}, /* [flg] Omit variable and dimension names and indices but print all values */
-      {"rad",no_argument,0,0}, /* [flg] Retain all dimensions */
-      {"retain_all_dimensions",no_argument,0,0}, /* [flg] Retain all dimensions */
-      {"orphan_dimensions",no_argument,0,0}, /* [flg] Retain all dimensions */
-      {"rph_dmn",no_argument,0,0}, /* [flg] Retain all dimensions */
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"secret",no_argument,0,0},
-      {"shh",no_argument,0,0},
-      {"srm",no_argument,0,0}, /* [flg] Print ncStream */
-      {"sysconf",no_argument,0,0}, /* [flg] Perform sysconf() test */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
-      {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
-      {"grp_xtr_var_xcl",no_argument,0,0}, /* [flg] Extract matching groups, exclude matching variables */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      {"jsn",no_argument,0,0}, /* [flg] Print JSON */
-      {"json",no_argument,0,0}, /* [flg] Print JSON */
-      {"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) */
-      {"ncml",no_argument,0,0}, /* [flg] Print XML (NcML) */
-      {"xml_no_location",no_argument,0,0}, /* [flg] Omit XML location tag */
-      {"ncml_no_location",no_argument,0,0}, /* [flg] Omit XML location tag */
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"fix_rec_dmn",required_argument,0,0}, /* [sng] Fix record dimension */
-      {"no_rec_dmn",required_argument,0,0}, /* [sng] Fix record dimension */
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      {"mk_rec_dmn",required_argument,0,0}, /* [sng] Name of record dimension in output */
-      {"mk_rec_dim",required_argument,0,0}, /* [sng] Name of record dimension in output */
-      {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"rgr",required_argument,0,0}, /* [sng] Regridding */
-      {"regridding",required_argument,0,0}, /* [sng] Regridding */
-      {"rgr_in",required_argument,0,0}, /* [sng] File containing fields to be regridded */
-      {"rgr_grd_src",required_argument,0,0}, /* [sng] File containing input grid */
-      {"rgr_grd_dst",required_argument,0,0}, /* [sng] File containing destination grid */
-      {"rgr_map",required_argument,0,0}, /* [sng] File containing mapping weights from source to destination grid */
-      {"map_file",required_argument,0,0}, /* [sng] File containing mapping weights from source to destination grid */
-      {"rgr_var",required_argument,0,0}, /* I [sng] Variable for special regridding treatment */
-      {"rgr_rnr",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
-      {"rnr",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
-      {"renormalize",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
-      {"scrip",required_argument,0,0}, /* SCRIP file */
-      {"tst_udunits",required_argument,0,0},
-      {"xml_spr_chr",required_argument,0,0}, /* [flg] Separator for XML character types */
-      {"xml_spr_nmr",required_argument,0,0}, /* [flg] Separator for XML numeric types */
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"pnetcdf",no_argument,0,'5'},
-      {"5",no_argument,0,'5'},
-      {"7",no_argument,0,'7'},
-      {"abc",no_argument,0,'a'},
-      {"alphabetize",no_argument,0,'a'},
-      {"append",no_argument,0,'A'},
-      {"apn",no_argument,0,'A'},
-      {"bnr",required_argument,0,'b'},
-      {"binary",required_argument,0,'b'},
-      {"binary-file",required_argument,0,'b'},
-      {"fl_bnr",required_argument,0,'b'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"data",required_argument,0,'H'},
-      {"debug",required_argument,0,'D'},
-      {"dbg_lvl",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
-      {"grp",required_argument,0,'g'},
-      {"group",required_argument,0,'g'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"hieronymus",no_argument,0,'H'}, /* fxm: need better mnemonic for -H */
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"lcl",required_argument,0,'l'},
-      {"local",required_argument,0,'l'},
-      {"metadata",no_argument,0,'m'},
-      {"mtd",no_argument,0,'m'},
-      {"Metadata",no_argument,0,'M'},
-      {"Mtd",no_argument,0,'M'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"print",required_argument,0,'P'},
-      {"prn",required_argument,0,'P'},
-      {"path",required_argument,0,'p'},
-      {"quench",no_argument,0,'q'},
-      {"quiet",no_argument,0,'Q'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"spinlock",no_argument,0,'S'}, /* [flg] Suspend with signal handler to facilitate debugging */
-      {"sng_fmt",required_argument,0,'s'},
-      {"string",required_argument,0,'s'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"units",no_argument,0,'u'},
-      {"var_val",no_argument,0,'V'}, /* [flg] Print variable values only */
-      {"variable",required_argument,0,'v'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {"get_grp_info",no_argument,0,0},
-      {"get_file_info",no_argument,0,0},
-      {"lbr_rcd",no_argument,0,0},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cdl",no_argument,0,0}, /* [flg] Print CDL */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"cmp",no_argument,0,0},
+    {"compiler",no_argument,0,0},
+    {"copyright",no_argument,0,0},
+    {"cpy",no_argument,0,0},
+    {"license",no_argument,0,0},
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdn",no_argument,0,0}, /* [flg] Print hidden attributes */
+    {"hidden",no_argument,0,0}, /* [flg] Print hidden attributes */
+    {"id",no_argument,0,0}, /* [flg] Print normally hidden information, like file, group, and variable IDs */
+    {"lbr",no_argument,0,0},
+    {"library",no_argument,0,0},
+    {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"md5_wrt_att",no_argument,0,0}, /* [flg] Write MD5 digests as attributes */
+    {"md5_write_attribute",no_argument,0,0}, /* [flg] Write MD5 digests as attributes */
+    {"mpi_implementation",no_argument,0,0},
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"no_blank",no_argument,0,0}, /* [flg] Print numeric missing values */
+    {"no-blank",no_argument,0,0}, /* [flg] Print numeric missing values */
+    {"noblank",no_argument,0,0}, /* [flg] Print numeric missing values */
+    {"no_clb",no_argument,0,0},
+    {"noclobber",no_argument,0,0},
+    {"no-clobber",no_argument,0,0},
+    {"no_clobber",no_argument,0,0},
+    {"no_dmn_var_nm",no_argument,0,0}, /* [flg] Omit variable and dimension names and indices but print all values */
+    {"no_nm_prn",no_argument,0,0}, /* [flg] Omit variable and dimension names and indices but print all values */
+    {"rad",no_argument,0,0}, /* [flg] Retain all dimensions */
+    {"retain_all_dimensions",no_argument,0,0}, /* [flg] Retain all dimensions */
+    {"orphan_dimensions",no_argument,0,0}, /* [flg] Retain all dimensions */
+    {"rph_dmn",no_argument,0,0}, /* [flg] Retain all dimensions */
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"secret",no_argument,0,0},
+    {"shh",no_argument,0,0},
+    {"srm",no_argument,0,0}, /* [flg] Print ncStream */
+    {"sysconf",no_argument,0,0}, /* [flg] Perform sysconf() test */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"intersection",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"nsx",no_argument,0,0}, /* [flg] Select intersection of specified groups and variables */
+    {"union",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"unn",no_argument,0,0}, /* [flg] Select union of specified groups and variables */
+    {"grp_xtr_var_xcl",no_argument,0,0}, /* [flg] Extract matching groups, exclude matching variables */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    {"jsn",no_argument,0,0}, /* [flg] Print JSON */
+    {"json",no_argument,0,0}, /* [flg] Print JSON */
+    {"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) */
+    {"ncml",no_argument,0,0}, /* [flg] Print XML (NcML) */
+    {"xml_no_location",no_argument,0,0}, /* [flg] Omit XML location tag */
+    {"ncml_no_location",no_argument,0,0}, /* [flg] Omit XML location tag */
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"fix_rec_dmn",required_argument,0,0}, /* [sng] Fix record dimension */
+    {"no_rec_dmn",required_argument,0,0}, /* [sng] Fix record dimension */
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    {"mk_rec_dmn",required_argument,0,0}, /* [sng] Name of record dimension in output */
+    {"mk_rec_dim",required_argument,0,0}, /* [sng] Name of record dimension in output */
+    {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"rgr",required_argument,0,0}, /* [sng] Regridding */
+    {"regridding",required_argument,0,0}, /* [sng] Regridding */
+    {"rgr_in",required_argument,0,0}, /* [sng] File containing fields to be regridded */
+    {"rgr_grd_src",required_argument,0,0}, /* [sng] File containing input grid */
+    {"rgr_grd_dst",required_argument,0,0}, /* [sng] File containing destination grid */
+    {"rgr_map",required_argument,0,0}, /* [sng] File containing mapping weights from source to destination grid */
+    {"map_file",required_argument,0,0}, /* [sng] File containing mapping weights from source to destination grid */
+    {"rgr_var",required_argument,0,0}, /* I [sng] Variable for special regridding treatment */
+    {"rgr_rnr",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
+    {"rnr",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
+    {"renormalize",required_argument,0,0}, /* [flg] Renormalize destination values by valid area */
+    {"scrip",required_argument,0,0}, /* SCRIP file */
+    {"tst_udunits",required_argument,0,0},
+    {"xml_spr_chr",required_argument,0,0}, /* [flg] Separator for XML character types */
+    {"xml_spr_nmr",required_argument,0,0}, /* [flg] Separator for XML numeric types */
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"pnetcdf",no_argument,0,'5'},
+    {"5",no_argument,0,'5'},
+    {"7",no_argument,0,'7'},
+    {"abc",no_argument,0,'a'},
+    {"alphabetize",no_argument,0,'a'},
+    {"append",no_argument,0,'A'},
+    {"apn",no_argument,0,'A'},
+    {"bnr",required_argument,0,'b'},
+    {"binary",required_argument,0,'b'},
+    {"binary-file",required_argument,0,'b'},
+    {"fl_bnr",required_argument,0,'b'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"data",required_argument,0,'H'},
+    {"debug",required_argument,0,'D'},
+    {"dbg_lvl",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"gpe",required_argument,0,'G'}, /* [sng] Group Path Edit (GPE) */
+    {"grp",required_argument,0,'g'},
+    {"group",required_argument,0,'g'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"hieronymus",no_argument,0,'H'}, /* fxm: need better mnemonic for -H */
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"lcl",required_argument,0,'l'},
+    {"local",required_argument,0,'l'},
+    {"metadata",no_argument,0,'m'},
+    {"mtd",no_argument,0,'m'},
+    {"Metadata",no_argument,0,'M'},
+    {"Mtd",no_argument,0,'M'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"print",required_argument,0,'P'},
+    {"prn",required_argument,0,'P'},
+    {"path",required_argument,0,'p'},
+    {"quench",no_argument,0,'q'},
+    {"quiet",no_argument,0,'Q'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"spinlock",no_argument,0,'S'}, /* [flg] Suspend with signal handler to facilitate debugging */
+    {"sng_fmt",required_argument,0,'s'},
+    {"string",required_argument,0,'s'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"units",no_argument,0,'u'},
+    {"var_val",no_argument,0,'V'}, /* [flg] Print variable values only */
+    {"variable",required_argument,0,'v'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {"get_grp_info",no_argument,0,0},
+    {"get_file_info",no_argument,0,0},
+    {"lbr_rcd",no_argument,0,0},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
-
+  
 #ifdef _LIBINTL_H
   setlocale(LC_ALL,""); /* LC_ALL sets all localization tokens to same value */
   bindtextdomain("nco","/home/zender/share/locale"); /* ${LOCALEDIR} is e.g., /usr/share/locale */
   /* MO files should be in ${LOCALEDIR}/es/LC_MESSAGES */
   textdomain("nco"); /* PACKAGE is name of program or library */
 #endif /* not _LIBINTL_H */
-
+  
   /* Start timer and save command line */ 
   ddra_info.tmr_flg=nco_tmr_srt;
   rcd+=nco_ddra((char *)NULL,(char *)NULL,&ddra_info);
@@ -471,8 +474,8 @@ main(int argc,char **argv)
   
   /* Get program name and set program enum (e.g., nco_prg_id=ncra) */
   nco_prg_nm=nco_prg_prs(argv[0],&nco_prg_id);
-
-/* MPI I/O: Either Parallel netCDF (PnetCDF) or HDF5-based
+  
+  /* MPI I/O: Either Parallel netCDF (PnetCDF) or HDF5-based
    export NETCDF_ROOT=/usr/local/parallel;export NETCDF_INC=/usr/local/parallel/include;export NETCDF_LIB=/usr/local/parallel/lib;export NETCDF4_ROOT=/usr/local/parallel;
    cd ~/nco/bld;make MPI=Y;cd -
    LD_LIBRARY_PATH=/usr/local/parallel/lib\:${LD_LIBRARY_PATH}
@@ -548,6 +551,10 @@ main(int argc,char **argv)
         rec_dmn_nm_fix=strdup(optarg);
       } /* endif fix_rec_dmn */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"get_grp_info") || !strcmp(opt_crr,"grp_info_get")) GET_GRP_INFO=True;
       if(!strcmp(opt_crr,"get_file_info")) GET_FILE_INFO=True;
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
@@ -605,9 +612,12 @@ main(int argc,char **argv)
         wgt_vld_thr=strtod(optarg,&sng_cnv_rcd);
         if(*sng_cnv_rcd) nco_sng_cnv_err(optarg,"strtod",sng_cnv_rcd);
       } /* endif rgr_rnr */
-      if(!strcmp(opt_crr,"rgr_var")) rgr_var=(char *)strdup(optarg);
+      if(!strcmp(opt_crr,"rgr_var")){
+        flg_rgr=True;
+	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)\nRegridding\t\t--rgr...\nSpinlock\t\t--spinlock\nStreams\t\t\t [...]
+        (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 [...]
         nco_exit(EXIT_SUCCESS);
       } /* endif "shh" */
       if(!strcmp(opt_crr,"srm")) PRN_SRM=True; /* [flg] Print ncStream */
@@ -957,20 +967,20 @@ main(int argc,char **argv)
       /* Initialize regridding structure */
       rgr_in=(char *)strdup(fl_in);
       rgr_out=(char *)strdup(fl_out);
-      rgr_nfo=nco_rgr_ini(in_id,rgr_arg,rgr_nbr,rgr_in,rgr_out,rgr_grd_src,rgr_grd_dst,rgr_map,rgr_var,wgt_vld_thr);
+      rgr_nfo=nco_rgr_ini(cmd_ln,in_id,rgr_arg,rgr_nbr,rgr_in,rgr_out,rgr_grd_src,rgr_grd_dst,rgr_map,rgr_var,wgt_vld_thr);
       rgr_nfo->fl_out_tmp=nco_fl_out_open(rgr_nfo->fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&bfr_sz_hnt,RAM_CREATE,RAM_OPEN,WRT_TMP_FL,&out_id);
 
       /* Copy Global Metadata */
       rgr_nfo->out_id=out_id;
-      //      out_id=rgr_nfo->out_id;
       nco_bool PCK_ATT_CPY=True; /* [flg] Copy attributes "scale_factor", "add_offset" */
       (void)nco_att_cpy(in_id,out_id,NC_GLOBAL,NC_GLOBAL,PCK_ATT_CPY);
       /* Catenate time-stamped command line to "history" global attribute */
       if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
+      if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
       if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
       if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
-      /* Regrid fields */
+      /* Regrid fields or generate grids */
       rcd=nco_rgr_ctl(rgr_nfo,trv_tbl);
       /* Change from NCO_NOERR to NC_NOERR */
       rcd=NC_NOERR;
@@ -1003,6 +1013,7 @@ main(int argc,char **argv)
       /* Catenate time-stamped command line to "history" global attribute */
       if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
       if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+      if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
       if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
 #ifdef ENABLE_MPI
       if(prc_rnk == rnk_mgr)
diff --git a/src/nco/nco.h b/src/nco/nco.h
index 7567db9..dd3bde5 100644
--- a/src/nco/nco.h
+++ b/src/nco/nco.h
@@ -296,17 +296,17 @@ extern "C" {
 # define NCO_VERSION_MINOR 5
 #endif /* !NCO_VERSION_MINOR */
 #ifndef NCO_VERSION_PATCH
-# define NCO_VERSION_PATCH 1
+# define NCO_VERSION_PATCH 2
 #endif /* !NCO_VERSION_PATCH */
 #ifndef NCO_VERSION_NOTE
-# define NCO_VERSION_NOTE  "" /* May be blank */
+# define NCO_VERSION_NOTE  "" /* Blank for final versions, non-blank (e.g., "beta37") for pre-release versions */
 #endif /* !NCO_VERSION_NOTE */
 #ifndef NCO_LIB_VERSION
   /* Define NC_LIB_VERSION as three-digit number for arithmetic comparisons by CPP */
 # 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.5.1"
+# define NCO_VERSION "4.5.2"
 #endif /* !NCO_VERSION */
 
 /* Compatibility tokens new to netCDF4 netcdf.h: */
@@ -881,6 +881,33 @@ extern "C" {
     nco_bool PRN_VAR_METADATA; /* [flg] Print variable metadata */
   } prn_fmt_sct;
   
+  /* Types used in regrid structure */
+  typedef enum nco_grd_2D_typ_enm{ /* [enm] Two-dimensional grid-type enum */
+    nco_grd_2D_nil=0,
+    nco_grd_2D_gss, /* Gaussian latitudes used by global spectral models: CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM */
+    nco_grd_2D_fv, /* FV scalar grid (lat[0]=-90): CAM FV, GEOS-CHEM, UCICTM, UKMO */
+    nco_grd_2D_eqa, /* Equi-angle offset grid, FV staggered velocity grid (lat[0]=-89.X)): CIESIN/SEDAC, IGBP-DIS, TOMS AAI */
+    nco_grd_2D_unk, /* Unknown or unclassified, POP displaced-pole */
+  } nco_grd_2D_typ_enm;
+
+  typedef enum nco_grd_lat_typ_enm{ /* [enm] Latitude grid-type enum */
+    nco_grd_lat_nil=0,
+    nco_grd_lat_unk, /* Unknown or unclassified latitude grid type (e.g., curvilinear) */ 
+    nco_grd_lat_gss, /* Gaussian latitude grid used by global spectral models: CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM */
+    nco_grd_lat_fv, /* FV latitude grid. Equi-angle (except at poles) latitude grid with odd number of latitudes so poles are considered at (and labeled as) centers of first and last gridcells (i.e., lat_ctr[0]=-90), and those polar gridcells span half the equi-angular latitude increment, aka FV scalar grid: CAM FV, GEOS-CHEM, UCICTM, UKMO */
+    nco_grd_lat_eqa, /* Equi-Angular latitude grid. Equi-angle (everywhere) latitude grid. Poles are at edges of first and last gridcells (i.e., lat_ctr[0]=-89.xxx). AKA FV-staggered velocity grid. Used by CIESIN/SEDAC, IGBP-DIS, TOMS AAI */
+  } nco_grd_lat_typ_enm;
+
+  typedef enum nco_grd_lon_typ_enm{ /* [enm] Longitude grid-type enum */
+    nco_grd_lon_nil=0,
+    nco_grd_lon_unk, /* Unknown or unclassified longitude grid type (e.g., curvilinear) */
+    nco_grd_lon_180_wst, /* Date line at west edge of first longitude cell */
+    nco_grd_lon_180_ctr, /* Date line at center of first longitude cell */
+    nco_grd_lon_Grn_wst, /* Greenwich at west edge of first longitude cell */
+    nco_grd_lon_Grn_ctr, /* Greenwich at center of first longitude cell */
+    nco_grd_lon_bb, /* Longitude grid determined by bounding box (lon_wst/lon_est) and gridcell number (lon_nbr) */
+  } nco_grd_lon_typ_enm;
+
   /* Regrid structure */
   typedef struct{ /* rgr_sct */
     // File names specifiable with individual command line switches
@@ -906,6 +933,20 @@ extern "C" {
     char *lon_nm; /* [sng] Name of dimension to recognize as longitude */
     char *lon_vrt_nm; /* [sng] Name of non-rectangular boundary variable for longitude */
     char *vrt_nm; /* [sng] Name of dimension to employ for vertices */
+    // User-specified grid properties
+    char *fl_grd; /* [sng] Name of grid file to create */
+    char *grd_ttl; /* [sng] Grid title */
+    double lat_sth; /* [dgr] Latitude of southern edge of grid */
+    double lon_wst; /* [dgr] Longitude of western edge of grid */
+    double lat_nrt; /* [dgr] Latitude of northern edge of grid */
+    double lon_est; /* [dgr] Longitude of eastern edge of grid */
+    long lat_nbr; /* [nbr] Number of latitudes in destination grid */
+    long lon_nbr; /* [nbr] Number of longitudes in destination grid */
+    nco_grd_2D_typ_enm grd_typ; /* [enm] Destination 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 */
+    // Other internal data and metadata 
+    char *cmd_ln; /* [sng] Command-line */
     double wgt_vld_thr; /* [frc] Weight threshold for valid destination value */
     int in_id; /* [id] Input netCDF file ID */
     int out_id; /* [id] Output netCDF file ID */
@@ -913,6 +954,7 @@ extern "C" {
     nco_bool flg_usr_rqs; /* [flg] User requested regridding */
     nco_bool flg_grd_src; /* [flg] User-specified input grid */
     nco_bool flg_grd_dst; /* [flg] User-specified destination grid */
+    nco_bool flg_grd; /* [flg] Create SCRIP-format grid file */
     nco_bool flg_map; /* [flg] User-specified mapping weights */
     nco_bool flg_rnr; /* [flg] Renormalize destination values by valid area */
   } rgr_sct;
@@ -1217,6 +1259,8 @@ extern "C" {
     char *nm; /* [sng] Variable name */
     char *nm_fll; /* [sng] Absolute variable name (needed for GTT search for object by full name) */
     char fmt[5]; /* [sng] Hint for printf()-style formatting */
+    double *wgt_sum; /* [frc] Running sum of per-file weights (ncra/ncea only) */
+    double wgt_crr; /* [frc] Weight of current record (ncra/ncea only) */
     dmn_sct **dim; /* [sct] Pointers to full dimension structures */
     int *dmn_id; /* [id] Contiguous vector of dimension IDs */
     int cid; /* [id] Dimension ID of associated coordinate, if any */
diff --git a/src/nco/nco_att_utl.c b/src/nco/nco_att_utl.c
index acec6c1..b87034d 100644
--- a/src/nco/nco_att_utl.c
+++ b/src/nco/nco_att_utl.c
@@ -1927,6 +1927,68 @@ nco_vrs_att_cat /* [fnc] Add NCO version global attribute */
 } /* end nco_vrs_att_cat() */
 
 void 
+nco_glb_att_add /* [fnc] Add global attributes */
+(const int out_id, /* I [id] netCDF output-file ID */
+ char **gaa_arg,  /* [sng] Global attribute arguments */
+ const int gaa_arg_nbr)  /* [nbr] Number of global attribute arguments */
+{
+  /* Purpose: Decode arguments into attributes and add as global metadata to output file */
+  aed_sct gaa_aed;
+  int gaa_idx;
+  int gaa_arg_idx;
+  int gaa_nbr=0;
+  kvm_sct *gaa_lst=NULL; /* [sct] List of all GAA specifications */
+  kvm_sct kvm;
+  ptr_unn att_val;
+
+  gaa_lst=(kvm_sct *)nco_malloc(NC_MAX_VARS*sizeof(kvm_sct));
+
+  /* Parse GAAs */
+  for(gaa_arg_idx=0;gaa_arg_idx<gaa_arg_nbr;gaa_arg_idx++){
+    if(!strstr(gaa_arg[gaa_arg_idx],"=")){
+      (void)fprintf(stdout,"%s: Invalid --gaa specification: %s. Must contain \"=\" sign, e.g., \"key=value\".\n",nco_prg_nm_get(),gaa_arg[gaa_arg_idx]);
+      if(gaa_lst) gaa_lst=(kvm_sct *)nco_free(gaa_lst);
+      nco_exit(EXIT_FAILURE);
+    } /* endif */
+    kvm=nco_sng2kvm(gaa_arg[gaa_arg_idx]);
+    /* nco_sng2kvm() converts argument "--gaa one,two=3" into kvm.key="one,two" and kvm.val=3
+       Then nco_lst_prs_2D() converts kvm.key into two items, "one" and "two", with the same value, 3 */
+    if(kvm.key){
+      int att_idx; /* [idx] Index over attribute names in current GAA argument */
+      int att_nbr; /* [nbr] Number of attribute names in current GAA argument */
+      char **att_lst;
+      att_lst=nco_lst_prs_2D(kvm.key,",",&att_nbr);
+      for(att_idx=0;att_idx<att_nbr;att_idx++){ /* Expand multi-attribute-name specification */
+        gaa_lst[gaa_nbr].key=strdup(att_lst[att_idx]);
+	gaa_lst[gaa_nbr].val=strdup(kvm.val);
+        gaa_nbr++;
+      } /* end for */
+      att_lst=nco_sng_lst_free(att_lst,att_nbr);
+    } /* end if */
+  } /* end for */
+
+  for(gaa_idx=0;gaa_idx<gaa_nbr;gaa_idx++){
+    /* Insert attribute value */
+    att_val.cp=gaa_lst[gaa_idx].val;
+    /* Initialize attribute edit structure */
+    gaa_aed.att_nm=gaa_lst[gaa_idx].key;
+    gaa_aed.var_nm=NULL;
+    gaa_aed.id=NC_GLOBAL;
+    gaa_aed.type=NC_CHAR;
+    /* Insert value into attribute structure */
+    gaa_aed.val=att_val;
+    gaa_aed.sz=strlen(gaa_aed.val.cp);
+    gaa_aed.mode=aed_overwrite;
+    /* Write attribute to disk */
+    (void)nco_aed_prc(out_id,NC_GLOBAL,gaa_aed);
+  } /* !gaa_idx */
+  
+  /* Free kvms */
+  if(gaa_lst) gaa_lst=nco_kvm_lst_free(gaa_lst,gaa_nbr);
+
+} /* end nco_glb_att_add() */
+ 
+void 
 nco_thr_att_cat /* [fnc] Add threading global attribute */
 (const int out_id, /* I [id] netCDF output-file ID */
  const int thr_nbr) /* I [nbr] Thread number */
diff --git a/src/nco/nco_att_utl.h b/src/nco/nco_att_utl.h
index b2c148c..b6481cf 100644
--- a/src/nco/nco_att_utl.h
+++ b/src/nco/nco_att_utl.h
@@ -159,6 +159,12 @@ nco_prs_rnm_lst /* [fnc] Set old_nm, new_nm elements of rename structure */
  char * const * const rnm_arg); /* I [sng] Unstructured list of old, new names */
 
 void 
+nco_glb_att_add /* [fnc] Add global attributes */
+(const int out_id, /* I [id] netCDF output-file ID */
+ char **gaa_arg,  /* [sng] Global attribute arguments */
+ const int gaa_arg_nbr);  /* [nbr] Number of global attribute arguments */
+
+void 
 nco_thr_att_cat /* [fnc] Add threading global attribute */
 (const int out_id, /* I [id] netCDF output-file ID */
  const int thr_nbr); /* I [nbr] Thread number */
diff --git a/src/nco/nco_cnf_typ.c b/src/nco/nco_cnf_typ.c
index a87e25a..71d31a7 100644
--- a/src/nco/nco_cnf_typ.c
+++ b/src/nco/nco_cnf_typ.c
@@ -127,7 +127,7 @@ nco_typ_cnv_rth /* [fnc] Convert char, short, long, int, and float types to doub
   /* 20130906:
      Users have long been uncomfortable with not implicitly converting floats to doubles
      A new section of the manual that describes the advantages and disadvantages:
-     http://nco.sf.net/nco.html#fxm
+     http://nco.sf.net/nco.html#dbl
      Implementing --dbl switch on ncwa, ncra, nces (ncap2?) to force implicit conversion */
   if(nco_rth_cnv_get() == nco_rth_flt_flt){
 
diff --git a/src/nco/nco_cnv_csm.c b/src/nco/nco_cnv_csm.c
index b83872d..c6296a7 100644
--- a/src/nco/nco_cnv_csm.c
+++ b/src/nco/nco_cnv_csm.c
@@ -55,7 +55,7 @@ nco_cnv_ccm_ccsm_cf_inq /* O [fnc] Check if file obeys CCM/CCSM/CF conventions *
       (void)fprintf(stderr,"%s: CONVENTION File \"%s\" attribute is \"%s\"\n",nco_prg_nm_get(),cnv_sng,att_val);
       if(cnv_sng == cnv_sng_LC) (void)fprintf(stderr,"%s: WARNING: This file uses a non-standard attribute (\"%s\") to indicate the netCDF convention. The correct attribute is \"%s\".\n",nco_prg_nm_get(),cnv_sng_LC,cnv_sng_UC);
       /* Only warn in arithmetic operators where conventions change behavior */
-      if(nco_dbg_lvl_get() >= nco_dbg_fl && nco_dbg_lvl_get() != nco_dbg_dev && nco_is_rth_opr(nco_prg_id_get())) (void)fprintf(stderr,"%s: INFO NCO attempts to abide by many official and unoffical metadata conventions including ARM, CCM, CCSM, and CF. To adhere to these conventions, NCO implements variable-specific exceptions in certain operators, e.g., ncbo will not subtract variables named \"date\" or \"gw\", and many operators will always leave coordinate variables unchanged. The ful [...]
+      if(nco_dbg_lvl_get() >= nco_dbg_fl && nco_dbg_lvl_get() != nco_dbg_dev && nco_is_rth_opr(nco_prg_id_get())) (void)fprintf(stderr,"%s: INFO NCO attempts to abide by many official and unofficial metadata conventions including ARM, CCM, CCSM, and CF. To adhere to these conventions, NCO implements variable-specific exceptions in certain operators, e.g., ncbo will not subtract variables named \"date\" or \"gw\", and many operators will always leave coordinate variables unchanged. The fu [...]
     } /* endif dbg */
     att_val=(char *)nco_free(att_val);
   } /* endif */
diff --git a/src/nco/nco_ctl.c b/src/nco/nco_ctl.c
index 23f1a59..733a32a 100644
--- a/src/nco/nco_ctl.c
+++ b/src/nco/nco_ctl.c
@@ -843,7 +843,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 "D/F#\n";
+  return "Parenthood\n";
 } /* end nco_nmn_get() */
 
 char * /* O [sng] nm_in stripped of any path (i.e., program name stub) */ 
@@ -954,41 +954,41 @@ nco_usg_prn(void)
 
   switch(prg_lcl){
   case ncap:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-F] [-f] [--fl_fmt fmt] [-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] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-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 sz] [-D nco_dbg_lvl] [-h] [--hdr_pad nbr] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] in.nc [[out.nc]]\n");
+    opt_sng=(char *)strdup("[-a ...] [--bfr sz] [-D nco_dbg_lvl] [--glb ...] [-h] [--hdr_pad nbr] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] in.nc [[out.nc]]\n");
     break;
   case ncbo:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--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 in_2.nc [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_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 in_2.nc [out.nc]\n");
     break;
   case ncflint:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fix_rec_crd] [--fl_fmt fmt] [-h] [--hdf] [--hdr_pad nbr] [-i var,val] [-L lvl] [-l path] [--msa] [--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]] in_1.nc in_2.nc [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_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]] in_1.nc in_2.nc [out.nc]\n");
     break;
   case ncks:
-    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [-a] [-b fl_bnr] [--bfr sz] [-C] [-c] [--cdl] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fix_rec_dmn dim] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--grp_xtr_var_xcl] [-H] [-h] [--hdn] [--hdr_pad nbr] [-L lvl] [-l path] [-M] [-m] [--map map.nc] [--md5_dgs] [--md5_wrt] [--mk_rec_dmn dim] [--msa] [--no_blank] [--no_tmp_fl] [-O] [-o out.nc] [-P] [-p pa [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-5] [-6] [-7] [-A] [-a] [-b fl_bnr] [--bfr sz] [-C] [-c] [--cdl] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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] [-L lvl] [-l path] [-M] [-m] [--map map.nc] [--md5_dgs] [--md5_wrt] [--mk_rec_dmn dim] [--msa] [--no_blank] [--no_tmp_fl] [-O] [-o out.nc] [...]
     break;
   case ncpdq:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [-a ...] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [-M pck_map] [--mrd] [--msa] [--no_tmp_fl] [-O] [-o out.nc] [-P pck_plc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-U] [-v ...] [-X box] [-x] in.nc [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [-a ...] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_tmp_fl] [-O] [-o out.nc] [-P pck_plc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-U] [-v ...] [-X box] [-x] in.nc [out.nc]\n");
     break;
   case ncra:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--mro] [--msa] [-n ...] [--no_cll_mth] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-w wgt] [-v ...] [-X box] [-x] [-y op_t [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_mth] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-w wgt] [-v ...] [-X b [...]
     break;
   case ncfe:
   case ncge:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-H] [-h] [--hdf] [--hdr_pad nbr] [-L lvl] [-l path] [--msa] [-n ...] [--no_tmp_fl] [--nsm_fl] [--nsm_grp] [--nsm_sfx] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] [-y op_typ] in.nc [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_tmp_fl] [--nsm_fl] [--nsm_grp] [--nsm_sfx] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] [-y o [...]
     break;
   case ncrcat:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [--md5_digest] [--msa] [-n ...] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] in.nc [...] [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [--rec_apn] [-t thr_nbr] [--unn] [-v ...] [-X box] [-x] in.nc [...] [out.nc]\n");
     break;
   case ncecat:
-    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [--gag] [-H] [-h] [--hdr_pad nbr] [-L lvl] [-l path] [-M] [--md5_digest] [--mrd] [--msa] [-n ...] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-u ulm_nm] [--unn] [-v ...] [-X box] [-x] in.nc [...] [out.nc]\n");
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-t thr_nbr] [-u ulm_nm] [--unn] [-v ...] [-X box] [-x] in.nc [...] [ [...]
     break;
   case ncrename:
-    opt_sng=(char *)strdup("[-a ...] [--bfr sz] [-D nco_dbg_lvl] [-d ...] [-g ...] [-h] [--hdr_pad nbr] [-l path] [-O] [-o out.nc] [-p path] [-R] [-r] [-v ...] in.nc [[out.nc]]\n");
+    opt_sng=(char *)strdup("[-a ...] [--bfr sz] [-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 sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--cnk_plc plc] [--cnk_scl sz] [-D nco_dbg_lvl] [-d ...]  [--dbl|flt] [-F] [--fl_fmt fmt] [-G grp:lvl] [-g ...] [-h] [--hdf] [--hdr_pad nbr] [-I] [-L lvl] [-l path] [-m mask] [-M mask_val] [-N] [--no_cll_mth] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-T mask_comp] [-t thr_nbr] [--unn] [-v  [...]
+    opt_sng=(char *)strdup("[-3] [-4] [-6] [-7] [-A] [-a ...] [-B mask_cond] [-b] [--bfr sz] [-C] [-c] [--cnk_byt sz] [--cnk_dmn nm,sz] [--cnk_map map] [--cnk_min min] [--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_mth] [--no_tmp_fl] [-O] [-o out.nc] [-p path] [--ppc ...] [-R] [-r] [--ram_all] [-T mask_comp] [-t thr_nbr] [ [...]
     break;
   default: nco_dfl_case_prg_id_err(); break;
   } /* end switch */
@@ -1054,6 +1054,7 @@ nco_usg_prn(void)
     if(prg_lcl == ncrename) (void)fprintf(stdout,"-g, --grp --group\told_grp,new_grp Group's old and new names\n");
     if(prg_lcl != ncrename) (void)fprintf(stdout,"-g, --grp grp1[,grp2[...]] Group(s) to process (regular expressions supported)\n");
   } /* end if */
+  if(strstr(opt_sng,"--glb")) (void)fprintf(stdout,"    --glb_att_add nm=val\tGlobal attribute to add\n");
   if(strstr(opt_sng,"--gxvx, --grp_xtr_var_xcl")) (void)fprintf(stdout,"    --gxvx, --grp_xtr_var_xcl\tGroup Extraction Variable Exclusion\n");
 #endif /* !ENABLE_NETCDF4 */
   if(strstr(opt_sng,"[-H]")){
@@ -1071,7 +1072,7 @@ nco_usg_prn(void)
 #endif /* !ENABLE_NETCDF4 */
   if(strstr(opt_sng,"[-l")) (void)fprintf(stdout,"-l, --lcl, --local path\tLocal storage path for remotely-retrieved files\n");
   if(strstr(opt_sng,"[-M")){
-    if(prg_lcl == ncecat) (void)fprintf(stdout,"-M, --glb_mtd_spp\tDo not copy global metadata\n");
+    if(prg_lcl == ncecat) (void)fprintf(stdout,"-M, --no_glb_mtd\tSuppress (do not copy) global metadata\n");
     if(prg_lcl == ncks) (void)fprintf(stdout,"-M, --Mtd, --Metadata\tToggle printing global metadata\n");
     if(prg_lcl == ncpdq) (void)fprintf(stdout,"-M, --pck_map, --pack_map, --map pck_map\tPack map [flt_sht,flt_byt,hgh_sht,hgh_byt,nxt_lsr]\n");
     if(prg_lcl == ncwa) (void)fprintf(stdout,"-M, --msk_val, --mask-value, --mask_value mask_val\tMasking value (default is 1.0)\n");
@@ -1085,11 +1086,14 @@ nco_usg_prn(void)
   if(strstr(opt_sng,"--md5_wrt_att")) (void)fprintf(stdout,"   --md5_wrt, --md5_write\tWrite MD5 digests as attributes\n");
   if(strstr(opt_sng,"--mk_rec_dmn")) (void)fprintf(stdout,"    --mk_rec_dmn dim\tDefine dim as record dimension in output file\n");
   if(strstr(opt_sng,"--mro")) (void)fprintf(stdout,"    --mro\t\tMulti-Record Output\n");
-  if(strstr(opt_sng,"[-N]")) (void)fprintf(stdout,"-N, --nmr, --numerator\tNo normalization\n");
+  if(strstr(opt_sng,"[-N]")){
+    if(prg_lcl == ncwa) (void)fprintf(stdout,"-N, --nmr, --numerator\tNo normalization\n");
+    if(prg_lcl == ncra || prg_lcl == ncfe || prg_lcl == ncge) (void)fprintf(stdout,"-N, --no_nrm_by_wgt\tNo normalization by weights\n");
+  } /* !-N */
   if(strstr(opt_sng,"[-n ...]")){
     /*    if(prg_lcl == ncwa) (void)fprintf(stdout,"-n\t\tNormalize by tally but not weight\n");*/
     if(prg_lcl != ncwa) (void)fprintf(stdout,"-n, --nintap nbr_files,[nbr_numeric_chars[,increment]] NINTAP-style abbreviation of file list\n");
-  } /* end if -n */
+  } /* !-n */
   if(strstr(opt_sng,"--no_blank")) (void)fprintf(stdout,"    --no_blank\t\tPrint numeric missing values instead of blanks (underscores)\n");
   if(strstr(opt_sng,"--no_cll_mth")) (void)fprintf(stdout,"    --no_cll_mth\tDo not add/modify cell_methods attributes\n");
   if(strstr(opt_sng,"--no_tmp_fl")) (void)fprintf(stdout,"    --no_tmp_fl\t\tDo not write output to temporary file\n");
diff --git a/src/nco/nco_fl_utl.c b/src/nco/nco_fl_utl.c
index 4dee582..d06aa88 100644
--- a/src/nco/nco_fl_utl.c
+++ b/src/nco/nco_fl_utl.c
@@ -689,7 +689,7 @@ nco_fl_mk_lcl /* [fnc] Retrieve input file and return local filename */
 
   /* Does file exist on local system? */
   if(!DAP_URL) rcd_stt=stat(fl_nm_lcl,&stat_sct);
-  if(rcd_stt == -1 && (nco_dbg_lvl_get() >= nco_dbg_fl)) (void)fprintf(stderr,"%s: INFO stat() #1 failed: %s does not exist\n",nco_prg_nm_get(),fl_nm_lcl);
+  if(rcd_stt == -1 && (nco_dbg_lvl_get() >= nco_dbg_fl)) (void)fprintf(stderr,"\n%s: INFO stat() #1 failed: %s does not exist\n",nco_prg_nm_get(),fl_nm_lcl);
 
   /* If not, check if file exists on local system under same path interpreted relative to current working directory */
   if(rcd_stt == -1){
@@ -1217,8 +1217,11 @@ nco_fl_nm_prs /* [fnc] Construct file name from input arguments */
   static int fl_nm_nbr_max;
   static int fl_nm_nbr_min;
   static int fl_nm_nbr_ttl;
+  static int mm_crr;
+  static int yyyy_crr;
 
   static nco_bool FIRST_INVOCATION=True;
+  static nco_bool flg_yyyymm=False;
 
   /* Free any old filename space */
   fl_nm=(char *)nco_free(fl_nm);
@@ -1263,14 +1266,22 @@ nco_fl_nm_prs /* [fnc] Construct file name from input arguments */
 	fl_nm_nbr_min=1;
       } /* end if */
 
-      /* Is there a .nc, .cdf, .hdf, or .hd5 suffix? */
-      if(strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-3,".nc",3) == 0)
+      if(abb_arg_nbr > 5){
+	if(!strcmp(fl_lst_abb[5],"yyyymm")) flg_yyyymm=True;
+      } /* end if */
+
+      /* Is there a .nc, .h5, .cdf, .hdf, .hd5, or .he5 suffix? */
+      if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-3,".nc",3))
 	fl_nm_sfx_lng=3;
-      else if(strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".cdf",4) == 0)
+      if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-3,".h5",3))
+	fl_nm_sfx_lng=3;
+      else if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".cdf",4))
+	fl_nm_sfx_lng=4;
+      else if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".hdf",4))
 	fl_nm_sfx_lng=4;
-      else if(strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".hdf",4) == 0)
+      else if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".hd5",4))
 	fl_nm_sfx_lng=4;
-      else if(strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".hd5",4) == 0)
+      else if(!strncmp(fl_lst_in[0]+strlen(fl_lst_in[0])-4,".he5",4))
 	fl_nm_sfx_lng=4;
 
       /* Initialize static information useful for future invocations */
@@ -1280,7 +1291,15 @@ nco_fl_nm_prs /* [fnc] Construct file name from input arguments */
       fl_nm_nbr_sng[fl_nm_nbr_dgt]='\0';
       fl_nm_nbr_crr=(int)strtol(fl_nm_nbr_sng,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
       if(*sng_cnv_rcd) nco_sng_cnv_err(fl_nm_nbr_sng,"strtol",sng_cnv_rcd);
-      (void)sprintf(fl_nm_nbr_sng_fmt,"%%0%dd",fl_nm_nbr_dgt);
+
+      if(flg_yyyymm){
+	yyyy_crr=fl_nm_nbr_crr/100;
+	mm_crr=fl_nm_nbr_crr%12;
+	mm_crr=fl_nm_nbr_crr-yyyy_crr*100;
+	(void)sprintf(fl_nm_nbr_sng_fmt,"%%0%dd%%02d",fl_nm_nbr_dgt-2);
+      }else{
+	(void)sprintf(fl_nm_nbr_sng_fmt,"%%0%dd",fl_nm_nbr_dgt);
+      } /* !flg_yyyymm */
 
       /* First filename is always specified on command line anyway... */
       fl_nm=(char *)strdup(fl_lst_in[0]);
@@ -1291,10 +1310,23 @@ nco_fl_nm_prs /* [fnc] Construct file name from input arguments */
     }else{ /* end if FIRST_INVOCATION */
       /* Create current filename from previous filename */
       fl_nm_nbr_crr+=fl_nm_nbr_ncr;
-      if(fl_nm_nbr_max)
-	if(fl_nm_nbr_crr > fl_nm_nbr_max)
-	  fl_nm_nbr_crr=fl_nm_nbr_min;
-      (void)sprintf(fl_nm_nbr_sng,fl_nm_nbr_sng_fmt,fl_nm_nbr_crr);
+      if(fl_nm_nbr_max){
+	if(flg_yyyymm){
+	  /* String contains dates (months) in YYYYMM format so increment left-most four digits (year) by one when  
+	     right-most two digits exceed fl_nm_nbr_max */
+	  mm_crr+=fl_nm_nbr_ncr;
+	  if(mm_crr > fl_nm_nbr_max){
+	    mm_crr=fl_nm_nbr_min;
+	    yyyy_crr++;
+	  } /* !mm_crr */
+	  (void)sprintf(fl_nm_nbr_sng,fl_nm_nbr_sng_fmt,yyyy_crr,mm_crr);
+	}else{
+	  if(fl_nm_nbr_crr > fl_nm_nbr_max) fl_nm_nbr_crr=fl_nm_nbr_min;
+	  (void)sprintf(fl_nm_nbr_sng,fl_nm_nbr_sng_fmt,fl_nm_nbr_crr);
+	} /* !flg_yyyymm */
+      }else{ /* !fl_nm_nbr_max */
+	(void)sprintf(fl_nm_nbr_sng,fl_nm_nbr_sng_fmt,fl_nm_nbr_crr);
+      } /* !fl_nm_nbr_max */
       fl_nm=(char *)strdup(fl_lst_in[0]);
       (void)strncpy(fl_nm+(fl_nm_1st_dgt-fl_lst_in[0]),fl_nm_nbr_sng,(size_t)fl_nm_nbr_dgt);
       if(fl_idx == fl_nm_nbr_ttl-1) fl_nm_nbr_sng=(char *)nco_free(fl_nm_nbr_sng);
diff --git a/src/nco/nco_grp_utl.c b/src/nco/nco_grp_utl.c
index d905a30..5d93bfd 100644
--- a/src/nco/nco_grp_utl.c
+++ b/src/nco/nco_grp_utl.c
@@ -7082,7 +7082,7 @@ nco_var_get_wgt_trv                 /* [fnc] Retrieve weighting or mask variable
     wgt_trv=trv_tbl_var_nm_fll(wgt_nm,trv_tbl);
     (void)nco_inq_grp_full_ncid(nc_id,wgt_trv->grp_nm_fll,&grp_id);
     (void)nco_inq_varid(grp_id,wgt_trv->nm,&var_id);
-    /* Transfer from table to local variable  */
+    /* Transfer from table to local variable */
     wgt_var=nco_var_fll_trv(grp_id,var_id,wgt_trv,trv_tbl);
     /* Retrieve variable NB: use GTT version, that "knows" all limits */
     (void)nco_msa_var_get_trv(nc_id,wgt_var,trv_tbl);
@@ -7091,7 +7091,8 @@ nco_var_get_wgt_trv                 /* [fnc] Retrieve weighting or mask variable
     /* Relative name given for weight. Must identify most-in-scope match... */
     int wgt_nbr=0; /* [nbr] Number of weight/mask variables in file */
     trv_sct **wgt_trv=NULL; /* [sct] Weight/mask list */
-    
+
+    /* Count matching weight names in order to allocate space */
     for(unsigned tbl_idx=0;tbl_idx<trv_tbl->nbr;tbl_idx++)
       if(trv_tbl->lst[tbl_idx].nco_typ == nco_obj_typ_var && (!strcmp(trv_tbl->lst[tbl_idx].nm,wgt_nm))) wgt_nbr++;
 
@@ -7099,8 +7100,8 @@ nco_var_get_wgt_trv                 /* [fnc] Retrieve weighting or mask variable
     wgt_trv=(trv_sct **)nco_malloc(wgt_nbr*sizeof(trv_sct *));
     idx_wgt=0;
 
+    /* Creat list of potential weight structures */
     for(unsigned tbl_idx=0;tbl_idx<trv_tbl->nbr;tbl_idx++){
-      /* Filter by name */
       if(trv_tbl->lst[tbl_idx].nco_typ == nco_obj_typ_var && !strcmp(trv_tbl->lst[tbl_idx].nm,wgt_nm)){
         wgt_trv[idx_wgt]=&trv_tbl->lst[tbl_idx]; 
         idx_wgt++;
@@ -7114,7 +7115,8 @@ nco_var_get_wgt_trv                 /* [fnc] Retrieve weighting or mask variable
 	 !strcmp(trv_tbl->lst[idx_var].nm_fll,var->nm_fll)){
 	trv_sct var_trv=trv_tbl->lst[idx_var];  
 
-	/* 20150711: This is buggy, at best it returns the last weight found, not the closest-in-scope */
+	/* 20150711: This is buggy, at best it returns last weight found, not closest-in-scope */
+	/* Which weight is closest-in-scope to variable? */
 	for(idx_wgt=0;idx_wgt<wgt_nbr;idx_wgt++){
 	  if(!strcmp(wgt_trv[idx_wgt]->grp_nm_fll,var_trv.grp_nm_fll)){
 	    (void)nco_inq_grp_full_ncid(nc_id,wgt_trv[idx_wgt]->grp_nm_fll,&grp_id);
diff --git a/src/nco/nco_mmr.c b/src/nco/nco_mmr.c
index ab30b64..cb8427c 100644
--- a/src/nco/nco_mmr.c
+++ b/src/nco/nco_mmr.c
@@ -18,10 +18,8 @@
    nco_malloc_flg() prints warning for ENOMEM errors, then returns control to calling routine
    nco_malloc_flg() plug-in replacements are malloc() and nco_malloc() 
    
-   nco_malloc_dbg(): Use this for large memory requests when calling routine supplies
-   its name and useful supplemental error message
-   nco_malloc_dbg() prints name of calling function, supplemental error message, and then 
-   dies and exits for all error conditions.
+   nco_malloc_dbg(): Use this for large memory requests when calling routine supplies its name and useful supplemental error message
+   nco_malloc_dbg() prints name of calling function, supplemental error message, and then dies and exits for all error conditions.
    nco_malloc_dbg() has no plug-in replacements (since it requires two extra arguments)
    
    None of these routines call malloc() when sz == 0 */
diff --git a/src/nco/nco_rgr.c b/src/nco/nco_rgr.c
index fcda70e..0dae45b 100644
--- a/src/nco/nco_rgr.c
+++ b/src/nco/nco_rgr.c
@@ -18,12 +18,14 @@ nco_rgr_ctl /* [fnc] Control regridding logic */
   int rcd=NCO_NOERR;
   const char fnc_nm[]="nco_rgr_ctl()";
 
-  nco_bool flg_map=False; /* [flg] Weight-based regridding */
+  nco_bool flg_grd=False; /* [flg] Create SCRIP-format grid file */
+  nco_bool flg_map=False; /* [flg] Regrid with external weights */
   nco_bool flg_smf=False; /* [flg] ESMF regridding */
   nco_bool flg_tps=False; /* [flg] Tempest regridding */
 
   /* Main control branching occurs here
      Branching complexity and utility will increase as regridding features are added */
+  if(rgr->flg_grd) flg_grd=True;
   if(rgr->flg_map) flg_map=True;
   if(rgr->flg_grd_src && rgr->flg_grd_dst) flg_smf=True;
   if(rgr->drc_tps && !flg_map) flg_tps=True;
@@ -31,14 +33,15 @@ nco_rgr_ctl /* [fnc] Control regridding logic */
   assert(!(flg_smf && flg_tps));
   assert(!(flg_map && flg_tps));
   
-  if(flg_map){
-    /* Regrid using external mapping weights */
-    rcd=nco_rgr_map(rgr,trv_tbl);
-  } /* !flg_map */
+  /* Create SCRIP-format grid file */
+  if(flg_grd) rcd=nco_grd_mk(rgr);
 
+  /* Regrid using external mapping weights */
+  if(flg_map) rcd=nco_rgr_map(rgr,trv_tbl);
+
+  /* Regrid using ESMF library */
   if(flg_smf){
 #ifdef ENABLE_ESMF
-    /* Regrid using ESMF library */
     (void)fprintf(stderr,"%s: %s calling nco_rgr_esmf() to generate and apply regridding map\n",nco_prg_nm_get(),fnc_nm);
     rcd=nco_rgr_esmf(rgr);
     /* Close output and free dynamic memory */
@@ -49,10 +52,8 @@ nco_rgr_ctl /* [fnc] Control regridding logic */
 #endif /* !ENABLE_ESMF */
 } /* !flg_smf */
   
-  if(flg_tps){
-    /* Regrid using Tempest regridding */
-    rcd=nco_rgr_tps(rgr);
-  } /* !flg_map */
+  /* Regrid using Tempest regridding */
+  if(flg_tps) rcd=nco_rgr_tps(rgr);
 
   return rcd;
 } /* end nco_rgr_ctl() */
@@ -62,6 +63,10 @@ nco_rgr_free /* [fnc] Deallocate regridding structure */
 (rgr_sct *rgr) /* I/O [sct] Regridding structure */
 {
   /* Purpose: Free all dynamic memory in regridding structure */
+
+  /* free() standalone command-line arguments */
+  if(rgr->cmd_ln) rgr->cmd_ln=(char *)nco_free(rgr->cmd_ln);
+  if(rgr->grd_ttl) rgr->grd_ttl=(char *)nco_free(rgr->grd_ttl);
   if(rgr->fl_grd_src) rgr->fl_grd_src=(char *)nco_free(rgr->fl_grd_src);
   if(rgr->fl_grd_dst) rgr->fl_grd_dst=(char *)nco_free(rgr->fl_grd_dst);
   if(rgr->fl_in) rgr->fl_in=(char *)nco_free(rgr->fl_in);
@@ -70,6 +75,9 @@ nco_rgr_free /* [fnc] Deallocate regridding structure */
   if(rgr->fl_map) rgr->fl_map=(char *)nco_free(rgr->fl_map);
   if(rgr->var_nm) rgr->var_nm=(char *)nco_free(rgr->var_nm);
 
+  /* free() strings associated with grid properties */
+  if(rgr->fl_grd) rgr->fl_grd=(char *)nco_free(rgr->fl_grd);
+
   /* Tempest */
   if(rgr->drc_tps) rgr->drc_tps=(char *)nco_free(rgr->drc_tps);
 
@@ -98,7 +106,8 @@ nco_rgr_free /* [fnc] Deallocate regridding structure */
   
 rgr_sct * /* O [sct] Regridding structure */
 nco_rgr_ini /* [fnc] Initialize regridding structure */
-(const int in_id, /* I [id] Input netCDF file ID */
+(const char * const cmd_ln, /* I [sng] Command-line */
+ const int in_id, /* I [id] Input netCDF file ID */
  char **rgr_arg, /* [sng] Regridding arguments */
  const int rgr_arg_nbr, /* [nbr] Number of regridding arguments */
  char * const rgr_in, /* I [sng] File containing fields to be regridded */
@@ -111,21 +120,6 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
 {
   /* Purpose: Initialize regridding structure */
      
-  /* Sample calls:
-     Debugging:
-     ncks -O -D 6 --rgr=Y ${DATA}/rgr/dstmch90_clm.nc ~/foo.nc
-
-     T62->T42 from scratch, minimal arguments:
-     ncks -O -D 6 --rgr=Y ${DATA}/rgr/dstmch90_clm.nc ~/foo.nc
-     T62->T42 from scratch, more arguments:
-     ncks -O -D 6 --rgr=Y --rgr_grd_dst=${DATA}/scrip/grids/remap_grid_T42.nc ${DATA}/rgr/dstmch90_clm.nc ~/foo.nc
-     T62->T42 from scratch, explicit arguments:
-     ncks -O --rgr=Y --rgr_grd_dst=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_out=${DATA}/rgr/rgr_out.nc ${DATA}/rgr/dstmch90_clm.nc ~/foo.nc
-     T42->T42 from scratch:
-     ncks -O --rgr=Y --rgr_grd_src=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_grd_dst=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_out=${DATA}/rgr/rgr_out.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc
-     T42->POP43 from existing weights:
-     ncks -O --map=${DATA}/scrip/rmp_T42_to_POP43_conserv.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc */
-
   const char fnc_nm[]="nco_rgr_ini()";
   
   rgr_sct *rgr;
@@ -133,7 +127,9 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
   /* Allocate */
   rgr=(rgr_sct *)nco_malloc(sizeof(rgr_sct));
   
-  /* Initialize */
+  /* Initialize variable directly or indirectly set via command-line (except for key-value arguments) */
+  rgr->cmd_ln=strdup(cmd_ln); /* [sng] Command-line */
+
   rgr->flg_usr_rqs=False; /* [flg] User requested regridding */
   rgr->out_id=int_CEWI; /* [id] Output netCDF file ID */
 
@@ -225,7 +221,7 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
     } /* end if */
   } /* end for */
 
-  /* NULL-initialize */
+  /* NULL-initialize key-value properties required for string variables */
   rgr->area_nm=NULL; /* [sng] Name of variable containing gridcell area */
   rgr->bnd_nm=NULL; /* [sng] Name of dimension to employ for spatial bounds */
   rgr->bnd_tm_nm=NULL; /* [sng] Name of dimension to employ for temporal bounds */
@@ -239,7 +235,92 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
   rgr->lon_vrt_nm=NULL; /* [sng] Name of non-rectangular boundary variable for longitude */
   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 grid file to create */
+  rgr->flg_grd=False; /* [flg] Create SCRIP-format grid file */
+  rgr->grd_ttl=strdup("None given (supply with --rgr grd_ttl=\"Grid Title\")"); /* [enm] Grid title */
+  rgr->grd_typ=nco_grd_2D_eqa; /* [enm] Grid type */
+  rgr->lat_typ=nco_grd_lat_eqa; /* [enm] Latitude grid type */
+  rgr->lon_typ=nco_grd_lon_Grn_ctr; /* [enm] Longitude grid type */
+  rgr->lat_nbr=180; /* [nbr] Number of latitudes in destination grid */
+  rgr->lon_nbr=360; /* [nbr] Number of longitudes in destination grid */
+  rgr->lat_sth=NC_MAX_DOUBLE; /* [dgr] Latitude of southern edge of grid */
+  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 */
+  
+  /* 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")){
+      rgr->fl_grd=(char *)strdup(rgr_lst[rgr_var_idx].val);
+      rgr->flg_grd=True;
+      continue;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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;
+    } /* endif */
+    if(!strcasecmp(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")){
+	rgr->lat_typ=nco_grd_lat_fv;
+	rgr->grd_typ=nco_grd_2D_fv;
+      }else if(!strcasecmp(rgr_lst[rgr_var_idx].val,"eqa") || !strcasecmp(rgr_lst[rgr_var_idx].val,"rgl") || !strcasecmp(rgr_lst[rgr_var_idx].val,"unf") || !strcasecmp(rgr_lst[rgr_var_idx].val,"uni")){
+	rgr->lat_typ=nco_grd_lat_eqa;
+	rgr->grd_typ=nco_grd_2D_eqa;
+      }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();
+      continue;
+    } /* endif */
+    if(!strcasecmp(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"))
+	rgr->lon_typ=nco_grd_lon_180_ctr;
+      else if(!strcasecmp(rgr_lst[rgr_var_idx].val,"Grn_wst"))
+	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();
+      continue;
+    } /* endif */
     if(!strcasecmp(rgr_lst[rgr_var_idx].key,"area_nm")){
       rgr->area_nm=(char *)strdup(rgr_lst[rgr_var_idx].val);
       continue;
@@ -292,7 +373,7 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
     nco_exit(EXIT_FAILURE);
   } /* end for */
 
-  /* Revert to defaults for any not specified on command-line */
+  /* Revert to defaults for any names not specified on command-line */
   if(!rgr->area_nm) rgr->area_nm=(char *)strdup("area"); /* [sng] Name of variable containing gridcell area */
   if(!rgr->bnd_nm) rgr->bnd_nm=(char *)strdup("nbnd"); /* [sng] Name of dimension to employ for spatial bounds */
   /* NB: CESM uses nbnd for temporal bounds. NCO defaults to nbnd for all bounds with two endpoints */
@@ -314,7 +395,7 @@ nco_rgr_ini /* [fnc] Initialize regridding structure */
 } /* end nco_rgr_ini() */
   
 int /* O [enm] Return code */
-nco_rgr_map /* [fnc] Regrid using external weights */
+nco_rgr_map /* [fnc] Regrid with external weights */
 (rgr_sct * const rgr, /* I/O [sct] Regridding structure */
  trv_tbl_sct * const trv_tbl) /* I/O [sct] Traversal Table */
 {
@@ -330,6 +411,9 @@ nco_rgr_map /* [fnc] Regrid using external weights */
      ncks -D 5 -O --map=${DATA}/maps/map_t42_to_fv129x256_aave.20150621.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc
      ncks -D 5 -O --map=${DATA}/maps/map_ne30np4_to_ne120np4_tps.20150618.nc ${DATA}/ne30/rgr/ne30_1D.nc ~/foo.nc
  
+     Mapfile formats ESMF, GRIDSPEC, SCRIP, and UGRID described here:
+     http://www.earthsystemmodeling.org/esmf_releases/public/ESMF_6_3_0rp1/ESMF_refdoc/node3.html#sec:fileformat:scrip
+
      Conventions:
      grid_size: Number of grid cells (product of lat*lon)
      address: Source and destination index for each link pair
@@ -365,9 +449,9 @@ nco_rgr_map /* [fnc] Regrid using external weights */
      Sparse matrix formulations:
 
      for(lnk_idx=0;lnk_idx<lnk_nbr;lnk_idx++){
-       // Normalization: fractional area
+       // Normalization: fractional area (fracarea)
        dst[ddr_dst[lnk_idx]]+=src[ddr_src[lnk_idx]]*remap_matrix[lnk_idx,0];
-       // Normalization: destination area
+       // Normalization: destination area (destarea)
        dst[ddr_dst[lnk_idx]]+=src[ddr_src[lnk_idx]]*remap_matrix[lnk_idx,0]/dst_area[ddr_dst[lnk_idx]];
        // Normalization: none
        dst[ddr_dst[lnk_idx]]+=src[ddr_src[lnk_idx]]*remap_matrix[lnk_idx,0]/(dst_area[ddr_dst[lnk_idx]]*dst_frc[ddr_dst[lnk_idx]);
@@ -375,13 +459,22 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 
      Documentation:
      NCL special cases described in popRemap.ncl, e.g., at
-     https://github.com/yyr/ncl/blob/master/ni/src/examples/gsun/popRemap.ncl */
+     https://github.com/yyr/ncl/blob/master/ni/src/examples/gsun/popRemap.ncl
+
+     Sample regrid T42->POP43, SCRIP:
+     ncks -O --map=${DATA}/scrip/rmp_T42_to_POP43_conserv.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc */
 
   const char fnc_nm[]="nco_rgr_map()"; /* [sng] Function name */
 
   char *fl_in;
   char *fl_pth_lcl=NULL;
 
+  const double rdn2dgr=180.0/M_PI;
+  const double dgr2rdn=M_PI/180.0;
+  const double eps_rlt=1.0e-14; /* [frc] Round-off error tolerance */
+  double lat_wgt_ttl=0.0; /* [frc] Actual sum of quadrature weights */
+  double area_out_ttl=0.0; /* [frc] Exact sum of area */
+
   int in_id; /* I [id] Input netCDF file ID */
   int out_id; /* I [id] Output netCDF file ID */
   int md_open; /* [enm] Mode flag for nc_open() call */
@@ -396,11 +489,20 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   int src_grid_rank_id; /* [id] Source grid rank dimension ID */
   int src_grid_size_id; /* [id] Source grid size dimension ID */
 
+  long int lat_idx;
+  long int lon_idx;
+
+  short int bnd_idx;
+
   nco_bool FL_RTR_RMT_LCN;
   nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
   nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool flg_dgn_area_out=False; /* [flg] Diagnose area_out from grid boundaries */
+  nco_bool flg_bnd_1D_usable=False; /* [flg] Usable 1D cell vertices exist */
   
-  nco_map_sct rgr_map;
+  nco_grd_2D_typ_enm nco_grd_2D_typ=nco_grd_2D_nil; /* [enm] Two-dimensional grid-type enum */
+
+  nco_mpf_sct rgr_map;
 
   size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
   
@@ -414,23 +516,25 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   if(RAM_OPEN) md_open=NC_NOWRITE|NC_DISKLESS; else md_open=NC_NOWRITE;
   rcd+=nco_fl_open(fl_in,md_open,&bfr_sz_hnt,&in_id);
 
-  /* Identify mapping file type
-     Generated by ESMF_Regridder: conventions = "NCAR-CSM"
-     Generated by SCRIP: conventions = "SCRIP"
-     Generated by Tempest: Title = "TempestRemap Offline Regridding Weight Generator" */
+  /* Identify mapping file type using string generated by weight-generator:
+     ESMF_Regridder: conventions = "NCAR-CSM"
+     NCO: conventions = "fxm"
+     SCRIP: conventions = "SCRIP"
+     Tempest: Title = "TempestRemap Offline Regridding Weight Generator" */
   char *att_val;
   char *cnv_sng=NULL_CEWI;
   /* netCDF standard is uppercase Conventions, though some models user lowercase */
   char cnv_sng_UC[]="Conventions"; /* Unidata standard     string (uppercase) */
   char cnv_sng_LC[]="conventions"; /* Unidata non-standard string (lowercase) */
-  char cnv_sng_tps[]="Title"; /* Tempest does not yet use convention (lowercase) */
+  char cnv_sng_tps[]="Title"; /* Tempest uses "Title" not "Conventions" attribute */
+  char name0_sng[]="name0"; /* [sng] Attribute where Tempest stores least rapidly varying dimension name */
   
   long att_sz;
 
   nc_type att_typ;
 
   nco_rgr_mpf_typ_enm nco_rgr_mpf_typ=nco_rgr_mpf_nil; /* [enm] Type of remapping file */
-  nco_rgr_grd_typ_enm nco_rgr_grd_typ=nco_rgr_grd_nil; /* [enm] Type of grid conversion */
+  nco_rgr_typ_enm nco_rgr_typ=nco_rgr_grd_nil; /* [enm] Type of grid conversion */
   
   /* Look for map-type signature in Conventions attribute */
   cnv_sng=cnv_sng_UC;
@@ -447,7 +551,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   } /* endif Tempest */
   
   if(rcd == NC_NOERR && att_typ == NC_CHAR){
-    att_val=(char *)nco_malloc(att_sz*nco_typ_lng(att_typ)+1L);
+    att_val=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
     rcd+=nco_get_att(in_id,NC_GLOBAL,cnv_sng,att_val,att_typ);
     /* NUL-terminate attribute before using strstr() */
     att_val[att_sz]='\0';
@@ -515,10 +619,9 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     if(strstr(att_val,"fracarea")) nco_rgr_nrm_typ=nco_rgr_nrm_fracarea;
     if(strstr(att_val,"destarea")) nco_rgr_nrm_typ=nco_rgr_nrm_destarea;
     if(strstr(att_val,"none")) nco_rgr_nrm_typ=nco_rgr_nrm_none;
-    assert(nco_rgr_nrm_typ == nco_rgr_nrm_destarea);
     if(att_val) att_val=(char *)nco_free(att_val);
   }else{
-    /* Tempest does not (yet) store a normalization attribute */
+    /* 20150712: Tempest does not store a normalization attribute */
     if(nco_rgr_mpf_typ == nco_rgr_mpf_Tempest) nco_rgr_nrm_typ=nco_rgr_nrm_unknown;
   } /* endif normalization */
   assert(nco_rgr_nrm_typ != nco_rgr_nrm_nil);
@@ -538,7 +641,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     if(strstr(att_val,"none")) nco_rgr_mth_typ=nco_rgr_mth_none;
     if(att_val) att_val=(char *)nco_free(att_val);
   }else{
-    /* Tempest does not (yet) store a map_method attribute */
+    /* Tempest does not store a map_method attribute */
     if(nco_rgr_mpf_typ == nco_rgr_mpf_Tempest) nco_rgr_mth_typ=nco_rgr_mth_unknown;
   } /* endif */
   assert(nco_rgr_mth_typ != nco_rgr_mth_nil);
@@ -548,22 +651,26 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     (void)fprintf(stderr,"%s: INFO %s regridding input metadata and grid sizes: ",nco_prg_nm_get(),fnc_nm);
     (void)fprintf(stderr,"mapfile_generator = %s, map_method = %s, normalization = %s, src_grid_size = n_a = %li, dst_grid_size = n_b = %li, src_grid_corners = nv_a = %li, dst_grid_corners = nv_b = %li, src_grid_rank = %li, dst_grid_rank = %li, num_links = n_s = %li, num_wgts = %li\n",nco_rgr_mpf_sng(nco_rgr_mpf_typ),nco_rgr_mth_sng(nco_rgr_mth_typ),nco_rgr_nrm_sng(nco_rgr_nrm_typ),rgr_map.src_grid_size,rgr_map.dst_grid_size,rgr_map.src_grid_corners,rgr_map.dst_grid_corners,rgr_map.src_g [...]
   } /* endif dbg */
-
+  if(nco_rgr_nrm_typ == nco_rgr_nrm_none){
+    (void)fprintf(stdout,"%s: ERROR %s reports requested normalization type = %s is not yet supported. Specifically, masks specified by a mask variable (dst_grid_imask,mask_b) are not yet supported. Ask Charlie to do this.\n",nco_prg_nm_get(),fnc_nm,nco_rgr_nrm_sng(nco_rgr_nrm_typ));
+    nco_exit(EXIT_FAILURE);
+  } /* !msk */
+    
   /* Set type of grid conversion */
-  if(rgr_map.src_grid_rank == 1 && rgr_map.dst_grid_rank == 1) nco_rgr_grd_typ=nco_rgr_grd_1D_to_1D;
-  if(rgr_map.src_grid_rank == 1 && rgr_map.dst_grid_rank == 2) nco_rgr_grd_typ=nco_rgr_grd_1D_to_2D;
-  if(rgr_map.src_grid_rank == 2 && rgr_map.dst_grid_rank == 1) nco_rgr_grd_typ=nco_rgr_grd_2D_to_1D;
-  if(rgr_map.src_grid_rank == 2 && rgr_map.dst_grid_rank == 2) nco_rgr_grd_typ=nco_rgr_grd_2D_to_2D;
-  assert(nco_rgr_grd_typ != nco_rgr_grd_nil);
+  if(rgr_map.src_grid_rank == 1 && rgr_map.dst_grid_rank == 1) nco_rgr_typ=nco_rgr_grd_1D_to_1D;
+  if(rgr_map.src_grid_rank == 1 && rgr_map.dst_grid_rank == 2) nco_rgr_typ=nco_rgr_grd_1D_to_2D;
+  if(rgr_map.src_grid_rank == 2 && rgr_map.dst_grid_rank == 1) nco_rgr_typ=nco_rgr_grd_2D_to_1D;
+  if(rgr_map.src_grid_rank == 2 && rgr_map.dst_grid_rank == 2) nco_rgr_typ=nco_rgr_grd_2D_to_2D;
+  assert(nco_rgr_typ != nco_rgr_grd_nil);
   /* Save typing later */
   nco_bool flg_grd_in_1D=False;
   nco_bool flg_grd_in_2D=False;
   nco_bool flg_grd_out_1D=False;
   nco_bool flg_grd_out_2D=False;
-  if(nco_rgr_grd_typ == nco_rgr_grd_1D_to_1D || nco_rgr_grd_typ == nco_rgr_grd_1D_to_2D) flg_grd_in_1D=True;
-  if(nco_rgr_grd_typ == nco_rgr_grd_2D_to_1D || nco_rgr_grd_typ == nco_rgr_grd_2D_to_2D) flg_grd_in_2D=True;
-  if(nco_rgr_grd_typ == nco_rgr_grd_1D_to_1D || nco_rgr_grd_typ == nco_rgr_grd_2D_to_1D) flg_grd_out_1D=True;
-  if(nco_rgr_grd_typ == nco_rgr_grd_1D_to_2D || nco_rgr_grd_typ == nco_rgr_grd_2D_to_2D) flg_grd_out_2D=True;
+  if(nco_rgr_typ == nco_rgr_grd_1D_to_1D || nco_rgr_typ == nco_rgr_grd_1D_to_2D) flg_grd_in_1D=True;
+  if(nco_rgr_typ == nco_rgr_grd_2D_to_1D || nco_rgr_typ == nco_rgr_grd_2D_to_2D) flg_grd_in_2D=True;
+  if(nco_rgr_typ == nco_rgr_grd_1D_to_1D || nco_rgr_typ == nco_rgr_grd_2D_to_1D) flg_grd_out_1D=True;
+  if(nco_rgr_typ == nco_rgr_grd_1D_to_2D || nco_rgr_typ == nco_rgr_grd_2D_to_2D) flg_grd_out_2D=True;
 
   /* Obtain grid values necessary to compute output latitude and longitude coordinates */
   int area_dst_id; /* [id] Area variable ID */
@@ -590,7 +697,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     rcd+=nco_inq_varid(in_id,"dst_grid_frac",&frc_dst_id); /* ESMF: frac_b */
     rcd+=nco_inq_varid(in_id,"dst_address",&row_dst_adr_id); /* ESMF: row */
     rcd+=nco_inq_varid(in_id,"src_address",&col_src_adr_id); /* ESMF: col */
-    rcd+=nco_inq_varid(in_id,"remap_matrix",&wgt_raw_id); /* fxm: remap_matrix[num_links,num_wgts] != S[n_s] */
+    rcd+=nco_inq_varid(in_id,"remap_matrix",&wgt_raw_id); /* NB: remap_matrix[num_links,num_wgts] != S[n_s] */
     break;
   case nco_rgr_mpf_ESMF:
   case nco_rgr_mpf_Tempest:
@@ -602,7 +709,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     rcd+=nco_inq_varid(in_id,"frac_b",&frc_dst_id); /* SCRIP: dst_grid_frac */
     rcd+=nco_inq_varid(in_id,"row",&row_dst_adr_id); /* SCRIP: dst_address */
     rcd+=nco_inq_varid(in_id,"col",&col_src_adr_id); /* SCRIP: src_address */
-    rcd+=nco_inq_varid(in_id,"S",&wgt_raw_id); /* fxm: remap_matrix[num_links,num_wgts] != S[n_s] */
+    rcd+=nco_inq_varid(in_id,"S",&wgt_raw_id); /* NB: remap_matrix[num_links,num_wgts] != S[n_s] */
     break;
   default:
     (void)fprintf(stderr,"%s: ERROR %s unknown map file type\n",nco_prg_nm_get(),fnc_nm);
@@ -621,7 +728,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   }else{ /* !SCRIP */
     msk_dst_id=NC_MIN_INT;
   } /* !Tempest */
-  /* Obtain fields whose name is independent of mapfile type */
+  /* 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);
 
@@ -630,28 +737,51 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   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 */
   if(flg_grd_in_2D){
+    lon_psn_src=0;
+    lat_psn_src=1;
     if(nco_rgr_mpf_typ == nco_rgr_mpf_Tempest){
-      lon_psn_src=1;
-      lat_psn_src=0;
-    }else{
-      lon_psn_src=0;
-      lat_psn_src=1;
+      /* Until 20150814, Tempest stored [src/dst]_grid_dims as [lat,lon] unlike SCRIP's [lon,lat] order
+	 Newer behavior follows SCRIP [lon,lat] order
+	 Challenge: Support both older and newer Tempest mapfiles
+	 Tempest (unlike SCRIP and ESMF) annotates [src/dst]_grid_dims with attributes that identify axis to which each element of [src/dst]_grid_dims refers
+	 Solution: Use Tempest [src/dst]_grid_dims attributes "name0" and/or "name1" to determine if axes' positions follow old order */
+      rcd=nco_inq_att_flg(in_id,dmn_sz_in_int_id,name0_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	att_val=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd+=nco_get_att(in_id,dmn_sz_in_int_id,name0_sng,att_val,att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	att_val[att_sz]='\0';
+	if(strstr(att_val,"lat")){
+	  lat_psn_src=0;
+	  lon_psn_src=1;
+	} /* !lat */
+	if(att_val) att_val=(char *)nco_free(att_val);
+      } /* end rcd && att_typ */
     } /* !Tempest */
   } /* !flg_grd_in_2D */
   if(flg_grd_out_2D){
+    lon_psn_dst=0;
+    lat_psn_dst=1;
     if(nco_rgr_mpf_typ == nco_rgr_mpf_Tempest){
-      lon_psn_dst=1;
-      lat_psn_dst=0;
-    }else{
-      lon_psn_dst=0;
-      lat_psn_dst=1;
+      rcd=nco_inq_att_flg(in_id,dmn_sz_in_int_id,name0_sng,&att_typ,&att_sz);
+      if(rcd == NC_NOERR && att_typ == NC_CHAR){
+	att_val=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+	rcd+=nco_get_att(in_id,dmn_sz_in_int_id,name0_sng,att_val,att_typ);
+	/* NUL-terminate attribute before using strstr() */
+	att_val[att_sz]='\0';
+	if(strstr(att_val,"lat")){
+	  lat_psn_dst=0;
+	  lon_psn_dst=1;
+	} /* !lat */
+	if(att_val) att_val=(char *)nco_free(att_val);
+      } /* end rcd && att_typ */
     } /* !Tempest */
   } /* !flg_grd_out_2D */
   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_grd_max=dmn_nbr_2D; /* [nbr] Maximum rank of grid variables */
   double *area_out; /* [sr] Area of destination grid */
-  double *frc_out; /* [frc] Fraction of destination grid */
+  double *frc_out=NULL; /* [frc] Fraction of destination grid */
   double *lat_bnd_out=NULL_CEWI; /* [dgr] Latitude  boundaries of rectangular destination grid */
   double *lat_crn_out=NULL; /* [dgr] Latitude  corners of rectangular destination grid */
   double *lat_ctr_out=NULL_CEWI; /* [dgr] Latitude  centers of rectangular destination grid */
@@ -664,7 +794,7 @@ nco_rgr_map /* [fnc] Regrid using 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; /* [flg] Mask of destination grid */
+  int *msk_out=NULL; /* [flg] Mask of 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=NULL;
@@ -689,11 +819,11 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   if(nco_rgr_mpf_typ == nco_rgr_mpf_Tempest){
     /* Check-for and workaround faulty Tempest grid sizes */
     if(flg_grd_in_1D && (rgr_map.src_grid_size != dmn_sz_in_int[0])){
-      (void)fprintf(stdout,"%s: WARNING %s input grid dimension sizes disagree rgr_map.src_grid_size = %ld != %d = dmn_sz_in[0]. Problem may be caused by incorrect src_grid_dims variable in Tempest mapfile. Attempting workaround ...\n",nco_prg_nm_get(),fnc_nm,rgr_map.src_grid_size,dmn_sz_in_int[0]);
+      (void)fprintf(stdout,"%s: WARNING %s reports input grid dimension sizes disagree rgr_map.src_grid_size = %ld != %d = dmn_sz_in[0]. Problem may be caused by incorrect src_grid_dims variable in Tempest mapfile. Attempting workaround ...\n",nco_prg_nm_get(),fnc_nm,rgr_map.src_grid_size,dmn_sz_in_int[0]);
       dmn_sz_in_int[0]=rgr_map.src_grid_size;
     } /* !bug */
     if(flg_grd_out_1D && (rgr_map.dst_grid_size != dmn_sz_out_int[0])){
-      (void)fprintf(stdout,"%s: WARNING %s output grid dimension sizes disagree rgr_map.dst_grid_size = %ld != %d = dmn_sz_out[0]. Problem may be caused by incorrect dst_grid_dims variable in Tempest mapfile. Attempting workaround ...\n",nco_prg_nm_get(),fnc_nm,rgr_map.dst_grid_size,dmn_sz_out_int[0]);
+      (void)fprintf(stdout,"%s: WARNING %s reports output grid dimension sizes disagree rgr_map.dst_grid_size = %ld != %d = dmn_sz_out[0]. Problem may be caused by incorrect dst_grid_dims variable in Tempest mapfile. Attempting workaround ...\n",nco_prg_nm_get(),fnc_nm,rgr_map.dst_grid_size,dmn_sz_out_int[0]);
       dmn_sz_out_int[0]=rgr_map.dst_grid_size;
     } /* !bug */
   } /* !Tempest */
@@ -709,6 +839,8 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     col_nbr_in=0;
     lon_nbr_in=dmn_sz_in_int[lon_psn_src];
     lat_nbr_in=dmn_sz_in_int[lat_psn_src];
+    /* Sanity-check */
+    assert(lat_nbr_in*lon_nbr_in == rgr_map.src_grid_size);
   } /* !src_grid_rank */
 
   const int bnd_tm_nbr_out=2; /* [nbr] Number of boundaries for output time */
@@ -723,22 +855,20 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     lon_nbr_out=dmn_sz_out_int[0];
   }else if(flg_grd_out_2D){
     bnd_nbr_out=2; /* NB: Assumes rectangular latitude and longitude and is invalid for other quadrilaterals */
-    col_nbr_out=0;
+    col_nbr_out=lat_nbr_out*lon_nbr_out;
     lat_nbr_out=dmn_sz_out_int[lat_psn_dst];
     lon_nbr_out=dmn_sz_out_int[lon_psn_dst];
+    /* Sanity-check */
+    assert(lat_nbr_out*lon_nbr_out == rgr_map.dst_grid_size);
   } /* !dst_grid_rank */
 
   if(nco_dbg_lvl_get() >= nco_dbg_scl){
-    (void)fprintf(stderr,"%s: INFO %s grid conversion type = %s with expected input and prescribed output grid sizes: ",nco_prg_nm_get(),fnc_nm,nco_rgr_grd_sng(nco_rgr_grd_typ));
-    (void)fprintf(stderr,"lat_in = %li, lon_in  %li, col_in = %li, lat_out = %li, lon_out = %li, col_out = %li\n",lat_nbr_in,lon_nbr_in,col_nbr_in,lat_nbr_out,lon_nbr_out,col_nbr_out);
+    (void)fprintf(stderr,"%s: INFO %s grid conversion type = %s with expected input and prescribed output grid sizes: ",nco_prg_nm_get(),fnc_nm,nco_rgr_grd_sng(nco_rgr_typ));
+    (void)fprintf(stderr,"lat_in = %li, lon_in = %li, col_in = %li, lat_out = %li, lon_out = %li, col_out = %li\n",lat_nbr_in,lon_nbr_in,col_nbr_in,lat_nbr_out,lon_nbr_out,col_nbr_out);
   } /* endif dbg */
 
-  /* Allocate space for and obtain coordinates and weights */
-  nc_type crd_typ_out=NC_DOUBLE;
-  area_out=(double *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(crd_typ_out));
-  frc_out=(double *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(crd_typ_out));
-  msk_out=(int *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(NC_INT));
-  
+  /* Allocate space for and obtain coordinates */
+  const nc_type crd_typ_out=NC_DOUBLE;
   if(flg_grd_out_1D){
     lon_ctr_out=(double *)nco_malloc(col_nbr_out*nco_typ_lng(crd_typ_out));
     lat_ctr_out=(double *)nco_malloc(col_nbr_out*nco_typ_lng(crd_typ_out));
@@ -757,16 +887,24 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     lat_bnd_out=(double *)nco_malloc(lat_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
   } /* !flg_grd_out_2D */
 
-  wgt_raw=(double *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_DOUBLE),"Unable to malloc() value buffer for remapping weights",fnc_nm);
-  col_src_adr=(int *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_INT),"Unable to malloc() value buffer for remapping addresses",fnc_nm);
-  row_dst_adr=(int *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_INT),"Unable to malloc() value buffer for remapping addresses",fnc_nm);
-  
+  /* Be sure all coordinates are in degrees not radians for simplicity and CF-compliance
+     NB: ${DATA}/scrip/rmp_T42_to_POP43_conserv.nc has [xy]?_a in degrees and [xy]?_b in radians */
+  nco_bool flg_crd_in_rdn=False; /* [flg] Destination coordinates are in radians not degrees */
+  char unt_sng[]="units";
+  rcd=nco_inq_att_flg(in_id,dst_grd_ctr_lat_id,unt_sng,&att_typ,&att_sz);
+  if(rcd == NC_NOERR && att_typ == NC_CHAR){
+    att_val=(char *)nco_malloc((att_sz+1L)*nco_typ_lng(att_typ));
+    rcd+=nco_get_att(in_id,dst_grd_ctr_lat_id,unt_sng,att_val,att_typ);
+    /* NUL-terminate attribute before using strstr() */
+    att_val[att_sz]='\0';
+    /* Match "radian" and "radians" */
+    if(strstr(att_val,"radian")) flg_crd_in_rdn=True;
+    if(att_val) att_val=(char *)nco_free(att_val);
+  } /* end rcd && att_typ */
+
   /* Arrays unroll into all longitudes for first latitude, then second latitude, ...
      Thus longitudes obtained by reading first block contiguously (unstrided)
      Latitudes obtained by reading unrolled data with stride of lon_nbr */
-  dmn_srt[0]=0L;
-  dmn_cnt[0]=rgr_map.dst_grid_size;
-  rcd=nco_get_vara(in_id,area_dst_id,dmn_srt,dmn_cnt,area_out,crd_typ_out);
   if(flg_grd_out_1D){
     dmn_srt[0]=0L;
     dmn_cnt[0]=col_nbr_out;
@@ -782,15 +920,38 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     dmn_cnt[0]=col_nbr_out;
     dmn_cnt[1]=bnd_nbr_out;
     rcd=nco_get_vara(in_id,dst_grd_crn_lat_id,dmn_srt,dmn_cnt,lat_bnd_out,crd_typ_out);
+    if(flg_crd_in_rdn){
+      for(idx=0;idx<col_nbr_out;idx++){
+	lon_ctr_out[idx]*=rdn2dgr;
+	lat_ctr_out[idx]*=rdn2dgr;
+      } /* !idx */
+      for(idx=0;idx<col_nbr_out*bnd_nbr_out;idx++){
+	lon_bnd_out[idx]*=rdn2dgr;
+	lat_bnd_out[idx]*=rdn2dgr;
+      } /* !idx */
+    } /* !rdn */
+    /* Is 1D interface information usable? Yes, unless if all interfaces are zeros
+       NB: Better algorithm for "usable" is that not all interfaces any cell are equal */
+    flg_bnd_1D_usable=True;
+    for(idx=0;idx<col_nbr_out*bnd_nbr_out;idx++)
+      if(lon_bnd_out[idx] != 0.0) break;
+    if(idx == col_nbr_out*bnd_nbr_out){
+      flg_bnd_1D_usable=False;
+    }else{
+      for(idx=0;idx<col_nbr_out*bnd_nbr_out;idx++)
+	if(lat_bnd_out[idx] != 0.0) break;
+      if(idx == col_nbr_out*bnd_nbr_out) flg_bnd_1D_usable=False;
+    } /* !usable */
+      
     if(nco_dbg_lvl_get() >= nco_dbg_crr){
       for(idx=0;idx<lon_nbr_out;idx++){
-	(void)fprintf(stdout,"lon[%li] = %g, vertices = ", idx,lon_ctr_out[idx]);
-	for(int bnd_idx=0;bnd_idx<bnd_nbr_out;bnd_idx++)
+	(void)fprintf(stdout,"lon[%li] = %g, vertices = ",idx,lon_ctr_out[idx]);
+	for(bnd_idx=0;bnd_idx<bnd_nbr_out;bnd_idx++)
 	  (void)fprintf(stdout,"%s%g%s",bnd_idx == 0 ? "[" : "",lon_bnd_out[bnd_nbr_out*idx+bnd_idx],bnd_idx == bnd_nbr_out-1 ? "]\n" : ", ");
       } /* end loop over lon */
       for(idx=0;idx<lat_nbr_out;idx++){
-	(void)fprintf(stdout,"lat[%li] = %g, vertices = ", idx,lat_ctr_out[idx]);
-	for(int bnd_idx=0;bnd_idx<bnd_nbr_out;bnd_idx++)
+	(void)fprintf(stdout,"lat[%li] = %g, vertices = ",idx,lat_ctr_out[idx]);
+	for(bnd_idx=0;bnd_idx<bnd_nbr_out;bnd_idx++)
 	  (void)fprintf(stdout,"%s%g%s",bnd_idx == 0 ? "[" : "",lat_bnd_out[bnd_nbr_out*idx+bnd_idx],bnd_idx == bnd_nbr_out-1 ? "]\n" : ", ");
       } /* end loop over lat */
     } /* endif dbg */
@@ -815,8 +976,32 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     dmn_cnt[1]=rgr_map.dst_grid_corners;
     dmn_srd[1]=1L;
     rcd=nco_get_vars(in_id,dst_grd_crn_lat_id,dmn_srt,dmn_cnt,dmn_srd,lat_crn_out,crd_typ_out);
+    if(flg_crd_in_rdn){
+      for(idx=0;idx<lon_nbr_out;idx++) lon_ctr_out[idx]*=rdn2dgr;
+      for(idx=0;idx<lat_nbr_out;idx++) lat_ctr_out[idx]*=rdn2dgr;
+      for(idx=0;idx<lon_nbr_out*rgr_map.dst_grid_corners;idx++) lon_crn_out[idx]*=rdn2dgr;
+      for(idx=0;idx<lat_nbr_out*rgr_map.dst_grid_corners;idx++) lat_crn_out[idx]*=rdn2dgr;
+    } /* !rdn */
   } /* !flg_grd_out_2D */
     
+  /* Allocate space for and obtain area, fraction, and mask, which are needed for both 1D and 2D grids */
+  area_out=(double *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(crd_typ_out));
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=rgr_map.dst_grid_size;
+  rcd=nco_get_vara(in_id,area_dst_id,dmn_srt,dmn_cnt,area_out,crd_typ_out);
+
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=rgr_map.dst_grid_size;
+  frc_out=(double *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(crd_typ_out));
+  rcd=nco_get_vara(in_id,frc_dst_id,dmn_srt,dmn_cnt,frc_out,crd_typ_out);
+
+  if(msk_dst_id != NC_MIN_INT){
+    msk_out=(int *)nco_malloc(rgr_map.dst_grid_size*nco_typ_lng(NC_INT));
+    dmn_srt[0]=0L;
+    dmn_cnt[0]=rgr_map.dst_grid_size;
+    rcd=nco_get_vara(in_id,msk_dst_id,dmn_srt,dmn_cnt,msk_out,NC_INT);
+  } /* !msk */
+  
   /* Derive 2D interface boundaries from lat and lon grid-center values
      NB: Procedures to derive interfaces from midpoints on rectangular grids are theoretically possible 
      However, ESMF often outputs interfaces values (e.g., yv_b) for midpoint coordinates (e.g., yc_b)
@@ -859,30 +1044,25 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   } /* !flg_grd_out_2D */
   
   if(flg_grd_out_2D){
-    long int lat_idx;
-    long int lon_idx;
-
     if(nco_dbg_lvl_get() >= nco_dbg_crr){
       for(idx=0;idx<lon_nbr_out;idx++) (void)fprintf(stdout,"lon[%li] = [%g, %g, %g]\n",idx,lon_bnd_out[2*idx],lon_ctr_out[idx],lon_bnd_out[2*idx+1]);
       for(idx=0;idx<lat_nbr_out;idx++) (void)fprintf(stdout,"lat[%li] = [%g, %g, %g]\n",idx,lat_bnd_out[2*idx],lat_ctr_out[idx],lat_bnd_out[2*idx+1]);
     } /* endif dbg */
 
     /* Diagnose type of two-dimensional output grid by testing second latitude center against formulae */
-    nco_grd_2D_typ_enm nco_grd_2D_typ=nco_grd_2D_nil; /* [enm] Two-dimensional grid-type enum */
     nco_grd_xtn_enm nco_grd_xtn=nco_grd_xtn_glb; /* [enm] Extent of grid */
-    const double lat_ctr_tst_ngl_eqi_pol=-90.0+180.0/(lat_nbr_out-1);
-    const double lat_ctr_tst_ngl_eqi_fst=-90.0+180.0*1.5/lat_nbr_out;
+    const double lat_ctr_tst_fv=-90.0+180.0/(lat_nbr_out-1);
+    const double lat_ctr_tst_eqa=-90.0+180.0*1.5/lat_nbr_out;
     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
        20150611: map_ne120np4_to_fv801x1600_bilin.150418.nc has yc_b[1600]=-89.775000006 not expected exact value lat_ctr[1]=-89.775000000000006 */
-    if((float)lat_ctr_out[1] == (float)lat_ctr_tst_ngl_eqi_fst) nco_grd_2D_typ=nco_grd_2D_ngl_eqi_fst;
-    if((float)lat_ctr_out[1] == (float)lat_ctr_tst_ngl_eqi_pol) nco_grd_2D_typ=nco_grd_2D_ngl_eqi_pol;
+    if((float)lat_ctr_out[1] == (float)lat_ctr_tst_eqa) nco_grd_2D_typ=nco_grd_2D_eqa;
+    if((float)lat_ctr_out[1] == (float)lat_ctr_tst_fv) nco_grd_2D_typ=nco_grd_2D_fv;
     double *wgt_Gss_out=NULL; // [frc] Gaussian weights double precision
     if(nco_grd_2D_typ == nco_grd_2D_nil){
       /* Check for Gaussian grid */
-      const double rdn2dgr=180.0/M_PI;
       double *lat_sin_out; // [frc] Sine of Gaussian latitudes double precision
       lat_sin_out=(double *)nco_malloc(lat_nbr_out*sizeof(double));
       wgt_Gss_out=(double *)nco_malloc(lat_nbr_out*sizeof(double));
@@ -890,53 +1070,51 @@ nco_rgr_map /* [fnc] Regrid using external weights */
       lat_ctr_tst_gss=rdn2dgr*asin(lat_sin_out[1]);
       /* 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_out[1] = %g, lat_ctr_tst_gss = %g\n",nco_prg_nm_get(),fnc_nm,lat_ctr_out[1],lat_ctr_tst_gss);
       if((float)lat_ctr_out[1] == (float)lat_ctr_tst_gss) nco_grd_2D_typ=nco_grd_2D_gss;
       if(lat_sin_out) lat_sin_out=(double *)nco_free(lat_sin_out);
     } /* !Gaussian */
     if(nco_grd_2D_typ == nco_grd_2D_nil){
       /* If still of unknown type, this 2D grid may be regional (not global) and rectangular
+	 This occurs, e.g., with the RRM CONUS regional equi-angular destination grid
 	 Find latitude increment, check if apparently constant throughout grid */
       double lat_ctr_ncr_srt; /* [dgr] First latitude increment */
       double lat_ctr_ncr_end; /* [dgr] Last latitude increment */
       lat_ctr_ncr_srt=lat_ctr_out[1]-lat_ctr_out[0];
       lat_ctr_ncr_end=lat_ctr_out[lat_nbr_out-1]-lat_ctr_out[lat_nbr_out-2];
       if(lat_ctr_ncr_srt == lat_ctr_ncr_end){
-	/* Type appears to be regular in latitude, check if it is consistent with regional equiangular grid */
+	/* Type appears to be equi-angular in latitude, check if it is consistent with regional equi-angular grid */
 	if(lat_ctr_out[0]-lat_ctr_ncr_srt > -90.0 && lat_ctr_out[lat_nbr_out-1]+lat_ctr_ncr_end < 90.0){
 	  if((float)(lat_ctr_out[0]+((lat_nbr_out-1)*lat_ctr_ncr_srt)) == (float)lat_ctr_out[lat_nbr_out-1]){
-	    nco_grd_2D_typ=nco_grd_2D_ngl_eqi_pol;
+	    nco_grd_2D_typ=nco_grd_2D_fv;
 	    nco_grd_xtn=nco_grd_xtn_rgn;
 	  } /* !rct */
 	} /* !rgn */
       } /* srt!=end */
-    } /* !RRM */
+    } /* !nil */
+    if(nco_grd_2D_typ == nco_grd_2D_nil){
+      /* If still of unknown type, this 2D grid may be weird
+	 This occurs, e.g., with the POP3 destination grid
+	 Change gridtype from nil (which means not-yet-set) to unknown (which means none of the others matched) */
+      nco_grd_2D_typ=nco_grd_2D_unk;
+    } /* !nil */
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed output latitude grid-type: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_2D_sng(nco_grd_2D_typ));
     if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO %s diagnosed output grid-extent: %s\n",nco_prg_nm_get(),fnc_nm,nco_grd_xtn_sng(nco_grd_xtn));
     
-    const double dgr2rdn=M_PI/180.0;
-    double lat_wgt_ttl=0.0; /* [frc] Actual sum of quadrature weights */
     switch(nco_grd_2D_typ){
-    case nco_grd_2D_ngl_eqi_fst:
-      /* Manually normalize polar offset grid latitude weights to sum to 2.0 for global extent */
-      for(idx=0;idx<lat_nbr_out;idx++){
-	if(nco_grd_xtn == nco_grd_xtn_glb){
-	  lat_wgt_out[idx]=cos(dgr2rdn*lat_ctr_out[idx]);
-	  lat_wgt_ttl+=lat_wgt_out[idx];
-	  lat_wgt_out[idx]*=2.0/lat_wgt_ttl;
-	}else{ /* !glb */
-	  lat_wgt_out[idx]=sin(dgr2rdn*lat_bnd_out[2*idx+1])-sin(dgr2rdn*lat_bnd_out[2*idx]);
-	} /* !glb */
-      } /* !idx */
-      break;
-    case nco_grd_2D_ngl_eqi_pol:
+    case nco_grd_2D_eqa:
+    case nco_grd_2D_fv:
       for(idx=0;idx<lat_nbr_out;idx++) lat_wgt_out[idx]=sin(dgr2rdn*lat_bnd_out[2*idx+1])-sin(dgr2rdn*lat_bnd_out[2*idx]);
       break;
     case nco_grd_2D_gss:
       for(idx=0;idx<lat_nbr_out;idx++) lat_wgt_out[idx]=wgt_Gss_out[idx];
       break;
       if(wgt_Gss_out) wgt_Gss_out=(double *)nco_free(wgt_Gss_out);
+    case nco_grd_2D_unk:
+      for(idx=0;idx<lat_nbr_out;idx++) lat_wgt_out[idx]=0.0;
+      if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: WARNING %s reports unknown output latitude grid-type\n",nco_prg_nm_get(),fnc_nm);
+      break;
     default:
-      (void)fprintf(stderr,"%s: ERROR %s unknown output latitude grid-type\n",nco_prg_nm_get(),fnc_nm);
       nco_dfl_case_generic_err(); break;
     } /* end nco_grd_2D_typ switch */
     
@@ -945,28 +1123,263 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     lat_wgt_ttl=0.0;
     for(idx=0;idx<lat_nbr_out;idx++) lat_wgt_ttl+=lat_wgt_out[idx];
     lat_wgt_ttl_xpc=sin(dgr2rdn*lat_bnd_out[2*(lat_nbr_out-1)+1])-sin(dgr2rdn*lat_bnd_out[0]);
-    assert(1.0-lat_wgt_ttl/lat_wgt_ttl_xpc < 1.0e-14); /* [frc] Round-off tolerance for sum of quadrature weights */
-    
-    if(nco_grd_xtn == nco_grd_xtn_rgn){
-      /* 20150710: Tempest regionally refined grids like conus for ACME RRM may have area_out=0 */
-      if((bnd_nbr_out == 2 || bnd_nbr_out == 4) && nco_grd_2D_typ == nco_grd_2D_ngl_eqi_pol){ 
-	/* If area_out contains a zero... */
-	for(lat_idx=0;lat_idx<lat_nbr_out;lat_idx++)
-	  for(lon_idx=0;lon_idx<lon_nbr_out;lon_idx++)
-	    if(area_out[lat_idx*lon_nbr_out+lon_idx] == 0.0) break;
-	if(lat_idx != lat_nbr_out || lon_idx != lon_nbr_out){
-	  if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO Regional regular rectangular grid detected with zero-valued output area(s). Likely a TempestRemap regional output grid. Creating area_out from analystic formula.\n",nco_prg_nm_get());
-	  /* Regular quadrilaterals on equiangular grids have areas Mr. Enenstein taught us */
-	  for(lat_idx=0;lat_idx<lat_nbr_out;lat_idx++)
-	    for(lon_idx=0;lon_idx<lon_nbr_out;lon_idx++)
-	      area_out[lat_idx*lon_nbr_out+lon_idx]=dgr2rdn*(lon_bnd_out[2*lon_idx+1]-lon_bnd_out[2*lon_idx])*(sin(dgr2rdn*lat_bnd_out[2*lat_idx+1])-sin(dgr2rdn*lat_bnd_out[2*lat_idx]));
-	} /* !zero */
-      } /* !quad */
-    } /* !rgn */
+    if(nco_grd_2D_typ != nco_grd_2D_unk) assert(1.0-lat_wgt_ttl/lat_wgt_ttl_xpc < eps_rlt);
+  } /* !flg_grd_out_2D */
     
+  /* When possible, ensure area_out is non-zero
+     20150722: ESMF documentation says "The grid area array is only output when the conservative remapping option is used"
+     Actually, ESMF does (always?) output area, but area==0.0 unless conservative remapping is used
+     20150721: ESMF bilinear interpolation map ${DATA}/maps/map_ne30np4_to_fv257x512_bilin.150418.nc has area==0.0
+     20150710: Tempest regionally refined grids like bilinearly interpolated CONUS for ACME RRM has area_out==0
+     20150821: ESMF always outputs area_out=0.0 for bilinear interpolation
+     Check whether NCO must diagnose and provide its own area_out */
+  /* If area_out contains any zero... */
+  for(idx=0;idx<rgr_map.dst_grid_size;idx++)
+    if(area_out[idx] == 0.0) break;
+  if(idx != rgr_map.dst_grid_size){
+    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stdout,"%s: INFO Output grid detected with zero-valued output area(s) at idx = %ld (and likely others, too).\n",nco_prg_nm_get(),idx);
+  } /* !zero */
+
+  for(idx=0;idx<rgr_map.dst_grid_size;idx++)
+    if(area_out[idx] != 0.0) break;
+  if(idx == rgr_map.dst_grid_size){
+    (void)fprintf(stdout,"%s: INFO %s reports area_out from mapfile is everywhere zero. This is expected for bilinearly interpolated output maps produced by ESMF_RegridWeightGen. ",nco_prg_nm_get(),fnc_nm);
+    if(flg_grd_out_2D && (bnd_nbr_out == 2 || bnd_nbr_out == 4)){
+      (void)fprintf(stdout,"Since the destination grid provides cell bounds information, NCO will diagnose area (and output it as a variable named \"%s\") from the destination gridcell boundaries. NCO diagnoses quadrilateral area for rectangular output grids from a formula that assumes that cell boundaries follow arcs of constant latitude and longitude. This differs from the area of cells with boundaries that follow great circle arcs (used by, e.g., ESMF_RegridWeightGen and Tempest). To  [...]
+      flg_dgn_area_out=True;
+    }else if(flg_grd_out_1D && flg_bnd_1D_usable){
+      (void)fprintf(stdout,"Since the destination grid provides cell bounds information, NCO will diagnose area (and output it as a variable name \"%s\") from the destination gridcell boundaries. NCO diagnoses spherical polygon area for unstructured output grids from formulae that assume that cell boundaries follow great circle arcs (as do, e.g., ESMFRegridWeightGen and Tempest). This differs from the area of cells with boundaries that follow lines of constant latitude or longitude. To d [...]
+      flg_dgn_area_out=True;
+    }else{ /* !1D */
+      (void)fprintf(stdout,"However, NCO cannot find enough boundary information, or it is too stupid about spherical trigonometry, to diagnose area_out. NCO will output an area variable (named \"%s\") copied from the input mapfile. This area will be everywhere zero.\n",rgr->area_nm);
+    } /* !2D */
+  } /* !area */
+      
+  if(flg_dgn_area_out){
+    if(flg_grd_out_1D && flg_bnd_1D_usable){
+      if(nco_dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stdout,"INFO: Diagnosing area_out for 1D grid\n");
+      /* Use L'Huilier's Theorem not Girard's Formula
+	 http://mathworld.wolfram.com/LHuiliersTheorem.html
+	 Girard's formula depends on pi-angle and angle is usually quite small in our applications so precision would be lost
+	 L'Huilier's theorem depends only on angles (a,b,c) and semi-perimeter (s) and is well-conditioned for small angles
+	 semi-perimeter = half-perimeter of triangle = 0.5*(a+b+c)
+	 Spherical Excess (SE) difference between the sum of the angles of a spherical triangle area and a planar triangle area with same interior angles (which has sum equal to pi)
+	 SE is also the solid angle subtended by the spherical triangle and that's, well, astonishing and pretty cool
+	 Wikipedia shows a better SE formula for triangles which are ill-conditions L'Huillier's formula because a = b ~ 0.5c
+	 https://en.wikipedia.org/wiki/Spherical_trigonometry#Area_and_spherical_excess 
+	 So-called "proper" spherical triangle are those for which all angles are less than pi, so a+b+c<3*pi
+	 Cartesian coordinates of (lat,lon)=(theta,phi) are (x,y,z)=(cos(theta)*cos(phi),cos(theta)*sin(phi),sin(theta)) 
+	 Dot-product rule for vectors gives interior angle/arc length between two points:
+	 cos(a)=u dot v=cos(theta1)*cos(phi1)*cos(theta2)*cos(phi2)+cos(theta1)*sin(phi1)*cos(theta2)*sin(phi2)+sin(theta1)*sin(theta2)
+	 Spherical law of cosines relates interior angles/arc-lengths (a,b,c) to surface angles (A,B,C) in spherical triangle:
+	 https://en.wikipedia.org/wiki/Spherical_law_of_cosines
+	 cos(a)=cos(b)*cos(c)+sin(b)*sin(c)*cos(A)
+	 cos(b)=cos(c)*cos(a)+sin(c)*sin(a)*cos(B)
+	 cos(c)=cos(a)*cos(b)+sin(a)*sin(b)*cos(C)
+	 cos(A)=[cos(a)-cos(b)*cos(c)]/[sin(b)*sin(c)]
+	 cos(B)=[cos(b)-cos(c)*cos(a)]/[sin(c)*sin(a)]
+	 cos(C)=[cos(c)-cos(a)*cos(b)]/[sin(a)*sin(b)]
+	 Bounds information on unstructured grids will use bounds_nbr=maximum(vertice_nbr)
+	 Unused vertices are stored as either repeated points (ACME does this) or, conceiveably, as missing values
+	 Given (lat,lon) for N-points algorithm to find area of spherical polygon is:
+	 1. Girard method:
+	   A. Find interior angles/arc-lengths (a,b,c,d...) using spherical law of cosines along each edge
+	   B. Apply generalized Girard formula SE_n = Sum(A_n) - (N-2) - pi
+	 2. L'Huillier method
+	   A. First three non-identical points form first triangle with sides A,B,C (first+second point define A, etc.)
+	      i. First vertice anchors all triangles
+	     ii. Last vertice of preceding triangle becomes second vertice of next triangle
+	    iii. Next non-identical point becomes last vertice of next triangle
+	     iv. Side C of previous triangle is side A of next triangle
+	   B. For each triangle, compute area with L'Huillier formula unless A = B ~ 0.5*C */
+      double *lat_bnd_rdn=NULL_CEWI; /* [rdn] Latitude  boundaries of rectangular destination grid */
+      double *lon_bnd_rdn=NULL_CEWI; /* [rdn] Longitude boundaries of rectangular destination grid */
+      double *lat_bnd_sin=NULL_CEWI; /* [frc] Sine of latitude  boundaries of rectangular destination grid */
+      double *lon_bnd_sin=NULL_CEWI; /* [frc] Sine of longitude boundaries of rectangular destination grid */
+      double *lat_bnd_cos=NULL_CEWI; /* [frc] Cosine of latitude  boundaries of rectangular destination grid */
+      double *lon_bnd_cos=NULL_CEWI; /* [frc] Cosine of longitude boundaries of rectangular destination grid */
+      lon_bnd_rdn=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      lat_bnd_rdn=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      lon_bnd_cos=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      lat_bnd_cos=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      lon_bnd_sin=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      lat_bnd_sin=(double *)nco_malloc(col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      memcpy(lat_bnd_rdn,lat_bnd_out,col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      memcpy(lon_bnd_rdn,lon_bnd_out,col_nbr_out*bnd_nbr_out*nco_typ_lng(crd_typ_out));
+      for(idx=0;idx<col_nbr_out*bnd_nbr_out;idx++){
+	lon_bnd_rdn[idx]*=dgr2rdn;
+	lat_bnd_rdn[idx]*=dgr2rdn;
+	lon_bnd_cos[idx]=cos(lon_bnd_rdn[idx]);
+	lat_bnd_cos[idx]=cos(lat_bnd_rdn[idx]);
+	lon_bnd_sin[idx]=sin(lon_bnd_rdn[idx]);
+	lat_bnd_sin[idx]=sin(lat_bnd_rdn[idx]);
+      } /* !idx */
+      double lon_dlt; /* [rdn] Longitudinal difference */
+      double lat_dlt; /* [rdn] Latitudinal difference */
+      double sin_hlf_tht; /* [frc] Sine of half angle/great circle arc theta connecting two points */
+      double ngl_a; /* [rdn] Interior angle/great circle arc a */
+      double ngl_b; /* [rdn] Interior angle/great circle arc b */
+      double ngl_c; /* [rdn] Interior angle/great circle arc c */
+      double prm_smi; /* [rdn] Semi-perimeter of triangle */
+      double xcs_sph_qtr_tan; /* [frc] Tangent of one-quarter the spherical excess */
+      double xcs_sph; /* [sr] Spherical excess */
+      int tri_nbr; /* [nbr] Number of triangles in polygon */
+      long idx_a; /* [idx] Point A 1-D index */
+      long idx_b; /* [idx] Point B 1-D index */
+      long idx_c; /* [idx] Point C 1-D index */
+      for(unsigned int col_idx=0;col_idx<col_nbr_out;col_idx++){
+	area_out[col_idx]=0.0;
+	tri_nbr=0;
+	/* A is always first vertice */
+	idx_a=bnd_nbr_out*col_idx; 
+	/* Start search for B at next vertice */
+	bnd_idx=1;
+	/* bnd_idx labels offset from point A of potential location of triangle points B and C 
+	   We know that bnd_idx(A) == 0, bnd_idx(B) < bnd_nbr_out-1, bnd_idx(C) < bnd_nbr_out */
+	while(bnd_idx<bnd_nbr_out-1){
+	  /* Only first triangle must search for B, subsequent triangles recycle previous C as current B */
+	  if(tri_nbr == 0){
+	    /* Skip repeated points that must occur when polygon has fewer than allowed vertices */
+	    while(lon_bnd_out[idx_a] == lon_bnd_out[idx_a+bnd_idx] && lat_bnd_out[idx_a] == lat_bnd_out[idx_a+bnd_idx]){
+	      /* Next vertice may not duplicate A */
+	      bnd_idx++;
+	      /* If there is no room for C then all triangles found */
+	      if(bnd_idx == bnd_nbr_out-1) break;
+	    } /* !while */
+	    /* Jump to next column when all triangles found */
+	    if(bnd_idx == bnd_nbr_out-1) break;
+	  } /* !tri_nbr */
+	  idx_b=idx_a+bnd_idx;
+	  /* Search for C at next vertice */
+	  bnd_idx++;
+	  while(lon_bnd_out[idx_b] == lon_bnd_out[idx_a+bnd_idx] && lat_bnd_out[idx_b] == lat_bnd_out[idx_a+bnd_idx]){
+	    /* Next vertice may not duplicate B */
+	    bnd_idx++;
+	    /* If there is no room for C then all triangles found */
+	    if(bnd_idx == bnd_nbr_out) break;
+	  } /* !while */
+	  /* Jump to next column when all triangles found */
+	  if(bnd_idx == bnd_nbr_out) break;
+	  idx_c=idx_a+bnd_idx;
+	  /* Valid triangle, vertices are known and labeled */
+	  tri_nbr++;
+	  /* Compute interior angle/great circle arc a for first triangle; subsequent triangles recycle previous arc c */
+	  if(tri_nbr == 1){
+           /* 20150831: Test by computing ncol=0 area in conus chevrons grid:
+	      ncks -O -D 5 -v FSNT --map ${DATA}/maps/map_ne30np4_to_fv257x512_aave.20150823.nc ${DATA}/ne30/rgr/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc ${DATA}/ne30/rgr/fv_FSNT.nc
+	      ncks -O -D 5 -v FSNT --map ${DATA}/maps/map_fv257x512_to_conusx4v1np4_chevrons_bilin.20150901.nc ${DATA}/ne30/rgr/fv_FSNT.nc ${DATA}/ne30/rgr/dogfood.nc
+	      ncks -H -s %20.15e -v area -d ncol,0 ${DATA}/ne30/rgr/dogfood.nc
+	      ncks -H -s %20.15e -v grid_area -d grid_size,0 ${DATA}/grids/conusx4v1np4_chevrons_scrip_c150815.nc
+
+	      ncol=0 on conus chevrons file:
+	      3.653857995295246e-05 raw GLL weight
+	      3.653857995294302e-05 matlab N-2 triangles
+	      3.653857995294301e-05 matlab N   triangles
+	      3.653857995294258e-05 new NCO (haversine)
+	      3.653857995289623e-05 old NCO (acos) */
+           /* Computing great circle arcs over small arcs requires care since the central angle is near 0 degrees
+	       Cosine small angles changes slowly for such angles, and leads to precision loss
+	       Use haversine formula instead of sphereical law of cosines formula
+	       https://en.wikipedia.org/wiki/Great-circle_distance */
+            /* Interior angle/great circle arc a, spherical law of cosines formula (loses precision):
+	       cos_a=lat_bnd_cos[idx_a]*lon_bnd_cos[idx_a]*lat_bnd_cos[idx_b]*lon_bnd_cos[idx_b]+
+	       lat_bnd_cos[idx_a]*lon_bnd_sin[idx_a]*lat_bnd_cos[idx_b]*lon_bnd_sin[idx_b]+
+	       lat_bnd_sin[idx_a]*lat_bnd_sin[idx_b];ngl_a=acos(cos_a); */
+	    /* Interior angle/great circle arc a, haversine formula: */
+	    lon_dlt=fabs(lon_bnd_rdn[idx_a]-lon_bnd_rdn[idx_b]);
+	    lat_dlt=fabs(lat_bnd_rdn[idx_a]-lat_bnd_rdn[idx_b]);
+	    sin_hlf_tht=sqrt(pow(sin(0.5*lat_dlt),2)+lat_bnd_cos[idx_a]*lat_bnd_cos[idx_b]*pow(sin(0.5*lon_dlt),2));
+	    ngl_a=2.0*asin(sin_hlf_tht);
+          }else{
+	    ngl_a=ngl_c;
+	  } /* !tri_nbr */
+	  /* Interior angle/great circle arc b */
+	  lon_dlt=fabs(lon_bnd_rdn[idx_b]-lon_bnd_rdn[idx_c]);
+	  lat_dlt=fabs(lat_bnd_rdn[idx_b]-lat_bnd_rdn[idx_c]);
+          sin_hlf_tht=sqrt(pow(sin(0.5*lat_dlt),2)+lat_bnd_cos[idx_b]*lat_bnd_cos[idx_c]*pow(sin(0.5*lon_dlt),2));
+	  ngl_b=2.0*asin(sin_hlf_tht);
+	  /* Interior angle/great circle arc c */
+	  lon_dlt=fabs(lon_bnd_rdn[idx_c]-lon_bnd_rdn[idx_a]);
+	  lat_dlt=fabs(lat_bnd_rdn[idx_c]-lat_bnd_rdn[idx_a]);
+          sin_hlf_tht=sqrt(pow(sin(0.5*lat_dlt),2)+lat_bnd_cos[idx_c]*lat_bnd_cos[idx_a]*pow(sin(0.5*lon_dlt),2));
+	  ngl_c=2.0*asin(sin_hlf_tht);
+	  /* Ill-conditioned? */
+	  if(((float)ngl_a == (float)ngl_b && (float)ngl_a == (float)(0.5*ngl_c)) || /* c is half a and b */
+          ((float)ngl_b == (float)ngl_c && (float)ngl_b == (float)(0.5*ngl_a)) || /* a is half b and c */
+          ((float)ngl_c == (float)ngl_a && (float)ngl_c == (float)(0.5*ngl_b))){  /* b is half c and a */
+          (void)fprintf(stdout,"%s: WARNING %s reports col_idx = %u triangle %d is ill-conditioned. Spherical excess and thus cell area are likely inaccurate. Ask Charlie to implement SAS formula...\n",nco_prg_nm_get(),fnc_nm,col_idx,tri_nbr);
+	  } /* !ill */
+	  /* Semi-perimeter */
+	  prm_smi=0.5*(ngl_a+ngl_b+ngl_c);
+	  /* L'Huillier's formula */
+	  xcs_sph_qtr_tan=sqrt(tan(0.5*prm_smi)*tan(0.5*(prm_smi-ngl_a))*tan(0.5*(prm_smi-ngl_b))*tan(0.5*(prm_smi-ngl_c)));
+	  xcs_sph=4.0*atan(xcs_sph_qtr_tan);
+	  area_out[col_idx]+=xcs_sph;
+	  /* Begin search for next B at current C */
+	  bnd_idx=idx_c-idx_a;
+	} /* !tri_idx */
+	if(nco_dbg_lvl_get() >= nco_dbg_io) (void)fprintf(stdout,"%s: INFO %s reports col_idx = %u has %d triangles\n",nco_prg_nm_get(),fnc_nm,col_idx,tri_nbr);
+      } /* !col_idx */
+      if(lat_bnd_rdn) lat_bnd_rdn=(double *)nco_free(lat_bnd_rdn);
+      if(lon_bnd_rdn) lon_bnd_rdn=(double *)nco_free(lon_bnd_rdn);
+      if(lat_bnd_cos) lat_bnd_cos=(double *)nco_free(lat_bnd_cos);
+      if(lon_bnd_cos) lon_bnd_cos=(double *)nco_free(lon_bnd_cos);
+      if(lat_bnd_sin) lat_bnd_sin=(double *)nco_free(lat_bnd_sin);
+      if(lon_bnd_sin) lon_bnd_sin=(double *)nco_free(lon_bnd_sin);
+    } /* !1D */
+    if(flg_grd_out_2D && nco_grd_2D_typ != nco_grd_2D_unk){
+      /* Mr. Enenstein and George O. Abell taught me the area of spherical zones
+	 Spherical zone area is exact and faithful to underlying rectangular equi-angular grid
+	 However, ESMF and Tempest both appear to always approximate spherical polygons as connected by great circle arcs
+	 fxm: Distinguish spherical zone shapes (e.g., equi-angular) from great circle arcs (e.g., unstructured polygons) */
+      for(lat_idx=0;lat_idx<lat_nbr_out;lat_idx++)
+	for(lon_idx=0;lon_idx<lon_nbr_out;lon_idx++)
+	  area_out[lat_idx*lon_nbr_out+lon_idx]=dgr2rdn*(lon_bnd_out[2*lon_idx+1]-lon_bnd_out[2*lon_idx])*(sin(dgr2rdn*lat_bnd_out[2*lat_idx+1])-sin(dgr2rdn*lat_bnd_out[2*lat_idx]));
+    } /* !spherical zones */
+  } /* !flg_dgn_area_out */
+
+  /* Verify frc_out is sometimes non-zero */
+  for(idx=0;idx<rgr_map.dst_grid_size;idx++)
+    if(frc_out[idx] != 0.0) break;
+  if(idx == rgr_map.dst_grid_size){
+    (void)fprintf(stdout,"%s: ERROR %s reports frc_out contains all zeros\n",nco_prg_nm_get(),fnc_nm);
+    nco_exit(EXIT_FAILURE);
+  } /* !always zero */
+  /* Test whether frc_out is ever zero... */
+  for(idx=0;idx<rgr_map.dst_grid_size;idx++)
+    if(frc_out[idx] == 0.0) break;
+  if(nco_dbg_lvl_get() >= nco_dbg_std)
+    if(idx != rgr_map.dst_grid_size)
+      (void)fprintf(stdout,"%s: INFO %s reports frc_out contains zero-elements (e.g., at 1D idx=%ld)\n",nco_prg_nm_get(),fnc_nm,idx);
+  /* Normalizing by frc_out is redundant iff frc_out == 1.0, so we can save time without sacrificing accuracy
+     However, frc_out is often (e.g., for CS <-> RLL maps) close but not equal to unity (an ESMF_Regrid_Weight_Gen issue?)
+     Hence, decide whether to normalize by frc_out by diagnosing the furthest excursion of frc_out from unity */
+  nco_bool flg_frc_out_one=True;
+  double frc_out_dff_one; /* [frc] Deviation of frc_out from 1.0 */
+  double frc_out_dff_one_max=0.0; /* [frc] Maximum deviation of frc_out from 1.0 */
+  long idx_max_dvn; /* [idx] Index of maximum deviation from 1.0 */
+  for(idx=0;idx<rgr_map.dst_grid_size;idx++){
+    frc_out_dff_one=fabs(frc_out[idx]-1.0);
+    if(frc_out_dff_one > frc_out_dff_one_max){
+      frc_out_dff_one_max=frc_out_dff_one;
+      idx_max_dvn=idx;
+    } /* !max */
+  } /* !idx */
+  if(frc_out_dff_one_max > eps_rlt) flg_frc_out_one=False;
+  nco_bool flg_frc_nrm=False;
+  if(!flg_frc_out_one && (nco_rgr_nrm_typ == nco_rgr_nrm_destarea || nco_rgr_nrm_typ == nco_rgr_nrm_none)) flg_frc_nrm=True;
+  if(flg_frc_nrm){
+    (void)fprintf(stdout,"%s: INFO %s reports global metadata specifies normalization with type = %s and frc_dst = dst_frac = frac_b = frc_out contains non-unity elements (maximum deviation of %g occurs for frc_out[%ld] = %g). Will apply \'destarea\' normalization to all regridded arrays.\n",nco_prg_nm_get(),fnc_nm,nco_rgr_nrm_sng(nco_rgr_nrm_typ),frc_out_dff_one_max,idx_max_dvn,frc_out[idx_max_dvn]);
+  } /* !sometimes non-unity */
+  if(flg_frc_nrm && rgr->flg_rnr){
+    (void)fprintf(stdout,"%s: ERROR %s reports manual request (with --rnr) to renormalize fields with non-unity frc_dst = dst_frac = frac_b at same time global metadata specifies normalization type = %s. Normalizing twice may be an error, depending on intent of each. Call Charlie and tell him how NCO should handle this.\n",nco_prg_nm_get(),fnc_nm,nco_rgr_nrm_sng(nco_rgr_nrm_typ));
+    nco_exit(EXIT_FAILURE);
+  } /* !flg_rnr */
+
+  /* Detailed summary of 2D grids now available including quality-checked coordinates and area */
+  if(flg_grd_out_2D){
     if(nco_dbg_lvl_get() >= nco_dbg_sbr){
       (void)fprintf(stderr,"%s: INFO %s reports destination rectangular latitude grid:\n",nco_prg_nm_get(),fnc_nm);
-      double area_out_ttl=0.0; /* [frc] Exact sum of area */
       lat_wgt_ttl=0.0;
       area_out_ttl=0.0;
       for(idx=0;idx<lat_nbr_out;idx++)
@@ -974,7 +1387,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
       for(lat_idx=0;lat_idx<lat_nbr_out;lat_idx++)
 	for(lon_idx=0;lon_idx<lon_nbr_out;lon_idx++)
 	  area_out_ttl+=area_out[lat_idx*lon_nbr_out+lon_idx];
-      (void)fprintf(stdout,"lat_wgt_ttl = %20.15f, area_ttl = %20.15f, frc_lat_wgt = %20.15f, frc_area = %20.15f\n",lat_wgt_ttl,area_out_ttl,lat_wgt_ttl/2.0,area_out_ttl/(4.0*M_PI));
+      (void)fprintf(stdout,"lat_wgt_ttl = %20.15f, frc_lat_wgt = %20.15f, area_ttl = %20.15f, frc_area = %20.15f\n",lat_wgt_ttl,lat_wgt_ttl/2.0,area_out_ttl,area_out_ttl/(4.0*M_PI));
       for(idx=0;idx<lon_nbr_out;idx++) (void)fprintf(stdout,"lon[%li] = [%g, %g, %g]\n",idx,lon_bnd_out[2*idx],lon_ctr_out[idx],lon_bnd_out[2*idx+1]);
       for(idx=0;idx<lat_nbr_out;idx++) (void)fprintf(stdout,"lat[%li] = [%g, %g, %g]\n",idx,lat_bnd_out[2*idx],lat_ctr_out[idx],lat_bnd_out[2*idx+1]);
       for(idx=0;idx<lat_nbr_out;idx++) (void)fprintf(stdout,"lat[%li], wgt[%li] = %20.15f, %20.15f\n",idx,idx,lat_ctr_out[idx],lat_wgt_out[idx]);
@@ -985,12 +1398,31 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     } /* endif dbg */
   } /* !flg_grd_out_2D */
 
+  /* Allocate space for and obtain weights and addresses */
+  wgt_raw=(double *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_DOUBLE),fnc_nm,"Unable to malloc() value buffer for remapping weights");
+  col_src_adr=(int *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_INT),fnc_nm,"Unable to malloc() value buffer for remapping addresses");
+  row_dst_adr=(int *)nco_malloc_dbg(rgr_map.num_links*nco_typ_lng(NC_INT),fnc_nm,"Unable to malloc() value buffer for remapping addresses");
+
   /* Obtain remap matrix addresses and weights from map file */
   dmn_srt[0]=0L;
   dmn_cnt[0]=rgr_map.num_links;
-  rcd=nco_get_vara(in_id,wgt_raw_id,dmn_srt,dmn_cnt,wgt_raw,NC_DOUBLE);
   rcd=nco_get_vara(in_id,col_src_adr_id,dmn_srt,dmn_cnt,col_src_adr,NC_INT);
   rcd=nco_get_vara(in_id,row_dst_adr_id,dmn_srt,dmn_cnt,row_dst_adr,NC_INT);
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=rgr_map.num_links;
+  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]
+       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) */
+    dmn_srd[0]=1L;
+    dmn_srt[1]=0L;
+    dmn_cnt[1]=1L;
+    dmn_srd[1]=rgr_map.num_wgts;
+    rcd=nco_get_vars(in_id,wgt_raw_id,dmn_srt,dmn_cnt,dmn_srd,wgt_raw,NC_DOUBLE);
+  } /* !SCRIP */
+
   /* Optimize row/column access by pre-subtracting one to account for Fortran index offset relative to C */
   size_t lnk_nbr; /* [nbr] Number of links */
   size_t lnk_idx; /* [idx] Link index */
@@ -1020,6 +1452,39 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   in_id=rgr->in_id;
   out_id=rgr->out_id;
 
+  /* Sanity check that input data file matches expectations from mapfile */
+  char *col_nm=rgr->col_nm; /* [sng] Name of horizontal spatial dimension on unstructured grid */
+  char *lat_nm=rgr->lat_nm; /* [sng] Name of dimension to recognize as latitude */
+  char *lon_nm=rgr->lon_nm; /* [sng] Name of dimension to recognize as longitude */
+  int dmn_id_col; /* [id] Dimension ID */
+  int dmn_id_lat; /* [id] Dimension ID */
+  int dmn_id_lon; /* [id] Dimension ID */
+  if(flg_grd_in_1D){
+    long col_nbr_in_dat; /* [nbr] Number of columns in input datafile */
+    rcd=nco_inq_dimid(in_id,col_nm,&dmn_id_col);
+    rcd=nco_inq_dimlen(in_id,dmn_id_col,&col_nbr_in_dat);
+    if(col_nbr_in != col_nbr_in_dat){
+      (void)fprintf(stdout,"%s: ERROR %s reports mapfile and data file dimension sizes disagree: mapfile col_nbr_in = %ld != %ld = col_nbr_in from datafile. HINT: Check that source grid (i.e., \"grid A\") used to create mapfile matches grid on which data are stored in input datafile.\n",nco_prg_nm_get(),fnc_nm,col_nbr_in,col_nbr_in_dat);
+      nco_exit(EXIT_FAILURE);
+    } /* !err */
+  } /* !1D */
+  if(flg_grd_in_2D){
+    long lat_nbr_in_dat; /* [nbr] Number of latitudes in input datafile */
+    rcd=nco_inq_dimid(in_id,lat_nm,&dmn_id_lat);
+    rcd=nco_inq_dimlen(in_id,dmn_id_lat,&lat_nbr_in_dat);
+    if(lat_nbr_in != lat_nbr_in_dat){
+      (void)fprintf(stdout,"%s: ERROR %s reports mapfile and data file dimension sizes disagree: mapfile lat_nbr_in = %ld != %ld = lat_nbr_in from datafile. HINT: Check that source grid (i.e., \"grid A\") used to create mapfile matches grid on which data are stored in input datafile.\n",nco_prg_nm_get(),fnc_nm,lat_nbr_in,lat_nbr_in_dat);
+      nco_exit(EXIT_FAILURE);
+    } /* !err */
+    long lon_nbr_in_dat; /* [nbr] Number of longitudes in input datafile */
+    rcd=nco_inq_dimid(in_id,lon_nm,&dmn_id_lon);
+    rcd=nco_inq_dimlen(in_id,dmn_id_lon,&lon_nbr_in_dat);
+    if(lon_nbr_in != lon_nbr_in_dat){
+      (void)fprintf(stdout,"%s: ERROR %s reports mapfile and data file dimension sizes disagree: mapfile lon_nbr_in = %ld != %ld = lon_nbr_in from datafile. HINT: Check that source grid (i.e., \"grid A\") used to create mapfile matches grid on which data are stored in input datafile.\n",nco_prg_nm_get(),fnc_nm,lon_nbr_in,lon_nbr_in_dat);
+      nco_exit(EXIT_FAILURE);
+    } /* !err */
+  } /* !2D */
+    
   /* Do not extract extensive variables like lon, lat, and area
      If necessary, create them from scratch from remap data */
   const int var_xcl_lst_nbr=13; /* [nbr] Number of objects on exclusion list */
@@ -1042,9 +1507,6 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     } /* endif */
   } /* end loop */
   
-  char *col_nm=rgr->col_nm; /* [sng] Name of horizontal spatial dimension on unstructured grid */
-  char *lat_nm=rgr->lat_nm; /* [sng] Name of dimension to recognize as latitude */
-  char *lon_nm=rgr->lon_nm; /* [sng] Name of dimension to recognize as longitude */
   char *dmn_nm_cp; /* [sng] Dimension name as char * to reduce indirection */
   int dmn_idx; /* [idx] Dimension index */
   int dmn_nbr_in; /* [nbr] Number of dimensions in input variable */
@@ -1092,7 +1554,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
       } /* endif not regridded */
     } /* end nco_obj_typ_var */
   } /* end idx_tbl */
-  if(!var_rgr_nbr) (void)fprintf(stdout,"%s: WARNING %s reports no variables fit regridding criteria. The regridder expects something to regrid, and variables not regridded are copied straight to output. HINT: If the name(s) of the input horizontal spatial dimensions to be regridded (e.g., latitude and longitude or column) do not match NCO's preset defaults (case-insensitive unambiguous forms and abbreviations of \"latitude\", \"longitude\", and \"ncol\", respectively) then change the di [...]
+  if(!var_rgr_nbr) (void)fprintf(stdout,"%s: WARNING %s reports no variables fit regridding criteria. The regridder expects something to regrid, and variables not regridded are copied straight to output. HINT: If the name(s) of the input horizontal spatial dimensions to be regridded (e.g., latitude and longitude or column) do not match NCO's preset defaults (case-insensitive unambiguous forms and abbreviations of \"latitude\", \"longitude\", and \"ncol\", respectively) then change the di [...]
   
   if(nco_dbg_lvl_get() >= nco_dbg_sbr){
     for(idx_tbl=0;idx_tbl<trv_nbr;idx_tbl++){
@@ -1113,9 +1575,6 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   char *lat_wgt_nm;
   char *lon_bnd_nm_out;
   char *lon_nm_out;
-  int dmn_id_lat; /* [id] Dimension ID */
-  int dmn_id_col; /* [id] Dimension ID */
-  int dmn_id_lon; /* [id] Dimension ID */
   int dmn_id_bnd; /* [id] Dimension ID */
   int dmn_id_bnd_tm; /* [id] Dimension ID */
   int area_out_id; /* [id] Variable ID for area */
@@ -1252,7 +1711,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	  for(dmn_idx=0;dmn_idx<dmn_nbr_in;dmn_idx++){
 	    rcd=nco_inq_dimname(in_id,dmn_id_in[dmn_idx],dmn_nm);
 	    if(flg_grd_out_1D){
-	      if((nco_rgr_grd_typ == nco_rgr_grd_2D_to_1D) && (!strcmp(dmn_nm,lat_nm) || !strcmp(dmn_nm,lon_nm))){
+	      if((nco_rgr_typ == nco_rgr_grd_2D_to_1D) && (!strcmp(dmn_nm,lat_nm) || !strcmp(dmn_nm,lon_nm))){
 		/* Replace orthogonal horizontal dimensions by unstructured horizontal dimension already defined */
 		if(!strcmp(dmn_nm,lat_nm)){
 		  dmn_id_out[dmn_idx]=dmn_id_col;
@@ -1273,7 +1732,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	      } /* !lat && !lon */
 	    } /* !2D_to_1D */
 	    if(flg_grd_out_2D){
-	      if(nco_rgr_grd_typ == nco_rgr_grd_1D_to_2D && !strcmp(dmn_nm,col_nm)){
+	      if(nco_rgr_typ == nco_rgr_grd_1D_to_2D && !strcmp(dmn_nm,col_nm)){
 		/* Replace unstructured horizontal dimension by orthogonal horizontal dimensions already defined */
 		dmn_id_out[dmn_idx]=dmn_id_lat;
 		dmn_id_out[dmn_idx+1]=dmn_id_lon;
@@ -1569,7 +2028,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
     if(att_val) att_val=(char *)nco_free(att_val);
   } /* !flg_grd_out_2D */
   
-  att_nm=strdup("mapping_file");
+  att_nm=strdup("map_file");
   att_val=strdup(fl_in);
   aed_mtd.att_nm=att_nm;
   aed_mtd.var_nm=NULL;
@@ -1582,7 +2041,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
   if(att_nm) att_nm=(char *)nco_free(att_nm);
   if(att_val) att_val=(char *)nco_free(att_val);
 
-  att_nm=strdup("source_file");
+  att_nm=strdup("input_file");
   att_val=strdup(rgr->fl_in);
   aed_mtd.att_nm=att_nm;
   aed_mtd.var_nm=NULL;
@@ -1705,12 +2164,12 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 # endif /* 480 */
 #endif /* !__GNUC__ */
 #if defined( __INTEL_COMPILER)
-# pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,flg_rnr,fnc_nm,lnk_nbr,out_id,row_dst_adr,wgt_raw,wgt_vld_thr)
+# pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,flg_frc_nrm,flg_rnr,fnc_nm,frc_out,lnk_nbr,out_id,row_dst_adr,wgt_ra [...]
 #else /* !__INTEL_COMPILER */
 # ifdef GXX_OLD_OPENMP_SHARED_TREATMENT
-#  pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,fnc_nm,lnk_nbr,out_id,row_dst_adr,wgt_raw)
+#  pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,flg_frc_nrm,fnc_nm,frc_out,lnk_nbr,out_id,row_dst_adr,wgt_raw)
 # else /* !old g++ */
-#  pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,lnk_nbr,out_id,row_dst_adr,wgt_raw)
+#  pragma omp parallel for default(none) firstprivate(dmn_cnt,dmn_srt,dmn_id_in,dmn_id_out,tally,var_val_dbl_in,var_val_dbl_out,wgt_vld_out) private(dmn_idx,dmn_nbr_in,dmn_nbr_out,dmn_nbr_max,dst_idx,has_mss_val,idx,idx_in,idx_out,idx_tbl,in_id,lnk_idx,lvl_idx,lvl_nbr,mss_val_dbl,rcd,thr_idx,trv,val_in_fst,val_out_fst,var_id_in,var_id_out,var_nm,var_sz_in,var_sz_out,var_typ_out,var_typ_rgr,var_val_crr) shared(col_src_adr,flg_frc_nrm,frc_out,lnk_nbr,out_id,row_dst_adr,wgt_raw)
 # endif /* !old g++ */
 #endif /* !__INTEL_COMPILER */
   for(idx_tbl=0;idx_tbl<trv_nbr;idx_tbl++){
@@ -1746,7 +2205,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	  var_sz_in*=dmn_cnt[dmn_idx];
 	  dmn_srt[dmn_idx]=0L;
 	} /* end loop over dimensions */
-	var_val_dbl_in=(double *)nco_malloc_dbg(var_sz_in*nco_typ_lng(var_typ_rgr),"Unable to malloc() input value buffer",fnc_nm);
+	var_val_dbl_in=(double *)nco_malloc_dbg(var_sz_in*nco_typ_lng(var_typ_rgr),fnc_nm,"Unable to malloc() input value buffer");
 	rcd=nco_get_vara(in_id,var_id_in,dmn_srt,dmn_cnt,var_val_dbl_in,var_typ_rgr);
 
 	for(dmn_idx=0;dmn_idx<dmn_nbr_out;dmn_idx++){
@@ -1754,7 +2213,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	  var_sz_out*=dmn_cnt[dmn_idx];
 	  dmn_srt[dmn_idx]=0L;
 	} /* end loop over dimensions */
-	var_val_dbl_out=(double *)nco_malloc_dbg(var_sz_out*nco_typ_lng(var_typ_rgr),"Unable to malloc() input value buffer",fnc_nm);
+	var_val_dbl_out=(double *)nco_malloc_dbg(var_sz_out*nco_typ_lng(var_typ_rgr),fnc_nm,"Unable to malloc() input value buffer");
 	
 	lvl_nbr=1;
 	for(dmn_idx=0;dmn_idx<dmn_nbr_out-2;dmn_idx++) lvl_nbr*=dmn_cnt[dmn_idx];
@@ -1764,7 +2223,7 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	/* Missing value setup */
 	has_mss_val=nco_mss_val_get_dbl(in_id,var_id_in,&mss_val_dbl);
 	if(has_mss_val) tally=(int *)nco_calloc(var_sz_out,nco_typ_lng(NC_INT));
-	if(has_mss_val && flg_rnr) wgt_vld_out=(double *)nco_malloc_dbg(var_sz_out*nco_typ_lng(var_typ_rgr),"Unable to malloc() input weight buffer",fnc_nm);
+	if(has_mss_val && flg_rnr) wgt_vld_out=(double *)nco_malloc_dbg(var_sz_out*nco_typ_lng(var_typ_rgr),fnc_nm,"Unable to malloc() input weight buffer");
 	if(has_mss_val && flg_rnr) 
 	  for(dst_idx=0;dst_idx<var_sz_out;dst_idx++) wgt_vld_out[dst_idx]=0.0;
 
@@ -1812,6 +2271,18 @@ nco_rgr_map /* [fnc] Regrid using external weights */
 	      val_out_fst+=grd_sz_out;
 	    } /* end loop over lvl */
 	  } /* lvl_nbr > 1 */
+
+	  if(!flg_frc_nrm){
+	    /* frc_dst = frc_out = dst_frac = frac_b contains non-unity elements and normalization type is "destarea" or "none"
+	       When this occurs, follow "destarea" normalization procedure
+	       See SCRIP manual p. 11 and http://www.earthsystemmodeling.org/esmf_releases/public/ESMF_6_3_0rp1/ESMF_refdoc/node3.html#SECTION03028000000000000000
+	       NB: Both frc_out and NCO's renormalization (below) could serve the same purpose
+	       Applying both could lead to double-normalizing by missing values
+	       fxm: Be sure this does not occur! */
+	    for(dst_idx=0;dst_idx<var_sz_out;dst_idx++)
+	      if(frc_out[dst_idx] != 0.0) var_val_dbl_out[dst_idx]/=frc_out[dst_idx];
+	  } /* flg_frc_out_one */
+ 
 	  /* NCL and ESMF treatment of weights and missing values described at
 	     https://www.ncl.ucar.edu/Applications/ESMF.shtml#WeightsAndMasking
 	     http://earthsystemmodeling.org/esmf_releases/non_public/ESMF_6_1_1/ESMF_refdoc/node5.html#SECTION05012600000000000000
@@ -1915,15 +2386,15 @@ nco_bsl_zro /* Return Bessel function zeros */
     121.7377420880, 124.8793089132, 128.0208770059, 131.1624462752, 
     134.3040166383, 137.4455880203, 140.5871603528, 143.7287335737, 
     146.8703076258, 150.0118824570, 153.1534580192, 156.2950342685};
-  const int bsl_zro_tbl_nbr_max=sizeof(bsl_zro_tbl)/sizeof(double); /* [nbr] */
+  const int bsl_zro_tbl_nbr_max=50; /* [nbr] */
   int bsl_idx; /* [idx] Counting index */
     
   /* Main Code */
   if(nco_dbg_lvl_get() >= nco_dbg_sbr) (void)fprintf(stdout,"%s: DEBUG Entering %s\n",nco_prg_nm_get(),fnc_nm);
     
-  assert(bsl_zro_tbl_nbr_max == 51); /* 51 is original size of 50 plus extra value for Fortran offset */
-
-  for(bsl_idx=1;bsl_idx<=bsl_zro_nbr;bsl_idx++)
+  /* NB: Initialize bsl_zro[0] but (in C) never use it
+     Initialization prevents uninitialized memory warnings */
+  for(bsl_idx=0;bsl_idx<=bsl_zro_nbr;bsl_idx++)
     if(bsl_idx <= bsl_zro_tbl_nbr_max) bsl_zro[bsl_idx]=bsl_zro_tbl[bsl_idx];
 
   if(bsl_zro_nbr > bsl_zro_tbl_nbr_max)
@@ -1959,13 +2430,14 @@ nco_lat_wgt_gss /* [fnc] Compute and return sine of Gaussian latitudes and their
      19970123 Modified by Jim Rosinski to use real*16 arithmetic in order to 
      achieve (nearly) identical weights and latitudes on all machines.
      ~2000: Converted to Fortran9X by C. Zender, changed all real*16 statements to double precision (real*8)
-     20150530: Converted to C99 by C. Zender */
+     20150530: Converted to C99 by C. Zender
+     20150725: Verified against tabulation at http://pomax.github.io/bezierinfo/legendre-gauss.html#n64 */
   
   const char fnc_nm[]="nco_lat_wgt_gss()"; /* [sng] Function name */
-  const double eps_rlt=1.0e-15; // Convergence criterion (NB: Threshold was 1.0d-27 in real*16, 1.0e-15 is for real*8)
+  const double eps_rlt=1.0e-16; // Convergence criterion (NB: Threshold was 1.0d-27 in real*16, 1.0e-15 fine for real*8, 1.0e-16 pushes double precision to the brink)
   const double pi=M_PI; // [frc] 3
   const int itr_nbr_max=20; // [nbr] Maximum number of iterations
-  double c; // Constant combination
+  double c_cff; // Constant combination coefficient
   double lat_idx_dbl; // Latitude index, double precision
   double lat_nnr_idx_dbl; // Inner latitude index, double precision
   double lat_nbr_dbl; // [nbr] Number of latitudes, double precision
@@ -1975,6 +2447,7 @@ nco_lat_wgt_gss /* [fnc] Compute and return sine of Gaussian latitudes and their
   double pkmrk; // Polynomial
   double sp; // Current iteration latitude increment
   double xz; // Abscissa estimate
+  double cos_arg; // Intermediate parameter introduced while attempting to eliminate valgrind "uninitialised value" warnings
   int itr_cnt; // Iteration counter
   int lat_idx; // [idx] Counting index (latitude)
   int lat_sym_idx; // [idx] Counting index (symmetric latitude)
@@ -1986,25 +2459,27 @@ nco_lat_wgt_gss /* [fnc] Compute and return sine of Gaussian latitudes and their
   /* Main Code */
   if(nco_dbg_lvl_get() >= nco_dbg_sbr) (void)fprintf(stdout,"%s: DEBUG Entering %s\n",nco_prg_nm_get(),fnc_nm);
     
-  /* Create arrays with Fortran indexing to keep numerical algorithm identical */
+  /* Arrays with Fortran indexing (indicated by "plus one" = "_p1") keep numerical algorithm in C identical to Fortran */
   lat_sin_p1=(double *)nco_malloc((lat_nbr+1)*sizeof(double)); // Sine of Gaussian latitudes double precision
   wgt_Gss_p1=(double *)nco_malloc((lat_nbr+1)*sizeof(double)); // Gaussian weights double precision
     
   /* Use Newton iteration to find abscissas */
-  c=0.25*(1.0-4.0/(pi*pi));
+  c_cff=0.25*(1.0-4.0/(pi*pi));
   lat_nbr_dbl=lat_nbr;
-  lat_nbr_rcp2=lat_nbr/2; // Integer arithmetic
+  lat_nbr_rcp2=lat_nbr/2; // NB: Integer arithmetic
   (void)nco_bsl_zro(lat_nbr_rcp2,lat_sin_p1);
-  for(lat_idx=1;lat_idx<=lat_nbr_rcp2;lat_idx++){
-    xz=cos(lat_sin_p1[lat_idx]/sqrt((lat_nbr_dbl+0.5)*(lat_nbr_dbl+0.5)+c));
+  for(lat_idx=1;lat_idx<=lat_nbr_rcp2;lat_idx++){ // NB: Loop starts at 1
+    // 20150713: Introduce intermediate parameter cos_arg in attempt to eliminate valgrind "uninitialised value" warnings emitted by cos() (actually __cos_sse())
+    // Warnings occur with gcc-compiled code, not with clang-compiled code
+    cos_arg=lat_sin_p1[lat_idx]/sqrt((lat_nbr_dbl+0.5)*(lat_nbr_dbl+0.5)+c_cff);
+    xz=cos(cos_arg);
     /* First approximation to xz */
     itr_cnt=0;
     /* goto label_73 */
   label_73:
     pkm2=1.0;
     pkm1=xz;
-    itr_cnt=itr_cnt+1;
-    if(itr_cnt > itr_nbr_max){
+    if(++itr_cnt > itr_nbr_max){
       (void)fprintf(stdout,"%s: ERROR %s reports no convergence in %d iterations for lat_idx = %d\n",nco_prg_nm_get(),fnc_nm,itr_nbr_max,lat_idx);
       nco_exit(EXIT_FAILURE);
     } /* endif */
@@ -2019,6 +2494,7 @@ nco_lat_wgt_gss /* [fnc] Compute and return sine of Gaussian latitudes and their
     pkmrk=(lat_nbr_dbl*(pkm1-xz*pk))/(1.0-xz*xz);
     sp=pk/pkmrk;
     xz=xz-sp;
+    /* NB: Easy to introduce bug here by not replacing Fortran abs() with C fabs() */
     if(fabs(sp) > eps_rlt) goto label_73;
     lat_sin_p1[lat_idx]=xz;
     wgt_Gss_p1[lat_idx]=(2.0*(1.0-xz*xz))/((lat_nbr_dbl*pkm1)*(lat_nbr_dbl*pkm1));
@@ -2127,10 +2603,10 @@ nco_grd_2D_sng /* [fnc] Convert two-dimensional grid-type enum to string */
 {
   /* Purpose: Convert two-dimensional grid-type enum to string */
   switch(nco_grd_2D_typ){
-  case nco_grd_2D_nil: return "Unknown 2D grid type (possibly regional not global 2D grid?)";
-  case nco_grd_2D_gss: return "Gaussian latitude grid used by global spectral models: CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM";
-  case nco_grd_2D_ngl_eqi_pol: return "Equi-angle latitude grid with odd number of latitudes so poles are at centers of first and last gridcells (i.e., lat_ctr[0]=-90), aka FV scalar grid: CAM FV, GEOS-CHEM, UCICTM, UKMO";
-  case nco_grd_2D_ngl_eqi_fst: return "Equi-angle latitude grid with even number of latitudes so poles are at edges of first and last gridcells (i.e., lat_ctr[0]=-89.xxx), aka FV staggered velocity grid: CIESIN/SEDAC, IGBP-DIS, TOMS AAI";
+  case nco_grd_2D_unk: return "Unknown or unclassified 2D grid type (e.g., POP displaced-pole)";
+  case nco_grd_2D_gss: return "Gaussian latitude grid. Used by spectral transform models, e.g., CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM.";
+  case nco_grd_2D_fv: return "Cap grid. Uniform/Equi-angle (except at poles) latitude grid with poles are considered at (and labeled as) centers of first and last gridcells (i.e., lat_ctr[0]=-90), and those polar gridcells span half the equi-angular latitude increment. AKA FV-scalar grid (in Lin-Rood representation). Used by CAM FV, GEOS-CHEM, UCICTM, UKMO.";
+  case nco_grd_2D_eqa: return "Uniform/Equi-Angular latitude grid. Uniform/Equi-angle (everywhere) latitude grid. When global (not regional) in extent, poles are at edges of first and last gridcells (i.e., lat_ctr[0]=-89.xxx). When global forms valid FV-staggered AKA FV velocity grid (for Lin-Rood representation). Used by CIESIN/SEDAC, IGBP-DIS, TOMS AAI.";
   default: nco_dfl_case_generic_err(); break;
   } /* end switch */
 
@@ -2138,6 +2614,42 @@ nco_grd_2D_sng /* [fnc] Convert two-dimensional grid-type enum to string */
   return (char *)NULL;
 } /* end nco_grd_2D_sng() */
 
+const char * /* O [sng] String describing latitude grid-type */
+nco_grd_lat_sng /* [fnc] Convert latitude grid-type enum to string */
+(const nco_grd_lat_typ_enm nco_grd_lat_typ) /* I [enm] Latitude grid-type enum */
+{
+  /* Purpose: Convert latitude grid-type enum to string */
+  switch(nco_grd_lat_typ){
+  case nco_grd_lat_unk: return "Unknown or unclassified latitude grid type (e.g., curvilinear)";
+  case nco_grd_lat_gss: return "Gaussian latitude grid used by global spectral models: CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM";
+  case nco_grd_lat_fv: return "Cap-latitude grid. Uniform/Equi-angle (except at poles) latitude grid with poles are considered at (and labeled as) centers of first and last gridcells (i.e., lat_ctr[0]=-90), and those polar gridcells span half the equi-angular latitude increment. AKA FV-scalar grid (in Lin-Rood representation). Used by: CAM FV, GEOS-CHEM, UCICTM, UKMO";
+  case nco_grd_lat_eqa: return "Uniform/Equi-Angular latitude grid. Uniform/Equi-angle (everywhere) latitude grid. When global (not regional) in extent, poles are at edges of first and last gridcells (e.g., lat_ctr[0]=-89.xxx). When global can be latitude-component of a valid FV-staggered grid AKA FV velocity grid (for Lin-Rood representation). Used by: CIESIN/SEDAC, IGBP-DIS, TOMS AAI";
+  default: nco_dfl_case_generic_err(); break;
+  } /* end switch */
+
+  /* Some compilers: e.g., SGI cc, need return statement to end non-void functions */
+  return (char *)NULL;
+} /* end nco_grd_lat_sng() */
+
+const char * /* O [sng] String describing longitude grid-type */
+nco_grd_lon_sng /* [fnc] Convert longitude grid-type enum to string */
+(const nco_grd_lon_typ_enm nco_grd_lon_typ) /* I [enm] Longitude grid-type enum */
+{
+  /* Purpose: Convert longitude grid-type enum to string */
+  switch(nco_grd_lon_typ){
+  case nco_grd_lon_unk: return "Unknown or unclassified longitude grid type (e.g., curvilinear)";
+  case nco_grd_lon_180_wst: return "Date line at west edge of first longitude cell";
+  case nco_grd_lon_180_ctr: return "Date line at center of first longitude cell";
+  case nco_grd_lon_Grn_wst: return "Greenwich at west edge of first longitude cell";
+  case nco_grd_lon_Grn_ctr: return "Greenwich at center of first longitude cell";
+  case nco_grd_lon_bb: return "Longitude grid determined by bounding box (lon_wst/lon_est) and gridcell number (lon_nbr)";
+  default: nco_dfl_case_generic_err(); break;
+  } /* end switch */
+
+  /* Some compilers: e.g., SGI cc, need return statement to end non-void functions */
+  return (char *)NULL;
+} /* end nco_grd_lon_sng() */
+
 const char * /* O [sng] String describing grid extent */
 nco_grd_xtn_sng /* [fnc] Convert two-dimensional grid-extent enum to string */
 (const nco_grd_xtn_enm nco_grd_xtn) /* I [enm] Grid-extent enum */
@@ -2156,10 +2668,10 @@ nco_grd_xtn_sng /* [fnc] Convert two-dimensional grid-extent enum to string */
 
 const char * /* O [sng] String describing grid conversion */
 nco_rgr_grd_sng /* [fnc] Convert grid conversion enum to string */
-(const nco_rgr_grd_typ_enm nco_rgr_grd_typ) /* I [enm] Grid conversion enum */
+(const nco_rgr_typ_enm nco_rgr_typ) /* I [enm] Grid conversion enum */
 {
   /* Purpose: Convert grid conversion enum to string */
-  switch(nco_rgr_grd_typ){
+  switch(nco_rgr_typ){
   case nco_rgr_grd_1D_to_1D: return "1D_to_1D";
   case nco_rgr_grd_1D_to_2D: return "1D_to_2D";
   case nco_rgr_grd_2D_to_1D: return "2D_to_1D";
@@ -2284,3 +2796,643 @@ nco_tps_cmd_sng /* [fnc] Convert Tempest remap command enum to command name */
   return (char *)NULL;
 } /* end nco_tps_cmd_sng() */
 
+int /* O [enm] Return code */
+nco_grd_mk /* [fnc] Create SCRIP-format grid file */
+(rgr_sct * const rgr) /* I/O [sct] Regridding structure */
+{
+  /* Purpose: Use grid information to create SCRIP-format grid file
+
+     Spherical geometry terminology:
+     spherical cap = spherical dome = volume cut-off by plane
+     spherical lune = digon = area bounded by two half-great circles = base of spherical wedge
+     spherical segment = volume defined by cutting sphere with pair parallel planes
+     spherical sector = volume subtended by lat1
+     spherical wedge = ungula = volume subtended by lon2-lon1
+     spherical zone = area of spherical segment excluding bases
+
+     ACME:
+     https://acme-svn2.ornl.gov/acme-repo/acme/mapping/grids
+     https://acme-svn2.ornl.gov/acme-repo/acme/inputdata/cpl/gridmaps
+
+     NCAR:
+     /glade/p/cesm/cseg/mapping/grids
+
+     Generate normal RLL grids:
+     ncks -O -D 1 --rgr grd_ttl='Equiangular grid 180x360' --rgr grid=${DATA}/grids/180x360_SCRIP.20150820.nc --rgr lat_nbr=180 --rgr lon_nbr=360 --rgr lat_typ=eqa --rgr lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
+     ncks -O -D 1 --rgr grd_ttl='Equiangular grid 90x180' --rgr grid=${DATA}/grids/90x180_SCRIP.20150820.nc --rgr lat_nbr=90 --rgr lon_nbr=180 --rgr lat_typ=eqa --rgr lon_typ=Grn_ctr ~/nco/data/in.nc ~/foo.nc
+
+     Generate maps for normal RLL grids:
+     ESMF_RegridWeightGen -s ${DATA}/grids/180x360_SCRIP.20150820.nc -d ${DATA}/grids/90x180_SCRIP.20150820.nc -w ${DATA}/maps/map_180x360_to_90x180.20150820.nc --method conserve
+     ESMF_RegridWeightGen -s ${DATA}/grids/90x180_SCRIP.20150820.nc -d ${DATA}/grids/180x360_SCRIP.20150820.nc -w ${DATA}/maps/map_90x180_to_180x360.20150820.nc --method conserve
+
+     Generate ACME grids:
+     ncks -O -D 1 --rgr grd_ttl='FV-scalar grid 129x256' --rgr grid=${DATA}/grids/129x256_SCRIP.20150724.nc --rgr lat_nbr=129 --rgr lon_nbr=256 --rgr lat_typ=cap --rgr lon_typ=Grn_ctr  ~/nco/data/in.nc ~/foo.nc
+     ncks -O -D 1 --rgr grd_ttl='FV-scalar grid 257x512' --rgr grid=${DATA}/grids/257x512_SCRIP.20150724.nc --rgr lat_nbr=257 --rgr lon_nbr=512 --rgr lat_typ=cap --rgr lon_typ=Grn_ctr  ~/nco/data/in.nc ~/foo.nc
+     ncks -O -D 1 --rgr grd_ttl='FV-scalar grid 801x1600' --rgr grid=${DATA}/grids/801x1600_SCRIP.20150724.nc --rgr lat_nbr=801 --rgr lon_nbr=1600 --rgr lat_typ=cap --rgr lon_typ=Grn_ctr  ~/nco/data/in.nc ~/foo.nc
+
+     Generate ACME maps:
+     ESMF_RegridWeightGen -s ${DATA}/grids/ne30np4_pentagons.091226.nc -d ${DATA}/grids/129x256_SCRIP.20150724.nc -w ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150724.nc --method conserve
+     ESMF_RegridWeightGen -s ${DATA}/grids/ne30np4_pentagons.091226.nc -d ${DATA}/grids/257x512_SCRIP.20150724.nc -w ${DATA}/maps/map_ne30np4_to_fv257x512_bilin.20150724.nc --method bilinear
+     ESMF_RegridWeightGen -s ${DATA}/grids/ne120np4_pentagons.100310.nc -d ${DATA}/grids/257x512_SCRIP.20150724.nc -w ${DATA}/maps/map_ne120np4_to_fv257x512_aave.20150724.nc --method conserve
+     ESMF_RegridWeightGen -s ${DATA}/grids/ne120np4_pentagons.100310.nc -d ${DATA}/grids/801x1600_SCRIP.20150724.nc -w ${DATA}/maps/map_ne120np4_to_fv801x1600_bilin.20150724.nc --method bilinear */
+
+  const char fnc_nm[]="nco_grd_mk()"; /* [sng] Function name */
+
+  const double rdn2dgr=180.0/M_PI;
+  const double dgr2rdn=M_PI/180.0;
+
+  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_grd_max=dmn_nbr_2D; /* [nbr] Maximum rank of grid variables */
+  const int itr_nbr_max=20; // [nbr] Maximum number of iterations
+ 
+  const nc_type crd_typ=NC_DOUBLE;
+
+  char *fl_out_tmp=NULL_CEWI;
+  char *fl_out;
+  char area_nm[]="grid_area"; /* 20150830: NB ESMF_RegridWeightGen --user_areas looks for variable named "grid_area" */
+  char dmn_sz_nm[]="grid_dims";
+  char grd_crn_lat_nm[]="grid_corner_lat";
+  char grd_crn_lon_nm[]="grid_corner_lon";
+  char grd_crn_nm[]="grid_corners";
+  char grd_ctr_lat_nm[]="grid_center_lat";
+  char grd_ctr_lon_nm[]="grid_center_lon";
+  char grd_rnk_nm[]="grid_rank";
+  char grd_sz_nm[]="grid_size";
+  char msk_nm[]="grid_imask";
+  
+  double *grd_ctr_lat; /* [dgr] Latitude  centers of grid */
+  double *grd_ctr_lon; /* [dgr] Longitude centers of grid */
+  double *grd_crn_lat; /* [dgr] Latitude  corners of grid */
+  double *grd_crn_lon; /* [dgr] Longitude corners of grid */
+  double *area; /* [sr] Area of grid */
+  double *lat_bnd=NULL_CEWI; /* [dgr] Latitude  boundaries of rectangular grid */
+  double *lat_crn=NULL; /* [dgr] Latitude  corners of rectangular grid */
+  double *lat_ctr=NULL_CEWI; /* [dgr] Latitude  centers of rectangular grid */
+  double *lat_ntf=NULL; /* [dgr] Latitude  interfaces of rectangular grid */
+  double *lat_wgt=NULL; /* [dgr] Latitude  weights of rectangular grid */
+  double *lon_bnd=NULL_CEWI; /* [dgr] Longitude boundaries of rectangular grid */
+  double *lon_crn=NULL; /* [dgr] Longitude corners of rectangular grid */
+  double *lon_ctr=NULL_CEWI; /* [dgr] Longitude centers of rectangular grid */
+  double *lon_ntf=NULL; /* [dgr] Longitude interfaces of rectangular grid */
+
+  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_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 lat_ncr; /* [dgr] Latitude increment */
+  double lon_spn; /* [dgr] Longitude span */
+  double lat_spn; /* [dgr] Latitude span */
+  double *wgt_Gss=NULL; // [frc] Gaussian weights double precision
+
+  int *msk=NULL; /* [flg] Mask of grid */
+  int *dmn_sz_int; /* [nbr] Array of dimension sizes of grid */
+
+  int dmn_ids[dmn_nbr_grd_max]; /* [id] Dimension IDs array for output variable */
+
+  int fl_out_fmt=NC_FORMAT_CLASSIC; /* [enm] Output file format */
+  int out_id; /* I [id] Output netCDF file ID */
+  int rcd=NC_NOERR;
+
+  int area_id; /* [id] Area variable ID */
+  int dmn_id_grd_crn; /* [id] Grid corners dimension ID */
+  int dmn_id_grd_rnk; /* [id] Grid rank dimension ID */
+  int dmn_id_grd_sz; /* [id] Grid size dimension ID */
+  int dmn_sz_int_id; /* [id] Grid dimension sizes ID */
+  int grd_crn_lat_id; /* [id] Grid corner latitudes  variable ID */
+  int grd_crn_lon_id; /* [id] Grid corner longitudes variable ID */
+  int grd_ctr_lat_id; /* [id] Grid center latitudes  variable ID */
+  int grd_ctr_lon_id; /* [id] Grid center longitudes variable ID */
+  int itr_cnt; /* Iteration counter */
+  int msk_id; /* [id] Mask variable ID */
+
+  long dmn_srt[dmn_nbr_grd_max];
+  long dmn_cnt[dmn_nbr_grd_max];
+
+  long bnd_nbr; /* [nbr] Number of bounds in gridcell */
+  long grd_crn_nbr; /* [nbr] Number of corners in gridcell */
+  long grd_rnk_nbr; /* [nbr] Number of dimensions in grid */
+  long grd_sz_nbr; /* [nbr] Number of gridcells in grid */
+  long idx; /* [idx] Counting index for unrolled grids */
+  long idx2; /* [idx] Counting index for unrolled grids */
+  long lat_idx2; /* [idx] Counting index for unrolled latitude */
+  long lon_idx2; /* [idx] Counting index for unrolled longitude */
+  long crn_idx; /* [idx] Counting index for corners */
+  long lat_idx;
+  long lat_nbr; /* [nbr] Number of latitudes in grid */
+  long lon_idx;
+  long lon_nbr; /* [nbr] Number of longitudes in grid */
+  
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=True; /* Option O */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool WRT_TMP_FL=False; /* [flg] Write output to temporary file */
+  nco_bool flg_grd_2D=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 */
+
+  size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
+
+  grd_typ=rgr->grd_typ; /* [enm] Grid type */
+  fl_out=rgr->fl_grd;
+  lat_typ=rgr->lat_typ; /* [enm] Latitude grid type */
+  lon_typ=rgr->lon_typ; /* [enm] Longitude grid type */
+  lat_nbr=rgr->lat_nbr; /* [nbr] Number of latitudes in grid */
+  lon_nbr=rgr->lon_nbr; /* [nbr] Number of longitudes in grid */
+  lat_sth=rgr->lat_sth; /* [dgr] Latitude of southern edge of grid */
+  lon_wst=rgr->lon_wst; /* [dgr] Longitude of western edge of grid */
+  lat_nrt=rgr->lat_nrt; /* [dgr] Latitude of northern edge of grid */
+  lon_est=rgr->lon_est; /* [dgr] Longitude of eastern edge of grid */
+
+  /* Assume 2D grid */
+  flg_grd_2D=True;
+  grd_rnk_nbr=dmn_nbr_2D;
+  /* Assume quadrilaterals */
+  grd_crn_nbr=4;
+  /* Assume rectangles */
+  bnd_nbr=2;
+  grd_sz_nbr=lat_nbr*lon_nbr;
+
+  /* Allocate space for output data */
+  area=(double *)nco_malloc(grd_sz_nbr*nco_typ_lng(crd_typ));
+  dmn_sz_int=(int *)nco_malloc(grd_rnk_nbr*nco_typ_lng((nc_type)NC_INT));
+  msk=(int *)nco_malloc(grd_sz_nbr*nco_typ_lng((nc_type)NC_INT));
+  
+  lat_bnd=(double *)nco_malloc(lat_nbr*bnd_nbr*nco_typ_lng(crd_typ));
+  lat_crn=(double *)nco_malloc(lat_nbr*grd_crn_nbr*nco_typ_lng(crd_typ));
+  lat_ctr=(double *)nco_malloc(lat_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(lon_nbr*bnd_nbr*nco_typ_lng(crd_typ));
+  lon_crn=(double *)nco_malloc(lon_nbr*grd_crn_nbr*nco_typ_lng(crd_typ));
+  lon_ctr=(double *)nco_malloc(lon_nbr*nco_typ_lng(crd_typ));
+  lon_ntf=(double *)nco_malloc((lon_nbr+1L)*nco_typ_lng(crd_typ));
+  wgt_Gss=(double *)nco_malloc(lat_nbr*nco_typ_lng(crd_typ));
+  
+  grd_ctr_lat=(double *)nco_malloc(grd_sz_nbr*nco_typ_lng(crd_typ));
+  grd_ctr_lon=(double *)nco_malloc(grd_sz_nbr*nco_typ_lng(crd_typ));
+  grd_crn_lat=(double *)nco_malloc(grd_crn_nbr*grd_sz_nbr*nco_typ_lng(crd_typ));
+  grd_crn_lon=(double *)nco_malloc(grd_crn_nbr*grd_sz_nbr*nco_typ_lng(crd_typ));
+  
+  /* Define 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 */
+  if(grd_rnk_nbr == dmn_nbr_2D){
+    lon_psn=0;
+    lat_psn=1;
+  } /* !flg_grd_in_2D */
+  dmn_sz_int[lon_psn]=lon_nbr;
+  dmn_sz_int[lat_psn]=lat_nbr;
+
+  for(idx=0;idx<grd_sz_nbr;idx++) msk[idx]=1;
+
+  /* Compute rectangular arrays
+     NB: Much is a more-generic rewrite of map/map_grd.F90:map_grd_mk() */
+
+  /* 20150827: 
+     Old rule: Longitude grid was entirely specified by one of four longitude map tokens: Grn_ctr,Grn_wst,180_ctr,180_wst
+     New rule: User may specify bounds (lon_wst,lon_est,lat_sth,lat_nrt) independently of grid token
+     Such bounds ALWAYS refer bounding box interface edges, NEVER to centers of first last gridcells
+     Bounds and number of gridcells completely determine uniform grid so former longitude-type tokens have no effect when bounds specified (so letting grid-type tokens affect grid would over-determine grid and lead to errors)
+     Hence, grid-type tokens may be used as short-hand to specify grids but may not be required to exist later (because regional grids would not have specified them)
+     Grid grid-type tokens lon_bb/lat_bb imply bounding box was originally used to specify bounds
+     1x1 degree global grid with first longitude centered at Greenwich:
+     --lon_nbr=360 --lon_typ Grn_ctr
+     --lon_nbr=360 --lon_wst=-0.5 --lon_est=359.5
+     1x1 degree global grid with Greenwich at west edge of first longitude:
+     --lon_nbr=360 --lon_typ Grn_wst
+     --lon_nbr=360 --lon_wst=0.0 --lon_est=360.0
+     1x1 degree regional grid, total size 9x9 degrees, Greenwich at center of middle gridcell:
+     --lon_nbr=9 --lon_wst=-4.5 --lon_est=4.5
+     1x1 degree regional grid, total size 10x10 degrees, Greenwich at east/west edges of middle two gridcells
+     --lon_nbr=10 --lon_wst=-5.0 --lon_est=5.0 */
+  
+  /* Were east/west longitude bounds set explicitly or implicitly?
+     NB: This is redundant since it was done in nco_rgr_ini(), but better safe than sorry */
+  if(lon_wst != NC_MAX_DOUBLE || lon_est != NC_MAX_DOUBLE) lon_typ=rgr->lon_typ=nco_grd_lon_bb;
+  
+  if(lon_wst == NC_MAX_DOUBLE){
+    /* Precomputed longitude grids begin with longitude 0.0 or -180.0 degrees */
+    switch(lon_typ){
+    case nco_grd_lon_bb:
+    case nco_grd_lon_Grn_ctr:
+    case nco_grd_lon_Grn_wst:
+      lon_wst=0.0;
+      break;
+    case nco_grd_lon_180_ctr:
+    case nco_grd_lon_180_wst:
+      lon_wst=-180.0;
+      break;
+    default:
+      nco_dfl_case_generic_err(); break;
+    } /* !lon_typ */
+  } /* !lon */
+
+  if(lon_est == NC_MAX_DOUBLE){
+    /* Precomputed longitude grids end with longitude 360.0 or 180.0 degrees */
+    switch(lon_typ){
+    case nco_grd_lon_bb:
+    case nco_grd_lon_Grn_ctr:
+    case nco_grd_lon_Grn_wst:
+      lon_est=360.0;
+      break;
+    case nco_grd_lon_180_ctr:
+    case nco_grd_lon_180_wst:
+      lon_est=180.0;
+      break;
+    default:
+      nco_dfl_case_generic_err(); break;
+    } /* !lon_typ */
+  } /* !lon */
+
+  /* Determine longitude increment from span of pre-centered bounding box (centering will not change span) */
+  lon_spn=lon_est-lon_wst;
+  lon_ncr=lon_spn/lon_nbr;
+
+  /* Centering: If user did not set explicit longitude bounds then... */
+  if(lon_typ != nco_grd_lon_bb)
+    /* map_lon_ctr_typ determines whether lon_wst refers to cell center or Western edge */
+    if((lon_typ == nco_grd_lon_Grn_ctr) || (lon_typ == nco_grd_lon_180_ctr)) lon_wst=lon_wst-(lon_ncr/2.0);
+
+  /* Re-derive lon_est from lon_wst and lon_nbr (more fundamental properties) */
+  lon_est=lon_wst+lon_ncr*lon_nbr;
+
+  /* lon_wst and lon_est have been set and will not change */
+  lon_ntf[0]=lon_wst;
+  lon_ntf[lon_nbr]=lon_est;
+
+  for(lon_idx=1;lon_idx<lon_nbr;lon_idx++)
+    lon_ntf[lon_idx]=lon_ntf[0]+lon_idx*lon_ncr;
+  /* Ensure rounding errors do not produce unphysical grid */
+  lon_ntf[lon_nbr]=lon_ntf[0]+lon_spn;
+  
+  /* Finished with longitude, now tackle latitude */
+  
+  /* Were south/north latitude bounds set explicitly or implicitly? */
+  //  if(lat_sth != NC_MAX_DOUBLE || lat_nrt != NC_MAX_DOUBLE) lon_typ=rgr->lat_typ=nco_grd_lat_bb;
+  if(lat_sth == NC_MAX_DOUBLE) lat_sth=-90.0;
+  if(lat_nrt == NC_MAX_DOUBLE) lat_nrt=90.0;
+  
+  /* Determine latitude increment from span of pre-centered bounding box (centering will not change span) */
+  lat_spn=lat_nrt-lat_sth;
+  lat_ncr=lat_spn/lat_nbr;
+
+  double *lat_sin=NULL; // [frc] Sine of Gaussian latitudes double precision
+  lat_ntf[0]=lat_sth;
+  switch(lat_typ){
+  case nco_grd_lat_fv:
+    lat_ncr=lat_spn/(lat_nbr-1);
+    lat_ntf[1]=lat_ntf[0]+0.5*lat_ncr;
+    for(lat_idx=2;lat_idx<lat_nbr;lat_idx++)
+      lat_ntf[lat_idx]=lat_ntf[1]+(lat_idx-1)*lat_ncr;
+    break;
+  case nco_grd_lat_eqa:
+    lat_ncr=lat_spn/lat_nbr;
+    for(lat_idx=1;lat_idx<lat_nbr;lat_idx++)
+      lat_ntf[lat_idx]=lat_ntf[0]+lat_idx*lat_ncr;
+    break;
+  case nco_grd_lat_gss:
+    lat_sin=(double *)nco_malloc(lat_nbr*sizeof(double));
+    (void)nco_lat_wgt_gss(lat_nbr,lat_sin,wgt_Gss);
+    for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+      lat_ctr[lat_idx]=rdn2dgr*asin(lat_sin[lat_idx]);
+    /* First guess for lat_ntf is midway between Gaussian abscissae */
+    for(lat_idx=1;lat_idx<lat_nbr;lat_idx++)
+      lat_ntf[lat_idx]=0.5*(lat_ctr[lat_idx-1]+lat_ctr[lat_idx]);
+    /* Iterate guess until area between interfaces matches Gaussian weight */
+    for(lat_idx=1;lat_idx<lat_nbr;lat_idx++){
+      double fofx_at_x0; /* [frc] Function to iterate evaluated at current guess */
+      double dfdx_at_x0; /* [frc] Derivation of equation evaluated at current guess */
+      const double eps_rlt_cnv=1.0e-15; // Convergence criterion (1.0e-16 pushes double precision to the brink)
+      itr_cnt=0;
+      lat_wgt_gss=sin(dgr2rdn*lat_ntf[lat_idx])-sin(dgr2rdn*lat_ntf[lat_idx-1]);
+      fofx_at_x0=wgt_Gss[lat_idx-1]-lat_wgt_gss;
+      while(fabs(fofx_at_x0) > eps_rlt_cnv){
+	/* Newton-Raphson iteration:
+	   Let x=lat_ntf[lat_idx], y0=lat_ntf[lat_idx-1], gw = Gaussian weight (exact solution)
+	   f(x)=sin(dgr2rdn*x)-sin(dgr2rdn*y0)-gw=0 
+	   dfdx(x)=dgr2rdn*(dgr2rdn*x)
+	   x_better=x0-f(x0)/f'(x0) */
+	dfdx_at_x0=dgr2rdn*cos(dgr2rdn*lat_ntf[lat_idx]);
+	lat_ntf[lat_idx]+=fofx_at_x0/dfdx_at_x0; /* NB: not sure why this is minus not plus but it works :) */
+	lat_wgt_gss=sin(dgr2rdn*lat_ntf[lat_idx])-sin(dgr2rdn*lat_ntf[lat_idx-1]);
+	fofx_at_x0=wgt_Gss[lat_idx-1]-lat_wgt_gss;
+	if(++itr_cnt > itr_nbr_max){
+	  (void)fprintf(stdout,"%s: ERROR %s reports no convergence in %d iterations for lat_idx = %ld\n",nco_prg_nm_get(),fnc_nm,itr_nbr_max,lat_idx);
+	  nco_exit(EXIT_FAILURE);
+	} /* endif */
+      } /* !while */
+    } /* !lat */
+    break;
+  default:
+    nco_dfl_case_generic_err(); break;
+  } /* !lat_typ */
+  /* Ensure rounding errors do not produce unphysical grid */
+  lat_ntf[lat_nbr]=lat_nrt;
+  
+  /* Always define longitude centers midway between interfaces */
+  for(lon_idx=0;lon_idx<=lon_nbr-1;lon_idx++)
+    lon_ctr[lon_idx]=0.5*(lon_ntf[lon_idx]+lon_ntf[lon_idx+1]);
+
+  /* Many grids have center latitude equally spaced between interfaces */
+  for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+      lat_ctr[lat_idx]=0.5*(lat_ntf[lat_idx]+lat_ntf[lat_idx+1]);
+
+  /* Cap grids excepted---they place centers of first/last gridcells at poles */
+  if(lat_typ == nco_grd_lat_fv){
+    lat_ctr[0]=lat_ntf[0];
+    for(lat_idx=1;lat_idx<lat_nbr-1;lat_idx++)
+      lat_ctr[lat_idx]=0.5*(lat_ntf[lat_idx]+lat_ntf[lat_idx+1]);
+    lat_ctr[lat_nbr-1]=lat_ntf[lat_nbr];
+  } /* !cap */
+  /* Gaussian grids centerpoints are defined by solutions to Legendre polynomials */
+  if(lat_typ == nco_grd_lat_gss){
+    for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+      lat_ctr[lat_idx]=rdn2dgr*asin(lat_sin[lat_idx]);
+  } /* !Gaussian */
+  
+  for(idx=0;idx<lon_nbr;idx++){
+    lon_bnd[2*idx]=lon_ntf[idx];
+    lon_bnd[2*idx+1]=lon_ntf[idx+1];
+  } /* end loop over longitude */
+  for(idx=0;idx<lat_nbr;idx++){
+    lat_bnd[2*idx]=lat_ntf[idx];
+    lat_bnd[2*idx+1]=lat_ntf[idx+1];
+  } /* end loop over latitude */
+  
+  if(nco_dbg_lvl_get() >= nco_dbg_crr){
+    for(idx=0;idx<lat_nbr;idx++){
+    (void)fprintf(stdout,"lat[%li] = %g, vertices = ",idx,lat_ctr[idx]);
+    for(int bnd_idx=0;bnd_idx<bnd_nbr;bnd_idx++)
+      (void)fprintf(stdout,"%s%g%s",bnd_idx == 0 ? "[" : "",lat_bnd[bnd_nbr*idx+bnd_idx],bnd_idx == bnd_nbr-1 ? "]\n" : ", ");
+  } /* end loop over lat */
+  } /* endif dbg */
+
+  /* Use centers and boundaries to diagnose latitude weights */
+  switch(lat_typ){
+  case nco_grd_lat_eqa:
+  case nco_grd_lat_fv:
+    for(lat_idx=0;lat_idx<lat_nbr;lat_idx++) lat_wgt[lat_idx]=sin(dgr2rdn*lat_ntf[lat_idx+1])-sin(dgr2rdn*lat_ntf[lat_idx]);
+    break;
+  case nco_grd_lat_gss:
+    for(lat_idx=0;lat_idx<lat_nbr;lat_idx++) lat_wgt[lat_idx]=wgt_Gss[lat_idx];
+    break;
+  default:
+    nco_dfl_case_generic_err(); break;
+  } /* !lat_typ */
+
+  /* Fuzzy test of latitude weight normalization */
+  const double eps_rlt_max=1.0e-14; /* [frc] Round-off error tolerance */
+  double lat_wgt_ttl_xpc; /* [frc] Expected sum of latitude weights */
+  lat_wgt_ttl=0.0;
+  for(idx=0;idx<lat_nbr;idx++) lat_wgt_ttl+=lat_wgt[idx];
+  lat_wgt_ttl_xpc=sin(dgr2rdn*lat_bnd[2*(lat_nbr-1)+1])-sin(dgr2rdn*lat_bnd[0]);
+  if(grd_typ != nco_grd_2D_unk && 1.0-lat_wgt_ttl/lat_wgt_ttl_xpc > eps_rlt_max){
+    (void)fprintf(stdout,"%s: ERROR %s reports grid normalization does not meet precision tolerance eps_rlt_max = %20.15f\nlat_wgt_ttl = %20.15f, lat_wgt_ttl_xpc = %20.15f, lat_wgt_frc = %20.15f, eps_rlt = %20.15f\n",nco_prg_nm_get(),fnc_nm,eps_rlt_max,lat_wgt_ttl,lat_wgt_ttl_xpc,lat_wgt_ttl/lat_wgt_ttl_xpc,1.0-lat_wgt_ttl/lat_wgt_ttl_xpc);
+    nco_exit(EXIT_FAILURE);
+  } /* !imprecise */
+
+  assert(grd_crn_nbr == 4);
+  for(lon_idx=0;lon_idx<lon_nbr;lon_idx++){
+    idx=grd_crn_nbr*lon_idx;
+    lon_crn[idx]=lon_ntf[lon_idx];
+    lon_crn[idx+1]=lon_ntf[lon_idx+1];
+    lon_crn[idx+2]=lon_ntf[lon_idx+1];
+    lon_crn[idx+3]=lon_ntf[lon_idx];
+  } /* !lon_idx */
+
+  for(lat_idx=0;lat_idx<lat_nbr;lat_idx++){
+    idx=grd_crn_nbr*lat_idx;
+    lat_crn[idx]=lat_ntf[lat_idx];
+    lat_crn[idx+1]=lat_ntf[lat_idx];
+    lat_crn[idx+2]=lat_ntf[lat_idx+1];
+    lat_crn[idx+3]=lat_ntf[lat_idx+1];
+  } /* !lat_idx */
+  
+  for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+    for(lon_idx=0;lon_idx<lon_nbr;lon_idx++)
+      area[lat_idx*lon_nbr+lon_idx]=dgr2rdn*(lon_bnd[2*lon_idx+1]-lon_bnd[2*lon_idx])*(sin(dgr2rdn*lat_bnd[2*lat_idx+1])-sin(dgr2rdn*lat_bnd[2*lat_idx]));
+
+  if(flg_grd_2D){
+    if(nco_dbg_lvl_get() >= nco_dbg_sbr){
+      (void)fprintf(stderr,"%s: INFO %s reports destination rectangular latitude grid:\n",nco_prg_nm_get(),fnc_nm);
+      lat_wgt_ttl=0.0;
+      area_ttl=0.0;
+      for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+	lat_wgt_ttl+=lat_wgt[lat_idx];
+      for(lat_idx=0;lat_idx<lat_nbr;lat_idx++)
+	for(lon_idx=0;lon_idx<lon_nbr;lon_idx++)
+	  area_ttl+=area[lat_idx*lon_nbr+lon_idx];
+      (void)fprintf(stdout,"lat_wgt_ttl = %20.15f, frc_lat_wgt = %20.15f, area_ttl = %20.15f, frc_area = %20.15f\n",lat_wgt_ttl,lat_wgt_ttl/2.0,area_ttl,area_ttl/(4.0*M_PI));
+    } /* endif dbg */
+  } /* !flg_grd_2D */
+
+  /* Stuff rectangular arrays into unrolled arrays */
+  for(lat_idx=0;lat_idx<lat_nbr;lat_idx++){
+    for(lon_idx=0;lon_idx<lon_nbr;lon_idx++){
+      idx=lat_idx*lon_nbr+lon_idx;
+      grd_ctr_lat[idx]=lat_ctr[lat_idx];
+      grd_ctr_lon[idx]=lon_ctr[lon_idx];
+      for(crn_idx=0;crn_idx<grd_crn_nbr;crn_idx++){
+	idx2=grd_crn_nbr*idx+crn_idx;
+	lat_idx2=lat_idx*grd_crn_nbr+crn_idx;
+	lon_idx2=lon_idx*grd_crn_nbr+crn_idx;
+	grd_crn_lat[idx2]=lat_crn[lat_idx2];
+	grd_crn_lon[idx2]=lon_crn[lon_idx2];
+      } /* !crn */
+    } /* !lon */
+  } /* !lat */
+  
+  /* Open grid file */
+  fl_out_tmp=nco_fl_out_open(fl_out,FORCE_APPEND,FORCE_OVERWRITE,fl_out_fmt,&bfr_sz_hnt,RAM_CREATE,RAM_OPEN,WRT_TMP_FL,&out_id);
+
+  /* Define dimensions */
+  rcd=nco_def_dim(out_id,grd_crn_nm,grd_crn_nbr,&dmn_id_grd_crn);
+  rcd=nco_def_dim(out_id,grd_sz_nm,grd_sz_nbr,&dmn_id_grd_sz);
+  rcd=nco_def_dim(out_id,grd_rnk_nm,grd_rnk_nbr,&dmn_id_grd_rnk);
+  
+  /* Define variables */
+  (void)nco_def_var(out_id,dmn_sz_nm,(nc_type)NC_INT,dmn_nbr_1D,&dmn_id_grd_rnk,&dmn_sz_int_id);
+  (void)nco_def_var(out_id,area_nm,(nc_type)crd_typ,dmn_nbr_1D,&dmn_id_grd_sz,&area_id);
+  (void)nco_def_var(out_id,msk_nm,(nc_type)NC_INT,dmn_nbr_1D,&dmn_id_grd_sz,&msk_id);
+  (void)nco_def_var(out_id,grd_ctr_lat_nm,crd_typ,dmn_nbr_1D,&dmn_id_grd_sz,&grd_ctr_lat_id);
+  (void)nco_def_var(out_id,grd_ctr_lon_nm,crd_typ,dmn_nbr_1D,&dmn_id_grd_sz,&grd_ctr_lon_id);
+  dmn_ids[0]=dmn_id_grd_sz;
+  dmn_ids[1]=dmn_id_grd_crn;
+  (void)nco_def_var(out_id,grd_crn_lat_nm,crd_typ,dmn_nbr_2D,dmn_ids,&grd_crn_lat_id);
+  dmn_ids[0]=dmn_id_grd_sz;
+  dmn_ids[1]=dmn_id_grd_crn;
+  (void)nco_def_var(out_id,grd_crn_lon_nm,crd_typ,dmn_nbr_2D,dmn_ids,&grd_crn_lon_id);
+  
+  /* Define "units" attributes */
+  aed_sct aed_mtd;
+  char *att_nm;
+  char *att_val;
+  
+  att_nm=strdup("title");
+  att_val=strdup(rgr->grd_ttl);
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=NULL;
+  aed_mtd.id=NC_GLOBAL;
+  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,NC_GLOBAL,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  att_nm=strdup("Conventions");
+  att_val=strdup("SCRIP");
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=NULL;
+  aed_mtd.id=NC_GLOBAL;
+  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,NC_GLOBAL,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  const char usr_cpp[]=TKN2SNG(USER); /* [sng] Hostname from C pre-processor */
+  att_nm=strdup("created_by");
+  att_val=strdup(usr_cpp);
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=NULL;
+  aed_mtd.id=NC_GLOBAL;
+  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,NC_GLOBAL,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  (void)nco_hst_att_cat(out_id,rgr->cmd_ln);
+
+  att_nm=strdup("latitude_grid_type");
+  att_val=strdup(nco_grd_lat_sng(lat_typ));
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=NULL;
+  aed_mtd.id=NC_GLOBAL;
+  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,NC_GLOBAL,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  att_nm=strdup("longitude_grid_type");
+  att_val=strdup(nco_grd_lon_sng(lon_typ));
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=NULL;
+  aed_mtd.id=NC_GLOBAL;
+  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,NC_GLOBAL,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  att_nm=strdup("units");
+  att_val=strdup("steradian");
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.var_nm=area_nm;
+  aed_mtd.id=area_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,area_id,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+
+  att_nm=strdup("units");
+  att_val=strdup("degrees");
+  aed_mtd.att_nm=att_nm;
+  aed_mtd.sz=strlen(att_val);
+  aed_mtd.type=NC_CHAR;
+  aed_mtd.val.cp=att_val;
+  aed_mtd.mode=aed_create;
+  /* Add same units attribute to four different variables */
+  aed_mtd.var_nm=grd_ctr_lat_nm;
+  aed_mtd.id=grd_ctr_lat_id;
+  (void)nco_aed_prc(out_id,grd_ctr_lat_id,aed_mtd);
+  aed_mtd.var_nm=grd_ctr_lon_nm;
+  aed_mtd.id=grd_ctr_lon_id;
+  (void)nco_aed_prc(out_id,grd_ctr_lon_id,aed_mtd);
+  aed_mtd.var_nm=grd_crn_lat_nm;
+  aed_mtd.id=grd_crn_lat_id;
+  (void)nco_aed_prc(out_id,grd_crn_lat_id,aed_mtd);
+  aed_mtd.var_nm=grd_crn_lon_nm;
+  aed_mtd.id=grd_crn_lon_id;
+  (void)nco_aed_prc(out_id,grd_crn_lon_id,aed_mtd);
+  if(att_nm) att_nm=(char *)nco_free(att_nm);
+  if(att_val) att_val=(char *)nco_free(att_val);
+  
+  /* Begin data mode */
+  (void)nco_enddef(out_id);
+  
+  /* Write variables */
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=grd_rnk_nbr;
+  rcd=nco_put_vara(out_id,dmn_sz_int_id,dmn_srt,dmn_cnt,dmn_sz_int,(nc_type)NC_INT);
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  rcd=nco_put_vara(out_id,area_id,dmn_srt,dmn_cnt,area,crd_typ);
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  rcd=nco_put_vara(out_id,msk_id,dmn_srt,dmn_cnt,msk,(nc_type)NC_INT);
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  rcd=nco_put_vara(out_id,grd_ctr_lat_id,dmn_srt,dmn_cnt,grd_ctr_lat,crd_typ);
+  dmn_srt[0]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  rcd=nco_put_vara(out_id,grd_ctr_lon_id,dmn_srt,dmn_cnt,grd_ctr_lon,crd_typ);
+  dmn_srt[0]=0L;
+  dmn_srt[1]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  dmn_cnt[1]=grd_crn_nbr;
+  rcd=nco_put_vara(out_id,grd_crn_lat_id,dmn_srt,dmn_cnt,grd_crn_lat,crd_typ);
+  dmn_srt[0]=0L;
+  dmn_srt[1]=0L;
+  dmn_cnt[0]=grd_sz_nbr;
+  dmn_cnt[1]=grd_crn_nbr;
+  rcd=nco_put_vara(out_id,grd_crn_lon_id,dmn_srt,dmn_cnt,grd_crn_lon,crd_typ);
+  
+  /* Close output file and move it from temporary to permanent location */
+  (void)nco_fl_out_cls(fl_out,fl_out_tmp,out_id);
+  
+  /* Free memory associated with input file */
+  if(dmn_sz_int) dmn_sz_int=(int *)nco_free(dmn_sz_int);
+  if(msk) msk=(int *)nco_free(msk);
+  if(area) area=(double *)nco_free(area);
+  if(grd_ctr_lat) grd_ctr_lat=(double *)nco_free(grd_ctr_lat);
+  if(grd_ctr_lon) grd_ctr_lon=(double *)nco_free(grd_ctr_lon);
+  if(grd_crn_lat) grd_crn_lat=(double *)nco_free(grd_crn_lat);
+  if(grd_crn_lon) grd_crn_lon=(double *)nco_free(grd_crn_lon);
+  if(lat_bnd) lat_bnd=(double *)nco_free(lat_bnd);
+  if(lat_crn) lat_crn=(double *)nco_free(lat_crn);
+  if(lat_ctr) lat_ctr=(double *)nco_free(lat_ctr);
+  if(lat_ntf) lat_ntf=(double *)nco_free(lat_ntf);
+  if(lat_sin) lat_sin=(double *)nco_free(lat_sin);
+  if(lat_wgt) lat_wgt=(double *)nco_free(lat_wgt);
+  if(lon_bnd) lon_bnd=(double *)nco_free(lon_bnd);
+  if(lon_crn) lon_crn=(double *)nco_free(lon_crn);
+  if(lon_ctr) lon_ctr=(double *)nco_free(lon_ctr);
+  if(lon_ntf) lon_ntf=(double *)nco_free(lon_ntf);
+  if(wgt_Gss) wgt_Gss=(double *)nco_free(wgt_Gss);
+  
+  return rcd;
+} /* !nco_grd_mk() */
+
diff --git a/src/nco/nco_rgr.h b/src/nco/nco_rgr.h
index 0a6dcf4..d6ec1c3 100644
--- a/src/nco/nco_rgr.h
+++ b/src/nco/nco_rgr.h
@@ -62,20 +62,13 @@ extern "C" {
     nco_rgr_mpf_Tempest,
   } nco_rgr_mpf_typ_enm;
 
-  typedef enum nco_rgr_grd_typ_enm{ /* [enm] Regrid type enum */
+  typedef enum nco_rgr_typ_enm{ /* [enm] Regrid type enum */
     nco_rgr_grd_nil=0,
     nco_rgr_grd_1D_to_1D,
     nco_rgr_grd_1D_to_2D,
     nco_rgr_grd_2D_to_1D,
     nco_rgr_grd_2D_to_2D,
-  } nco_rgr_grd_typ_enm;
-
-  typedef enum nco_grd_2D_typ_enm{ /* [enm] Two-dimensional grid-type enum */
-    nco_grd_2D_nil=0,
-    nco_grd_2D_gss, /* Gaussian latitudes used by global spectral models: CCM 1-3, CAM 1-3, LSM, MATCH, UCICTM */
-    nco_grd_2D_ngl_eqi_pol, /* Equi-angle grid including poles, the FV scalar grid (lat[0]=-90): CAM FV, GEOS-CHEM, UCICTM, UKMO */
-    nco_grd_2D_ngl_eqi_fst, /* Equi-angle offset grid, FV staggered velocity grid (lat[0]=-89.X)): CIESIN/SEDAC, IGBP-DIS, TOMS AAI */
-  } nco_grd_2D_typ_enm;
+  } nco_rgr_typ_enm;
 
   typedef enum nco_grd_xtn_enm{ /* [enm] Grid-extent enum */
     nco_grd_xtn_nil=0,
@@ -101,7 +94,7 @@ extern "C" {
     nco_rgr_mth_unknown, /* Tempest */
   } nco_rgr_mth_typ_enm;
 
-  typedef struct{ /* nco_map_sct */
+  typedef struct{ /* nco_mpf_sct */
     /* Contents of SCRIP-generated or -compliant remapping file */
     long int src_grid_size; /* [nbr] Source grid size (src_grid_size or n_a) */
     long int dst_grid_size; /* [nbr] Destination grid size (dst_grid_size or n_b) */
@@ -115,13 +108,17 @@ extern "C" {
     char *map_method; /* [sng] Remapping method */
     char *source_grid; /* [sng] Source grid */
     char *dest_grid; /* [sng] Destination grid */
-  } nco_map_sct;
+  } nco_mpf_sct;
   
   void
   nco_bsl_zro /*  Return Bessel function zeros */
   (const int bsl_zro_nbr, /* O [nbr] Order of Bessel function */
    double * const bsl_zro); /* O [frc] Bessel zero */
-  
+
+  int /* O [enm] Return code */
+  nco_grd_mk /* [fnc] Create SCRIP-format grid file */
+  (rgr_sct * const rgr); /* I/O [sct] Regridding structure */
+
   void
   nco_lat_wgt_gss /* [fnc] Compute and return sine of Gaussian latitudes and their weights */
   (const int lat_nbr, /* I [nbr] Latitude number */
@@ -129,7 +126,7 @@ extern "C" {
    double * const wgt_Gss); /* O [frc] Gaussian weights */
 
   int /* O [enm] Return code */
-  nco_rgr_map /* [fnc] Regrid using external weights */
+  nco_rgr_map /* [fnc] Regrid with external weights */
   (rgr_sct * const rgr_nfo, /* I/O [sct] Regridding structure */
    trv_tbl_sct * const trv_tbl); /* I/O [sct] Traversal Table */
 
@@ -140,7 +137,8 @@ extern "C" {
 
   rgr_sct * /* O [sct] Regridding structure */
   nco_rgr_ini /* [fnc] Initialize regridding structure */
-  (const int in_id, /* I [id] Input netCDF file ID */
+  (const char * const cmd_ln, /* I [sng] Command-line */
+   const int in_id, /* I [id] Input netCDF file ID */
    char **rgr_arg, /* [sng] Regridding arguments */
    const int rgr_nbr, /* [nbr] Number of regridding arguments */
    char * const rgr_in, /* I [sng] File containing fields to be regridded */
@@ -163,13 +161,21 @@ extern "C" {
   nco_grd_2D_sng /* [fnc] Convert two-dimensional grid-type enum to string */
   (const nco_grd_2D_typ_enm nco_grd_2D_typ); /* I [enm] Two-dimensional grid-type enum */
 
+  const char * /* O [sng] String describing latitude grid-type */
+  nco_grd_lat_sng /* [fnc] Convert latitude grid-type enum to string */
+  (const nco_grd_lat_typ_enm nco_grd_lat_typ); /* I [enm] Latitude grid-type enum */
+
+  const char * /* O [sng] String describing longitude grid-type */
+  nco_grd_lon_sng /* [fnc] Convert longitude grid-type enum to string */
+  (const nco_grd_lon_typ_enm nco_grd_lon_typ); /* I [enm] Longitude grid-type enum */
+
   const char * /* O [sng] String describing grid extent */
   nco_grd_xtn_sng /* [fnc] Convert two-dimensional grid-extent enum to string */
   (const nco_grd_xtn_enm nco_grd_xtn); /* I [enm] Grid-extent enum */
 
   const char * /* O [sng] String describing grid conversion */
   nco_rgr_grd_sng /* [fnc] Convert grid conversion enum to string */
-  (const nco_rgr_grd_typ_enm nco_rgr_grd_typ); /* I [enm] Grid conversion enum */
+  (const nco_rgr_typ_enm nco_rgr_typ); /* I [enm] Grid conversion enum */
 
   const char * /* O [sng] String describing regridding method */
   nco_rgr_mth_sng /* [fnc] Convert regridding method enum to string */
diff --git a/src/nco/nco_rth_utl.c b/src/nco/nco_rth_utl.c
index 87d3b2d..c7408e8 100644
--- a/src/nco/nco_rth_utl.c
+++ b/src/nco/nco_rth_utl.c
@@ -134,7 +134,7 @@ nco_opr_drv /* [fnc] Intermediate control of arithmetic operations for ncra/nces
      20130112: The same logic applies to CF-style coordinates, e.g., 
      to variables matching CF "bounds", "climatology", and "coordinates" conventions */
   if(var_prc->is_crd_var){
-    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
+    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->wgt_crr,var_prc->wgt_sum,var_prc->val,var_prc_out->val);
     return;
   } /* !var_prc->is_crd_var */
 
@@ -162,7 +162,7 @@ nco_opr_drv /* [fnc] Intermediate control of arithmetic operations for ncra/nces
        Following loops, do comparative maximum after taking absolute value */
     (void)nco_var_abs(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->val);
     if(idx_rec == 0) (void)nco_var_copy(var_prc->type,var_prc->sz,var_prc->val,var_prc_out->val); 
-    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
+    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->wgt_crr,var_prc->wgt_sum,var_prc->val,var_prc_out->val);
     break;	
   case nco_op_mibs: /* Mean absolute value */
     /* Always take the absolute value of the fresh input
@@ -182,14 +182,14 @@ nco_opr_drv /* [fnc] Intermediate control of arithmetic operations for ncra/nces
        (with nco_var_add_tll_ncra()) only check new addend (not running sum) against missing value.
        Hence (as of 20120521) nco_var_copy_tll() specifically resets sum to zero rather than to missing value
        Parent function (e.g., ncra.c) must post-process ttl buffers nco_op_ttl with nco_var_tll_zro_mss_val() */
-    if(idx_rec == 0) (void)nco_var_copy_tll(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val); else (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
+    if(idx_rec == 0) (void)nco_var_copy_tll(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val); else (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->wgt_crr,var_prc->wgt_sum,var_prc->val,var_prc_out->val);
     break;
   case nco_op_avg: /* Average */
   case nco_op_sqrt: /* Squareroot will produce the squareroot of the mean */
   case nco_op_sqravg: /* Square of the mean */
     /* These operations all require subsequent normalization, where degenerate tallies are accounted for
        Thus, they all call nco_var_add_tll_ncra() every iteration, without special treatment on first iteration */
-    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
+    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->wgt_crr,var_prc->wgt_sum,var_prc->val,var_prc_out->val);
     break;
   case nco_op_rms: /* Root mean square */
   case nco_op_rmssdn: /* Root mean square normalized by N-1 */
@@ -197,7 +197,7 @@ nco_opr_drv /* [fnc] Intermediate control of arithmetic operations for ncra/nces
     /* Square values in var_prc first */
     nco_var_mlt(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->val,var_prc->val);
     /* Sum the squares */
-    (void)nco_var_add_tll_ncra(var_prc_out->type,var_prc_out->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
+    (void)nco_var_add_tll_ncra(var_prc_out->type,var_prc_out->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->wgt_crr,var_prc->wgt_sum,var_prc->val,var_prc_out->val);
     break;
   } /* end switch */
 } /* end nco_opr_drv() */
diff --git a/src/nco/nco_scm.c b/src/nco/nco_scm.c
index 2ed6f97..d277db4 100644
--- a/src/nco/nco_scm.c
+++ b/src/nco/nco_scm.c
@@ -149,7 +149,7 @@ nco_cpy_prn(void) /* [fnc] Print copyright notice */
 {
   /* Purpose: Print copyright notice */
   (void)fprintf(stderr,"Copyright (C) 1995--2015 Charlie Zender\n");
-  (void)fprintf(stdout,"This program is part of NCO, the netCDF Operators.\nNCO is free software and comes with a BIG FAT KISS and ABOLUTELY NO WARRANTY\nYou may redistribute and/or modify NCO under the terms of the\nGNU General Public License (GPL) Version 3 with exceptions described in the LICENSE file\nGPL: http://www.gnu.org/copyleft/gpl.html\nLICENSE: https://github.com/czender/nco/tree/master/LICENSE\n");
+  (void)fprintf(stdout,"This program is part of NCO, the netCDF Operators.\nNCO is free software and comes with a BIG FAT KISS and ABOLUTELY NO WARRANTY\nYou may redistribute and/or modify NCO under the terms of the\nGNU General Public License (GPL) Version 3 with exceptions described in the LICENSE file\nGPL: http://www.gnu.org/copyleft/gpl.html\nLICENSE: https://github.com/nco/nco/tree/master/LICENSE\n");
 } /* end copyright_prn() */
 
 void
diff --git a/src/nco/nco_sld.c b/src/nco/nco_sld.c
index 27e324f..dc82ead 100644
--- a/src/nco/nco_sld.c
+++ b/src/nco/nco_sld.c
@@ -200,6 +200,22 @@ nco_esmf_pll_mth_sng /* [fnc] Convert ESMF pole method type enum to string */
   return (char *)NULL;
 } /* end nco_esmf_pll_mth_sng() */
 
+const char * /* O [sng] String version of ESMC_PoleKind_Flag enum */
+nco_esmf_pll_knd_sng /* [fnc] Convert ESMF pole type enum to string */
+(const int nco_esmf_pll_knd) /* I [enm] ESMF pole type enum ESMC_PoleKind_Flag */
+{
+  /* Purpose: Convert ESMF pole method enum ESMC_PoleKind_Flag to string */
+  switch(nco_esmf_pll_knd){
+  case ESMC_POLEKIND_NONE: return "ESMC_POLEKIND_NONE";
+  case ESMC_POLEKIND_MONOPOLE: return "ESMC_POLEKIND_MONOPOLE";
+  case ESMC_POLEKIND_BIPOLE: return "ESMC_POLEKIND_BIPOLE";
+  default: abort(); break;
+  } /* end switch */
+
+  /* Some compilers: e.g., SGI cc, need return statement to end non-void functions */
+  return (char *)NULL;
+} /* end nco_esmf_pll_knd_sng() */
+
 const char * /* O [sng] String version of ESMC_UnmappedAction_Flag enum */
 nco_esmf_unm_act_sng /* [fnc] Convert ESMF unmapped action type enum to string */
 (const int nco_esmf_unm_act) /* I [enm] ESMF unmapped action type enum ESMC_UnmappedAction_Flag */
@@ -248,8 +264,10 @@ nco_rgr_esmf /* [fnc] Regrid using ESMF library */
      ${DATA}/esmf/src/Infrastructure/Field/tests/ESMC_FieldRegridUTest.C
      ${DATA}/esmf/src/Infrastructure/Field/tests/ESMC_FieldRegridCsrvUTest.C
 
-     Usage:
-     ncks -4 -O -C -v ppc_dbl --ppc /ppc_dbl=3 ~/nco/data/in.nc ~/foo.nc */
+     Sample call, T42->T42:
+     ncks -O --rgr_grd_src=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_grd_dst=${DATA}/scrip/grids/remap_grid_T42.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc
+     ncks -O --rgr_var=LANDFRAC --rgr_grd_src=${DATA}/grids/T42.nc --rgr_grd_dst=${DATA}/grids/T62.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc
+     ncks -O --rgr lat_nbr=180 --rgr_grd_src=${DATA}/grids/T62.nc --rgr_grd_dst=${DATA}/grids/T42.nc ${DATA}/dstmch90/dstmch90_clm.nc ~/foo.nc */
   
   const char fnc_nm[]="nco_rgr_esmf()"; /* [sng] Function name */
   const char fl_nm_esmf_log[]="nco_rgr_log_foo.txt"; /* [sng] Log file for ESMF routines */
@@ -640,5 +658,434 @@ nco_rgr_esmf /* [fnc] Regrid using ESMF library */
   ESMC_Finalize();
 
   return rcd;
-} /* nco_rgr_esmf */
+} /* !nco_rgr_esmf() */
+
+int /* O [enm] Return code */
+nco_rgr_esmf2 /* [fnc] Regrid using ESMF library */
+(rgr_sct * const rgr) /* I/O [sct] Regridding structure */
+{
+  /* Purpose: Regrid fields using ESMF library (actually ESMC interface to ESMF library)
+     ESMC is C-interface to ESMF documented at
+     http://www.earthsystemmodeling.org/esmf_releases/last_built/ESMC_crefdoc/ESMC_crefdoc.html
+     ESMF Developer's Guide
+     http://www.earthsystemmodeling.org/documents/dev_guide
+     ESMF_RegridWeightGen
+     http://www.earthsystemcog.org/projects/regridweightgen
+     http://www.earthsystemmodeling.org/python_releases/last_esmpy/esmpy_doc/html/index.html
+
+     ESMF C-interface examples:
+     ${DATA}/esmf/src/Infrastructure/Field/tests/ESMC_FieldRegridUTest.C
+     ${DATA}/esmf/src/Infrastructure/Field/tests/ESMC_FieldRegridCsrvUTest.C
+
+     Sample call, T42->T42:
+     ncks -O --rgr_grd_src=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_grd_dst=${DATA}/scrip/grids/remap_grid_T42.nc --rgr_out=${DATA}/rgr/rgr_out.nc ${DATA}/rgr/essgcm14_clm.nc ~/foo.nc */
+
+  const char fnc_nm[]="nco_rgr_esmf2()"; /* [sng] Function name */
+  const char fl_nm_esmf_log[]="nco_rgr_log_foo.txt"; /* [sng] Log file for ESMF routines */
+  
+  /* SCRIP rank-2 grids are almost always lat,lon (C) and lon,lat (Fortran)
+     Indexing is confusing because ESMF always uses Fortran-ordering convention with mixture of 0- and 1-based indices
+     netCDF always uses C-ordering convention with 0-based indices
+     No data transposition is necessary because variable RAM is always in C-order (same as netCDF)
+     However, Fortran and C (i.e., ESMF and netCDF) access that same RAM using different conventions
+     2-D data are always C[lat,lon] or F(lon,lat) in practice
+     2-D stored in netCDF or RAM as C[lon,lat] and F(lat,lon) are possible, though not seen in practice
+     NCO regridding below assumes data are in C[lat,lon] order
+     NCO hardcoded subscript conventions follow this pattern:
+     crd_idx_[axs]_[ibs]_[dmn]_[grd] where
+     axs = access convention = C or Fortran = _c_ or _f_ 
+     ibs = index base = 0 or 1 = _0bs_ or _1bs_ for zero-based or one-based indices
+     NB: axs is independent from ibs! 
+     dmn = dimension = lon or lat
+     grd = grid = source or destination */
+  const int crd_idx_c_0bs_lat_dst=0; /* [dgr] 0-based index of latitude  in C       representation of rank-2 destination grids */
+  const int crd_idx_c_0bs_lon_dst=1; /* [dgr] 0-based index of longitude in C       representation of rank-2 destination grids */
+  const int crd_idx_f_0bs_lat_dst=1; /* [dgr] 0-based index of latitude  in Fortran representation of rank-2 destination grids */
+  const int crd_idx_f_0bs_lat_src=1; /* [dgr] 0-based index of latitude  in Fortran representation of rank-2 source grids */
+  const int crd_idx_f_0bs_lon_dst=0; /* [dgr] 0-based index of longitude in Fortran representation of rank-2 destination grids */
+  const int crd_idx_f_0bs_lon_src=0; /* [dgr] 0-based index of longitude in Fortran representation of rank-2 source grids */
+  const int crd_idx_f_1bs_lat_dst=2; /* [dgr] 1-based index of latitude  in Fortran representation of rank-2 destination grids */
+  const int crd_idx_f_1bs_lat_src=2; /* [dgr] 1-based index of latitude  in Fortran representation of rank-2 source grids */
+  const int crd_idx_f_1bs_lon_dst=1; /* [dgr] 1-based index of longitude in Fortran representation of rank-2 destination grids */
+  const int crd_idx_f_1bs_lon_src=1; /* [dgr] 1-based index of longitude in Fortran representation of rank-2 source grids */
+
+  double *lon_in;
+  double *lat_in;
+
+  enum ESMC_StaggerLoc stg_lcn_src=ESMC_STAGGERLOC_CENTER; /* [enm] Stagger location of source grid */
+  enum ESMC_StaggerLoc stg_lcn_dst=ESMC_STAGGERLOC_CENTER; /* [enm] Stagger location of destination grid */
+
+  int *dmn_id;
+  int dmn_nbr;
+  int dmn_nbr_grd=2;
+  int flg_openMPEnabledFlag; /* [flg] ESMF library was compiled with OpenMP enabled */
+  int flg_pthreadsEnabledFlag; /* [flg] ESMF library was compiled with Pthreads enabled */
+  int idx;
+  int in_id; /* I [id] Input netCDF file ID */
+  int localPet; /* [id] ID of PET that issued call */
+  int out_id; /* I [id] Output netCDF file ID */
+  int peCount; /* [nbr] Number of PEs referenced by ESMF_VM */
+  int petCount; /* [nbr] Number of PETs referenced by ESMF_VM */
+  int rcd=ESMF_SUCCESS;
+  int rcd_esmf; /* [enm] Return codes from ESMF functions */
+  int var_in_id;
+  
+  long *dmn_cnt;
+  long *dmn_srt;
+  
+  nc_type var_typ_in;
+  nc_type crd_typ_out=NC_DOUBLE;
+  nc_type var_typ_out=NC_DOUBLE;
+  
+  void *void_ptr_var;
+  
+  /* Initialize */
+  in_id=rgr->in_id;
+  out_id=rgr->out_id;
+  
+  /* Obtain input longitude type and length */
+  char lon_nm_in[]="lon";
+  (void)nco_inq_varid(in_id,lon_nm_in,&var_in_id);
+  (void)nco_inq_var(in_id,var_in_id,(char *)NULL,&var_typ_in,&dmn_nbr,(int *)NULL,(int *)NULL);
+  if(var_typ_in != NC_DOUBLE){
+    assert(var_typ_in == NC_FLOAT);
+    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO WARNING Cheapskate regridding input file %s stores coordinate as NC_FLOAT\n",nco_prg_nm_get(),rgr->fl_in);
+  } /* !var_typ_in */
+
+  /* Allocate space to hold dimension metadata */
+  dmn_cnt=(long *)nco_malloc(dmn_nbr*sizeof(long));
+  dmn_id=(int *)nco_malloc(dmn_nbr*sizeof(int));
+  dmn_srt=(long *)nco_malloc(dmn_nbr*sizeof(long));
+  (void)nco_inq_vardimid(in_id,var_in_id,dmn_id);
+  /* Get input dimension sizes */
+  long dmn_sz=1L; /* [nbr] Number of elements in dimension (will be self-multiplied) */
+  for(idx=0;idx<dmn_nbr;idx++){
+    (void)nco_inq_dimlen(in_id,dmn_id[idx],dmn_cnt+idx);
+    dmn_srt[idx]=0L;
+    dmn_sz*=dmn_cnt[idx];
+  } /* end loop over dim */
+  
+  int *max_idx; /* [nbr] Zero-based array containing dimension sizes in order? */
+  max_idx=(int *)nco_malloc(dmn_nbr_grd*sizeof(int));
+  max_idx[crd_idx_f_0bs_lon_src]=dmn_sz; /* [nbr] Number of elements in dimensions */
+  
+  /* Allocate space for and obtain longitude */
+  lon_in=(double *)nco_malloc(dmn_sz*nco_typ_lng(crd_typ_out));
+  rcd=nco_get_vara(in_id,var_in_id,dmn_srt,dmn_cnt,lon_in,crd_typ_out);
+
+  /* Obtain input latitude type and length */
+  char lat_nm_in[]="lat";
+  (void)nco_inq_varid(in_id,lat_nm_in,&var_in_id);
+  (void)nco_inq_var(in_id,var_in_id,(char *)NULL,&var_typ_in,&dmn_nbr,(int *)NULL,(int *)NULL);
+  if(var_typ_in != NC_DOUBLE){
+    assert(var_typ_in == NC_FLOAT);
+    if(nco_dbg_lvl_get() >= nco_dbg_std) (void)fprintf(stderr,"%s: INFO WARNING Cheapskate regridding input file %s stores coordinate as NC_FLOAT\n",nco_prg_nm_get(),rgr->fl_in);
+  } /* !var_typ_in */
+  (void)nco_inq_vardimid(in_id,var_in_id,dmn_id);
+  dmn_sz=1L;
+  /* Get dimension sizes from input file */
+  for(idx=0;idx<dmn_nbr;idx++){
+    (void)nco_inq_dimlen(in_id,dmn_id[idx],dmn_cnt+idx);
+    dmn_srt[idx]=0L;
+    dmn_sz*=dmn_cnt[idx];
+  } /* end loop over dim */
+  max_idx[crd_idx_f_0bs_lat_src]=dmn_sz; /* [nbr] Number of elements in dimensions */
+
+  /* Allocate space for and obtain latitude */
+  lat_in=(double *)nco_malloc(dmn_sz*nco_typ_lng(crd_typ_out));
+  rcd=nco_get_vara(in_id,var_in_id,dmn_srt,dmn_cnt,lat_in,crd_typ_out);
+
+  /* Initialize before any other ESMC API calls!
+     ESMC_ArgLast is ALWAYS at the end to indicate the end of opt args */
+  ESMC_Initialize(&rcd_esmf,
+		  ESMC_InitArgDefaultCalKind(ESMC_CALKIND_GREGORIAN),
+		  ESMC_InitArgLogFilename(fl_nm_esmf_log),
+		  ESMC_InitArgLogKindFlag(ESMC_LOGKIND_MULTI),
+		  ESMC_ArgLast);
+  enum ESMC_LogMsgType_Flag log_msg_typ=ESMC_LOGMSG_TRACE;
+  if(rcd_esmf != ESMF_SUCCESS){
+    ESMC_LogWrite("ESMC_Initialize() failed",log_msg_typ);
+    /* 20150621: 
+       Prevent clang sometimes uninitialized warnings by using abort() before goto
+       All of the following "abort()" statements could be replace "goto rgr_cln:" statements
+       gcc is fine with this, but it triggers clang "sometimes uninitialized" warnings
+       g++ (without -fpermissive) emits "jump to label" "crosses initialization" warnings 
+       when pointers are declared between the goto statment and the label statement 
+       Hence we abandon the false premise of recovery after ESMC errors, and just abort() */
+    abort();
+  } /* endif */
+  
+  /* Set log to flush after every message */
+  rcd_esmf=ESMC_LogSet(ESMF_TRUE);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  /* Obtain VM */
+  ESMC_VM vm;
+  vm=ESMC_VMGetGlobal(&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* Set-up local PET info */
+  /* Source: ${DATA}/esmf/src/Infrastructure/VM/interface/ESMC_VM.C */
+  rcd_esmf=ESMC_VMGet(vm,&localPet,&petCount,&peCount,(MPI_Comm *)NULL,&flg_pthreadsEnabledFlag,&flg_openMPEnabledFlag);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* 20150718: Create destination grid from user specifications */
+  /* First create ESMC_InterfaceInt that describes grid size 
+     Then use that ESMC_InterfaceInt to create ESMC_Grid
+     ESMC_InterfaceInt stores grid indexing information for all dimensions */
+  int *max_idx_dst; /* [nbr] Zero-based array containing dimension sizes in order? */
+  int dmn_nbr_grd_dst=2;
+  max_idx_dst=(int *)nco_malloc(dmn_nbr_grd_dst*sizeof(int));
+  max_idx_dst[crd_idx_f_0bs_lon_src]=rgr->lat_nbr*rgr->lon_nbr; /* [nbr] Number of elements in dimensions */
+
+  ESMC_InterfaceInt grd_ntf_dst;
+  /* Source: ${DATA}/esmf/src/Infrastructure/Util/interface/ESMC_Interface.C
+     NB: ESMF is fragile in that dynamic memory provided as input to grids cannot be immediately freed
+     In other words, ESMF copies the values of pointers but not the contents of pointers to provided arrays
+     To be concrete, the max_idx_dst array provided below cannot be freed until after the ESMC_Finalize() is called */
+  grd_ntf_dst=ESMC_InterfaceIntCreate(max_idx_dst,dmn_nbr_grd_dst,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  int flg_isSphere=1; /* [flg] Set to 1 for spherical grid, or 0 for regional. Defaults to 1 (True). */
+  int flg_addCornerStagger=0; /* [flg] Add corner stagger to grid. Defaults to 0 (False). */
+  int flg_addUserArea=0; /* [flg] Read cell area from Grid file (instead of calculate it). Defaults to 0 (False). */
+  int flg_addMask=0; /* [flg] Generate mask using missing value attribute in var_nm (iff GRIDSPEC) */
+  /* 20150424: ESMF library bug at ESMCI_Grid.C line 365 means var_nm must non-NULL so set to blank name */
+  char var_nm[]=""; /* [sng] Iff addMask == 1 use this variable's missing value attribute */
+  char **crd_nm=NULL; /* [sng] Iff GRIDSPEC use these lon/lat variable coordinates */
+  enum ESMC_FileFormat_Flag grd_fl_typ=ESMC_FILEFORMAT_SCRIP;
+  enum ESMC_PoleKind_Flag poleKind[2]={ESMC_POLEKIND_MONOPOLE,ESMC_POLEKIND_MONOPOLE}; /* [enm] Pole type */
+  enum ESMC_CoordSys_Flag crd_sys=ESMC_COORDSYS_SPH_DEG; /* NB: ESMF supports ESMC_COORDSYS_SPH_DEG only? */
+  enum ESMC_TypeKind_Flag typ_knd=ESMC_TYPEKIND_R8; /* NB: NCO default is to use double precision for coordinates */
+  ESMC_Grid grd_dst;
+  // int periodicDim=crd_idx_f_1bs_lon_dst; /* [idx] Periodic dimension */
+  // int poleDim=crd_idx_f_1bs_lat_dst; /* [idx] Pole dimension */
+  grd_dst=ESMC_GridCreate1PeriDim(grd_ntf_dst,&crd_sys,&typ_knd,poleKind,&rcd_esmf); // API: /usr/local/include/ESMC_Grid.h
+  //  grd_dst=ESMC_GridCreate1PeriDim(grd_ntf_dst,&periodicDim,&poleDim,&crd_sys,&typ_knd,&poleKind,&rcd_esmf); // API: http://www.earthsystemmodeling.org/esmf_releases/last_built/ESMC_crefdoc/node5.html#SECTION05055200000000000000
+  //  grd_dst=ESMC_GridCreateFromFile(rgr->fl_grd_dst,grd_fl_typ,&flg_isSphere,&flg_addCornerStagger,&flg_addUserArea,&flg_addMask,var_nm,crd_nm,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  int *msk_dst; /* [enm] Destination grid mask */
+  enum ESMC_GridItem_Flag grd_itm=ESMC_GRIDITEM_MASK;
+  msk_dst=(int *)ESMC_GridGetItem(grd_dst,grd_itm,stg_lcn_dst,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  int *bnd_lwr_dst=(int *)nco_malloc(dmn_nbr_grd*sizeof(int));
+  int *bnd_upr_dst=(int *)nco_malloc(dmn_nbr_grd*sizeof(int));
+  double *lon_dst; /* [dgr] Destination grid longitude */
+  double *lat_dst; /* [dgr] Destination grid latitude */
+  /* 20150427: Written documentation is somewhat inadequate or misleading to normal C-programmers
+     Some ESMC_Grid***() functions, like this one, return allocated void pointers that must be cast to desired numeric type
+     Source: ${DATA}/esmf/src/Infrastructure/Grid/interface/ESMC_Grid.C */
+  lon_dst=(double *)ESMC_GridGetCoord(grd_dst,crd_idx_f_1bs_lon_dst,stg_lcn_dst,bnd_lwr_dst,bnd_upr_dst,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  lat_dst=(double *)ESMC_GridGetCoord(grd_dst,crd_idx_f_1bs_lat_dst,stg_lcn_dst,bnd_lwr_dst,bnd_upr_dst,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  double *lon_out; /* [dgr] Longitude dimension for output file */
+  double *lat_out; /* [dgr] Latitude  dimension for output file */
+  lon_out=(double *)nco_malloc(bnd_upr_dst[crd_idx_f_0bs_lon_dst]*sizeof(double));
+  lat_out=(double *)nco_malloc(bnd_upr_dst[crd_idx_f_0bs_lat_dst]*sizeof(double));
+  for(idx=0;idx<bnd_upr_dst[crd_idx_f_0bs_lon_dst];idx++) lon_out[idx]=lon_dst[idx];
+  for(idx=0;idx<bnd_upr_dst[crd_idx_f_0bs_lat_dst];idx++) lat_out[idx]=lat_dst[idx];
+  const long var_sz_dst=bnd_upr_dst[crd_idx_f_0bs_lon_dst]*bnd_upr_dst[crd_idx_f_0bs_lat_dst]; /* [nbr] Number of elements in variable */
+  for(idx=0;idx<var_sz_dst;idx++) msk_dst[idx]=0;
+
+  /* Create source grid with same sizes as those in input data file */
+  ESMC_InterfaceInt max_idx_src;
+  /* Source: ${DATA}/esmf/src/Infrastructure/Util/interface/ESMC_Interface.C
+     NB: ESMF is fragile in that dynamic memory provided as input to grids cannot be immediately freed
+     In other words, ESMF copies the values of pointers but not the contents of pointers to provided arrays
+     To be concrete, the max_idx array provided below cannot be freed until after the ESMC_Finalize() is called */
+  max_idx_src=ESMC_InterfaceIntCreate(max_idx,dmn_nbr_grd,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  ESMC_Grid grd_src;
+  /* Source: ${DATA}/esmf/src/Infrastructure/Grid/interface/ESMC_Grid.C */
+  grd_src=ESMC_GridCreateNoPeriDim(max_idx_src,&crd_sys,&typ_knd,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  /* fxm: why destroy this now? */
+  ESMC_InterfaceIntDestroy(&max_idx_src);
+  /* Define stagger locations on source grid. Necessary for remapping later? */
+  rcd_esmf=ESMC_GridAddCoord(grd_src,stg_lcn_src);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  
+  /* Allocate */
+  int *bnd_lwr_src=(int *)nco_malloc(dmn_nbr_grd*sizeof(int));
+  int *bnd_upr_src=(int *)nco_malloc(dmn_nbr_grd*sizeof(int));
+  double *lon_src; /* [dgr] Source grid longitude */
+  double *lat_src; /* [dgr] Source grid latitude  */
+  lon_src=(double *)ESMC_GridGetCoord(grd_src,crd_idx_f_1bs_lon_src,stg_lcn_src,bnd_lwr_src,bnd_upr_src,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  lat_src=(double *)ESMC_GridGetCoord(grd_src,crd_idx_f_1bs_lat_src,stg_lcn_src,NULL,NULL,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  if(nco_dbg_lvl_get() >= nco_dbg_crr){
+    (void)fprintf(stderr,"%s: INFO %s reports\n",nco_prg_nm_get(),fnc_nm);
+    (void)fprintf(stderr,"ESMC_VMGet(): localPet = %d, petCount = %d, peCount = %d, pthreadsEnabledFlag = %s, openMPEnabledFlag = %s\n",localPet,petCount,peCount,flg_pthreadsEnabledFlag ? "Enabled" : "Disabled",flg_openMPEnabledFlag ? "Enabled" : "Disabled");
+    (void)fprintf(stderr,"ESMC_GridCreateFromFile(): filename = %s, fileTypeFlag = %s, isSphere = %s, addCornerStagger = %s, addUserArea = %s, addMask = %s, var_nm = %s, crd_nm = %s\n",rgr->fl_grd_dst,nco_esmf_fl_fmt_sng(grd_fl_typ),flg_isSphere ? "Enabled" : "Disabled",flg_addCornerStagger ? "Enabled" : "Disabled",flg_addUserArea ? "Enabled" : "Disabled",flg_addMask ? "Enabled" : "Disabled",var_nm,crd_nm ? "non-NULL" : "NULL");
+    (void)fprintf(stderr,"ESMC_GridGetCoord(): bnd_lwr_dst[0..1] = %d, %d; bnd_upr_dst[0..1] = %d, %d;\n",bnd_lwr_dst[0],bnd_lwr_dst[1],bnd_upr_dst[0],bnd_upr_dst[1]);
+    (void)fprintf(stderr,"ESMC_InterfaceIntCreate(): No printable information\n");
+    (void)fprintf(stderr,"ESMC_GridCreateNoPeriDim(): crd_sys = %s, typ_knd = %s\n",nco_esmf_crd_sys_sng(crd_sys),nco_esmf_typ_knd_sng(typ_knd));
+    (void)fprintf(stderr,"ESMC_GridAddCoord(): stg_lcn_src = %s,  stg_lcn_dst = %s\n",nco_esmf_stg_lcn_sng(stg_lcn_src),nco_esmf_stg_lcn_sng(stg_lcn_dst));
+    (void)fprintf(stderr,"ESMC_GridGetCoord(): bnd_lwr_src[0..1] = %d, %d; bnd_upr_src[0..1] = %d, %d;\n",bnd_lwr_src[0],bnd_lwr_src[1],bnd_upr_src[0],bnd_upr_src[1]);
+    //    (void)fprintf(stderr,"ESMC_InterfaceIntCreate(): max_idx_src[0..1] = %d, %d\n",max_idx_src[0],max_idx_src[1]);
+  } /* endif dbg */
+
+  /* Type-conversion and cell-center coordinates */
+  for(idx=0;idx<bnd_upr_src[crd_idx_f_0bs_lat_src];idx++) lat_src[idx]=lat_in[idx];
+  for(idx=0;idx<bnd_upr_src[crd_idx_f_0bs_lon_src];idx++) lon_src[idx]=lon_in[idx];
+  idx=0;
+  for(int idx_lat=0;idx_lat<bnd_upr_src[crd_idx_f_0bs_lat_src];idx_lat++){
+    for(int idx_lon=0;idx_lon<bnd_upr_src[crd_idx_f_0bs_lon_src];idx_lon++){
+      lon_src[idx]=lon_in[idx_lon];
+      lat_src[idx]=lat_in[idx_lat];
+      idx++;
+    } /* endfor */
+  } /* endfor */
+  
+  /* Create source field from source grid */
+  ESMC_Field fld_src;
+  ESMC_InterfaceInt *gridToFieldMap=NULL; /* [idx] Map of all grid dimensions to field dimensions */
+  ESMC_InterfaceInt *ungriddedLBound=NULL; /* [idx] Lower bounds of ungridded dimensions */
+  ESMC_InterfaceInt *ungriddedUBound=NULL; /* [idx] Upper bounds of ungridded dimensions */
+  fld_src=ESMC_FieldCreateGridTypeKind(grd_src,typ_knd,stg_lcn_src,gridToFieldMap,ungriddedLBound,ungriddedUBound,"fld_src",&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  /* Create destination field from destination grid */
+  ESMC_Field fld_dst;
+  fld_dst=ESMC_FieldCreateGridTypeKind(grd_dst,typ_knd,stg_lcn_dst,gridToFieldMap,ungriddedLBound,ungriddedUBound,"fld_dst",&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* Get field pointers */
+  double *fld_src_ptr;
+  int localDe=0; /* [idx] Local DE for which information is requested [0..localDeCount-1] */
+  fld_src_ptr=(double *)ESMC_FieldGetPtr(fld_src,localDe,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+  double *fld_dst_ptr;
+  fld_dst_ptr=(double *)ESMC_FieldGetPtr(fld_dst,localDe,&rcd_esmf);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* Get variables from input file */
+  (void)nco_inq_varid(in_id,rgr->var_nm,&var_in_id);
+  (void)nco_inq_var(in_id,var_in_id,(char *)NULL,&var_typ_in,&dmn_nbr,(int *)NULL,(int *)NULL);
+  /* Get dimension IDs from input file */
+  (void)nco_inq_vardimid(in_id,var_in_id,dmn_id);
+  long var_sz_src=1L; /* [nbr] Number of elements in variable (will be self-multiplied) */
+  /* Get input dimension sizes */
+  for(idx=0;idx<dmn_nbr;idx++){
+    (void)nco_inq_dimlen(in_id,dmn_id[idx],dmn_cnt+idx);
+    dmn_srt[idx]=0L;
+    var_sz_src*=dmn_cnt[idx];
+  } /* end loop over dim */
+
+  /* Allocate space for and obtain input latitude */
+  void_ptr_var=(void *)nco_malloc_dbg(var_sz_src*nco_typ_lng(var_typ_in),"Unable to malloc() value buffer when copying hyperslab from input to output file",fnc_nm);
+  rcd=nco_get_vara(in_id,var_in_id,dmn_srt,dmn_cnt,void_ptr_var,var_typ_in);
+  float *var_fld=(float *)void_ptr_var;
+
+  /* Type-conversion and ensure every cell has data */
+  idx=0;
+  for(int idx_lat=bnd_lwr_src[crd_idx_f_0bs_lat_src];idx_lat<=bnd_upr_src[crd_idx_f_0bs_lat_src];idx_lat++){
+    for(int idx_lon=bnd_lwr_src[crd_idx_f_0bs_lon_src];idx_lon<=bnd_upr_src[crd_idx_f_0bs_lon_src];idx_lon++){
+      fld_src_ptr[idx]=(double)var_fld[idx];
+      idx++;
+    } /* idx_lon */
+  } /* idx_lat */
+
+  /* Initialize dst data ptr */
+  idx=0;
+  for(int idx_lat=bnd_lwr_dst[crd_idx_f_0bs_lat_src];idx_lat<=bnd_upr_dst[crd_idx_f_0bs_lat_src];idx_lat++){
+    for(int idx_lon=bnd_lwr_dst[crd_idx_f_0bs_lon_src];idx_lon<=bnd_upr_dst[crd_idx_f_0bs_lon_src];idx_lon++){
+      fld_dst_ptr[idx]=0.0;
+      idx++;
+    } /* idx_lon */
+  } /* idx_lat */
+
+  ESMC_LogWrite("nco_rgr_esmf2() invoking ESMC to start regridstore actions",log_msg_typ);
+  /* int *msk_val=(int *)nco_malloc(sizeof(int));
+     msk_val[0]=1;
+     ESMC_InterfaceInt i_msk_val=ESMC_InterfaceIntCreate(msk_val,1,&rcd_esmf);
+     rcd_esmf = ESMC_FieldRegridStore(fld_src,fld_dst,&i_msk_val,&i_msk_val,&rte_hnd,NULL,NULL,NULL,&unmap_act,NULL,NULL);
+     rcd_esmf=ESMC_FieldRegridStore(fld_src,fld_dst,NULL,NULL,&rte_hnd,NULL,NULL,NULL,&unmap_act,NULL,NULL); */
+
+  ESMC_Field *cll_frc_dst=NULL; /* [frc] Fraction of each cell participating in regridding, destination grid */
+  ESMC_Field *cll_frc_src=NULL; /* [frc] Fraction of each cell participating in regridding, source grid */
+  ESMC_InterfaceInt *msk_src_rgr=NULL; /* [idx] Points to mask while regridding, source grid */
+  /* fxm: unsure whether/why need both msk_dst (above) and msk_dst_rgr (below) */
+  ESMC_InterfaceInt *msk_dst_rgr=NULL; /* [idx] Points to mask while regridding, destination grid */
+  ESMC_RouteHandle rte_hnd;
+  enum ESMC_RegridMethod_Flag rgr_mth=ESMC_REGRIDMETHOD_BILINEAR; /* [flg] Regrid method (default bilinear) */
+  enum ESMC_PoleMethod_Flag pll_mth=ESMC_POLEMETHOD_ALLAVG; /* [flg] Regrid method (default ESMC_POLEMETHOD_ALLAVG) */
+  enum ESMC_UnmappedAction_Flag unm_act=ESMC_UNMAPPEDACTION_ERROR; /* [flg] Unmapped action (default ESMC_UNMAPPEDACTION_ERROR) */
+  int pll_nbr=int_CEWI; /* [nbr] Number of points to average (iff ESMC_POLEMETHOD_NPNTAVG) */
+  /* Source: ${DATA}/esmf/src/Infrastructure/Field/interface/ESMC_Field.C */
+  rcd_esmf=ESMC_FieldRegridStore(fld_src,fld_dst,msk_src_rgr,msk_dst_rgr,&rte_hnd,&rgr_mth,&pll_mth,&pll_nbr,&unm_act,cll_frc_src,cll_frc_dst);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  enum ESMC_Region_Flag rgn_flg=ESMC_REGION_TOTAL; /* [flg] Whether/how to zero input fields before regridding (default ESMC_REGION_TOTAL) */
+  rcd_esmf=ESMC_FieldRegrid(fld_src,fld_dst,rte_hnd,&rgn_flg);
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* Call once on each PET */
+  rcd_esmf=ESMC_Finalize();
+  if(rcd_esmf != ESMF_SUCCESS) abort();
+
+  /* Write regridded data to netCDF file */
+  int var_out_id; /* [id] Variable ID */
+  int lon_out_id; /* [id] Variable ID for longitude */
+  int lat_out_id; /* [id] Variable ID for latitude  */
+  int dmn_id_lat; /* [id] Dimension ID */
+  int dmn_id_lon; /* [id] Dimension ID */
+  char *lat_nm_out=lat_nm_in;
+  char *lon_nm_out=lon_nm_in;
+  (void)nco_def_dim(out_id,lat_nm_out,bnd_upr_dst[crd_idx_f_0bs_lat_dst],&dmn_id_lat);
+  (void)nco_def_dim(out_id,lon_nm_out,bnd_upr_dst[crd_idx_f_0bs_lon_dst],&dmn_id_lon);
+  int dmn_ids_out[2]; /* [id] Dimension IDs array for output variable */
+  long dmn_srt_out[2];
+  long dmn_cnt_out[2];
+  dmn_ids_out[crd_idx_c_0bs_lat_dst]=dmn_id_lat;
+  dmn_ids_out[crd_idx_c_0bs_lon_dst]=dmn_id_lon;
+  (void)nco_def_var(out_id,lon_nm_out,crd_typ_out,(int)1,&dmn_id_lon,&lon_out_id);
+  (void)nco_def_var(out_id,lat_nm_out,crd_typ_out,(int)1,&dmn_id_lat,&lat_out_id);
+  (void)nco_def_var(out_id,rgr->var_nm,var_typ_out,(int)2,dmn_ids_out,&var_out_id);
+  (void)nco_enddef(out_id);
+  dmn_srt_out[crd_idx_c_0bs_lat_dst]=0L;
+  dmn_srt_out[crd_idx_c_0bs_lon_dst]=0L;
+  dmn_cnt_out[crd_idx_c_0bs_lat_dst]=bnd_upr_dst[crd_idx_f_0bs_lat_dst];
+  dmn_cnt_out[crd_idx_c_0bs_lon_dst]=bnd_upr_dst[crd_idx_f_0bs_lon_dst];
+  (void)nco_put_vara(out_id,lat_out_id,dmn_srt_out,dmn_cnt_out,lat_out,crd_typ_out);
+  (void)nco_put_vara(out_id,lon_out_id,dmn_srt_out,dmn_cnt_out,lon_out,crd_typ_out);
+  (void)nco_put_vara(out_id,var_out_id,dmn_srt_out,dmn_cnt_out,fld_dst_ptr,var_typ_out);
+
+  /* Close output file and move it from temporary to permanent location */
+  (void)nco_fl_out_cls(rgr->fl_out,rgr->fl_out_tmp,out_id);
+
+  goto rgr_cln; /* Prevent 'rgr_cln' defined but not used warning */
+
+ rgr_cln:
+  if(rcd_esmf != ESMF_SUCCESS){
+    /* ESMF return codes are enumerated in ESMC_ReturnCodes.h and ESMC_LogErr.h
+       However, there seems to be no translator function for these codes */
+    (void)fprintf(stderr,"%s: ERROR %s received ESMF return code %d\nSee ESMC_ReturnCodes.h or ESMC_LogErr.h for more information, e.g.,\n/bin/more /usr/local/include/ESMC_ReturnCodes.h | grep %d\n",nco_prg_nm_get(),fnc_nm,rcd_esmf,rcd_esmf);
+  } /* rcd_esmf */
+  if(max_idx) max_idx=(int *)nco_free(max_idx);
+  if(bnd_lwr_src) bnd_lwr_src=(int *)nco_free(bnd_lwr_src);
+  if(bnd_upr_src) bnd_upr_src=(int *)nco_free(bnd_upr_src);
+  if(bnd_lwr_dst) bnd_lwr_dst=(int *)nco_free(bnd_lwr_dst);
+  if(bnd_upr_dst) bnd_upr_dst=(int *)nco_free(bnd_upr_dst);
+  if(void_ptr_var) void_ptr_var=(void *)nco_free(void_ptr_var);
+  if(lat_out) lat_out=(double *)nco_free(lat_out);
+  if(lon_out) lon_out=(double *)nco_free(lon_out);
+  if(dmn_cnt) dmn_cnt=(long *)nco_free(dmn_cnt);
+  if(dmn_id) dmn_id=(int *)nco_free(dmn_id);
+  if(dmn_srt) dmn_srt=(long *)nco_free(dmn_srt);
+
+  rcd_esmf=ESMC_FieldRegridRelease(&rte_hnd);
+  rcd_esmf=ESMC_FieldDestroy(&fld_src);
+  rcd_esmf=ESMC_FieldDestroy(&fld_dst);
+  rcd_esmf=ESMC_GridDestroy(&grd_src);
+  rcd_esmf=ESMC_GridDestroy(&grd_dst);
+  ESMC_Finalize();
+
+  return rcd;
+} /* !nco_rgr_esmf2() */
 #endif /* !ENABLE_ESMF */
diff --git a/src/nco/nco_sld.h b/src/nco/nco_sld.h
index edaf2da..350c296 100644
--- a/src/nco/nco_sld.h
+++ b/src/nco/nco_sld.h
@@ -43,6 +43,10 @@ extern "C" {
   nco_rgr_esmf /* [fnc] Regrid using ESMF library */
   (rgr_sct * const rgr_nfo); /* I/O [sct] Regridding structure */
 
+  int /* O [enm] Return code */
+  nco_rgr_esmf2 /* [fnc] Regrid using ESMF library */
+  (rgr_sct * const rgr); /* I/O [sct] Regridding structure */
+
   const char * /* O [sng] String version of ESMC_StaggerLoc enum */
   nco_esmf_stg_lcn_sng /* [fnc] Convert ESMF stagger location enum to string */
   (const int nco_esmf_stg_lcn); /* I [enm] ESMF stagger location enum ESMC_StaggerLoc */
@@ -67,6 +71,10 @@ extern "C" {
   nco_esmf_pll_mth_sng /* [fnc] Convert ESMF pole method type enum to string */
   (const int nco_esmf_pll_mth); /* I [enm] ESMF pole method type enum ESMC_PoleMethod_Flag */
 
+  const char * /* O [sng] String version of ESMC_PoleKind_Flag enum */
+  nco_esmf_pll_knd_sng /* [fnc] Convert ESMF pole type enum to string */
+  (const int nco_esmf_pll_knd); /* I [enm] ESMF pole type enum ESMC_PoleKind_Flag */
+
   const char * /* O [sng] String version of ESMC_Region_Flag enum */
   nco_esmf_rgn_flg_sng /* [fnc] Convert ESMF region flag enum to string */
   (const int nco_esmf_rgn_flg); /* I [enm] ESMF region flag enum ESMC_Region_Flag */
diff --git a/src/nco/nco_var_rth.c b/src/nco/nco_var_rth.c
index 7f0ba79..ae3ecf1 100644
--- a/src/nco/nco_var_rth.c
+++ b/src/nco/nco_var_rth.c
@@ -635,6 +635,8 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
  const int has_mss_val, /* I [flg] Flag for missing values */
  ptr_unn mss_val, /* I [flg] Value of missing value */
  long * restrict const tally, /* I/O [nbr] Counter space */
+ const double wgt_crr, /* I [frc] Weight of current record (ncra/ncea only) */
+ double * restrict const wgt_sum, /* I/O [frc] Running sum of per-file weights (ncra/ncea only) */
  ptr_unn op1, /* I [val] Values of first operand */
  ptr_unn op2) /* I/O [val] Values of second operand (running sum) on input, values of new sum on output */
 {
@@ -686,6 +688,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.fp[idx] != mss_val_flt){
 	  op2.fp[idx]+=op1.fp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -702,6 +705,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.dp[idx] != mss_val_dbl){
 	  op2.dp[idx]+=op1.dp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -718,6 +722,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.ip[idx] != mss_val_ntg){
 	  op2.ip[idx]+=op1.ip[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -734,6 +739,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.sp[idx] != mss_val_short){
 	  op2.sp[idx]+=op1.sp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -750,6 +756,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.usp[idx] != mss_val_ushort){
 	  op2.usp[idx]+=op1.usp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -766,6 +773,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.uip[idx] != mss_val_uint){
 	  op2.uip[idx]+=op1.uip[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -782,6 +790,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.i64p[idx] != mss_val_int64){
 	  op2.i64p[idx]+=op1.i64p[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -798,6 +807,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.ui64p[idx] != mss_val_uint64){
 	  op2.ui64p[idx]+=op1.ui64p[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -814,6 +824,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.bp[idx] != mss_val_byte){
 	  op2.bp[idx]+=op1.bp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -830,6 +841,7 @@ nco_var_add_tll_ncra /* [fnc] Add first operand to second operand, increment tal
       for(idx=0;idx<sz;idx++){
 	if(op1.ubp[idx] != mss_val_ubyte){
 	  op2.ubp[idx]+=op1.ubp[idx];
+	  if(wgt_sum) wgt_sum[idx]+=wgt_crr;
 	  tally[idx]++;
 	} /* end if */
       } /* end for */
@@ -2198,6 +2210,99 @@ nco_var_nrm_sdn /* [fnc] Normalize value of first operand by count-1 in tally ar
 } /* end of nco_var_nrm_sdn */
 
 void
+nco_var_nrm_wgt /* [fnc] Normalize value of first operand by weight array */
+(const nc_type type, /* I [enm] netCDF type of operand */
+ const long sz, /* I [nbr] Size (in elements) of operand */
+ const int has_mss_val, /* I [flg] Flag for missing values */
+ ptr_unn mss_val, /* I [val] Value of missing value */
+ const long * const tally, /* I [nbr] Counter to normalize by */
+ const double * const wgt, /* I [nbr] Weight to normalize by */
+ ptr_unn op1) /* I/O [val] Values of first operand on input, normalized result on output */
+{
+  /* Threads: Routine is thread safe and calls no unsafe routines */
+  /* Purpose: Normalize value of first operand by value in weight array 
+     Routine is only called by ncra/ncea for variables that have missing values and weights */
+  
+  /* Normalization is currently defined as op1:=op1/wgt */  
+  
+  long idx;
+  
+  /* Typecast pointer to values before access */
+  (void)cast_void_nctype(type,&op1);
+  if(has_mss_val) (void)cast_void_nctype(type,&mss_val);
+  
+  switch(type){
+  case NC_FLOAT:
+    {
+      const float mss_val_flt=*mss_val.fp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.fp[idx]*=tally[idx]/wgt[idx]; else op1.fp[idx]=mss_val_flt;
+    }
+    break;
+  case NC_DOUBLE:
+    {
+      const double mss_val_dbl=*mss_val.dp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.dp[idx]*=tally[idx]/wgt[idx]; else op1.dp[idx]=mss_val_dbl;
+    }
+    break;
+  case NC_INT:
+    {
+      const nco_int mss_val_ntg=*mss_val.ip;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.ip[idx]*=tally[idx]/wgt[idx]; else op1.ip[idx]=mss_val_ntg;
+    }
+    break;
+  case NC_SHORT:
+    {
+      const nco_short mss_val_short=*mss_val.sp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.sp[idx]*=tally[idx]/wgt[idx]; else op1.sp[idx]=mss_val_short;
+    }
+    break;
+  case NC_USHORT:
+    {
+      const nco_ushort mss_val_ushort=*mss_val.usp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.usp[idx]*=tally[idx]/wgt[idx]; else op1.usp[idx]=mss_val_ushort;
+    }
+    break;
+  case NC_UINT:
+    {
+      const nco_uint mss_val_uint=*mss_val.uip;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.uip[idx]*=tally[idx]/wgt[idx]; else op1.uip[idx]=mss_val_uint;
+    }
+    break;
+  case NC_INT64:
+    {
+      const nco_int64 mss_val_int64=*mss_val.i64p;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.i64p[idx]*=tally[idx]/wgt[idx]; else op1.i64p[idx]=mss_val_int64;
+    }
+    break;
+  case NC_UINT64:
+    {
+      const nco_uint64 mss_val_uint64=*mss_val.ui64p;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.ui64p[idx]*=tally[idx]/wgt[idx]; else op1.ui64p[idx]=mss_val_uint64;
+    }
+    break;
+  case NC_BYTE:
+    {
+      const nco_byte mss_val_byte=*mss_val.bp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.bp[idx]*=tally[idx]/wgt[idx]; else op1.bp[idx]=mss_val_byte;
+    }
+    break;
+  case NC_UBYTE:
+    {
+      const nco_ubyte mss_val_ubyte=*mss_val.ubp;
+      for(idx=0;idx<sz;idx++) if(tally[idx] != 0L) op1.ubp[idx]*=tally[idx]/wgt[idx]; else op1.ubp[idx]=mss_val_ubyte;
+    }
+    break;
+  case NC_CHAR: break; /* Do nothing */
+  case NC_STRING: break; /* Do nothing */
+  default: nco_dfl_case_nc_type_err(); break;
+  } /* end switch */
+  
+  /* NB: it is not neccessary to un-typecast pointers to values after access 
+     because we have only operated on local copies of them. */
+  
+} /* end nco_var_nrm_wgt() */
+
+void
 nco_var_pwr /* [fnc] Raise first operand to power of second operand */
 (const nc_type type, /* I [type] netCDF type of operands */
  const long sz, /* I [nbr] Size (in elements) of operands */
@@ -2611,12 +2716,12 @@ nco_var_zero /* [fnc] Zero value of first operand */
 {
   /* Purpose: Zero value of first operand */
   
-  /* fxm: According to hjm, floats and ints all use same bit pattern for zero
+  /* NB: Floats and integers all use same bit pattern for zero
+     Confirm this with 
      ccc --tst=bnr --int_foo=0 
-     and
      ccc --dbg=0 --tst=gsl --gsl_a=0.0 
-     confirm this.
-     Hence, it may be faster to use memset() system call to zero memory 
+     Hence, it is fast to use memset() rather than explicit loop to zero memory
+     calloc() would also work if interactions with NC_CHAR and NC_STRING were predictable
      Same approach is used in nco_zero_long() */
   
   size_t sz_byt; /* [B] Number of bytes in variable buffer */
diff --git a/src/nco/nco_var_rth.h b/src/nco/nco_var_rth.h
index 7762a13..4041534 100644
--- a/src/nco/nco_var_rth.h
+++ b/src/nco/nco_var_rth.h
@@ -79,6 +79,8 @@ extern "C" {
    const int has_mss_val, /* I [flg] Flag for missing values */
    ptr_unn mss_val, /* I [val] Value of missing value */
    long * restrict const tally, /* I/O [nbr] Counter space */
+   const double wgt_crr, /* I [frc] Weight of current record (ncra/ncea only) */
+   double * restrict const wgt_sum, /* I/O [frc] Running sum of per-file weights (ncra/ncea only) */
    ptr_unn op1, /* I [val] Values of first operand */
    ptr_unn op2); /* I/O [val] Values of second operand (running sum) on input, values of new sum on output */
   
@@ -176,6 +178,16 @@ extern "C" {
    ptr_unn op1); /* I/O [val] Values of first operand on input, normalized result on output */
   
   void
+  nco_var_nrm_wgt /* [fnc] Normalize value of first operand by weight array */
+  (const nc_type type, /* I [enm] netCDF type of operand */
+   const long sz, /* I [nbr] Size (in elements) of operand */
+   const int has_mss_val, /* I [flg] Flag for missing values */
+   ptr_unn mss_val, /* I [val] Value of missing value */
+   const long * const tally, /* I [nbr] Counter to normalize by */
+   const double * const wgt, /* I [nbr] Weight to normalize by */
+   ptr_unn op1); /* I/O [val] Values of first operand on input, normalized result on output */
+    
+  void
   nco_var_pwr /* [fnc] Raise first operand to power of second operand */
   (const nc_type type, /* I [type] netCDF type of operands */
    const long sz, /* I [nbr] Size (in elements) of operands */
diff --git a/src/nco/nco_var_utl.c b/src/nco/nco_var_utl.c
index b18c101..2f52a38 100644
--- a/src/nco/nco_var_utl.c
+++ b/src/nco/nco_var_utl.c
@@ -854,6 +854,10 @@ nco_var_dpl /* [fnc] Duplicate input variable */
     var_cpy->tally=(long *)nco_malloc_dbg(var_cpy->sz*sizeof(long),"Unable to malloc() tally buffer in variable deep-copy",fnc_nm);
     (void)memcpy((void *)(var_cpy->tally),(void *)(var->tally),var_cpy->sz*sizeof(long));
   } /* end if */
+  if(var->wgt_sum){
+    var_cpy->wgt_sum=(double *)nco_malloc_dbg(var_cpy->sz*sizeof(double),"Unable to malloc() wgt_sum buffer in variable deep-copy",fnc_nm);
+    (void)memcpy((void *)(var_cpy->wgt_sum),(void *)(var->wgt_sum),var_cpy->sz*sizeof(double));
+  } /* end if */
   if(var->dim){
     var_cpy->dim=(dmn_sct **)nco_malloc(var_cpy->nbr_dim*sizeof(dmn_sct *));
     (void)memcpy((void *)(var_cpy->dim),(void *)(var->dim),var_cpy->nbr_dim*sizeof(var->dim[0]));
@@ -1012,6 +1016,7 @@ nco_var_free /* [fnc] Free all memory associated with variable structure */
   var->nm_fll=(char *)nco_free(var->nm_fll);
   var->mss_val.vp=nco_free(var->mss_val.vp);
   var->tally=(long *)nco_free(var->tally);
+  var->wgt_sum=(double *)nco_free(var->wgt_sum);
   var->dmn_id=(int *)nco_free(var->dmn_id);
   var->cnk_sz=(size_t *)nco_free(var->cnk_sz);
   var->dim=(dmn_sct **)nco_free(var->dim);
@@ -1074,6 +1079,8 @@ var_dfl_set /* [fnc] Set defaults for each member of variable structure */
   var->mss_val.vp=NULL;
   var->val.vp=NULL;
   var->tally=NULL;
+  var->wgt_sum=NULL; /* [frc] Running sum of per-file weights (ncra/ncea only) */
+  var->wgt_crr=0.0; /* [frc] Weight of current record (ncra/ncea only) */
   var->xrf=NULL;
   var->nbr_dim=-1;
   var->nbr_att=-1;
diff --git a/src/nco/ncpdq.c b/src/nco/ncpdq.c
index b191e1f..bb40cc1 100644
--- a/src/nco/ncpdq.c
+++ b/src/nco/ncpdq.c
@@ -90,31 +90,11 @@ main(int argc,char **argv)
   aed_sct *aed_lst_add_fst=NULL_CEWI;
   aed_sct *aed_lst_scl_fct=NULL_CEWI;
 
-  nco_bool dmn_rvr_rdr[NC_MAX_DIMS]; /* [flg] Reverse dimensions */
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool IS_REORDER=False; /* Re-order mode */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
-  nco_bool flg_dmn_prc_usr_spc=False; /* [flg] Processed dimensions specified on command line */
-
   char **dmn_rdr_lst_in=NULL_CEWI; /* Option a */
   char **dmn_rdr_lst_in_rvr=NULL_CEWI; /* Option a (same list, keep the '-' )*/
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in=NULL_CEWI;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char **grp_lst_in=NULL_CEWI;
   char *aux_arg[NC_MAX_DIMS];
@@ -180,6 +160,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int idx=int_CEWI;
   int idx_rdr=int_CEWI;
   int in_id;  
@@ -204,6 +185,27 @@ main(int argc,char **argv)
 
   md5_sct *md5=NULL; /* [sct] MD5 configuration */
 
+  nco_bool dmn_rvr_rdr[NC_MAX_DIMS]; /* [flg] Reverse dimensions */
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool IS_REORDER=False; /* Re-order mode */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order*/
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
+  nco_bool flg_dmn_prc_usr_spc=False; /* [flg] Processed dimensions specified on command line */
+
   size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
   size_t cnk_min_byt=NCO_CNK_SZ_MIN_BYT_DFL; /* [B] Minimize size of variable to chunk */
   size_t cnk_sz_byt=0UL; /* [B] Chunk size in bytes */
@@ -228,8 +230,7 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-  { /* Structure ordered by short option key if possible */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
     /* Long options with no argument, no short option counterpart */
     {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
     {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
@@ -274,6 +275,8 @@ main(int argc,char **argv)
     {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
     {"fl_fmt",required_argument,0,0},
     {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
     {"hdr_pad",required_argument,0,0},
     {"header_pad",required_argument,0,0},
     {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
@@ -400,6 +403,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -706,6 +713,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
@@ -738,6 +746,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
diff --git a/src/nco/ncra.c b/src/nco/ncra.c
index 213f045..fd6c248 100644
--- a/src/nco/ncra.c
+++ b/src/nco/ncra.c
@@ -32,7 +32,7 @@
    University of California, Irvine
    Irvine, CA 92697-3100 */
 
-/* URL: https://github.com/czender/nco/tree/master/src/nco/ncra.c
+/* URL: https://github.com/nco/nco/tree/master/src/nco/ncra.c
    
    Usage:
    ncra -O -n 3,4,1 -p ${HOME}/nco/data h0001.nc ~/foo.nc
@@ -120,6 +120,7 @@ main(int argc,char **argv)
 {
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **grp_lst_in=NULL_CEWI;
   char **var_lst_in=NULL_CEWI;
   char **wgt_lst_in=NULL_CEWI;
@@ -147,7 +148,7 @@ main(int argc,char **argv)
 
   const char * const CVS_Id="$Id$"; 
   const char * const CVS_Revision="$Revision$";
-  const char * const opt_sht_lst="3467ACcD:d:FG:g:HhL:l:n:Oo:p:P:rRt:v:w:X:xY:y:-:";
+  const char * const opt_sht_lst="3467ACcD:d:FG:g:HhL:l:Nn:Oo:p:P:rRt:v:w:X:xY:y:-:";
 
   cnk_sct cnk; /* [sct] Chunking structure */
 
@@ -191,6 +192,7 @@ main(int argc,char **argv)
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int flg_input_complete_nbr=0; /* [nbr] Number of record dimensions completed */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int grp_id;        /* [ID] Group ID */
   int grp_lst_in_nbr=0; /* [nbr] Number of groups explicitly specified by user */
   int grp_out_id;    /* [ID] Group ID (output) */
@@ -248,6 +250,7 @@ main(int argc,char **argv)
   nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
   nco_bool HISTORY_APPEND=True; /* Option h */
   nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+  nco_bool NORMALIZE_BY_WEIGHT=True; /* [flg] Normalize by command-line weight */
   nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
   nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
   nco_bool REC_APN=False; /* [flg] Append records directly to output file */
@@ -304,123 +307,126 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-    { /* Structure ordered by short option key if possible */
-      /* Long options with no argument, no short option counterpart */
-      {"cll_mth",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
-      {"cell_methods",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
-      {"no_cll_mth",no_argument,0,0}, /* [flg] Do not add/modify cell_methods attributes */
-      {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
-      {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
-      {"dbl",no_argument,0,0}, /* [flg] Arithmetic convention: promote float to double */
-      {"flt",no_argument,0,0}, /* [flg] Arithmetic convention: keep single-precision */
-      {"rth_dbl",no_argument,0,0}, /* [flg] Arithmetic convention: promote float to double */
-      {"rth_flt",no_argument,0,0}, /* [flg] Arithmetic convention: keep single-precision */
-      {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
-      {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
-      {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
-      {"mro",no_argument,0,0}, /* [flg] Multi-Record Output */
-      {"multi_record_output",no_argument,0,0}, /* [flg] Multi-Record Output */
-      {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-      {"nsm_fl",no_argument,0,0},
-      {"nsm_grp",no_argument,0,0},
-      {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
-      {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
-      {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
-      {"rec_apn",no_argument,0,0}, /* [flg] Append records directly to output file */
-      {"record_append",no_argument,0,0}, /* [flg] Append records directly to output file */
-      {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
-      {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
-      {"version",no_argument,0,0},
-      {"vrs",no_argument,0,0},
-      /* Long options with argument, no short option counterpart */
-      {"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 */
-      {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
-      {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
-      {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
-      {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
-      {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
-      {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
-      {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
-      {"fl_fmt",required_argument,0,0},
-      {"file_format",required_argument,0,0},
-      {"hdr_pad",required_argument,0,0},
-      {"header_pad",required_argument,0,0},
-      {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
-      {"nsm_sfx",required_argument,0,0},
-      {"ensemble_suffix",required_argument,0,0},
-      /* Long options with short counterparts */
-      {"3",no_argument,0,'3'},
-      {"4",no_argument,0,'4'},
-      {"64bit",no_argument,0,'4'},
-      {"netcdf4",no_argument,0,'4'},
-      {"append",no_argument,0,'A'},
-      {"coords",no_argument,0,'c'},
-      {"crd",no_argument,0,'c'},
-      {"no-coords",no_argument,0,'C'},
-      {"no-crd",no_argument,0,'C'},
-      {"debug",required_argument,0,'D'},
-      {"nco_dbg_lvl",required_argument,0,'D'},
-      {"dimension",required_argument,0,'d'},
-      {"dmn",required_argument,0,'d'},
-      {"fortran",no_argument,0,'F'},
-      {"ftn",no_argument,0,'F'},
-      {"fl_lst_in",no_argument,0,'H'},
-      {"file_list",no_argument,0,'H'},
-      {"history",no_argument,0,'h'},
-      {"hst",no_argument,0,'h'},
-      {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
-      {"local",required_argument,0,'l'},
-      {"lcl",required_argument,0,'l'},
-      {"nintap",required_argument,0,'n'},
-      {"overwrite",no_argument,0,'O'},
-      {"ovr",no_argument,0,'O'},
-      {"output",required_argument,0,'o'},
-      {"fl_out",required_argument,0,'o'},
-      {"path",required_argument,0,'p'},
-      {"pack",required_argument,0,'P'},
-      {"retain",no_argument,0,'R'},
-      {"rtn",no_argument,0,'R'},
-      {"revision",no_argument,0,'r'},
-      {"thr_nbr",required_argument,0,'t'},
-      {"threads",required_argument,0,'t'},
-      {"omp_num_threads",required_argument,0,'t'},
-      {"variable",required_argument,0,'v'},
-      {"wgt",required_argument,0,'w'},
-      {"weight",required_argument,0,'w'},
-      {"auxiliary",required_argument,0,'X'},
-      {"exclude",no_argument,0,'x'},
-      {"xcl",no_argument,0,'x'},
-      {"pseudonym",required_argument,0,'Y'},
-      {"program",required_argument,0,'Y'},
-      {"prg_nm",required_argument,0,'Y'},
-      {"math",required_argument,0,'y'},
-      {"operation",required_argument,0,'y'},
-      {"op_typ",required_argument,0,'y'},
-      {"help",no_argument,0,'?'},
-      {"hlp",no_argument,0,'?'},
-      {0,0,0,0}
-    }; /* end opt_lng */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
+    /* Long options with no argument, no short option counterpart */
+    {"cll_mth",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
+    {"cell_methods",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
+    {"no_cll_mth",no_argument,0,0}, /* [flg] Do not add/modify cell_methods attributes */
+    {"cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"clean",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"mmr_cln",no_argument,0,0}, /* [flg] Clean memory prior to exit */
+    {"drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dirty",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"mmr_drt",no_argument,0,0}, /* [flg] Allow dirty memory on exit */
+    {"dbl",no_argument,0,0}, /* [flg] Arithmetic convention: promote float to double */
+    {"flt",no_argument,0,0}, /* [flg] Arithmetic convention: keep single-precision */
+    {"rth_dbl",no_argument,0,0}, /* [flg] Arithmetic convention: promote float to double */
+    {"rth_flt",no_argument,0,0}, /* [flg] Arithmetic convention: keep single-precision */
+    {"hdf4",no_argument,0,0}, /* [flg] Treat file as HDF4 */
+    {"hdf_upk",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"hdf_unpack",no_argument,0,0}, /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
+    {"md5_dgs",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"md5_digest",no_argument,0,0}, /* [flg] Perform MD5 digests */
+    {"mro",no_argument,0,0}, /* [flg] Multi-Record Output */
+    {"multi_record_output",no_argument,0,0}, /* [flg] Multi-Record Output */
+    {"msa_usr_rdr",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"msa_user_order",no_argument,0,0}, /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+    {"nsm_fl",no_argument,0,0},
+    {"nsm_grp",no_argument,0,0},
+    {"ram_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"create_ram",no_argument,0,0}, /* [flg] Create file in RAM */
+    {"open_ram",no_argument,0,0}, /* [flg] Open (netCDF3) file(s) in RAM */
+    {"diskless_all",no_argument,0,0}, /* [flg] Open (netCDF3) and create file(s) in RAM */
+    {"rec_apn",no_argument,0,0}, /* [flg] Append records directly to output file */
+    {"record_append",no_argument,0,0}, /* [flg] Append records directly to output file */
+    {"wrt_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"write_tmp_fl",no_argument,0,0}, /* [flg] Write output to temporary file */
+    {"no_tmp_fl",no_argument,0,0}, /* [flg] Do not write output to temporary file */
+    {"version",no_argument,0,0},
+    {"vrs",no_argument,0,0},
+    /* Long options with argument, no short option counterpart */
+    {"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 */
+    {"chunk_byte",required_argument,0,0}, /* [B] Chunk size in bytes */
+    {"cnk_dmn",required_argument,0,0}, /* [nbr] Chunk size */
+    {"chunk_dimension",required_argument,0,0}, /* [nbr] Chunk size */
+    {"cnk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"chunk_map",required_argument,0,0}, /* [nbr] Chunking map */
+    {"cnk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"chunk_min",required_argument,0,0}, /* [B] Minimize size of variable to chunk */
+    {"cnk_plc",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"chunk_policy",required_argument,0,0}, /* [nbr] Chunking policy */
+    {"cnk_scl",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
+    {"fl_fmt",required_argument,0,0},
+    {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
+    {"hdr_pad",required_argument,0,0},
+    {"header_pad",required_argument,0,0},
+    {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"precision_preserving_compression",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"quantize",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
+    {"nsm_sfx",required_argument,0,0},
+    {"ensemble_suffix",required_argument,0,0},
+    /* Long options with short counterparts */
+    {"3",no_argument,0,'3'},
+    {"4",no_argument,0,'4'},
+    {"64bit",no_argument,0,'4'},
+    {"netcdf4",no_argument,0,'4'},
+    {"append",no_argument,0,'A'},
+    {"coords",no_argument,0,'c'},
+    {"crd",no_argument,0,'c'},
+    {"no-coords",no_argument,0,'C'},
+    {"no-crd",no_argument,0,'C'},
+    {"debug",required_argument,0,'D'},
+    {"nco_dbg_lvl",required_argument,0,'D'},
+    {"dimension",required_argument,0,'d'},
+    {"dmn",required_argument,0,'d'},
+    {"fortran",no_argument,0,'F'},
+    {"ftn",no_argument,0,'F'},
+    {"fl_lst_in",no_argument,0,'H'},
+    {"file_list",no_argument,0,'H'},
+    {"history",no_argument,0,'h'},
+    {"hst",no_argument,0,'h'},
+    {"dfl_lvl",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"deflate",required_argument,0,'L'}, /* [enm] Deflate level */
+    {"local",required_argument,0,'l'},
+    {"lcl",required_argument,0,'l'},
+    {"no-normalize-by-weight",no_argument,0,'N',},
+    {"no_nrm_by_wgt",no_argument,0,'N',},
+    {"nintap",required_argument,0,'n'},
+    {"overwrite",no_argument,0,'O'},
+    {"ovr",no_argument,0,'O'},
+    {"output",required_argument,0,'o'},
+    {"fl_out",required_argument,0,'o'},
+    {"path",required_argument,0,'p'},
+    {"pack",required_argument,0,'P'},
+    {"retain",no_argument,0,'R'},
+    {"rtn",no_argument,0,'R'},
+    {"revision",no_argument,0,'r'},
+    {"thr_nbr",required_argument,0,'t'},
+    {"threads",required_argument,0,'t'},
+    {"omp_num_threads",required_argument,0,'t'},
+    {"variable",required_argument,0,'v'},
+    {"wgt",required_argument,0,'w'},
+    {"weight",required_argument,0,'w'},
+    {"auxiliary",required_argument,0,'X'},
+    {"exclude",no_argument,0,'x'},
+    {"xcl",no_argument,0,'x'},
+    {"pseudonym",required_argument,0,'Y'},
+    {"program",required_argument,0,'Y'},
+    {"prg_nm",required_argument,0,'Y'},
+    {"math",required_argument,0,'y'},
+    {"operation",required_argument,0,'y'},
+    {"op_typ",required_argument,0,'y'},
+    {"help",no_argument,0,'?'},
+    {"hlp",no_argument,0,'?'},
+    {0,0,0,0}
+  }; /* end opt_lng */
   int opt_idx=0; /* Index of current long option into opt_lng array */
-
+  
 #ifdef _LIBINTL_H
   setlocale(LC_ALL,""); /* LC_ALL sets all localization tokens to same value */
   bindtextdomain("nco","/home/zender/share/locale"); /* ${LOCALEDIR} is e.g., /usr/share/locale */
@@ -493,6 +499,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
       if(!strcmp(opt_crr,"dbl") || !strcmp(opt_crr,"rth_dbl")) nco_rth_cnv=nco_rth_flt_dbl; /* [flg] Arithmetic convention: promote float to double */
       if(!strcmp(opt_crr,"flt") || !strcmp(opt_crr,"rth_flt")) nco_rth_cnv=nco_rth_flt_flt; /* [flg] Arithmetic convention: keep single-precision */
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -595,9 +605,12 @@ main(int argc,char **argv)
     case 'l': /* Local path prefix for files retrieved from remote file system */
       fl_pth_lcl=(char *)strdup(optarg);
       break;
+    case 'N':
+      NORMALIZE_BY_WEIGHT=False;
+      break;
     case 'n': /* NINTAP-style abbreviation of files to average */
       fl_lst_abb=nco_lst_prs_2D(optarg,",",&abb_arg_nbr);
-      if(abb_arg_nbr < 1 || abb_arg_nbr > 5){
+      if(abb_arg_nbr < 1 || abb_arg_nbr > 6){
         (void)fprintf(stdout,gettext("%s: ERROR Incorrect abbreviation for file list\n"),nco_prg_nm_get());
         (void)nco_usg_prn();
         nco_exit(EXIT_FAILURE);
@@ -651,7 +664,7 @@ main(int argc,char **argv)
 	  if(*sng_cnv_rcd) nco_sng_cnv_err(wgt_lst_in[idx],"strtod",sng_cnv_rcd);
 	  wgt_avg_scl+=wgt_arr[idx];
 	} /* end loop over elements */
-	wgt_avg_scl/=wgt_nbr;
+	if(NORMALIZE_BY_WEIGHT) wgt_avg_scl/=wgt_nbr; else wgt_avg_scl=1.0/wgt_nbr;
 	assert(wgt_avg_scl != 0.0);
 	for(idx=0L;idx<wgt_nbr;idx++) wgt_arr[idx]/=wgt_avg_scl;
       } /* !wgt_nm */
@@ -799,6 +812,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 
@@ -847,17 +861,12 @@ main(int argc,char **argv)
 
   /* Allocate and, if necesssary, initialize accumulation space for processed variables */
   for(idx=0;idx<nbr_var_prc;idx++){
-    if(nco_prg_id == ncra || nco_prg_id == ncrcat){
-      /* Allocate space for only one record */
-      var_prc[idx]->sz=var_prc[idx]->sz_rec=var_prc_out[idx]->sz=var_prc_out[idx]->sz_rec;
-    } /* endif */
+    /* Record operators only need space for one record, not entire variable */
+    if(nco_prg_id == ncra || nco_prg_id == ncrcat) var_prc[idx]->sz=var_prc[idx]->sz_rec=var_prc_out[idx]->sz=var_prc_out[idx]->sz_rec;
     if(nco_prg_id == ncra || nco_prg_id == ncfe || nco_prg_id == ncge){
-      var_prc_out[idx]->tally=var_prc[idx]->tally=(long *)nco_malloc(var_prc_out[idx]->sz*sizeof(long));
-      var_prc_out[idx]->val.vp=(void *)nco_malloc(var_prc_out[idx]->sz*nco_typ_lng(var_prc_out[idx]->type));
-      if(nco_prg_id == ncfe || nco_prg_id == ncge){
-        (void)nco_zero_long(var_prc_out[idx]->sz,var_prc_out[idx]->tally);
-        (void)nco_var_zero(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->val);
-      } /* end if ncfe || ncge */
+      if((wgt_arr || wgt_nm) && var_prc[idx]->has_mss_val) var_prc_out[idx]->wgt_sum=var_prc[idx]->wgt_sum=(double *)nco_calloc(var_prc_out[idx]->sz,sizeof(double));
+      var_prc_out[idx]->tally=var_prc[idx]->tally=(long *)nco_calloc(var_prc_out[idx]->sz,sizeof(long));
+      var_prc_out[idx]->val.vp=(void *)nco_calloc(var_prc_out[idx]->sz,nco_typ_lng(var_prc_out[idx]->type));
     } /* end if */
   } /* end loop over idx */
 
@@ -1003,7 +1012,7 @@ main(int argc,char **argv)
           if(nco_dbg_lvl >= nco_dbg_scl) (void)fprintf(fp_stdout,"%s: INFO Record %ld of %s contributes to output record %ld\n",nco_prg_nm_get(),idx_rec_crr_in,fl_in,idx_rec_out[idx_rec]);
 
 #ifdef _OPENMP
-#pragma omp parallel for default(none) private(idx,in_id) shared(CNV_ARM,FLG_BFR_NRM,FLG_MRO,REC_FRS_GRP,REC_LST_DSR,base_time_crr,base_time_srt,fl_idx,fl_in,fl_nbr,fl_out,flg_skp1,flg_skp2,gpe,grp_id,grp_out_fll,grp_out_id,idx_rec,idx_rec_crr_in,idx_rec_out,in_id_arr,lmt_rec,md5,nbr_dmn_fl,nbr_rec,nbr_var_prc,nco_dbg_lvl,nco_op_typ,nco_prg_id,out_id,rcd,rec_usd_cml,trv_tbl,var_out_id,var_prc,var_prc_out,var_prc_typ_pre_prm,var_trv,wgt_arr,wgt_avg,wgt_nbr,wgt_nm,wgt_out,wgt_scv)
+#pragma omp parallel for default(none) private(idx,in_id) shared(CNV_ARM,FLG_BFR_NRM,FLG_MRO,NORMALIZE_BY_WEIGHT,REC_FRS_GRP,REC_LST_DSR,base_time_crr,base_time_srt,fl_idx,fl_in,fl_nbr,fl_out,flg_skp1,flg_skp2,gpe,grp_id,grp_out_fll,grp_out_id,idx_rec,idx_rec_crr_in,idx_rec_out,in_id_arr,lmt_rec,md5,nbr_dmn_fl,nbr_rec,nbr_var_prc,nco_dbg_lvl,nco_op_typ,nco_prg_id,out_id,rcd,rec_usd_cml,trv_tbl,var_out_id,var_prc,var_prc_out,var_prc_typ_pre_prm,var_trv,wgt_arr,wgt_avg,wgt_avg_scl,wgt_nbr, [...]
 #endif /* !_OPENMP */
           for(idx=0;idx<nbr_var_prc;idx++){
 
@@ -1079,13 +1088,18 @@ main(int argc,char **argv)
 		    wgt_scv.val.d=wgt_arr[fl_idx];
 		  } /* !wgt_arr */
 		  if(wgt_nm){
-		    wgt_scv.val.d=wgt_out->val.dp[0]; /* Per-record weight */
 		    wgt_scv.type=wgt_out->type;
+		    wgt_scv.val.d=wgt_out->val.dp[0]; /* Per-record weight */
 		  } /* !wgt_nm */
+		  if(var_prc[idx]->wgt_sum) var_prc[idx]->wgt_crr=wgt_scv.val.d;
 		  nco_scv_cnf_typ(var_prc[idx]->type,&wgt_scv);
-		  if(nco_dbg_lvl > nco_dbg_std && (wgt_nm || wgt_arr)) (void)fprintf(fp_stdout,"wgt_nm = %s, var_nm = %s, idx = %li, typ = %s, wgt_val = %g, var_val=%g\n",wgt_nm ? wgt_out->nm_fll : "NULL",var_prc[idx]->nm,idx_rec_crr_in,nco_typ_sng(wgt_scv.type),wgt_scv.val.d,var_prc[idx]->val.dp[0]);
+		  if(nco_dbg_lvl > nco_dbg_std && (wgt_nm || wgt_arr)) (void)fprintf(fp_stdout,"wgt_nm = %s, var_nm = %s, idx = %li, typ = %s, wgt_val = %g, wgt_crr = %g, var_val=%g\n",wgt_nm ? wgt_out->nm_fll : "NULL",var_prc[idx]->nm,idx_rec_crr_in,nco_typ_sng(wgt_scv.type),wgt_scv.val.d,var_prc[idx]->wgt_crr,var_prc[idx]->val.dp[0]);
 		  (void)nco_var_scv_mlt(var_prc[idx]->type,var_prc[idx]->sz,var_prc[idx]->has_mss_val,var_prc[idx]->mss_val,var_prc[idx]->val,&wgt_scv);
-		  /* Increment running total of wgt_out after its application to last processed variable */
+		  if(wgt_nm && var_prc[idx]->has_mss_val){
+		    (void)fprintf(fp_stdout,"%s: ERROR %s -w wgt_nm does not yet work on variables that contain missing values and variable %s contains a missing value attribute. This is TODO nco1124. %s will now quit rather than compute possibly erroneous values. HINT: Restrict the %s -w wgt_nm operation to variables with no missing value attributes.\n",nco_prg_nm_get(),nco_prg_nm_get(),nco_prg_nm_get(),var_prc[idx]->nm,nco_prg_nm_get());
+		    nco_exit(EXIT_FAILURE);
+		  } /* !wgt_nm */
+		  /* Increment running total of wgt_out after its application to last processed variable for this record */
 		  if(wgt_nm && (idx == nbr_var_prc-1)){
 		    if(flg_rth_ntl) nco_opr_drv((long)0L,nco_op_typ,wgt_out,wgt_avg); else nco_opr_drv((long)1L,nco_op_typ,wgt_out,wgt_avg);
 		  } /* !wgt_nm */
@@ -1146,6 +1160,12 @@ main(int argc,char **argv)
             (void)nco_opr_nrm(nco_op_typ,nbr_var_prc,var_prc,var_prc_out,lmt_rec[idx_rec]->nm_fll,trv_tbl);
             FLG_BFR_NRM=False; /* [flg] Current output buffers need normalization */
 
+	    for(idx=0;idx<nbr_var_prc;idx++){
+	      if(var_prc[idx]->wgt_sum){
+		if(NORMALIZE_BY_WEIGHT) (void)nco_var_nrm_wgt(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->tally,var_prc_out[idx]->wgt_sum,var_prc_out[idx]->val);
+	      } /* !wgt_sum */
+	    } /* !idx */
+	      
 	    if(wgt_nm && (nco_op_typ == nco_op_avg || nco_op_typ == nco_op_mebs)){
 	      /* Compute mean of per-record weight, by normalizing running sum of weight by tally
 		 Then normalize all numerical record variables by mean of per-record weight
@@ -1159,7 +1179,7 @@ main(int argc,char **argv)
 	      for(idx=0;idx<nbr_var_prc;idx++){
 		if(var_prc_out[idx]->is_crd_var || var_prc[idx]->type == NC_CHAR || var_prc[idx]->type == NC_STRING) continue;
 		nco_scv_cnf_typ(var_prc_out[idx]->type,&wgt_avg_scv);
-		(void)nco_var_scv_dvd(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->val,&wgt_avg_scv);
+		if(NORMALIZE_BY_WEIGHT) (void)nco_var_scv_dvd(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->val,&wgt_avg_scv);
 	      } /* end loop over var */
 	    } /* !wgt_nm */
 
@@ -1339,7 +1359,7 @@ main(int argc,char **argv)
             (void)nco_msa_var_get_trv(in_id,var_prc[idx_prc],trv_tbl1);
 
             /* Convert char, short, long, int, and float types to doubles before arithmetic
-            Output variable type is "sticky" so only convert on first member */
+	       Output variable type is "sticky" so only convert on first member */
             if(fl_idx == 0 && idx_mbr == 0) var_prc_out[idx_prc]=nco_typ_cnv_rth(var_prc_out[idx_prc],nco_op_typ);
             var_prc[idx_prc]=nco_var_cnf_typ(var_prc_out[idx_prc]->type,var_prc[idx_prc]);
             /* Perform arithmetic operations: avg, min, max, ttl, ... */
@@ -1416,6 +1436,12 @@ main(int argc,char **argv)
   if(FLG_BFR_NRM){
     (void)nco_opr_nrm(nco_op_typ,nbr_var_prc,var_prc,var_prc_out,(char *)NULL,(trv_tbl_sct *)NULL);
     
+    for(idx=0;idx<nbr_var_prc;idx++){
+      if(var_prc[idx]->wgt_sum){
+	if(NORMALIZE_BY_WEIGHT) (void)nco_var_nrm_wgt(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->tally,var_prc_out[idx]->wgt_sum,var_prc_out[idx]->val);
+      } /* !wgt_sum */
+    } /* !idx */
+
     if(wgt_nm && (nco_op_typ == nco_op_avg || nco_op_typ == nco_op_mebs)){
       /* Compute mean of per-record weight, by normalizing running sum of weight by tally
 	 Then normalize all numerical record variables by mean of per-record weight
@@ -1429,7 +1455,7 @@ main(int argc,char **argv)
       for(idx=0;idx<nbr_var_prc;idx++){
 	if(var_prc_out[idx]->is_crd_var || var_prc[idx]->type == NC_CHAR || var_prc[idx]->type == NC_STRING) continue;
 	nco_scv_cnf_typ(var_prc_out[idx]->type,&wgt_avg_scv);
-	(void)nco_var_scv_dvd(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->val,&wgt_avg_scv);
+	if(NORMALIZE_BY_WEIGHT) (void)nco_var_scv_dvd(var_prc_out[idx]->type,var_prc_out[idx]->sz,var_prc_out[idx]->has_mss_val,var_prc_out[idx]->mss_val,var_prc_out[idx]->val,&wgt_avg_scv);
       } /* end loop over var */
     } /* !wgt_nm */
   } /* !FLG_BFR_NRM */
@@ -1485,12 +1511,10 @@ main(int argc,char **argv)
     } /* end loop over idx */
   } /* end if ncfe and ncge */
 
-  /* Free averaging and tally buffers */
+  /* Free averaging, tally, and weight buffers */
   if(nco_prg_id == ncra || nco_prg_id == ncfe || nco_prg_id == ncge){
-#ifdef _OPENMP
-#pragma omp parallel for default(none) private(idx) shared(nbr_var_prc,nco_op_typ,var_prc,var_prc_out)
-#endif /* !_OPENMP */
     for(idx=0;idx<nbr_var_prc;idx++){
+      if((wgt_arr || wgt_nm) && var_prc[idx]->has_mss_val) var_prc_out[idx]->wgt_sum=var_prc[idx]->wgt_sum=(double *)nco_free(var_prc[idx]->wgt_sum);
       var_prc_out[idx]->tally=var_prc[idx]->tally=(long *)nco_free(var_prc[idx]->tally);
       var_prc_out[idx]->val.vp=nco_free(var_prc_out[idx]->val.vp);
     } /* end loop over idx */
diff --git a/src/nco/ncrename.c b/src/nco/ncrename.c
index 8a845ad..3b92a0e 100644
--- a/src/nco/ncrename.c
+++ b/src/nco/ncrename.c
@@ -88,18 +88,9 @@ main(int argc,char **argv)
   extern int errno; /* [enm] Error code in errno.h */
 #endif /* __GNUG__ */
 
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool FL_OUT_NEW=False;
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
-
   char **fl_lst_abb=NULL; /* Option a */
   char **fl_lst_in;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char *att_rnm_arg[NC_MAX_ATTRS];
   char *cmd_ln;
   char *dmn_rnm_arg[NC_MAX_DIMS];
@@ -133,6 +124,7 @@ main(int argc,char **argv)
   int abb_arg_nbr=0;
   int fl_fmt; /* [enm] Output (and input) file format */
   int fl_nbr=0;
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int mch_nbr_att=0; /* [nbr] Number of renamed attributes */
   int mch_nbr_var=0; /* [nbr] Number of renamed variables */
   int mch_nbr_grp=0; /* [nbr] Number of renamed groups */
@@ -147,6 +139,16 @@ main(int argc,char **argv)
   int opt;
   int rcd=NC_NOERR; /* [rcd] Return code */
 
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool FL_OUT_NEW=False;
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool flg_cln=False; /* [flg] Clean memory prior to exit */
+
   rnm_sct *var_rnm_lst=NULL_CEWI;
   rnm_sct *dmn_rnm_lst=NULL_CEWI;
   rnm_sct *grp_rnm_lst=NULL_CEWI;
@@ -183,6 +185,8 @@ main(int argc,char **argv)
     /* Long options with argument, no short option counterpart */
     {"bfr_sz_hnt",required_argument,0,0}, /* [B] Buffer size hint */
     {"buffer_size_hint",required_argument,0,0}, /* [B] Buffer size hint */
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
     {"hdr_pad",required_argument,0,0},
     {"header_pad",required_argument,0,0},
     /* Long options with short counterparts */
@@ -243,6 +247,10 @@ main(int argc,char **argv)
       } /* endif cnk */
       if(!strcmp(opt_crr,"cln") || !strcmp(opt_crr,"mmr_cln") || !strcmp(opt_crr,"clean")) flg_cln=True; /* [flg] Clean memory prior to exit */
       if(!strcmp(opt_crr,"drt") || !strcmp(opt_crr,"mmr_drt") || !strcmp(opt_crr,"dirty")) flg_cln=False; /* [flg] Clean memory prior to exit */
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
         hdr_pad=strtoul(optarg,&sng_cnv_rcd,NCO_SNG_CNV_BASE10);
diff --git a/src/nco/ncwa.c b/src/nco/ncwa.c
index 5212468..abcd284 100644
--- a/src/nco/ncwa.c
+++ b/src/nco/ncwa.c
@@ -96,42 +96,13 @@ char **ncap_fl_spt_glb; /* [fl] Script file */
 int 
 main(int argc,char **argv)
 {
-  nco_bool CNV_CCM_CCSM_CF;
-  nco_bool DO_CONFORM_MSK=False; /* Did nco_var_cnf_dmn() find truly conforming mask? */
-  nco_bool DO_CONFORM_WGT=False; /* Did nco_var_cnf_dmn() find truly conforming weight? */
-  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
-  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
-  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
-  nco_bool FL_RTR_RMT_LCN;
-  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
-  nco_bool FORCE_APPEND=False; /* Option A */
-  nco_bool FORCE_OVERWRITE=False; /* Option O */
-  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
-  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
-  nco_bool HISTORY_APPEND=True; /* Option h */
-  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
-  nco_bool MULTIPLY_BY_TALLY=False; /* Not currently implemented */
-  nco_bool MUST_CONFORM=False; /* [flg] Must nco_var_cnf_dmn() find truly conforming variables? */
-  nco_bool NORMALIZE_BY_TALLY=True; /* Not currently implemented */
-  nco_bool NORMALIZE_BY_WEIGHT=True; /* Not currently implemented */
-  nco_bool NRM_BY_DNM=True; /* Option N Normalize by denominator */
-  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
-  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
-  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
-  nco_bool WGT_MSK_CRD_VAR=True; /* [flg] Weight and/or mask coordinate variables */
-  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
-  nco_bool flg_cll_mth=True; /* [flg] Add/modify cell_methods attributes */
-  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
-  nco_bool flg_dmn_prc_usr_spc=False; /* [flg] Processed dimensions specified on command line */
-  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
-  nco_bool flg_rdd=False; /* [flg] Retain degenerate dimensions */
-  
-  char *aux_arg[NC_MAX_DIMS];
   char **dmn_avg_lst_in=NULL_CEWI; /* Option a */
   char **fl_lst_abb=NULL; /* Option n */
   char **fl_lst_in=NULL_CEWI;
+  char **gaa_arg=NULL; /* [sng] Global attribute arguments */
   char **var_lst_in=NULL_CEWI;
   char **grp_lst_in=NULL_CEWI;
+  char *aux_arg[NC_MAX_DIMS];
   char *cmd_ln;
   char *cnk_arg[NC_MAX_DIMS];
   char *cnk_map_sng=NULL_CEWI; /* [sng] Chunking map */
@@ -193,6 +164,7 @@ main(int argc,char **argv)
   int fl_in_fmt; /* [enm] Input file format */
   int fl_out_fmt=NCO_FORMAT_UNDEFINED; /* [enm] Output file format */
   int fll_md_old; /* [enm] Old fill mode */
+  int gaa_nbr=0; /* [nbr] Number of global attributes to add */
   int grp_lst_in_nbr=0; /* [nbr] Number of groups explicitly specified by user */
   int idx=int_CEWI;
   int in_id;  
@@ -217,6 +189,36 @@ main(int argc,char **argv)
 
   md5_sct *md5=NULL; /* [sct] MD5 configuration */
 
+  nco_bool CNV_CCM_CCSM_CF;
+  nco_bool DO_CONFORM_MSK=False; /* Did nco_var_cnf_dmn() find truly conforming mask? */
+  nco_bool DO_CONFORM_WGT=False; /* Did nco_var_cnf_dmn() find truly conforming weight? */
+  nco_bool EXCLUDE_INPUT_LIST=False; /* Option c */
+  nco_bool EXTRACT_ALL_COORDINATES=False; /* Option c */
+  nco_bool EXTRACT_ASSOCIATED_COORDINATES=True; /* Option C */
+  nco_bool FL_RTR_RMT_LCN;
+  nco_bool FL_LST_IN_FROM_STDIN=False; /* [flg] fl_lst_in comes from stdin */
+  nco_bool FORCE_APPEND=False; /* Option A */
+  nco_bool FORCE_OVERWRITE=False; /* Option O */
+  nco_bool FORTRAN_IDX_CNV=False; /* Option F */
+  nco_bool GRP_VAR_UNN=False; /* [flg] Select union of specified groups and variables */
+  nco_bool HISTORY_APPEND=True; /* Option h */
+  nco_bool MSA_USR_RDR=False; /* [flg] Multi-Slab Algorithm returns hyperslabs in user-specified order */
+  nco_bool MULTIPLY_BY_TALLY=False; /* Not currently implemented */
+  nco_bool MUST_CONFORM=False; /* [flg] Must nco_var_cnf_dmn() find truly conforming variables? */
+  nco_bool NORMALIZE_BY_TALLY=True; /* Not currently implemented */
+  nco_bool NORMALIZE_BY_WEIGHT=True; /* Not currently implemented */
+  nco_bool NRM_BY_DNM=True; /* Option N Normalize by denominator */
+  nco_bool RAM_CREATE=False; /* [flg] Create file in RAM */
+  nco_bool RAM_OPEN=False; /* [flg] Open (netCDF3-only) file(s) in RAM */
+  nco_bool RM_RMT_FL_PST_PRC=True; /* Option R */
+  nco_bool WGT_MSK_CRD_VAR=True; /* [flg] Weight and/or mask coordinate variables */
+  nco_bool WRT_TMP_FL=True; /* [flg] Write output to temporary file */
+  nco_bool flg_cll_mth=True; /* [flg] Add/modify cell_methods attributes */
+  nco_bool flg_cln=True; /* [flg] Clean memory prior to exit */
+  nco_bool flg_dmn_prc_usr_spc=False; /* [flg] Processed dimensions specified on command line */
+  nco_bool flg_ddra=False; /* [flg] DDRA diagnostics */
+  nco_bool flg_rdd=False; /* [flg] Retain degenerate dimensions */
+  
   size_t bfr_sz_hnt=NC_SIZEHINT_DEFAULT; /* [B] Buffer size hint */
   size_t cnk_min_byt=NCO_CNK_SZ_MIN_BYT_DFL; /* [B] Minimize size of variable to chunk */
   size_t cnk_sz_byt=0UL; /* [B] Chunk size in bytes */
@@ -248,8 +250,7 @@ main(int argc,char **argv)
   int prc_nbr=0; /* [nbr] Number of MPI processes */
 #endif /* !ENABLE_MPI */
   
-  static struct option opt_lng[]=
-  { /* Structure ordered by short option key if possible */
+  static struct option opt_lng[]={ /* Structure ordered by short option key if possible */
     /* Long options with no argument, no short option counterpart */
     {"cll_mth",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
     {"cell_methods",no_argument,0,0}, /* [flg] Add/modify cell_methods attributes */
@@ -295,6 +296,8 @@ main(int argc,char **argv)
     {"chunk_scalar",required_argument,0,0}, /* [nbr] Chunk size scalar */
     {"fl_fmt",required_argument,0,0},
     {"file_format",required_argument,0,0},
+    {"gaa",required_argument,0,0}, /* [sng] Global attribute add */
+    {"glb_att_add",required_argument,0,0}, /* [sng] Global attribute add */
     {"hdr_pad",required_argument,0,0},
     {"header_pad",required_argument,0,0},
     {"ppc",required_argument,0,0}, /* [nbr] Precision-preserving compression, i.e., number of total or decimal significant digits */
@@ -438,6 +441,10 @@ main(int argc,char **argv)
       if(!strcmp(opt_crr,"fl_fmt") || !strcmp(opt_crr,"file_format")) rcd=nco_create_mode_prs(optarg,&fl_out_fmt);
       if(!strcmp(opt_crr,"dbl") || !strcmp(opt_crr,"rth_dbl")) nco_rth_cnv=nco_rth_flt_dbl; /* [flg] Arithmetic convention: promote float to double */
       if(!strcmp(opt_crr,"flt") || !strcmp(opt_crr,"rth_flt")) nco_rth_cnv=nco_rth_flt_flt; /* [flg] Arithmetic convention: keep single-precision */
+      if(!strcmp(opt_crr,"gaa") || !strcmp(opt_crr,"glb_att_add")){
+        gaa_arg=(char **)nco_realloc(gaa_arg,(gaa_nbr+1)*sizeof(char *));
+        gaa_arg[gaa_nbr++]=(char *)strdup(optarg);
+      } /* endif gaa */
       if(!strcmp(opt_crr,"hdf4")) nco_fmt_xtn=nco_fmt_xtn_hdf4; /* [enm] Treat file as HDF4 */
       if(!strcmp(opt_crr,"hdf_upk") || !strcmp(opt_crr,"hdf_unpack")) nco_upk_cnv=nco_upk_HDF; /* [flg] HDF unpack convention: unpacked=scale_factor*(packed-add_offset) */
       if(!strcmp(opt_crr,"hdr_pad") || !strcmp(opt_crr,"header_pad")){
@@ -760,6 +767,7 @@ main(int argc,char **argv)
   /* Catenate time-stamped command line to "history" global attribute */
   if(HISTORY_APPEND) (void)nco_hst_att_cat(out_id,cmd_ln);
   if(HISTORY_APPEND && FORCE_APPEND) (void)nco_prv_att_cat(fl_in,in_id,out_id);
+  if(gaa_nbr > 0) (void)nco_glb_att_add(out_id,gaa_arg,gaa_nbr);
   if(HISTORY_APPEND) (void)nco_vrs_att_cat(out_id);
   if(thr_nbr > 0 && HISTORY_APPEND) (void)nco_thr_att_cat(out_id,thr_nbr);
 

-- 
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