Re: [ferret_users] Bitwise operations in Ferret

```Paulo,

Thanks for the code snippet. After thinking through the details and looking
at how Ferret is interpreting the netCDF file, I think I have things
working. In addition to your trick of dividing by powers of two and
whittling down to get all the different bits, one also has to be careful
with the sign bit. In my netCDF file, the QA flags are stored as the netCDF
byte type and it appears that the highest order bit is being used for the
sign. So, the variable fed into your "f1_7" and "r1_7" arrays must be
adjusted to account for negative values. Using your syntax, I would need to
add the following line and modified definitions for f1_7 and r1_7:

let mds_positive = if mds lt 0 then abs(mds)+128 else mds
let f1_7 = int(mds_positive[k=1]/2^7)
let r1_7 = mod(mds_positive[k=1],2^7)

Your repeat loop can then be used as is.

For the record if anybody tries this trick based on finding it in the
archive...users beware. This will only work on data stored as type byte. If
the bits are encoded into integers with all digits significant, then there
will be possible information loss when Ferret converts the integers into
floats. Based on recent user group discussions on precision within Ferret,
my understanding is that all data variables are stored as single precision
floats.

-Bill

On 4/20/09 4:20 AM, "Paulo B. Oliveira" <pbo@xxxxxxxxx> wrote:

> Dear Bill,
>
> I had the same problem when dealing with MERIS data.
> I've used a repeat cycle to iteratively define a series of variables
> (f1_"bit") that extract the value of each bit using decreasing powers of
> 2, the INT() and MOD() function.
>
> Here is the code I wrote to extract the land,cloud,water and pcd's flags
> from a 2D var - "mds" containing the real representation of 8bit flag
> word.
>
> let f1_7 = int(mds/2^7); let r1_7 = mod(mds,2^7)
>
> repeat/range=6:0:-1/name=pw ( \
>  let f1_`pw` = int(r1_`pw+1`/ 2^`pw`);\
>  let r1_`pw` = mod(r1_`pw+1`,2^`pw`);\
> )
>
> let/tit=land  land  = if f1_7 then f1_7
> let/tit=cloud cloud = if f1_6 then f1_6
> let/tit=water water = if f1_5 then f1_5
>
> let not_cloud = if cloud then 1/0 else 1
>
> let/tit=pcd_1_13 pcd_1_13 = if f1_4 then f1_4
> let/tit=pcd_14   pcd_14   = if f1_3 then f1_3
> let/tit=pcd_15   pcd_15   = if f1_2 then f1_2
> let/tit=pcd_16   pcd_16   = if f1_1 then f1_1
> let/tit=pcd_17   pcd_17   = if f1_0 then f1_0
>
> I hope that helps,
>
> Regards,
>
> Paulo.
> ------------------------------------------------
> Paulo B. Oliveira
> INRB / IPIMAR - Sea and Fisheries Research Lab.
> Av. Brasilia
> 1449-006 Lisboa
> Portugal
> Tel.: +351 213027068
>
> -------------------------------------------------------------
> On Fri, 2009-04-17 at 15:06 -0700, Gustafson, William I wrote:
>> Dear Ferreters,
>>
>> Are there some tricks to do bitwise operations in Ferret? I have some
>> MODIS satellite data that has quality assurance (QA) information saved
>> at the bit level. For example, for a particular byte of the QA data,
>> bits 1 & 2 are used for the optical thickness confidence QA, and bits
>> 6 & 7 are used for the effective radius confidence QA. I would like to
>> do masking on particular settings of these bits. How can I do that?
>>
>> My search so far has not found anything. The AND and OR operators just
>> treat 0 as false and non-zero as true?they do not operate at the bit
>> level. I have pondered doing this with an external function, but that
>> defeats the simplicity I am looking for. I need to hand of the final
>> script to other users that would not necessarily have the know-how to
>> install external functions on their machines.
>>
>> Thanks for any suggestions!
>>
>> -Bill
>> ___________________________________________
>> William I. Gustafson Jr., Ph.D.
>> Scientist
>> ATMOSPHERIC SCIENCES AND GLOBAL CHANGE DIVISION
>>
>> Pacific Northwest National Laboratory
>> P.O. 999, MSIN K9-30
>> Richland, WA  99352
>> Tel: 509-372-6110
>> William.Gustafson@xxxxxxx
>> http://www.pnl.gov/atmospheric/staff/staff_info.asp?staff_num=5716

```