#!/bin/csh -f
#
#       $Id: ncl_convert2nc,v 1.22 2010-04-05 22:37:28 dbrown Exp $

#       Copyright (C) 2005
#       University Corporation for Atmospheric Research
#       All Rights Reserved

#       File:       ncl_convert2nc
#       Author:     Rick Grubin
#                   Original NCL code written by Dennis Shea
#
#       National Center for Atmospheric Research
#       POB 3000, Boulder, Colorado

# This script converts a NCL-supported file type (GRIB[1, 2], HDF, HDF-EOS) to a netCDF-formatted file.
# It can also convert between several NetCDF formats - classic, 64-bit offset, and NetCDF4 classic.
# In addition, it can be used to extract particular variables into a NetCDF file.
# It does not handle CCM data.  See:  http://www.cgd.ucar.edu/cms/ccm3/tools.
#
# This script determines what data type it was invoked with based on the suffix of the data
# file(s) provided to it.  Data must be of a type supported by NCL.  This information is
# provided to the NCL portion of this script for data-dependent processing.
#
#   ncl_convert2nc inputFile [-i input_directory] [-o output_directory] [-v var1[,...]] [-c comment] [-d] [-h] [other_options]
#       inputFile             name of file [required]
#       [-i input_directory]  location of input file  [default: current directory]
#       [-o output_directory] location of output file [default: current directory]
#       [-e extension]        file type, defined by extension, to convert
#       [-u [time_name]]      name of the NCL-named time dimension to be UNLIMITED
#                               if time_name not specified NCL will attempt to find a suitable time dimension:
#                               if GRIB it will contain the substring "initial_time", otherwise "time" (any case);
#                               error will occur if the dimension found is not the left-most dimension
#       [-U new_time_name]    if -u is specified, will rename the NCL-named time dimension for netCDF 
#       [-sed sed1[,...]]     GRIB files only; set single element dimensions [default: none]
#                                choices are initial_time, forecast_time, level, ensemble,
#                                probability, all, none"
#       [-itime]              GRIB files only; set initial time as a single element dimension
#                                (same as -sed initial_time)
#       [-ftime]              GRIB files only; set forecast time as a single element dimension
#                                  (same as -sed forecast_time)
#       [-tps]                GRIB files only; remove suffix representing a time period (e.g. 2h)
#                             from statistically processed variables, leaving only type of
#                             processing as a suffix (e.g. _acc, _avg)
#       [-v var1[,...]]       user specified subset of variables [default: all variables]
#       [-L]                  support for writing large (>2Gb) netCDF files [default: no largefile support]
#       [-nc4]                output a NetCDF 4 
#       [-nc4c]               output a NetCDF 4 "classic" format file
#       [-cl compression_level]  compression level 0 - 9 [ default 0 - only meaningful for NetCDF 4 output]
#       [-th size_in_megabytes] theshold size: variables larger than specified size will be written incrementally
#                             in order to limit in-core memory requirements; 0 (the default) means no threshold
#                             -- ignored for variables that require a type conversion
#       [-no-uc]              turn off default conversion of unsigned integer types to corresponding signed types
#                             -- unsigned variables in the input will be skipped
#       [-no-i64c]            turn off default conversion of 64-bit integer types to double
#                             -- 64-bit integer types in the input will be skipped
#       [-no-sc]              turn off default conversion of string types to character
#                             -- string types in the input will be skipped
#       [-no-aa]              turn off default addition of the ncl_converted_from_type attribute
#                             when variable types are converted
#       [-c comment]          text to be included in netCDF file attribute [default: no comment]
#       [-l]                  list information about each variable as it is copied
#       [-d]                  upon exit: print contents of each netCDF file [like ncdump -h]
#       [-B] <file>           suppress informational messages; redirect messages to <file> if present [default: /dev/null]
#       [-h]                  usage message

onintr CLEANUP

set progname = `basename $0`
if ($#argv < 1) then
    goto USAGE
endif

# Location to write temporary files
set tmpdir = `ncargpath tmp`
if (! -w $tmpdir) then
    echo "Temporary directory $tmpdir does not exist or is not writable; cannot proceed (check environment variable TMPDIR)"
    exit(1)
endif 

# Input and output directories default values
set valid_file = 0
set idirs = ()
set hasdirin = 0
set dirin = `pwd`
set dirout = `pwd`

#
# Default values for script commandline parameters for NCL commands
#
set dynamic_unlim_name = 0
set time_name = ""
set TIME_NAME = ""
unset tmnm_set
unset TMNM_set

unset vars
set nvars = 0

set ncdfcomment = ""
set ncdflrgf_t = "classic"
set ncdf_type = "nc3"
set compression_level = -1
set threshold_level = 0
set unsigned_to_signed = 1
set int64_to_double = 1
set string_to_char  = 1
set add_attribute = 1
set list = 0

# Single Element Dimension variables
set seDims_t = ""
set singleElemDims = ""
set sed_n = 0
set sed_nt = 0
set sed_args = ""
set seds = ( '\(/'\\\"None\\\"'/\)' )

# Time Period Suffix variables
set tps = True

#
# Background/redirect mode
#
set fout = ""
set d_fout = "/dev/null"
set std_rd = ""
set f_rdir = ""
set redirect = 0

# Display resultant netCDF file when done
unset printonexit

# Suffix for all file arguments provided (default == none provided)
set have_esfx = 0

# Tell NCL to not echo its copyright notice
# This is not an advertised option
set noCN = ""

#
# First argument should be the input file(s); if it's not, exit.
# Check to see if the first argument contains a "-"
#
set hasdash = `echo $1 | awk '{print substr($0, 1, 1)}'`
if ("$hasdash" == "-") then
    goto USAGE
endif

    
#
# Collect the file arguments, check them later -- need the "-i" ("dirin")
# argument prior to checking for unqualified full/partial pathnames.  
#
# It's impossible to know if file arguments are valid at this point, so
# assume that if an argument has a "-" as its first character, it's an
# option and there are no (more) file arguments.
#
# NOTE: Bogus filenames are still *kept* at this point.
#
# Modified to work with filenames with spaces (somewhat tricky in csh) 
# two loops seem to be required: the first to create the right number of
# array elements by assigning "easy" small integer values, the second to assign
# the "difficult" strings with possible spaces and other special chars 
# to now-defined elements of the array
# this idiom is repeated later in this script
#
set nfiles = 0
set first = "$1"
set ifiles_t = ( )
while  ( $nfiles < $#argv )
    @ i = $nfiles + 1
    set hasdash = `echo "$argv[$i]" | awk '{print substr($0, 1, 1)}'`
    if ( "$hasdash" != "-" ) then
        @ nfiles += 1
	if ($nfiles == 1) then
	    set ifiles_t = ( $nfiles )
	else 
	    set ifiles_t = ( $ifiles_t $nfiles )
	endif
    else
        break
    endif
end

set i = 0
while  ($#argv > 0)
   set hasdash = `echo "$1" | awk '{print substr($0, 1, 1)}'`
    if ("$hasdash" != "-") then
        @ i += 1
        set ifiles_t[$i] = "$argv[1]"
	shift
    else
        break
    endif
end

#
# Parse options/arguments
#
while ($#argv > 0)
    switch ("$1")
        case "-i":
        case "-in":
        case "-input":
            shift
            set dirin = "$1"
            set len = `echo "$dirin" | awk '{print length($0)}'`
            if ($len > 0) then
                shift
                set hasdirin = 1
            else
                echo "${progname}: no input directory specified, defaulting to current directory."
            endif
            breaksw

        case "-o":
        case "-out":
        case "-output":
            shift
            set dirout = "$1"
            set len = `echo "$dirout" | awk '{print length($0)}'`
            if ($len > 0) then
                shift
            else
                echo "${progname}: no output directory specified, defaulting to current directory."
            endif
            breaksw

        case "-e":
        case "-ext":
        case "-extension";
            shift
            set esfx = "$1"
            set len = `echo $esfx | awk '{print length($0)}'`
            if ($len > 0) then
                set have_esfx = 1
                shift
            else
                echo "${progname}: no file extension specified, ignoring."
            endif
            breaksw

        case "-d"
            set printonexit = 1
            shift
            breaksw

        case "-u":
        case "-unlim":
            shift
	    if ("$1" =~ "-*" || "$1" == "") then
	        set dynamic_unlim_name = 1
                echo "determining unlimited dimension dynamically"
                set tmnm_set = 1
		breaksw
            endif
            set time_name = "$1"
            set len = `echo $time_name | awk '{print length($0)}'`
            if ($len > 0) then
                shift
                set tmnm_set = 1
            else
                echo "${progname}: no NCL unlimited time dimension specified, ignoring."
            endif
            breaksw

        case "-U":
            shift
            set TIME_NAME = "$1"
            set len = `echo $TIME_NAME | awk '{print length($0)}'`
            if ($len > 0) then
                shift
                set TMNM_set
            else
                echo "${progname}: no NCL-named time dimension specified for renaming, ignoring."
            endif
            breaksw

	case "-itime"
            @ sed_n = ($sed_n + 1)
            set seDims_t = `echo $seDims_t "initial_time"`
            shift
            breaksw
 
        case "-ftime"
             @ sed_n = ($sed_n + 1)
             set seDims_t = `echo $seDims_t "forecast_time"`
             shift
             breaksw

        case "-sed":
        case "-singleelemdims":
        case "-singleElemDims":
            shift
            set sed_args = "$1"

            # Determine number of args (count commas)
            set sed_nt = `echo $* | awk -F, '{print NF}'`
            if ($sed_nt == 0) then
                echo "${progname}: no single element dimension(s) specified." ; echo
                breaksw
            endif

            set sac = `echo $* | sed 's/, /,/g'`
            set sa = $sac[1]
            shift

            set sedline = `echo $sa | sed 's/,/ /g'`
            set seds = ( '\(/' )
            set n = 1
            while ($n < $sed_nt)
                set i  = `expr $n + 1`
                set s = $sedline[$n]
                set seds = ( $seds\\\"$s\\\"\',\' )
                @ n = ($n + 1)
            end
            set s = $sedline[$n]
            set seds = ( $seds\\\"$s\\\" )
	    
            breaksw

        case "-tps":
        case "-timeperiodsuffix":
        case "-timePeriodSuffix":
        case "-TimePeriodSuffix":
            shift
            set tps = False
            breaksw

        case "-v":
        case "-var":
        case "-vars":
        case "-variable":
        case "-variables":
            shift

            # Determine number of variables specified (count commas)
            # set ncommas = `echo $* | tr -cd '\,' | wc -c`
            # set ncommas = `echo $* | awk '{print(gsub(/,/, " "))}'`
            set ncommas = `echo $* | awk -F, '{print NF - 1}'`
            if ($ncommas == 0) then
                # only one variable, or none?
                set isopt = `echo $1 | grep -c '-'`
                set isfile = `echo $1 | grep -c '\.'`
                if ($isopt != 0  ||  $isfile != 0) then
                    echo "${progname}: warning: no variable(s) specified." ; echo
                    breaksw
                endif
            endif

            set nvars = `expr $ncommas + 1`
            # handle "space after commas" case
            set psv = `echo $* | sed 's/, /,/g'`
            set pvars = $psv[1]
            shift

            # Build array of variables as strings, quote so as to pass thru the shell
            set vline = `echo $pvars | sed 's/,/ /g'`
            set vars = ( '\(/' )
            set n = 1
            while ($n < $nvars)
                set v = $vline[$n]
                set vars = ( $vars\\\"$v\\\"\',\' )
                @ n = ($n + 1)
            end

            # Catch the last variable
            set vars = ( $vars\\\"$vline[$n]\\\"'/\)' )
            breaksw

        case "-L":
            set ncdflrgf_t = "64bitoffset"
            shift
            breaksw

        case "-nc4c":
            set ncdf_type = "netcdf4classic"
            shift
            breaksw

	case "-nc4":
            set ncdf_type = "netcdf4"
            shift
            breaksw

        case "-cl":
            shift
            set compression_level = $1
            shift
            breaksw

        case "-th":
            shift
            set threshold_level = $1
            shift
            breaksw

	case "-no-uc"
	case "-no-unsigned-conversion"
            set unsigned_to_signed = 0
            shift
            breaksw
	case "-no-i64c"
	case "-no-int64-conversion"
            set int64_to_double = 0
            shift
            breaksw

	case "-no-sc"
	case "-no-string-conversion"
            set string_to_char = 0
            shift
            breaksw

	case "-no-aa"
	case "-no-added-attributes"
            set add_attribute = 0
            shift
            breaksw
	
        case "-c":
        case "-comment":
            shift
            set ncdfcomment = "$1"
            shift
            breaksw

        case "-l":
        case "-list":
            set list = 1
            shift
            breaksw

        case "-B":
        case "-redirect":
            set fout = $d_fout
            shift
            if ("$1" == "") then
                # no redirection file specified, use default
                set std_rd = ">&! $fout &"
                set f_rdir = "$tmpdir/tmp$$.rdr"
                set redirect = 1
                breaksw
            else
                set hasdash = `echo "$1" | awk '{print substr($0, 1, 1)}'`
                if ("$hasdash" != "-") then
                    set fout = "$1"
                    set std_rd = ">& $fout &"
                    set f_rdir = "$tmpdir/tmp$$.rdr"
                    set redirect = 1
                shift
                endif
            endif
            breaksw

        case "-h":
        case "-help":
        case "--help":
            goto USAGE
            exit 0
            breaksw

        case "-Q":
        case "-nocopyrightnotice":
        case "-noCopyrightNotice":
            shift
            set noCN = "-Q"
            breaksw

        case "-*":
            echo "${progname}: warning: '$1' is not a valid option, ignoring." ; echo
            shift
            breaksw

        default:
            echo "${progname}: warning: '$1' is not a valid argument, ignoring." ; echo
            shift
            breaksw
    endsw
end

#
# If "-U" (rename NCL-name time dimension) was specified, "-u" (UNLIMITED dimension)
# had to also be specified.
#
#if ($?tmnm_set && ! $?TMNM_set) then
#    echo "NCL-named time dimension '$time_name' specified for renaming, but"
#    echo "new netCDF time dimension not named; ignoring '$time_name'."
#endif

if ($?TMNM_set && ! $?tmnm_set) then
    echo "New netCDF time dimension '$TIME_NAME' specified but no NCL-named time"
    echo "dimension to rename was specified; ignoring '$TIME_NAME'."
endif

#
# Single Element Dimensions
# set_nt has the count from the -sed option sed_n has count of -itime and -ftime

if ($sed_nt > 0 && $sed_n > 0) then
    @ i = 1
    while ($i <= $sed_n)
        set seds = ( $seds\',\'\\\"$seDims_t[$i]\\\" )
        @ i = ($i + 1)
    end
else if ($sed_n > 0) then
    @ i = 1
    set seds = ( '\(/'\\\"$seDims_t[$i]\\\" )
    @ i = ($i + 1)
    while ($i <= $sed_n)
        set seds = ( $seds\',\'\\\"$seDims_t[$i]\\\" )
        @ i = ($i + 1)
    end
else if ($sed_nt == 0) then
    set seds = ( '\(/'\\\"none\\\" )
endif
set seds = ( $seds'/\)' )

#
# if the -nc4c option is set, it overrides the -L option
#
if ($ncdf_type != "nc3") then
    set ncdflrgf_t = $ncdf_type
endif

#
# Split filenames into (full, relative) paths and filenames.  This will
# ensure that file arguments entered with full/relative paths are properly
# accounted for.  Files without a path will be assigned the value given
# with the "-i" switch (or its default if "-i" is not used).
#
# Check existence/readability of input file arguments; eliminate invalid entries.
# Guarantees a one-to-one correspondence between input and output file entries.
#
# No check is performed to determine if a file contains valid data; it is assumed
# that the user provides properly formatted data (regardless of filename).
#
set n = 1
set nbadf = 0
set ifiles = ()
set ifiles_r = ()
set ofiles = ()
set ftypes = ()

# first populate all the arrays with a "simple" value

while ($n <= $nfiles)
    if ($n == 1) then
       set idirs = ( $n )
       set ifiles = ( $n )
       set ifiles_r = ( $n )
       set ofiles = ( $n )
       set ftypes = ( $n )
    else
       set idirs = ( $idirs $n )
       set ifiles = ( $ifiles $n )
       set ifiles_r = ( $ifiles_r $n )
       set ofiles = ( $ofiles $n )
       set ftypes = ( $ftypes $n )
    endif
    @ n += 1
end

set n = 1
while ($n <= $nfiles)
    #
    # Was a URL provided?  This requires an OPeNDAP-enabled NCL.  If
    # it's a URL, don't bother verifying the file suffix.
    #
    set http = `echo "$ifiles_t[$n]" | awk '{print index($0, "http")}'`
    if ($http > 0) then
        set dir = `dirname "$ifiles_t[$n]"`
        #set $if = `echo $ifiles_t[$n] | awk -F\/ '{print $NF}'`
        set if = `basename "$ifiles_t[$n]"`
        set of = "$if:r"

	set idirs[$n] = "$dir"
	set ifiles[$n] = "$if"
	set ofiles[$n] = "$of"
	set ftypes[$n] = "OPenDAP"

        # Keep the name of the file actually specified on the command line

	set ifiles_r[$n] = "$ifiles_t[$n]"
        @ n += 1

        continue
    endif

    set valid_file = 0
    set t = "$ifiles_t[$n]"
    set fil = `basename "$t"`

    if ($hasdirin == 1) then
        set dir = "$dirin"
    else
        set dir = `dirname "$ifiles_t[$n]"`
    endif

    set relpath = `echo "$dir" | grep -c '.'`
    set haspath = `echo "$dir" | grep -c '/'`

    # Does the file exist, and is it readble, as named?
    # Must account for different data directory if specified
    # If an input file already has an extension, ignore "-e"
    # for that file.
    set sfx = "$fil"
    if ( "$sfx" !~ *\.* ) then
        set sfx = ""
    else
        while ("$sfx" =~ *\.*)
            set sfx = "$sfx:e"
        end
    endif

    set sfxlen = `echo "$sfx" | awk '{print length($0)}'`

    if (((-e "$ifiles_t[$n]") && (-r "$ifiles_t[$n]")) \
            || ((-e "$dirin/$ifiles_t[$n]") && (-r "$dirin/$ifiles_t[$n]"))) then
        if ($have_esfx == 1) then
            set psfx = "$esfx"
            set fil = "$fil"."$psfx"
        endif

        if ($sfxlen == 0) then
            if ($have_esfx == 1) then
                set psfx = "$esfx"
            else
                goto VALID_FILE
            endif
        else
	    set psfx = "$fil"
            set psfx = "$psfx:e"
        endif

        # Does the file have a suffix (delineated by a ".") or
        # was a suffix specified via command-line options? If
        # yes, does the suffix indicate requested data type?
        set lsfx = `echo "$psfx" | tr '[A-Z]' '[a-z]'`
        switch ($lsfx)
	   case nc:
	   case cdf:
	   case nc3:
	   case nc4:
	   case netcdf:
                set ftype = "NETCDF"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw
            case gr:
            case gr1:
            case grb:
            case grib:
            case grb1:
            case grib1:
            case gr2:
            case grb2:
            case grib2:
                set ftype = "GRIB"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdf:
            case h4:
                set ftype = "HDF"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdfeos:
            case he2:
            case he4:
                set ftype = "HDFEOS"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdf5:
            case h5:
                set ftype = "HDF5"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdfeos5:
            case he5:
                set ftype = "HDFEOS5"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            case ccm:
                echo "${progname}: file '${fil}': CCM files not supported.  Please use: ccm2nc"
                echo "  Download at:  http://www.cgd.ucar.edu/cms/ccm3/tools"
                echo
                @ nbadf += 1
                @ n += 1
                continue
                breaksw

            case shp:
            case mif:
            case gmt:
            case rt1:   # The possible TIGER suffixes...
            case rt2:
            case rt3:
            case rt4:
            case rt5:
            case rt6:
            case rt7:
            case rt8:
            case rt9:
            case rta:
            case rtb:
            case rtc:
            case rte:
            case rth:
            case rti:
            case rtm:
            case rtp:
            case rtr:
            case rts:
            case rtt:
            case rtu:
            case rtz:
                set ftype = "OGR"
                set if = "$fil"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw

            default:
                echo "${progname}: filetype '${lsfx}' not supported."
                echo
                @ nbadf += 1
                @ n += 1
                continue
                breaksw
        endsw
    else
        # The file, as named, doesn't exist or isn't readable.
        # Check existence/readability as an incomplete file name
        # (ex.: 'ruc.grb' ==> 'ruc' exists).  This emulates NCL's
        # 'addfile()' functionality.  If found, keep it as input.

        set tf = "$ifiles_t[$n]"
        if ($have_esfx == 1) then
            if (( (-e "$tf:r"."$esfx") && (-r "$tf:r"."$esfx")) \
                    || ( (-e "$dirin/$tf:r"."$esfx") && (-r "$dirin/$tf:r"."$esfx"))) then
                set psfx = "$esfx"
                set if = "$tf"
                set of = "$tf":r
            endif
        else
	    if ( !( ((-e "$tf:r") && (-r "$tf:r"))  \
                    || ((-e "$dirin/$tf:r") && (-r "$dirin/$tf:r")) ) ) then
            goto VALID_FILE
            endif
        endif

        if ($sfxlen == 0) then
            goto VALID_FILE
        else
	    set psfx = "$sfx"
        endif

        set lsfx = `echo $psfx | tr '[A-Z]' '[a-z]'`

	set tf = "$fil"
        switch ($lsfx)
	   case nc:
	   case cdf:
	   case nc3:
	   case nc4:
	   case netcdf:
                set ftype = "NETCDF"
                set if = "$tf"
                set of = "$if:r"

                set valid_file = 1
                goto VALID_FILE
                breaksw
            case gr:
            case gr1:
            case grb:
            case grib:
            case grb1:
            case grib1:
            case gr2:
            case grb2:
            case grib2:
                set ftype = "GRIB"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
		echo if " " of
                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdf:
            case h4:
                set ftype = "HDF"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdf5:
            case h5:
                set ftype = "HDF5"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdfeos:
            case he2:
            case he4:
                set ftype = "HDFEOS"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
                set valid_file = 1
                goto VALID_FILE
                breaksw

            case hdfeos5:
            case he5:
                set ftype = "HDFEOS5"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
                set valid_file = 1
                goto VALID_FILE
                breaksw

            case ccm:
                echo "${progname}: file '${fil}': CCM files not supported.  Please use: ccm2nc"
                echo "  Download at:  http://www.cgd.ucar.edu/cms/ccm3/tools"
                echo
                @ nbadf += 1
                @ n += 1
                continue
                breaksw

            case shp:
            case mif:
            case gmt:
            case rt1:   # The possible TIGER suffixes...
            case rt2:
            case rt3:
            case rt4:
            case rt5:
            case rt6:
            case rt7:
            case rt8:
            case rt9:
            case rta:
            case rtb:
            case rtc:
            case rte:
            case rth:
            case rti:
            case rtm:
            case rtp:
            case rtr:
            case rts:
            case rtt:
            case rtu:
            case rtz:
                set ftype = "OGR"
                set if = "$tf:r".$lsfx
                set of = "$tf:r"
                set valid_file = 1
                goto VALID_FILE
                breaksw
        endsw
    endif

    # Is the file valid -- i.e., it exists/is readable, and has a valid name?
    # If not, skip it, else set values for input/output filenames, and input 
    # directory.  Output directory is set by "-o" or assumed to be the current
    # working directory (default).
VALID_FILE:
#    if ($?valid_file) then
    if ($valid_file == 0) then
        echo "${progname}: file '$tf' not readable, does not contain recognized data, or doesn't exist, skipping."
        echo
        @ nbadf += 1
        @ n += 1
        continue
    else
        if (($haspath == 1) || ($relpath == 1)) then
	    set idirs[$n] = "$dir"
        else
	    set idirs[$n] = "$dirin"
	endif

	set ifiles[$n] = "$if"
	set ofiles[$n] = "$of"
	set ftypes[$n] = "$ftype"
    endif

    # Keep the name of the file actually specified on the command line
    set ifiles_r[$n] = "$ifiles_t[$n]"

    @ n += 1
end

unset ifiles_t

# Account for any discarded files
@ nfiles -= $nbadf

#
# Create temporary file to hold NCL script
#
set tmpfile = `date "+%s"`
set tmpfile = `printf "%x" $tmpfile`
set tmp_nclf = "$tmpdir/tmp$$-$tmpfile.ncl"
#echo $tmp_nclf
/bin/rm $tmp_nclf >& /dev/null
cat << 'EOF_NCL' >! $tmp_nclf

;***************************************************
; GRIB, GRIB2, HDF, HDF-EOS to netcdf
;***************************************************
;
; ncl_convert2nc inputFile
;           [-i input_directory]
;           [-o output_directory]
;           [-e extension]
;           [-u time_name]
;           [-U new_time_name]
;           [-sed sed1[,...]]
;           [-tps]
;           [-v var1[,...]]
;           [-L]
;           [-c comment]
;           [-d]
;           [-B] <file>
;           [-h]
;
; inputFile             name of GRIB/HDF/HDF-EOS file [required]
; [-i input_directory]  location of input file  [default: current directory] 
; [-o output_directory] location of output file [default: current directory] 
; [-e extension]        file type, defined by extension, to convert
; [-u time_name]        name of the NCL-named time dimension to be UNLIMITED
; [-U new_time_name]    if -u is specified, will rename the NCL-named time dimension for netCDF 
; [-sed sed1[,...]]     set single element time record dimensions [default: None]
;                         GRIB files only; choices are Initial_time, Forecast_time, Level,
;                         Ensemble, Probability, All, None
; [-tps]                GRIB files only; remove suffix representing a time period (e.g. 2h)
;                         from statistically processed variables, leaving only type of
;                         processing as a suffix (e.g. _acc, _avg)
; [-v var1[,...]]       user specified subset of variables [default: all variables]
;                       ncl_filedump can be used to determine desired variable names
; [-L]                  support for writing large (>2Gb) netCDF files [default: no largefile support]"
; [-c comment]          text to be included in netCDF file attribute [default: no comment] 
; [-d]                  upon exit: print contents each netCDF file [like ncdump -h] 
; [-B] <file>           suppress informational messages; redirect messages to <file> if present [default: /dev/null]
; [-h]                  this usage message
;
; Sample Usage 
;      (1) ncl_convert2nc U12345.grb
;             => U12345.nc [location current directory]  
;
;      (2) ncl_convert2nc U12345 -e grb -t
;             => apply ".grb" extension to input file(s)
;             => time coordinate type set to "string"
;
;      (3) ncl_convert2nc U12345.hdf -i /my/input    
;                [/my/input/U12345]
;             => U12345.nc [location current directory] 
;
;      (4) ncl_convert2nc U12345.hdfeos -i /my/input -o /my/output 
;             =>  /my/output/U12345.nc 
;
;      (5) ncl_convert2nc U12345.grb -i /my/input -o /my/output
;             => /my/output/U12345.nc 
;
;      (6) ncl_convert2nc U12345.hdf -c 'Data Support Section: ds124.1'
;             => /my/output/U12345.nc     [includes file attribute "ds124.1"] 
;
;      (7) ncl_convert2nc U12345.grb -o /my/output  \
;                     -v gridlat_236,gridlon_236,PRES_236_SFC,NCPCP_236_SFC_acc1h
;             => /my/output/U12345.nc    [contains 4 variables only] 
;
;      (8) ncl_convert2nc U12345.grb -v gridlat_236,gridlon_236,PRES_236_SFC -L
;             => U12345.nc [location current directory]
;                          [contains only three variables]
;                          [supports large files (>2Gb) for netCDF]
;
;      (9) ncl_convert2nc U78677.grb -u initial_time0_hours
;             => double initial_time0_hours(initial_time0_hours)       ; UNLIMITED
;             => initial_time0_hours:units = "hours since 1800-01-01 00:00" 
;             => float D_GDS4_HYBL_123(initial_time0_hours, lv_HYBL3, g4_lat_1, g4_lon_2) ;
;
;     (10) ncl_convert2nc U78677.grb -u initial_time0_hours -U time
;             => double time(time) ;                            ; UNLIMITED
;             => time:units = "hours since 1800-01-01 00:00" ;
;             => float D_GDS4_HYBL_123(time, lv_HYBL3, g4_lat_1, g4_lon_2) ;
;
;     (11) ncl_convert2nc U78677.grb -sed initial_time,forecast_time
;             => set Single Element Dimensions 'initial_time' and 'forecast_time'
;
;     (12) ncl_convert2nc U12345.he5 -i /my/input -o /my/output 
;             =>  /my/output/U12345.nc 
;
;
;***************************************************
; Multiple files
;  The driver shell script gets the expanded file
;  names and invokes this script, one file at a time
;***************************************************
; Sample usage of the NCL script:
;      (a) ncl 'fili="U12345.grb"' anyFile2nc.ncl_v1
;      (b) ncl 'fili="U12345.hdf"' -t
;      (c) ncl 'fili="U12345.hdfeos"'  ncDump=True anyFile2nc.ncl_v1
;      (d) ncl 'fili="U12345.grb"' 'filo=Ugrib' anyFile2nc.ncl_v1
;      (e) ncl 'fili="U12345.hdf"' 'diri="/my/input"' anyFile2nc.ncl_v1
;      (f) ncl 'fili="U12345.hdfeos"' 'diri="/my/input"' 'diro="/my/output"' anyFile2nc.ncl_v1
;      (g) ncl 'fili="U12345.grb"' 'diri="/my/input"' \
;              'diro="/my/output"'\
;              'comment="Data Support Section: ds124.1"' anyFile2nc.ncl_v1
;      (h) ncl 'fili="U12345.grb"' 'varSelect=(/"gridlat_236","gridlon_236", \
;                                           "PRES_236_SFC,"NCPCP_236_SFC_acc1h"/)  anyFile2nc.ncl_v1
;      (h) ncl 'fili="U12345.grb"' 'varSelect=(/"gridlat_236","gridlon_236", \
;                                           "PRES_236_SFC/) -L  anyFile2nc.ncl_v1
;      (i) ncl 'fili="U78677.hdf"' -u "forecast_time0_hours"
;      (j) ncl 'fili="U78677.hdfeos"' -u "initial_time0_hours -U time"
;      (k) ncl 'fili="U78677.grb"'  'singleElemDims=(/"forecast_time", "initial_time"/)
;      (l) ncl 'fili="U78677.he5"' -u "initial_time0_hours -U time"
;***************************************************

begin
;    debug          = True
    debug          = False

;***************************************************
; fili is *required*
;***************************************************
    if (.not. isvar("fili")) then
        print(pname + ": REQUIRED input file name(s) missing, exiting.")
        exit
    end if

;***************************************************
; The following are optional command line variables
;***************************************************
    if (.not. isvar("diri")) then
        diri  = "./"                     ; default input dir
    else
        diri = diri + "/"
    end if

    if (.not. isvar("diro")) then
        diro  = "./"                     ; default output dir
    else
        diro = diro + "/"
    end if

    if (.not. isvar("comment")) then
        comment = ""                     ; comment option
    end if

    iFileName = diri + fili

;***************************************************
; if the file starts with "http" check that it points to a valid URL
;***************************************************

    if (ftype .eq. "OPeNDAP") then
        if (.not. isfilepresent(iFileName)) then
	    print(iFileName + " is not accessible: exiting")
	    exit()
	end if
    end if
;***************************************************
; Specify that COARDS style output desired
; NOTE: [not yet implemented]
;***************************************************
    ;;setfileoption(f, "COARDS", True)   ; place holder

;***************************************************
; Specify the type of time coordinate
; [default is 'numeric'] [obsolete]
;
; Specify the type(s) of time record dimension
; NOTE: valid for GRIB files only
;***************************************************
    if (ftype .eq. "GRIB") then
;        setfileoption(f, "InitialTimeCoordinateType", "numeric")

        sed = singleElemDims
        if (debug) then
            print("Setting file option: SingleElementDimensions: " + sed)
        end if

        setfileoption("grib", "SingleElementDimensions", sed)

        tps = timePeriodSuffix
        if (debug) then
            print("Setting file option: TimePeriodSuffix: " + tps)
        end if

        setfileoption("grib", "TimePeriodSuffix", tps)
    end if

;***************************************************
;
; Specify the type(s) of time record dimension
; NOTE: valid for GRIB files only
;***************************************************
    time_dim_substring = "time"
    if (ftype .eq. "GRIB") then
;        setfileoption(f, "InitialTimeCoordinateType", "numeric")

        sed = singleElemDims
        if (debug) then
            print("Setting file option: SingleElementDimensions: " + sed)
        end if

        setfileoption("grib", "SingleElementDimensions", sed)

        tps = timePeriodSuffix
        if (debug) then
            print("Setting file option: TimePeriodSuffix: " + tps)
        end if

        setfileoption("grib", "TimePeriodSuffix", tps)

        if (dynamic_unlim_name .eq. 1) then
             time_dim_substring = "initial_time"
        end if
    end if

;***************************************************
; open file with appropriate extension
;***************************************************
    f = addfile(iFileName, "r")     ; suffix ok 

;***************************************************
; Get all the global [file] attributes.  These will
; be copied to the output file.
; NOTE: GRIB files will return "missing"
;***************************************************

    fInAtts = getvaratts( f )

;***************************************************
; Get *all* variables names on the file 
;     or
; Specify a subset of variables. All variable names,
; including coordinate variable names, must be
; specified.
;***************************************************
;***************************************************
; Get *all* variables names on the file 
;     or
; Specify a subset of variables. All variable names,
; including coordinate variable names, must be
; specified.
;***************************************************
    if (.not. isvar("nvars")) then    
        fVarNames = getfilevarnames(f)     ; all files names 
     else
        fVarNames = vars                     ; user specified variables
     end if

     nfNames = dimsizes(fVarNames)

     if (debug) then
        print(nfNames)
        print(fVarNames)
    end if

;***************************************************
; open output netcdf file
; Set for 'large file' or netCDFclassic support if specified
;***************************************************
    netcdfSizeType = ncdfSize
    setfileoption("netcdf", "format", netcdfSizeType)
    osuffix = ".nc"
    if (netcdfSizeType .eq. "netcdf4classic") then
        osuffix = ".nc4"
        if (ncdfCompLevel .gt. -1) then
            setfileoption("netcdf", "CompressionLevel", ncdfCompLevel)
        end if 
    end if

    ncFileName = diro + filo + osuffix 

    ofile_i = str_get_field(systemfunc("ls -iL '" + ncFileName + "' 2>/dev/null"),1," ")
    ifile_i = str_get_field(systemfunc("ls -iL '" + iFileName  + "' 2>/dev/null" ),1," ")
    if (.not. ismissing(ofile_i) .and. .not. ismissing(ifile_i) .and. ofile_i .eq. ifile_i) then
	ncFileName = ncFileName + ".nc"
    end if

    system("/bin/rm -f '" + ncFileName + "'")  ; remove pre-existing file (if any)
    fnc = addfile(ncFileName, "c")      ; "c"reate the netCDF file

;***************************************************
; define file options [version a033 and beyond]
;***************************************************
    setfileoption(fnc, "prefill", False)
    setfileoption(fnc, "suppressclose", True)
    setfileoption(fnc, "definemode", True)

;***********************************************
; assign standard file attributes [Sample]
;***********************************************
    fAtt               = True
    title = "NCL: convert-" + ftype + "-to-netCDF"
    fAtt@title         = title

    if (ftype .eq. "GRIB") then
        fAtt@grib_source   = fili
    end if

    if (ftype .eq. "NETCDF") then
        fAtt@netcdf_source   = fili
    end if

    if (ftype .eq. "HDF") then
        fAtt@hdf_source   = fili
    end if

    if (ftype .eq. "HDFEOS") then
        fAtt@hdfeos_source   = fili
    end if

    if (ftype .eq. "HDFEOS5") then
        fAtt@hdfeos5_source   = fili
    end if

    fAtt@Conventions   = "None"
    fAtt@system        = systemfunc("uname -a")
    fAtt@NCL_Version   = get_ncl_version()
    fAtt@creation_date = systemfunc ("date")
    if (comment .ne. "") then
        fAtt@comment   = comment 
    end if

;***********************************************
; copy input file attributes to output file
;***********************************************

    if (.not. all(ismissing(fInAtts))) then
        do i = 0, dimsizes(fInAtts) - 1
            fAtt@$fInAtts(i)$ = f@$fInAtts(i)$
        end do
    end if

    fileattdef(fnc, fAtt)

;************************************************
; If the file contains no readable variables then
; it is necessary to quit here
;************************************************
     if (all(ismissing(fVarNames))) then
         print(iFileName + " contains no variables readable by NCL: converting global attributes only")
	 delete(f)
	 exit()
     end if

;***********************************************
; predefine the file's dimension names, sizes
; and types
;***********************************************
    dimNames = getvardims(f)
    ind_ncl_scalar = ind(dimNames .eq. "ncl_scalar")
    if (.not. ismissing(ind_ncl_scalar)) then
	has_scalar_dim = True
    else
	has_scalar_dim = False
    end if
    dimSizes = getfiledimsizes(f)
    dimUnlim = new(dimsizes(dimNames), "logical")
    dimUnlim = False

;***********************************************
; file variable to make dimension as UNLIMITED
;***********************************************
    if (time_name .ne. "") then
        if (any(dimNames .eq. time_name)) then
            tu_dim = ind(dimNames .eq. time_name)
            dimUnlim(tu_dim) = True
            if (TIME_NAME .ne. "") then 
                dimNames(tu_dim) = TIME_NAME
            end if
        end if
    else if (dynamic_unlim_name .ne. 0) then
        if ((ftype .eq. "GRIB") .and. \
           (.not. (ismissing(all(str_match_ind(dimNames,"ensemble"))) .and. \
                ismissing(all(str_match_ind(dimNames,"probability"))))))
                print("Dimensions left of the initial_time dimension exist; initial_time dimension cannot be unlimited")
        else
            dim_ind = str_match_ind_ic(dimNames,time_dim_substring)
            if (.not. any(ismissing(dim_ind))) then
	        max_ind = maxind(dimSizes(dim_ind))
	        unlim_ind = dim_ind(max_ind)
                dimUnlim(unlim_ind) = True
                if (TIME_NAME .ne. "") then 
                    time_name = dimNames(unlim_ind)
                    dimNames(unlim_ind) = TIME_NAME
                end if
	    end if
            delete(dim_ind)
        end if
    end if
    end if
;
; if there is a scalar dimension then it should be the first one listed
;
    if (has_scalar_dim) then
        if (ind_ncl_scalar .eq. 0) then
            filedimdef(fnc, dimNames(1:), dimSizes(1:), dimUnlim(1:))
	else
	    endix = dimsizes(dimNames) - 2
  	    do i = ind_ncl_scalar, endix
                dimNames(i) = dimNames(i+1)
		dimSizes(i) = dimSizes(i+1)
		dimUnlim(i) = dimUnlim(i+1)
	    end do
	    filedimdef(fnc, dimNames(:endix), dimSizes(:endix), dimUnlim(:endix)) 
	end if
    else
        filedimdef(fnc, dimNames, dimSizes, dimUnlim)
    end if

    if (debug) then
        print(dimNames)
        print(dimSizes)
        print(dimUnlim)
    end if

;***************************************************
; optionally, create new names for the output netcdf
; file.  Add variable renaming later.
;***************************************************
    ncVarNames  = fVarNames         ; default: netCDF names <==>  NCL names
    if (time_name .ne. "" .and. TIME_NAME .ne. "") then
        if (any(ncVarNames .eq. time_name)) then
            tu_dim = ind(ncVarNames .eq. time_name)
            ncVarNames(tu_dim) = TIME_NAME
        end if
    end if

;***********************************************
; determine the type of each variable
;***********************************************
    varType = getfilevartypes(f, fVarNames)

    long_size = sizeof(1L)
    enumeric_types = (/"ubyte","ushort","uint","ulong","uint64","int64","string"/)
    convert_types = (/"byte","short","integer","long","double","double","character"/)
    str_to_c_ix = 6
    uint_to_sint_max_ix = 3
    if (long_size .eq. 8) then
        convert_types(3) = "double"
    end if 
    do_conversion = new(nfNames,logical)
    do_conversion = False
    str_dim_names = new(nfNames,string)
    num_strings = 0

;***********************************************
; loop over each variable: skip variables of type
; string [not allowed by netCDF v3.6.x]
; (1) define name, type and dimension names
; (2) rather than read in the variable [could be
;     big and slow], read each attribute of a
;     variable and assign to a dummy variable
;***********************************************
    do i = 0, nfNames - 1 
        if (debug) then
            print(" ")
            print(i + "  ncl_name = " + fVarNames(i))
            print(i + "  ncl_type = " + varType(i))
            print(i + "  dim_names " + getfilevardims(f, fVarNames(i)))
        end if
	
	en_ix = ind(varType(i) .eq. enumeric_types)
	create_attribute = False
        old_type = varType(i)
	if (.not. ismissing(en_ix)) then
	    new_type = convert_types(en_ix)
	    ; 
            ; note that no actual conversion is required when going from unsigned to signed integers, but clearly a conversion is 
	    ; required to go to double from integer
            ;
	    if (en_ix .eq. str_to_c_ix) then
	        if (string_to_char .eq. 0) then
		    print ("Classic model NetCDF does not support string types: " + fVarNames(i) + " will be skipped")
		    do_conversion(i) = _Missing
		else 
		    print ("Classic model NetCDF does not support string types, converting " +  fVarNames(i) + " to a character array")
		    print("Dimension 'ncl_strlen_" + num_strings + "' will be added")
	            do_conversion(i) = True
		    if (add_attribute .eq. 1) then
		        create_attribute = True
		    end if
		    dim_name = "ncl_strlen_" + num_strings
		    num_strings = num_strings + 1
		    dim_size = max(strlen(f->$fVarNames(i)$))
                    filedimdef(fnc, dim_name, dim_size, False)
	            str_dim_names(i) = dim_name
                end if
            end if
	    if (new_type .eq. "double") then
	        if (int64_to_double .eq. 0) then
		    print ("Classic model NetCDF does not support 64bit integer types: " + fVarNames(i) + " will be skipped")
		    do_conversion = _Missing
		else 
		    print ("Classic model NetCDF does not support 64bit integer types, converting " +  fVarNames(i) + " to double")
	            do_conversion(i) = True
		    if (add_attribute .eq. 1) then
		        create_attribute = True
		    end if
                end if
	    else
	        if (en_ix .le. uint_to_sint_max_ix) then
	            if (unsigned_to_signed .eq. 0) then
	                print ("Classic mode NetCDf does not support unsigned integer types: " + fVarNames(i) + " will be skipped")
			do_conversion(i) = _Missing
		    else 
                        print ("Classic mode NetCDf does not support unsigned integer types: " + fVarNames(i) + " will be written as type " + new_type)
		        if (add_attribute .eq. 1) then
		            create_attribute = True
		        end if
		    end if
		end  if
	    end if
	    varType(i) = new_type
        end if

        if (.not. ismissing(do_conversion(i))) then      ; netCDF (currently no strings)
                                                ; predefine variable
             dimVarNames = getfilevardims(f, fVarNames(i))
            if (TIME_NAME .ne. "") then
                if (any(dimVarNames .eq. time_name)) then
                    tu_dim  = ind(dimVarNames .eq. time_name)
                    dimVarNames(tu_dim) = TIME_NAME
                end if
	    end if
            if (do_conversion(i) .and. varType(i) .eq. "character") then
		dim_names = new(dimsizes(dimVarNames) + 1, string)
		dim_names(:dimsizes(dimVarNames) - 1) = dimVarNames
		dim_names(dimsizes(dim_names) -1) = str_dim_names(i)
		delete(dimVarNames)
		dimVarNames = dim_names
		delete(dim_names)
            end if
            filevardef(fnc, ncVarNames(i), varType(i), dimVarNames)
            delete(dimVarNames)

            varAtts = getfilevaratts(f, fVarNames(i))
            if (.not. all(ismissing(varAtts))) then
                nAtts   = dimsizes(varAtts)

                dumAtts = new (1, varType(i))    ; dummy to attach varAtts 
                delete(dumAtts@_FillValue)       ; delete auto assigned _FillValue

                do j = 0, nAtts - 1
		    att_val = f->$fVarNames(i)$@$varAtts(j)$
	            att_en_ix = ind(typeof(att_val) .eq. enumeric_types)
		    if (.not. ismissing(att_en_ix) .and. att_en_ix .lt. 5) then
		        if (convert_types(att_en_ix) .eq. "double") then
			    tmp_att_val = todouble(att_val)
			else
		            tmp_att_val = tosigned(att_val)
			end if
			delete(att_val)
			att_val = tmp_att_val
		        delete(tmp_att_val)
		    end if
                    dumAtts@$varAtts(j)$ = att_val
		    delete(att_val)
                end do
		if (create_attribute) then
                    dumAtts@NCL_converted_from_type = old_type
		end if

                if (debug) then                    ; can lead to much output
                    print(varAtts)
                    print(nAtts)
                    print(dumAtts) 
                end if

                ; define variable attributes
                filevarattdef(fnc, ncVarNames(i) , dumAtts)

                delete(dumAtts)
            end if
            delete(varAtts)

        end if
    end do

    setfileoption(fnc, "definemode", False) ; not necessary

;***************************************************************************************
; Write *only* data values to predefined locations.  If the variable exceeds a         *
; certain size, perform the operation in a loop to save on core memory. There          *
; is no way to get the size of a type in NCL (!!!).  The approach used could be        *
; inefficient if the leftmost dimensions have more elements than the rightmost.        *
; Hopefully that is a rare occurence -- certainly it would be very rare in GRIB files. *
;***************************************************************************************
    threshold_size = threshold_level * 1000000
    do i = 0, nfNames - 1
        if (.not. ismissing(do_conversion(i))) then
            if (debug) then
                print("write loop: i = " + i + "  " + fVarNames(i))
            end if

            dsizes = getfilevardimsizes(f,fVarNames(i))
            type_size = 1
            if (varType(i) .eq. "double") then
                type_size =  8
            else if (varType(i) .eq. "short") then
                type_size = 2
            else if (varType(i) .ne. "byte" .and. varType(i) .ne. "character") then
                type_size = 4
            end if
            end if
            end if

            tsize = product(dsizes) * type_size	    
            if (debug.or.verbose) then
                print(fVarNames(i) + " : " + tsize  + " (size in bytes) :  " + dimsizes(dsizes) + " (number of dimensions)")
            end if

            ndims = dimsizes(dsizes)
            ; no special handling for ndims greater than 6 or less than 3 or if doing a type conversion
	    ;
	    if (do_conversion(i)) then
	        if (varType(i) .eq. "character") then
		    tmp_char = stringtocharacter ( (/ f->$fVarNames(i)$ /)  ) 
		    tmp_size = dimsizes(tmp_char)
                    if (dimsizes(tmp_size) .eq. 1) then
                        fnc->$ncVarNames(i)$(0,:) = (/ tmp_char(:tmp_size-2) /)
                    else
                        fnc->$ncVarNames(i)$ = (/ tmp_char(:,:tmp_size(1)-2) /)
                    end if
		    delete(tmp_size)
		    delete(tmp_char)
		else
                    fnc->$ncVarNames(i)$ = todouble ( (/ f->$fVarNames(i)$ /)  )
	        end if
            else if (threshold_size .eq. 0 .or. tsize .lt. threshold_size .or. ndims .gt. 7 .or. ndims .lt. 3) then
                fnc->$ncVarNames(i)$ = (/ f->$fVarNames(i)$ /)
            else
                if (ndims .eq. 7) then
                    if (tsize / dsizes(0) .lt. threshold_size) then
                        do j = 0, dsizes(0) - 1
                            if (debug) then
                                print("copying " + fVarNames(i) + "(" + j + ",:,:,:,:,:,:)")
                            end if

                            fnc->$ncVarNames(i)$(j,:,:,:,:,:,:) = (/ f->$fVarNames(i)$(j,:,:,:,:,:,:) /)
                        end do
                    else
                        do j = 0, dsizes(0) - 1
                            do k = 0, dsizes(1) -1
                                if (debug) then
                                    print("copying " + fVarNames(i) + "(" + j + "," + k +  ",:,:,:,:,:)")
                                end if

                                fnc->$ncVarNames(i)$(j,k,:,:,:,:,:) = (/ f->$fVarNames(i)$(j,k,:,:,:,:,:) /)
                            end do
                        end do
                    end if
                end if

	        
                if (ndims .eq. 6) then
                    if (tsize / dsizes(0) .lt. threshold_size) then
                        do j = 0, dsizes(0) - 1
                            if (debug) then
                                print("copying " + fVarNames(i) + "(" + j + ",:,:,:,:,:)")
                            end if

                            fnc->$ncVarNames(i)$(j,:,:,:,:,:) = (/ f->$fVarNames(i)$(j,:,:,:,:,:) /)
                        end do
                    else
                        do j = 0, dsizes(0) - 1
                            do k = 0, dsizes(1) - 1
                                if (debug) then
                                    print("copying " + fVarNames(i) + "(" + j + "," + k +  ",:,:,:,:)")
                                end if

                                fnc->$ncVarNames(i)$(j,k,:,:,:,:) = (/ f->$fVarNames(i)$(j,k,:,:,:,:) /)
                            end do
                        end do
                    end if
                end if

                if (ndims .eq. 5) then
                    if (tsize / dsizes(0) .lt. threshold_size) then
                        do j = 0, dsizes(0) - 1
                            if (debug) then
                                print("copying " + fVarNames(i) + "(" + j + ",:,:,:,:)")
                            end if

                            fnc->$ncVarNames(i)$(j,:,:,:,:) = (/ f->$fVarNames(i)$(j,:,:,:,:) /)
                        end do
                    else
                        do j = 0, dsizes(0) - 1
                            do k = 0, dsizes(1) -1
                                if (debug) then
                                    print("copying " + fVarNames(i) + "(" + j + "," + k +  ",:,:,:)")
                                end if

                                fnc->$ncVarNames(i)$(j,k,:,:,:) = (/ f->$fVarNames(i)$(j,k,:,:,:) /)
                            end do
                        end do
                    end if
                end if

                if (ndims .eq. 4) then
                    if (tsize / dsizes(0) .lt. threshold_size) then
                        do j = 0, dsizes(0) - 1
                            if (debug) then
                                print("copying " + fVarNames(i) + "(" + j + ",:,:,:)")
                            end if

                            fnc->$ncVarNames(i)$(j,:,:,:) = (/ f->$fVarNames(i)$(j,:,:,:) /)
                        end do
                    else
                        do j = 0, dsizes(0) - 1
                            do k = 0, dsizes(1) -1
                                if (debug) then
                                    print("copying " + fVarNames(i) + "(" + j + "," + k +  ",:,:)")
                                end if

                                fnc->$ncVarNames(i)$(j,k,:,:) = (/ f->$fVarNames(i)$(j,k,:,:) /)
                            end do
                        end do
                    end if
                end if

                if (ndims .eq. 3) then
                    if (tsize / dsizes(0) .lt. threshold_size) then
                        do j = 0, dsizes(0) - 1
                            if (debug) then
                                print("copying " + fVarNames(i) + "(" + j + ",:,:)")
                            end if

                            fnc->$ncVarNames(i)$(j,:,:) = (/ f->$fVarNames(i)$(j,:,:) /)
                        end do
                    else
                        do j = 0, dsizes(0) - 1
                            do k = 0, dsizes(1) -1
                                if (debug) then
                                    print("copying " + fVarNames(i) + "(" + j + "," + k +  ",:)")
                                end if

                                fnc->$ncVarNames(i)$(j,k,:) = (/ f->$fVarNames(i)$(j,k,:) /)
                            end do
                        end do
                    end if
                end if
            end if
	    end if
            
            delete(dsizes)
        end if
    end do

    delete(f)   ; not necessary
 end 
'EOF_NCL'


#
# Loop over input file(s), executing NCL script
#
set n = 1
while ($n <= $nfiles)
    if ("$redirect" == 0) then
        echo "Processing file: $ifiles_r[$n]..."
        if ($?vars) then
            eval ncl $noCN -n 'pname=\"$progname\"' 'ftype=\"$ftypes[$n]\"' 'fili=\""$ifiles[$n]"\"' 'diri=\"'$idirs[$n]'\"' 'diro=\""$dirout"\"' 'filo=\""$ofiles[$n]"\"' nvars=$nvars vars=$vars 'ncdfSize=\""$ncdflrgf_t"\"' ncdfCompLevel=$compression_level threshold_level=$threshold_level unsigned_to_signed=$unsigned_to_signed int64_to_double=$int64_to_double string_to_char=$string_to_char add_attribute=$add_attribute singleElemDims=$seds 'timePeriodSuffix=$tps' dynamic_unlim_name=$dynamic_unlim_name 'time_name=\""$time_name"\"' 'TIME_NAME=\""$TIME_NAME"\"' 'comment=\""$ncdfcomment"\"' verbose=$list $tmp_nclf
        else
            eval ncl $noCN -n 'pname=\"$progname\"' 'ftype=\"$ftypes[$n]\"' 'fili=\""$ifiles[$n]"\"' 'diri=\""$idirs[$n]"\"' 'diro=\""$dirout"\"' 'filo=\""$ofiles[$n]"\"' 'ncdfSize=\""$ncdflrgf_t"\"' ncdfCompLevel=$compression_level threshold_level=$threshold_level unsigned_to_signed=$unsigned_to_signed int64_to_double=$int64_to_double string_to_char=$string_to_char add_attribute=$add_attribute singleElemDims=$seds 'timePeriodSuffix=$tps' dynamic_unlim_name=$dynamic_unlim_name 'time_name=\""$time_name"\"' 'TIME_NAME=\""$TIME_NAME"\"' 'comment=\""$ncdfcomment"\"' verbose=$list $tmp_nclf
        endif
    else
        # redirection requested
        (echo "Processing file: $ifiles_r[$n]..." >&! $f_rdir)
        if ($?vars) then
            (eval ncl $noCN -n 'pname=\"$progname\"' 'ftype=\"$ftypes[$n]\"' 'fili=\""$ifiles[$n]"\"' 'diri=\""$idirs[$n]"\"' 'diro=\""$dirout"\"' 'filo=\""$ofiles[$n]"\"' nvars=$nvars vars=$vars 'ncdfSize=\""$ncdflrgf_t"\"' ncdfCompLevel=$compression_level threshold_level=$threshold_level unsigned_to_signed=$unsigned_to_signed int64_to_double=$int64_to_double string_to_char=$string_to_char add_attribute=$add_attribute singleElemDims=$seds 'timePeriodSuffix=$tps' dynamic_unlim_name=$dynamic_unlim_name 'time_name=\""$time_name"\"' 'TIME_NAME=\""$TIME_NAME"\"' 'comment=\""$ncdfcomment"\"' verbose=$list $tmp_nclf >! $fout) >&! $f_rdir
        else
            (eval ncl $noCN -n 'pname=\"$progname\"' 'ftype=\"$ftypes[$n]\"' 'fili=\""$ifiles[$n]"\"' 'diri=\""$idirs[$n]"\"' 'diro=\""$dirout"\"' 'filo=\""$ofiles[$n]"\"' 'ncdfSize=\""$ncdflrgf_t"\"' ncdfCompLevel=$compression_level threshold_level=$threshold_level unsigned_to_signed=$unsigned_to_signed int64_to_double=$int64_to_double string_to_char=$string_to_char add_attribute=$add_attribute singleElemDims=$seds 'timePeriodSuffix=$tps' dynamic_unlim_name=$dynamic_unlim_name 'time_name=\""$time_name"\"' 'TIME_NAME=\""$TIME_NAME"\"' 'comment=\""$ncdfcomment"\"' verbose=$list $tmp_nclf >! $fout) >&! $f_rdir
        endif
    endif

    # Display output if requested.
    echo
    if ($?printonexit) then
        set fdump = `which ncl_filedump`
        if ($? != 0) then
            set fdump = `which ncdump`
            if ($? != 0) then
                echo "Can't locate 'ncl_filedump' or 'ncdump' to display output file."
            endif
        else
            if (-e $dirout/$ofiles[$n].nc) then
                echo "  Displaying $dirout/$ofiles[$n].nc"
                sleep 2
                $fdump -c "$dirout/$ofiles[$n].nc"
                echo ; echo
            endif
        endif
    endif

INCR:
    @ n += 1
    if (($n > $#ifiles) || ($n > $#ofiles)) then
        break
    endif
end


#
# Clean up
#
#echo $tmp_nclf
if ("$redirect" == 0) then
    /bin/rm -f $tmp_nclf
endif
/bin/rm -f $f_rdir
exit 0

CLEANUP:
  /bin/rm -f $tmp_nclf
  /bin/rm -f $f_rdir
  exit 1

USAGE:
echo "${progname} inputFile(s) OPTIONS"
echo "  inputFile(s)          name(s) of data file(s) [required]"
echo "                        [valid types: GRIB1 GRIB2 HDF HDF-EOS netCDF shapefile]"
echo "  [-i input_directory]  location of input file(s)  [default: current directory]"
echo "  [-o output_directory] location of output file(s) [default: current directory]"
echo "  [-e extension]        file type, defined by extension, to convert [example: grb]"
echo "  [-u [time_name]]      name of the NCL-named time dimension to be UNLIMITED"
echo "                          if time_name not specified NCL will attempt to find a suitable time dimension:"
echo "                          if GRIB it will contain the substring "initial_time", otherwise "time" (any case);"
echo "                          error will occur if the dimension found is not the left-most dimension"
echo "  [-U new_time_name]    if -u is specified: new name of UNLIMITED variable and dimension"
echo "  [-sed sed1[,...]]     GRIB files only; set single element dimensions [default: none]"
echo "                          choices are initial_time, forecast_time, level, ensemble,"
echo "                          probability, all, none"
echo "  [-itime]              GRIB files only; set initial time as a single element dimension"
echo "                          (same as -sed initial_time)"
echo "  [-ftime]              GRIB files only; set forecast time as a single element dimension"
echo "                          (same as -sed forecast_time)"
echo "  [-tps]                GRIB files only; remove suffix representing a time period (e.g. 2h)"
echo "                          from statistically processed variables, leaving only type of"
echo "                          processing as a suffix (e.g. _acc, _avg)"
echo "  [-v var1[,...]]       user specified subset of variables [default: all variables]"
echo "                        ncl_filedump can be used to determine desired variable names"
echo "  [-L]                  support for writing large (>2Gb) netCDF files [default: no largefile support]"
echo "  [-nc4c]               output a NetCDF 4 classic format file"
echo "  [-cl compression_level]  compression level 0 - 9 [ default 0 - only meaningful for NetCDF 4 output]"
echo "  [-th size_in_megabytes] theshold size: variables larger than specified size will be written incrementally"
echo "                        in order to limit in-core memory requirements; 0 (the default) means no threshold"
echo "                        -- ignored for variables that require a type conversion"
echo "  [-no-uc]              turn off default conversion of unsigned integer types to corresponding signed types"
echo "                        -- unsigned variables in the input will be skipped"
echo "  [-no-i64c]            turn off default conversion of 64-bit integer types to double"
echo "                        -- 64-bit integer types in the input will be skipped"
echo "  [-no-sc]              turn off default conversion of string types to character"
echo "                        -- string types in the input will be skipped"
echo "  [-no-aa]              turn off default addition of the 'ncl_converted_from_type' attribute"
echo "                        when variable types are converted"
echo "  [-c comment]          text to be included in netCDF file attribute [default: no comment]"
echo "  [-l]                  list some information about each variable as it is copied"
echo "  [-d]                  upon exit: print contents of each netCDF file [like ncdump -h]"
echo "  [-B] <file>           suppress informational messages; redirect messages to <file> if present"
echo "                        [default: /dev/null]"
echo "  [-h]                  this usage message"
