Re: possible bug or change regarding logical variables in NCL 5.1.0

From: David Brown <dbrown_at_nyahnyahspammersnyahnyah>
Date: Mon, 9 Mar 2009 18:58:36 -0600

Hi Jonathan,

I'm afraid I am to blame for this. It was a failure of imagination: I
was unable to imagine anyone wanting to
change the default _FillValue for a logical variable. I was fixing
some inconsistent behavior for the logical
type and, for reasons that I cannot fully explain now, it was easier
if I made the _FillValue unchangeable.
I didn't see the likelihood of this becoming an issue, but once
again, I have demonstrated the danger of
any form of backwards incompatibility.

We will need to discuss this to decide what to do about it. As a
point of reference, do you find the ability
to change the fill value for logical variables an important feature?
It seems that there must be other
ways to do what you are doing in this code, but maybe it truly is
easier and most sensible to modify
the _FillValue.

I apologize for your difficulty.
I would be interested to know from other users if this change will
cause them problems as well.

I did not have time to fully document the behavior of the logical
type yet as it is in the current version,
but some other things changed as well. Hopefully not in a way that
would cause problems or further
backwards incompatibility.

Here is a brief summary:
Formerly when converting a numeric array to logical, 0 became False,
1 became True, and other
numeric values were left alone, although when performing logical
operations all non-zero values (other
than the missing value) evaluated to True. The default missing value
was -1.
Now all non-zero numerical values get explicitly converted to True.
The missing value is printed as
'Missing' and is considered to be a non-numerical logical value. It
can be set explicitly
using a new keyword:

logical_missing = _Missing

The keyword has the underscore in front in order to make it less
likely to collide with a user's variable name.
The number -1 is, like all non-zero values, converts to True.
Missing numerical values are converted to logical Missing.

Of course you can also get a logical missing value by doing the
following:

logical_missing = new(1,logical)

  -dave

On Mar 9, 2009, at 4:10 PM, Jonathan Vigh wrote:

>
> Greetings,
> Upon upgrading to the new version of NCL (5.1.0), one of my
> functions stopped working. I now get the following error:
>
> warning:Logical type variable (whitespace) missing value can only
> be set
> to Missing: setting to Missing
> fatal:Subscript out of range, error in subscript #0
> fatal:An error occurred reading tChr
> fatal:Execute: Error occurred at or near line 322 in file
> ./module_read_vdm.ncl
>
> As you'll see in this function, I'm defining the _FillValue for a
> logical variable (whitespace) to be False rather than the default (-1)
> so that I can use it do some mask operations. For some reason, the new
> NCL doesn't seem to like this. Has there been a change to the behavior
> or handling of logical variables? My function code is below.
>
> Jonathan
>
>
>
> ;---------------------------------------------------------------------
> -
> ; This function parses a string into an array holding each
> ; of the strings ("words" or space- or tab-delimited items) with
> ; whitespace removed.
> ;
> ; It changes all the characters to upper case
> ;
> ; Author: Jonathan Vigh
> ;---------------------------------------------------------------------
> -
> undef("parse_by_whitespace")
> function parse_by_whitespace(tStr[1]:string)
> local
> space,tab,ii,is,tStr,tChr,nchars,stringOn,string_begin,string_end,stri
> ng_begin_indices,string_end_indices,nparsed_strings,output_array
>
> begin
> space = inttochar(32)
> tab = inttochar(9)
> nullChar = inttochar(0)
>
> tChr = stringtochar(tStr)
> nchars = dimsizes(tChr)
>
> ; Get indices where there are no whitespaces .
> ii = ind(tChr.ne.space.and.tChr.ne.tab.and.tChr.ne.nullChar)
>
> if (.not.all(ismissing(ii))) then ; First check to make sure the
> tStr isn't completely devoid of whitespace delimiters
>
> ; mask out a logical array that starts off being filled with 'True',
> then falsified by tests (using mask)
> whitespace = new(nchars+2,"logical") ; make this bigger
> than the
> actual character array by adding a phantom space in the beginning and
> end
>
> whitespace = True ; all positions are assumed
> to be
> whitespace at first (including the first and last positions which are
> really phantom positions)
> whitespace@_FillValue = False
>
> notwhitespace = whitespace ; transfer to another array
> which
> we will later make the opposite of whitespace
> notwhitespace(0) = False ; the first position in the array
> is phantom and must always be whitespace
> notwhitespace(nchars+1) = False ; the last position in the
> array
> is phantom and must always be whitespace
>
> whitespace(1:nchars) =
> mask(whitespace
> (1:nchars),tChr.ne.space.and.tChr.ne.tab.and.tChr.ne.nullChar,False)
> ; mask all the nonwhitespace positions to be False, so what's left are
> the whitespaces (as True)
> notwhitespace(1:nchars) =
> mask(notwhitespace
> (1:nchars),tChr.eq.space.or.tChr.eq.tab.or.tChr.eq.nullChar,False)
> ; mask all the whitespace positions to be False, so what's left are
> the
> nonwhitespaces (as True)
>
> ; explanation of the logic - the only way a string can begin is if the
> current character position is NOT whitespace, so we start with an
> array
> of all positions where this is True
> ; next we mask out all the possible ways a string can NOT start
> (i.e. if
> the previous character position is also NOT whitespace)
> string_begin =
> mask(notwhitespace(1:nchars),notwhitespace(0:nchars-1),False)
>
> ; and now we mask out all the possible ways a string can NOT end (i.e.
> if the next character position is also NOT whitespace)
> string_end =
> mask(notwhitespace(1:nchars),notwhitespace(2:nchars+1),False) ;
> now
> mask as True all positions where the next character is whitespace but
> the current one isn't
>
> string_begin_indices = ind(string_begin.eq.True)
> string_end_indices = ind(string_end.eq.True)
>
> ; Now load the parsed strings into a return array of strings
> nparsed_strings = dimsizes(string_begin_indices)
>
> ; Set up the output array filled with empty strings
> output_array = new(nparsed_strings,"string",string_FillValue)
>
> if (nparsed_strings .ge. 1) then
> do is = 0, nparsed_strings-1
> output_array(is) =
> chartostring(tChr(string_begin_indices(is):string_end_indices(is)))
> ; <- this is line 322 in the original file - the error message
> references this line
> end do
> else
> output_array = string_FillValue
> end if
>
> else
> output_array = tStr
> end if
>
> return(output_array)
> end
>
> _______________________________________________
> ncl-talk mailing list
> List instructions, subscriber options, unsubscribe:
> http://mailman.ucar.edu/mailman/listinfo/ncl-talk

_______________________________________________
ncl-talk mailing list
List instructions, subscriber options, unsubscribe:
http://mailman.ucar.edu/mailman/listinfo/ncl-talk
Received on Mon Mar 09 2009 - 18:58:36 MDT

This archive was generated by hypermail 2.2.0 : Mon Mar 09 2009 - 21:47:10 MDT