#!/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] # [-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] suppress informational messages; redirect messages to 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 "-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] ; [-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] suppress informational messages; redirect messages to 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] suppress informational messages; redirect messages to if present" echo " [default: /dev/null]" echo " [-h] this usage message"