;------------------------------------------------------------------------------ ; ; stringtochar2.ncl -- Convert string to character, without excess nulls. ; ; 2011-mar-23 Original version. By Dave Allured, NOAA/PSD/CIRES. ; 2011-may-02 Synchronize the "local" statement. ; 2011-oct-20 Interface change, remove dim_name argument. ; The length dimension is now always named automatically. ; 2012-feb-28 Fix dim transpose bug when input is an array of rank 1, size 1. ; 2012-jul-09 Handle the degenerate case of all empty input strings. ; ; Usage: out = stringtochar2 (string) ; ; Arguments: string = input string variable of any dimensionality. ; ; Return value: Returns a character array with one added dimension on ; the right, for the string length. This dimension is ; equal to the length of the longest string in the input ; array, not including a trailing null. ; ; Notes: ; ; The main purpose of this function is to facilitate writing ; string arrays into Netcdf output files as well formed ; character variables. ; ; This function is like the NCL built-in "stringtocharacter" ; function, with added features: ; ; * Excess trailing null characters are removed. Trailing nulls ; are added only for input strings that are shorter than the ; longest input string. If all strings in the input array are ; the same length, then there will be no trailing nulls in the ; output array. ; ; * An explicit dimension name is automatically generated for ; the added length dimension. ; ; * Input metadata is preserved, including any dimension names ; and coordinate variables. ; ; * Inputs of rank 1 and dimension 1, sometimes considered to be ; scalars, are handled differently. In this version, the output ; rank is one more than the input rank in all cases. In the ; original version, a single input dimension of (1) is removed, ; creating a special case where the output rank is the same as ; the input rank. This change was made to retain dimension- ; related metadata in the case of input dimension (1), and also ; to support generic processing of array-oriented data. ; ; The name of the added length dimension is "len" plus an integer ; equal to the string length. This is helpful for writing ; multiple character arrays into the same Netcdf file. Arrays ; with the same string length will share the same named dimension ; in the Netcdf file. ; ; The automatic dimension name may of course be renamed by the ; user, by simple reassignment in NCL. ; ; Named dimensions are *not* required on input. ; ; In the degenerate case of all empty input strings (zero length), ; trimming will not be performed, and the output will be a single ; null character for each input string. ; ; Please see NCL documentation for the original stringtocharacter ; function, for a description and examples of the general ; functionality. ; ; Required: contributed.ncl ; ;------------------------------------------------------------------------------ undef ("stringtochar2") function stringtochar2 (in:string) local c, ctran, dName, dimc, dims, dims_in, last_dim, len_dim, \ n, new_len, nkeep, out, rank, rank_c, rank_in begin c = stringtochar (in) ; convert input strings to char array ; Reduce length dimension by 1; remove trailing nulls. ; For unknown rank, we must use the ndtooned and transpose methods. dims_in = dimsizes (in) ; keep original dims to handle all cases rank_in = dimsizes (dims_in) ; number of original dimensions dimc = dimsizes (c) ; get char dim sizes plus string length; ; might not be true to original dims. rank_c = dimsizes (dimc) ; get dim number for added length dim. len_dim = rank_c - 1 new_len = dimc(len_dim) - 1 ; get character length, and reduce by 1 ; to eliminate trailing nulls new_len = max ((/ new_len, 1 /)) ; handle degenerate case of all zero ; length input strings ; Construct a new dims array from the explicit input dimensions. last_dim = rank_in rank = rank_in + 1 ; increase internal rank by 1 over input dims = new (rank, integer) dims(0:last_dim-1) = dims_in ; preserve all original dimensions dims(last_dim) = new_len ; add the revised char length dimension nkeep = product (dims) ; total # of chars, minus trailing nulls ctran = ndtooned (transpose (c)) ; all trailing nulls move to end out = (/ transpose (onedtond (ctran(0:nkeep-1), dims(::-1))) /) ; discard the nulls; reorder to normal ; (MUST flip dims for reverse transpose) ; constructors remove temp. dim names ; Restore all metadata. ;; copy_VarMeta (in, out) ; fails if output rank > input ; Copy input dim names and coord vars to output array. ; Modified version of copy_VarMeta from NCL 5.2.1. dName = getvardims (in) ; get input dim names, if any if (.not. all (ismissing (dName))) then ; for INPUT dimensions only: do n = 0, rank-2 if (.not. ismissing (dName(n))) then out!n = in!n ; copy original dim name if (iscoord (in, in!n)) then out&$out!n$ = in&$in!n$ ; copy coordinate variable end if end if end do end if copy_VarAtts (in, out) ; also copy attributes ; Make automatic dimension name for the added length dimension. out!last_dim = "len" + new_len return (out) end