This file is indexed.

/usr/bin/ncremap is in nco 4.5.4-1build1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
#!/bin/bash

# Purpose: Regrid (subsets of) variables from netCDF files
# Regrids all input files (possibly on different grids) to a single specified output grid

# Copyright (C) 2015-2016 Charlie Zender
# This file is part of NCO, the netCDF Operators. NCO is free software.
# You may redistribute and/or modify NCO under the terms of the 
# GNU General Public License (GPL) Version 3.

# As a special exception to the terms of the GPL, you are permitted 
# to link the NCO source code with the HDF, netCDF, OPeNDAP, and UDUnits
# libraries and to distribute the resulting executables under the terms 
# of the GPL, but in addition obeying the extra stipulations of the 
# HDF, netCDF, OPeNDAP, and UDUnits licenses.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
# See the GNU General Public License for more details.

# The original author of this software, Charlie Zender, seeks to improve
# it with your suggestions, contributions, bug-reports, and patches.
# Please contact the NCO project at http://nco.sf.net or write to
# Charlie Zender
# Department of Earth System Science
# University of California, Irvine
# Irvine, CA 92697-3100

# Source: https://github.com/nco/nco/tree/master/data/ncremap

# Prerequisites: Bash, NCO, ESMF_RegridWeightGen
# Script could use other shells, e.g., dash (Debian default) after re-writing function definition and looping constructs
# Script could use other weight-generators, e.g., TempestRemap by re-writing map-file command

# Script runs in one of four modes:
# 1. Free-will: Infer source and destination grids to generate map-file, then regrid
# 2. Old Grid: Use known-good destination grid to generate map-file then regrid
# 3. New Grid: Generate source-grid from ncks parameter string
# 4. Pre-Destination: Apply supplied map-file to all input files
# By default, ncremap deletes any intermediate grids and map-file that it generates
# Use Free-Will, Old-Grid, or New-Grid mode to process Swath-Like-Data (SLD) where each input may be a granule on a new grid, yet all inputs are to be regridded to the same output grid
# Use Pre-Destination mode to post-process models or analyses where all files are converted from the same source grid to the same destination grid so the map-file can be pre-generated and never change

# Additional Documentation:

# Configure paths at High-Performance Computer Centers (HPCCs) based on ${HOSTNAME}
if [ -z "${HOSTNAME}" ]; then
    if [ -f /bin/hostname ] && [ -x /bin/hostname ] ; then
	export HOSTNAME=`/bin/hostname`
    elif [ -f /usr/bin/hostname ] && [ -x /usr/bin/hostname ] ; then
	export HOSTNAME=`/usr/bin/hostname`
    fi # !hostname
fi # HOSTNAME
# Default input and output directory is ${DATA}
if [ -z "${DATA}" ]; then
    case "${HOSTNAME}" in 
	cooley* | cc* ) DATA="/projects/HiRes_EarthSys/${USER}" ; ;; # ALCF cooley compute nodes named ccNNN
	edison* | hopper* | nid* ) DATA="${SCRATCH}" ; ;; # NERSC edison compute nodes named nidNNNNN
	pileus* ) DATA="/lustre/atlas/proj-shared/cli115/${USER}" ; ;; # OLCF CADES
	rhea* ) DATA="/lustre/atlas/proj-shared/cli115/${USER}" ; ;; # OLCF rhea compute nodes named rheaNNN
	* ) DATA='/tmp' ; ;; # Other
    esac # !HOSTNAME
fi # DATA

# Test cases (examples for Charlie's machines):
# ls ${DATA}/sld/raw/*.nc | ncremap -a conserve -D 0 -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
# ncremap -a conserve -v FSNT -I ${DATA}/ne30/raw -s ${DATA}/grids/ne30np4_pentagons.091226.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
# ls ${DATA}/essgcm14/essgcm14*cam*0007*.nc | ncremap -a conserve -M -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
# ncremap -a conserve -v FSNT -I ${DATA}/ -s ${DATA}/grids/ne30np4_pentagons.091226.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
# ncremap -i AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr
# ncremap -v TSurfAir -i ${DATA}/hdf/AIRS.2015.01.15.001.L2.RetStd.v6.0.11.0.G15015142014.hdf -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -v CloudFrc_A -i ${DATA}/hdf/AIRS.2002.08.01.L3.RetStd_H031.v4.0.21.0.G06104133732.hdf -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/hdf/MOD04_L2.A2000055.0005.006.2014307165927.hdf -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/hdf/OMI-Aura_L2-OMIAuraSO2_2012m1222-o44888_v01-00-2014m0107t114720.h5 -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -v T -i ${DATA}/hdf/wrfout_v2_Lambert_notime.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -v StepTwoO3 -i ${DATA}/hdf/OMI-Aura_L2-OMTO3_2015m0731t0034-o58727_v003-2015m0731t080836.he5.nc -d ${DATA}/hdf/cam_time.nc -O ~/rgr
# ncremap -v TSurfStd -i ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc -G "--rgr grd_ttl='Default internally-generated grid' --rgr grid=~/rgr/ncremap_tmp_grd_dst.nc --rgr latlon=100,100 --rgr snwe=30.0,70.0,-130.0,-90.0" -O ~/rgr
# ncremap -x TSurfStd_ct -i ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/hdf/cice_hi_flt.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/hdf/cam_time.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# CESM & ACME:
# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.cam.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.clm2.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.cice.h.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.pop.h.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ncremap -i ${DATA}/ne120/raw/b1850c5_m2a.rtm.h0.0060-01.nc -g ${DATA}/grids/180x360_SCRIP.20150901.nc -O ~/rgr
# ACME benchmarks:
# ncremap -v FSNT,AODVIS -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -m map_ne30np4_to_fv129x256_aave.150418.nc   -O ~/rgr
# ncremap -v FSNT,AODVIS -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -m map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
# ncremap -v FSNT,AODVIS -w esmf    -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr
# ncremap -v FSNT,AODVIS -w tempest -i ${DATA}/ne30/raw/famipc5_ne30_v0.3_00003.cam.h0.1979-01.nc -s ${DATA}/grids/ne30np4_pentagons.091226.nc -g ${DATA}/grids/129x256_SCRIP.20150901.nc -O ~/rgr

# Debugging and Benchmarking:
# ncremap -D 1 -i ${DATA}/sld/raw/AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc -d ${DATA}/dstmch90/dstmch90_clm.nc -O ~/rgr > ~/ncremap.out 2>&1 &

# dbg_lvl: 0 = Quiet, print basic status during evaluation
#          1 = Print configuration, full commands, and status to output during evaluation
#          2 = As in dbg_lvl=1, but _do not evaluate commands_
#          3 = As in dbg_lvl=1, and pass debug level through to NCO/ncks
# thr_nbr: Thread number to use in NCO regridder, '-t 1' for one thread, '-t 2' for two threads...

# Set script name and run directory
drc_pwd=${PWD}
spt_nm=$(basename ${0}) # [sng] Script name
nco_version=$(ncks --version 2>&1 >/dev/null | grep NCO | awk '{print $5}')

# Set fonts for legibility
fnt_nrm=`tput sgr0` # Normal
fnt_bld=`tput bold` # Bold
fnt_rvr=`tput smso` # Reverse

# Defaults for command-line options and some derived variables
# Modify these defaults to save typing later
alg_typ='conserve' # [nbr] Algorithm for ESMF interpolation (bilinear|patch|neareststod|nearestdtos|conserve)
dbg_lvl=0 # [nbr] Debugging level
#drc_in="${drc_pwd}" # [sng] Input file directory
drc_in='' # [sng] Input file directory
drc_in_xmp='~/drc_in' # [sng] Input file directory for examples
drc_out="${drc_pwd}" # [sng] Output file directory
drc_out_xmp="~/rgr" # [sng] Output file directory for examples
dst_fl='' # [sng] Destination file
dst_xmp='dst.nc' # [sng] Destination file for examples
#esmf_opt='--src_regional --dst_regional --ignore_unmapped' # [sng] ESMF_RegridWeightGen options
esmf_opt='--ignore_unmapped' # [sng] ESMF_RegridWeightGen options
#fml_nm='' # [sng] Family name (e.g., 'amip', 'control', 'experiment')
fl_nbr=0 # [nbr] Number of files to remap
gaa_sng="--gaa rgr_script=${spt_nm} --gaa rgr_hostname=${HOSTNAME} --gaa rgr_version=${nco_version}" # [sng] Global attributes to add
grd_dst='' # [sng] Destination grid-file
grd_dst_glb="${DATA}/grids/180x360_SCRIP.20150901.nc" # [sng] Grid-file (destination) global
grd_dst_xmp='grd_dst.nc' # [sng] Destination grid-file for examples
grd_sng='' # [sng] Grid string
grd_src='' # [sng] Source grid-file
grd_src_xmp='grd_src.nc' # [sng] Source grid-file for examples
hdr_pad='1000' # [B] Pad at end of header section
in_fl='' # [sng] Input file
#in_fl='AIRS.2014.10.01.202.L2.TSurfStd.Regrid010.1DLatLon.hole.nc' # [sng] Input file
in_xmp='in.nc' # [sng] Input file for examples
map_fl='' # [sng] Map-file
map_xmp='map.nc' # [sng] Map-file for examples
mlt_map_flg='Yes' # [sng] Multi-map flag
mpi_flg='No' # [sng] Parallelize over nodes
msh_fl='' # [sng] Mesh-file (for Tempest)
nco_opt='-O --no_tmp_fl' # [sng] NCO defaults (e.g., '-O -6 -t 1')
nco_usr='' # [sng] NCO user-configurable options (e.g., '-D 1')
out_fl='' # [sng] Output file
out_xmp='out.nc' # [sng] Output file for examples
par_typ='' # [sng] Parallelism type
rgr_opt='--rgr lat_nm_out=lat --rgr lon_nm_out=lon' # [sng] Regridding options (e.g., '--rgr col_nm=lndgrid')
tps_opt='' # [sng] TempestRemap options
thr_nbr=2 # [nbr] Thread number for regridder
#var_lst='FSNT,AODVIS' # [sng] Variables to process (empty means all)
tmp_out_fl='ncremap_grd_tmp.nc' # [sng] Temporary output file
var_lst='' # [sng] Variables to process (empty means all)
var_xmp='FSNT' # [sng] Variable list for examples
wgt_gnr='esmf' # [sng] Weight-generator program
xtn_var='' # [sng] Extensive variables (e.g., 'TSurfStd_ct')

function fnc_usg_prn { # NB: dash supports fnc_nm (){} syntax, not function fnc_nm{} syntax
    # Print usage
    printf "\nQuick documentation for ${fnt_bld}${spt_nm}${fnt_nrm} (more at http://nco.sf.net/nco.html#ncremap)\n\n"
    printf "${fnt_rvr}Basic usage:${fnt_nrm} ${fnt_bld}$spt_nm -i in_fl -d dst_fl -o out_fl${fnt_nrm}\n\n"
    echo "Command-line options:"
    echo "${fnt_rvr}-a${fnt_nrm} ${fnt_bld}alg_typ${fnt_nrm}  Algorithm for ESMF weight generation (default ${fnt_bld}${alg_typ}${fnt_nrm})"
    echo "${fnt_rvr}-d${fnt_nrm} ${fnt_bld}dst_fl${fnt_nrm}   Data file to infer destination grid from (empty means none, i.e., use grd_fl, grd_sng or map_fl)) (default ${fnt_bld}${dst_fl}${fnt_nrm})"
    echo "${fnt_rvr}-D${fnt_nrm} ${fnt_bld}dbg_lvl${fnt_nrm}  Debugging level (default ${fnt_bld}${dbg_lvl}${fnt_nrm})"
    echo "${fnt_rvr}-E${fnt_nrm} ${fnt_bld}esmf_opt${fnt_nrm} ESMF ESMF_RegridWeightGen options (default ${fnt_bld}${esmf_opt}${fnt_nrm})"
#    echo "${fnt_rvr}-f${fnt_nrm} ${fnt_bld}fml_nm${fnt_nrm}   Family name (empty means none) (default ${fnt_bld}${fml_nm}${fnt_nrm})"
    echo "${fnt_rvr}-g${fnt_nrm} ${fnt_bld}grd_dst${fnt_nrm}  Grid-file (destination) (empty means none, i.e., infer from dst_fl or use grd_sng or map_fl) (default ${fnt_bld}${grd_dst}${fnt_nrm})"
    echo "${fnt_rvr}-G${fnt_nrm} ${fnt_bld}grd_sng${fnt_nrm}  Grid generation argument string (empty means none) (default ${fnt_bld}${grd_sng}${fnt_nrm})"
    echo "${fnt_rvr}-I${fnt_nrm} ${fnt_bld}drc_in${fnt_nrm}   Input directory (empty means none) (default ${fnt_bld}${drc_in}${fnt_nrm})"
    echo "${fnt_rvr}-i${fnt_nrm} ${fnt_bld}in_fl${fnt_nrm}    Input file (empty means use stdin or drc_in) (default ${fnt_bld}${in_fl}${fnt_nrm})"
    echo "${fnt_rvr}-M${fnt_nrm}          Multi-map-file toggle (unset means generate one map-file per input file)"
    echo "${fnt_rvr}-m${fnt_nrm} ${fnt_bld}map_fl${fnt_nrm}   Map-file (empty means generate internally) (default ${fnt_bld}${map_fl}${fnt_nrm})"
    echo "${fnt_rvr}-n${fnt_nrm} ${fnt_bld}nco_opt${fnt_nrm}  NCO options (empty means none) (default ${fnt_bld}${nco_opt}${fnt_nrm})"
    echo "${fnt_rvr}-O${fnt_nrm} ${fnt_bld}drc_out${fnt_nrm}  Output directory (default ${fnt_bld}${drc_out}${fnt_nrm})"
    echo "${fnt_rvr}-o${fnt_nrm} ${fnt_bld}out_fl${fnt_nrm}   Output-file (regridded file) (empty copies Input filename) (default ${fnt_bld}${out_fl}${fnt_nrm})"
    echo "${fnt_rvr}-p${fnt_nrm} ${fnt_bld}par_typ${fnt_nrm}  Parallelism type (default ${fnt_bld}${par_typ}${fnt_nrm})"
    echo "${fnt_rvr}-R${fnt_nrm} ${fnt_bld}rgr_opt${fnt_nrm}  Regridding options (empty means none) (default ${fnt_bld}${rgr_opt}${fnt_nrm})"
    echo "${fnt_rvr}-s${fnt_nrm} ${fnt_bld}grd_src${fnt_nrm}  Grid-file (source) (empty means infer or use map_fl) (default ${fnt_bld}${grd_src}${fnt_nrm})"
    echo "${fnt_rvr}-t${fnt_nrm} ${fnt_bld}thr_nbr${fnt_nrm}  Thread number for regridder (default ${fnt_bld}${thr_nbr}${fnt_nrm})"
    echo "${fnt_rvr}-T${fnt_nrm} ${fnt_bld}tps_opt${fnt_nrm}  TempestRemap GenerateOfflineMap options (default ${fnt_bld}${tps_opt}${fnt_nrm})"
    echo "${fnt_rvr}-v${fnt_nrm} ${fnt_bld}var_lst${fnt_nrm}  Variable list (empty means all) (default ${fnt_bld}${var_lst}${fnt_nrm})"
    echo "${fnt_rvr}-w${fnt_nrm} ${fnt_bld}wgt_gnr${fnt_nrm}  Weight-generator (default ${fnt_bld}${wgt_gnr}${fnt_nrm})"
    echo "${fnt_rvr}-x${fnt_nrm} ${fnt_bld}xtn_var${fnt_nrm}  Extensive variables (empty means none) (default ${fnt_bld}${xtn_var}${fnt_nrm})"
    printf "\n"
    printf "Examples: ${fnt_bld}$spt_nm -i ${in_xmp} -m ${map_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -i ${in_xmp} -g ${grd_dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -a bilinear -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -a conserve -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -w tempest  -i ${in_xmp} -d ${dst_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -v ${var_xmp} -i ${in_xmp} -m ${map_xmp} -o ${out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -m ${map_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -M -I ${drc_in_xmp} -d ${dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -M -I ${drc_in_xmp} -g ${grd_dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -s ${grd_src_xmp} -d ${dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -s ${grd_src_xmp} -g ${grd_dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -d ${dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}$spt_nm -I ${drc_in_xmp} -g ${grd_dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}ls mdl*2005*nc | $spt_nm -m ${map_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    printf "          ${fnt_bld}ls mdl*2005*nc | $spt_nm -d ${dst_xmp} -O ${drc_out_xmp} ${fnt_nrm}\n"
    exit 1
} # end fnc_usg_prn()

function dst_is_grd {
    # Is destination grid specified as SCRIP grid-file?
    # Usage: dst_is_grd ${fl}
    fl=${1}
    flg='Yes'
    #flg='No'
} # end dst_is_grd()

# Check argument number and complain accordingly
arg_nbr=$#
#printf "\ndbg: Number of arguments: ${arg_nbr}"
if [ ${arg_nbr} -eq 0 ]; then
  fnc_usg_prn
fi # !arg_nbr

# Parse command-line options:
# http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
# http://tuxtweaks.com/2014/05/bash-getopts
cmd_ln="${@}"
while getopts :a:D:d:E:f:g:G:h:I:i:Mm:n:O:o:p:R:s:T:t:v:w:x: OPT; do
    case ${OPT} in
	a) alg_typ=${OPTARG} ;; # Algorithm
	D) dbg_lvl=${OPTARG} ;; # Debugging level
	d) dst_fl=${OPTARG} ;; # Destination file
	E) esmf_opt=${OPTARG} ;; # ESMF options
#	f) fml_nm=${OPTARG} ;; # Family name
	g) grd_dst=${OPTARG} ;; # Destination grid-file
	G) grd_sng=${OPTARG} ;; # Grid generation string
	I) drc_in=${OPTARG} ;; # Input directory
	i) in_fl=${OPTARG} ;; # Input file
	M) mlt_map_flg='No' ;; # Multi-map flag
	m) map_fl=${OPTARG} ;; # Map-file
	n) nco_usr=${OPTARG} ;; # NCO options
	O) drc_out=${OPTARG} ;; # Output directory
	o) out_fl=${OPTARG} ;; # Output file
	p) par_typ=${OPTARG} ;; # Parallelism type
	R) rgr_opt=${OPTARG} ;; # Regridding options
	s) grd_src=${OPTARG} ;; # Source grid-file
	T) tps_opt=${OPTARG} ;; # Tempest options
	t) thr_usr=${OPTARG} ;; # Thread number
	v) var_lst=${OPTARG} ;; # Variables
	w) wgt_usr=${OPTARG} ;; # Weight-generator
	x) xtn_var=${OPTARG} ;; # Extensive variables
	\?) # Unrecognized option
	    printf "\nERROR: Option ${fnt_bld}-$OPTARG${fnt_nrm} not allowed"
	    fnc_usg_prn ;;
    esac
done
shift $((OPTIND-1)) # Advance one argument

# Derived variables
grd_dst_dfl="${drc_out}/ncremap_tmp_grd_dst.nc" # [sng] Grid-file (destination) default
grd_src_dfl="${drc_out}/ncremap_tmp_grd_src.nc" # [sng] Grid-file (source) default
tmp_out_fl="${drc_out}/${tmp_out_fl}" # [sng] Temporary output file
if [ ${alg_typ} = 'bilinear' ] || [ ${alg_typ} = 'bln' ] ; then 
    # ESMF algorithms are bilinear|patch|neareststod|nearestdtos|conserve
    alg_opt='bilinear'
elif [ ${alg_typ} = 'conserve' ] || [ ${alg_typ} = 'conservative' ] || [ ${alg_typ} = 'cns' ] ; then 
    alg_opt='conserve'
elif [ ${alg_typ} = 'nearestdtos' ] || [ ${alg_typ} = 'nds' ] || [ ${alg_typ} = 'dtos' ] ; then 
    alg_opt='nearestdtos'
elif [ ${alg_typ} = 'neareststod' ] || [ ${alg_typ} = 'nsd' ] || [ ${alg_typ} = 'stod' ] ; then 
    alg_opt='nearestdtos'
elif [ ${alg_typ} = 'patch' ] || [ ${alg_typ} = 'pch' ] || [ ${alg_typ} = 'ptc' ] ; then 
    alg_opt='patch'
fi # !alg_typ
if [ -z "${drc_in}" ]; then
    drc_in="${drc_pwd}"
else # !drc_in
    drc_in_usr_flg='Yes'
fi # !drc_in
if [ ${dbg_lvl} -ge 2 ]; then
    nco_opt="-D ${dbg_lvl} ${nco_opt}"
fi # !dbg_lvl
if [ -n "${nco_usr}" ]; then 
    nco_opt="${nco_usr} ${nco_opt}"
fi # !var_lst
if [ -n "${gaa_sng}" ]; then 
    nco_opt="${nco_opt} ${gaa_sng}"
fi # !var_lst
if [ -n "${hdr_pad}" ]; then 
    nco_opt="${nco_opt} --hdr_pad=${hdr_pad}"
fi # !hdr_pad
if [ -n "${var_lst}" ]; then 
    nco_var_lst="-v ${var_lst}"
fi # !var_lst
if [ -n "${xtn_var}" ]; then 
    rgr_opt="${rgr_opt} --xtn=${xtn_var}"
fi # !var_lst
if [ -n "${par_typ}" ]; then
    if [ "${par_typ}" != 'bck' ] && [ "${par_typ}" != 'mpi' ] && [ "${par_typ}" != 'nil' ]; then 
	    echo "ERROR: Invalid -p par_typ option = ${par_typ}"
	    echo "HINT: Valid par_typ arguments are 'bck', 'mpi', and 'nil'"
	    exit 1
    fi # !par_typ
fi # !par_typ
if [ "${par_typ}" = 'bck' ]; then 
    par_opt=' &'
elif [ "${par_typ}" = 'mpi' ]; then 
    mpi_flg='Yes'
    par_opt=' &'
fi # !par_typ
if [ -n "${out_fl}" ]; then 
    out_usr_flg='Yes'
fi # !out_fl
if [ -n "${thr_usr}" ]; then 
    thr_nbr="${thr_usr}"
fi # !thr_usr
if [ -n "${wgt_usr}" ]; then 
    wgt_gnr="${wgt_usr}"
fi # !wgt_usr    
if [ "${wgt_gnr}" != 'esmf' ] && [ "${wgt_gnr}" != 'tempest' ] ; then 
	    echo "ERROR: Invalid -w wgt_gnr option = ${wgt_gnr}"
	    echo "HINT: Valid wgt_gnr arguments are 'esmf' and 'tempest'"
	    exit 1
fi # !wgt_gnr

if [ -n "${in_fl}" ]; then
    # Single file argument
    fl_in[${fl_nbr}]=${in_fl}
    let fl_nbr=${fl_nbr}+1
else # !in_fl
    # Detecting input on stdin:
    # http://stackoverflow.com/questions/2456750/detect-presence-of-stdin-contents-in-shell-script
    # ls ${DATA}/ne30/raw/famipc5*1979*.nc | ncremap -D 1 -m ${DATA}/maps/map_ne30np4_to_fv129x256_aave.20150901.nc -O ~/rgr
    if [ -t 0 ]; then 
	if [ "${drc_in_usr_flg}" = 'Yes' ]; then
	    for fl in "${drc_in}"/*.nc "${drc_in}"/*.nc3 "${drc_in}"/*.nc4 "${drc_in}"/*.cdf "${drc_in}"/*.hdf "${drc_in}"/*.he5 "${drc_in}"/*.h5 ; do
		if [ -f "${fl}" ]; then
		    fl_in[${fl_nbr}]=${fl}
		    let fl_nbr=${fl_nbr}+1
		fi # !file
	    done
	else # !drc_in
	    echo "ERROR: Must specify input file with -i or with stdin"
	    echo "HINT: Pipe file list to script via stdin with, e.g., 'ls *.nc | ${spt_nm}'"
	    exit 1
	fi # !drc_in
    else
	# Input awaits on unit 0, i.e., on stdin
	while read -r line; do # NeR05 p. 179
	    fl_in[${fl_nbr}]=${line}
	    let fl_nbr=${fl_nbr}+1
	done < /dev/stdin
    fi # stdin
fi # !in_fl
if [ -n "${dst_fl}" ]; then 
    if [ ! -e "${dst_fl}" ]; then
	echo "ERROR: Unable to find specified destination-file ${dst_fl}"
	echo "HINT: Supply the full path-name for the destination-file"
	exit 1
    fi # ! -e
    dst_usr_flg='Yes'
fi # !dst_fl
if [ -n "${grd_dst}" ]; then 
    if [ ! -e "${grd_dst}" ]; then
	echo "ERROR: Unable to find specified destination grid-file ${grd_dst}"
	echo "HINT: Supply the full path-name for the destination grid, or generate one automatically with -G"
	exit 1
    fi # ! -e
    grd_dst_usr_flg='Yes'
else
    grd_dst=${grd_dst_dfl} # [sng] Grid-file default
fi # !grd_dst
if [ -n "${grd_src}" ]; then 
    if [ ! -e "${grd_src}" ]; then
	echo "ERROR: Unable to find specified source grid-file ${grd_src}"
	exit 1
    fi # ! -e
    grd_src_usr_flg='Yes'
else
    grd_src=${grd_src_dfl} # [sng] Grid-file default
fi # !grd_src
if [ -z "${grd_sng}" ]; then 
    grd_sng_dfl="--rgr grd_ttl='Default internally-generated grid' --rgr grid=${grd_dst_dfl} --rgr latlon=100,100 --rgr snwe=30.0,70.0,-130.0,-90.0" # [sng] Grid string default
    grd_sng="${grd_sng_dfl}"
else
    grd_sng_usr_flg='Yes'
fi # !grd_sng
if [ -n "${map_fl}" ]; then 
    if [ ! -e "${map_fl}" ]; then
	echo "ERROR: Unable to find specified regrid map ${map_fl}"
	echo "HINT: Supply the full path-name for the regridding map"
	exit 1
    fi # ! -e
    map_usr_flg='Yes'
else
    if [ "${wgt_gnr}" = 'esmf' ]; then 
	map_fl_dfl="${drc_out}/ncremap_tmp_map_${wgt_gnr}_${alg_opt}.nc" # [sng] Map-file default
    fi # !esmf
    if [ "${wgt_gnr}" = 'tempest' ]; then 
	map_fl_dfl="${drc_out}/ncremap_tmp_map_${wgt_gnr}.nc" # [sng] Map-file default
	msh_fl_dfl="${drc_out}/ncremap_tmp_msh_ovr_${wgt_gnr}.g" # [sng] Mesh-file default
	msh_fl=${msh_fl_dfl}
    fi # !tempest
    map_fl=${map_fl_dfl}
fi # !map_fl

# Print initial state
if [ ${dbg_lvl} -ge 2 ]; then
    printf "dbg: alg_opt  = ${alg_opt}\n"
    printf "dbg: dbg_lvl  = ${dbg_lvl}\n"
    printf "dbg: drc_in   = ${drc_in}\n"
    printf "dbg: drc_out  = ${drc_out}\n"
    printf "dbg: dst_fl   = ${dst_fl}\n"
#    printf "dbg: fml_nm   = ${fml_nm}\n"
    printf "dbg: gaa_sng  = ${gaa_sng}\n"
    printf "dbg: grd_dst  = ${grd_dst}\n"
    printf "dbg: grd_sng  = ${grd_sng}\n"
    printf "dbg: grd_src  = ${grd_src}\n"
    printf "dbg: hdr_pad  = ${hdr_pad}\n"
    printf "dbg: in_fl    = ${in_fl}\n"
    printf "dbg: map_fl   = ${map_fl}\n"
    printf "dbg: mlt_map  = ${mlt_map_flg}\n"
    printf "dbg: mpi_flg  = ${mpi_flg}\n"
    printf "dbg: nco_opt  = ${nco_opt}\n"
    printf "dbg: nd_nbr   = ${nd_nbr}\n"
    printf "dbg: out_fl   = ${out_fl}\n"
    printf "dbg: par_typ  = ${par_typ}\n"
    printf "dbg: thr_nbr  = ${thr_nbr}\n"
    printf "dbg: var_lst  = ${var_lst}\n"
    printf "Asked to regrid ${fl_nbr} files:\n"
    for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
	printf "${fl_in[${fl_idx}]}\n"
    done # !fl_idx
fi # !dbg
if [ ${dbg_lvl} -ge 2 ]; then
    if [ ${mpi_flg} = 'Yes' ]; then
	for ((nd_idx=0;nd_idx<${nd_nbr};nd_idx++)); do
	    printf "dbg: nd_nm[${nd_idx}] = ${nd_nm[${nd_idx}]}\n"
	done # !nd
    fi # !mpi
fi # !dbg

# Create output directory
mkdir -p ${drc_out}

# Human-readable summary
if [ ${dbg_lvl} -ge 1 ]; then
    printf "NCO regridder invoked with command:\n"
    echo "${spt_nm} ${cmd_ln}"
fi # !dbg
date_srt=$(date +"%s")

if [ -f 'PET0.RegridWeightGen.Log' ]; then
    printf "${spt_nm}: Removing PET0.RegridWeightGen.Log file from current directory before running\n"
    /bin/rm -f PET0.RegridWeightGen.Log
fi # !PETO
printf "Started processing at `date`.\n"
printf "NCO version is ${nco_version}\n"
if [ "${map_usr_flg}" = 'Yes' ] && [ -n "${wgt_usr}" ] ; then
    printf "${spt_nm}: ERROR Specifying both '-m map_fl' and '-w wgt_gnr' is not allowed (the weight-generator is unnecessary)\n"
    exit 1
fi # wgt_usr
if [ "${grd_src_usr_flg}" = 'Yes' ]; then
    if [ "${map_usr_flg}" = 'Yes' ]; then 
	printf "${spt_nm}: ERROR Specifying both '-s grd_src' and '-m map_fl' is ambiguous and forbidden\n"
	exit 1
    fi # !map_usr_flg
fi # !grd_src_usr_flg
    
if [ "${dst_usr_flg}" = 'Yes' ]; then 
    if [ "${map_usr_flg}" = 'Yes' ]; then 
	printf "${spt_nm}: ERROR Specify either '-d dst_fl' or '-m map_fl' not both\n"
	exit 1
    fi # !map_usr_flg
    if [ "${grd_dst_usr_flg}" = 'Yes' ]; then 
	printf "${spt_nm}: ERROR Specify either '-d dst_fl' or '-g grd_dst' not both\n"
	exit 1
    fi # !grd_dst_usr_flg
else # !dst_usr_flg
    if [ "${grd_dst_usr_flg}" = 'Yes' ]; then 
	if [ "${map_usr_flg}" = 'Yes' ]; then 
	    printf "${spt_nm}: ERROR Specify either '-g grd_dst' or '-m map_fl' not both\n"
	    exit 1
	fi # !map_usr_flg
    else
	if [ "${map_usr_flg}" != 'Yes' ] && [ "${grd_sng_usr_flg}" != 'Yes' ] ; then 
	    printf "${spt_nm}: ERROR Must use one of '-d dst_fl', '-g grd_dst', '-G grd_sng', or '-m map_fl'\n"
	    exit 1
	fi # !map_usr_flg
    fi # !grd_dst_usr_flg
fi # !dst_usr_flg

# Generate destination grid, if necessary, once (only) before loop over input files
# Block 1: Destination grid
# Unlike source grid, same destination grid is used for all files
# Generate destination grid at most one-time
# Eventually we will allow destination grid to be provided as grid-file, map-file, or data-file
# Currently we require user to know (and specify) means by which destination grid is provided
if [ "${map_usr_flg}" = 'Yes' ]; then 
    printf "Source and destination grids will both be read from supplied map-file ${map_fl}\n"
else # !map_usr_flg
    fl_idx=0 # [idx] Current file index
    if [ "${dst_usr_flg}" = 'Yes' ]; then 
	# Block 1 Loop 1: Generate, check, and store (but do not yet execute) commands
	# Infer destination grid-file from data file
	printf "Destination grid will be inferred from data-file ${dst_fl} and stored as ${grd_dst}\n"
	cmd_dst[${fl_idx}]="ncks ${nco_opt} --rgr nfr=y --rgr grid=${grd_dst} ${dst_fl} ${tmp_out_fl}"
    else # !dst_usr_flg
	if [ "${grd_dst_usr_flg}" = 'Yes' ]; then 
	    printf "Destination grid supplied by user as ${grd_dst}\n"
	else
	    if [ "${grd_sng_usr_flg}" = 'Yes' ]; then 
		printf "Destination grid will be generated from NCO grid string ${grd_sng}\n"
		cmd_dst[${fl_idx}]="ncks ${nco_opt} ${grd_sng} ${fl_in[0]} ${tmp_out_fl}"
	    else
		printf "${spt_nm}: ERROR Grid string grd_sng not provided\n"
		exit 1
	    fi # !grd_sng_usr_flg
	fi # !grd_dst_usr_flg
    fi # !dst_usr_flg
    if [ "${dst_usr_flg}" = 'Yes' ] || [ "${grd_dst_usr_flg}" != 'Yes' ]; then 
	# Block 1 Loop 2: Execute and/or echo commands
	if [ ${dbg_lvl} -ge 1 ]; then
	    echo ${cmd_dst[${fl_idx}]}
	fi # !dbg
	if [ ${dbg_lvl} -ne 2 ]; then
	    eval ${cmd_dst[${fl_idx}]}
	    if [ $? -ne 0 ]; then
		printf "${spt_nm}: ERROR Failed to generate destination grid. Debug this:\n${cmd_dst[${fl_idx}]}\n"
		exit 1
	    fi # !err
	    if [ "${grd_sng_usr_flg}" = 'Yes' ]; then 
		/bin/rm -f ${tmp_out_fl}
	    fi # !grd_sng_usr_flg
	fi # !dbg
    fi # !dst_usr_flg || grd_dst_usr_flg
    printf "Weight-generation type: ${wgt_gnr}\n"
    if [ "${wgt_gnr}" = 'esmf' ]; then 
	printf "ESMF's ESMF_RegridWeightGen will generate map-file internally and store it as ${map_fl}\n"
	printf "Algorithm used to generate weights in map-file is: ${alg_opt}\n"
    fi # !esmf
    if [ "${wgt_gnr}" = 'tempest' ]; then 
	printf "TempestRemap's GenerateOverlapMesh and GenerateOfflineMap will generate map-file internally and store it as ${map_fl}\n"
    fi # !tempest
    if [ ${fl_nbr} -ge 2 ]; then 
	if [ "${mlt_map_flg}" = 'Yes' ]; then 
	    printf "Input files assumed to use unique input grids, one map-file will be generated per input file\n"
	else # !mlt_map_flg
	    printf "Input files assumed to use same input grid, only one map-file will be generated\n"
	fi # !mlt_map_flg
    fi # !fl_nbr
fi # !map_usr

# If user provides source gridfile, assume it applies to every input file
# Do not infer source gridfiles from input files within file loop
# Generate map-file once outside of file loop, and re-use it for every input file
if [ "${grd_src_usr_flg}" = 'Yes' ]; then
    printf "Source grid supplied by user as ${grd_src}\n"
    fl_idx=0
    if [ "${wgt_gnr}" = 'esmf' ]; then 
	cmd_map[${fl_idx}]="ESMF_RegridWeightGen -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${esmf_opt} > /dev/null"
    fi # !esmf
    if [ "${wgt_gnr}" = 'tempest' ]; then 
	cmd_msh[${fl_idx}]="GenerateOverlapMesh --a ${grd_src} --b ${grd_dst} --out ${msh_fl} > /dev/null"
	cmd_map[${fl_idx}]="GenerateOfflineMap --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${tps_opt} > /dev/null"
	# 20160101: TempestRemap programs have false positive error returns (failures reported as successes) so remove old map/mesh before generating new
	/bin/rm -f ${msh_fl} ${map_fl}
	if [ ${dbg_lvl} -ge 1 ]; then
	    echo ${cmd_msh[${fl_idx}]}
	fi # !dbg
	if [ ${dbg_lvl} -ne 2 ]; then
	    eval ${cmd_msh[${fl_idx}]}
	    if [ $? -ne 0 ] || [ ! -f ${msh_fl} ] ; then
		printf "${spt_nm}: ERROR Failed to generate mesh-file. Debug this:\n${cmd_msh[${fl_idx}]}\n"
		exit 1
	    fi # !err
	fi # !dbg
    fi # !tempest
    if [ ${dbg_lvl} -ge 1 ]; then
	echo ${cmd_map[${fl_idx}]}
    fi # !dbg
    if [ ${dbg_lvl} -ne 2 ]; then
	eval ${cmd_map[${fl_idx}]}
	if [ $? -ne 0 ] || [ ! -f ${map_fl} ] ; then
	    printf "${spt_nm}: ERROR Failed to generate map-file. Debug this:\n${cmd_map[${fl_idx}]}\n"
	    if [ "${wgt_gnr}" = 'esmf' ]; then 
		printf "${spt_nm}: HINT When ESMF fails to generate map-files, it often puts additional debugging information in the file named PET0.RegridWeightGen.Log in the invocation directory (${drc_pwd})\n"
	    fi # !esmf
	    exit 1
	fi # !err
    fi # !dbg
    # Set map_usr_flg to 'Yes' here to avoid re-generating map within file loop
    map_usr_flg='Yes'
fi # !grd_src_usr_flg

# Begin loop over input files
for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
    in_fl=${fl_in[${fl_idx}]}
    if [ "$(basename ${in_fl})" = "${in_fl}" ]; then
	in_fl="${drc_pwd}/${in_fl}"
    fi # !basename
    if [ "${out_usr_flg}" = 'Yes' ]; then 
	if [ ${fl_nbr} -ge 2 ]; then 
	    echo "ERROR: Single output filename specified with -o for multiple input files"
	    echo "HINT: For multiple input files use -O option to specify output directory and do not use -o option. Output files will have same name as input files, but will be in different directory."
	    exit 1
	fi # !fl_nbr
    else # !out_usr_flg
	out_fl="${drc_out}/$(basename ${in_fl})" # [sng] Output-file default
    fi # !out_fl
    if [ "${in_fl}" = "${out_fl}" ]; then
	echo "ERROR: Input file = Output file = ${in_fl}"
	echo "HINT: To prevent inadvertent data loss, ${spt_nm} insists that Input file and Output filenames differ"
	exit 1
    fi # !basename

    # Generate new map unless map-file was supplied or already-generated (as indicated by map_usr_flg)
    if [ "${map_usr_flg}" != 'Yes' ]; then
	# Block 2: Source grid
	# Block 2 Loop 1: Source gridfile command
	if [ ! -e "${in_fl}" ]; then
	    echo "${spt_nm}: ERROR Unable to find Input file ${in_fl}"
	    echo "HINT: All files implied to exist must be in the directory specified by their filename or in ${drc_in} before ${spt_nm} will proceed"
	    exit 1
	fi # ! -e
	# Infer source grid-file from input data file
	cmd_src[${fl_idx}]="ncks ${nco_opt} --rgr nfr=y --rgr grid=${grd_src} ${in_fl} ${tmp_out_fl}"
	
	# Block 2 Loop 2: Execute and/or echo commands
	if [ ${dbg_lvl} -ge 1 ]; then
	    echo ${cmd_src[${fl_idx}]}
	fi # !dbg
	if [ ${dbg_lvl} -ne 2 ]; then
	    eval ${cmd_src[${fl_idx}]}
	    if [ $? -ne 0 ]; then
		printf "${spt_nm}: ERROR Failed to generate source grid. Debug this:\n${cmd_src[${fl_idx}]}\n"
		exit 1
	    fi # !err
	fi # !dbg
	
	# Block 3: Source->destination maps
	# Block 3 Loop 1: Map-file commands
	printf "Grid(src): ${grd_src}\n"
	printf "Grid(dst): ${grd_dst}\n"
	printf "Map-File : ${map_fl}\n"
	if [ "${wgt_gnr}" = 'esmf' ]; then 
	    cmd_map[${fl_idx}]="ESMF_RegridWeightGen -s ${grd_src} -d ${grd_dst} -w ${map_fl} --method ${alg_opt} ${esmf_opt} > /dev/null"
	fi # !esmf
	if [ "${wgt_gnr}" = 'tempest' ]; then 
	    printf "Mesh-File: ${msh_fl}\n"
	    cmd_msh[${fl_idx}]="GenerateOverlapMesh --a ${grd_src} --b ${grd_dst} --out ${msh_fl} ${tps_opt} > /dev/null"
	    cmd_map[${fl_idx}]="GenerateOfflineMap --in_mesh ${grd_src} --out_mesh ${grd_dst} --ov_mesh ${msh_fl} --out_map ${map_fl} ${tps_opt} > /dev/null"
	    # 20160101: TempestRemap programs have false negative error returns (failures reported as successes) so remove old map/mesh before generating new
	    /bin/rm -f ${msh_fl} ${map_fl}
	    if [ ${dbg_lvl} -ge 1 ]; then
		echo ${cmd_msh[${fl_idx}]}
	    fi # !dbg
	    if [ ${dbg_lvl} -ne 2 ]; then
		eval ${cmd_msh[${fl_idx}]}
		if [ $? -ne 0 ] || [ ! -f ${msh_fl} ] ; then
		    printf "${spt_nm}: ERROR Failed to generate mesh-file. Debug this:\n${cmd_msh[${fl_idx}]}\n"
		    exit 1
		fi # !err
	    fi # !dbg
	fi # !tempest
	
	# Block 3 Loop 2: Execute and/or echo commands
	if [ ${dbg_lvl} -ge 1 ]; then
	    echo ${cmd_map[${fl_idx}]}
	fi # !dbg
	if [ ${dbg_lvl} -ne 2 ]; then
	    eval ${cmd_map[${fl_idx}]}
	    if [ $? -ne 0 ] || [ ! -f ${map_fl} ] ; then
		printf "${spt_nm}: ERROR Failed to generate map-file. Debug this:\n${cmd_map[${fl_idx}]}\n"
		if [ "${wgt_gnr}" = 'esmf' ]; then 
		    printf "${spt_nm}: HINT When ESMF fails to generate map-files, it often puts additional debugging information in the file named PET0.RegridWeightGen.Log in the invocation directory (${drc_pwd})\n"
		fi # !esmf
		exit 1
	    fi # !err
	fi # !dbg

	# Prevent creating new source gridfile and map-file after first iteration
	if [ "${mlt_map_flg}" = 'No' ] && [ ${fl_idx} -eq 0 ] ; then 
	    map_usr_flg='Yes'
	fi # !mlt_map_flg

    fi # !map_usr_flg
    
    # Block 4: Regrid
    printf "Input : ${in_fl}\n"
    printf "Output: ${out_fl}\n"
    cmd_rgr[${fl_idx}]="ncks -t ${thr_nbr} ${nco_opt} ${nco_var_lst} ${rgr_opt} --map=${map_fl} ${in_fl} ${out_fl}"
    
    # Block 4 Loop 2: Execute and/or echo commands
    if [ ${dbg_lvl} -ge 1 ]; then
	echo ${cmd_rgr[${fl_idx}]}
    fi # !dbg
    if [ ${dbg_lvl} -ne 2 ]; then
	eval ${cmd_rgr[${fl_idx}]}
	if [ -z "${par_opt}" ]; then
	    eval ${cmd_rgr[${fl_idx}]}
	    if [ $? -ne 0 ]; then
		printf "${spt_nm}: ERROR Failed to regrid. cmd_rgr[${fl_idx}] failed. Debug this:\n${cmd_rgr[${fl_idx}]}\n"
		exit 1
	    fi # !err
	else # !par_typ
	    eval ${cmd_rgr[${fl_idx}]} ${par_opt}
	    rgr_pid[${fl_idx}]=$!
	fi # !par_typ
    fi # !dbg
done # !fl_idx

# wait() for parallel regridding, if any, to finish
if [ -n "${par_opt}" ]; then
    for ((fl_idx=0;fl_idx<${fl_nbr};fl_idx++)); do
	wait ${rgr_pid[${fl_idx}]}
	if [ $? -ne 0 ]; then
	    printf "${spt_nm}: ERROR Failed to regrid. cmd_rgr[${fl_idx}] failed. Debug this:\n${cmd_rgr[${fl_idx}]}\n"
	    exit 1
	fi # !err
    done # !fl_idx
fi # !par_typ

date_end=$(date +"%s")
printf "Completed processing of ${fl_nbr} file(s) at `date`.\n"
date_dff=$((date_end-date_srt))
echo "Quick plots of results from last regridded file:"
echo "ncview  ${out_fl} &"
echo "panoply ${out_fl} &"
echo "Elapsed time $((date_dff/60))m$((date_dff % 60))s"

exit 0