MPLNET The NASA Micro-Pulse Lidar Network National Aeronautics and
Space Administration
Goddard Space
Flight Center

About Bitwise Flags

Several MPLNET data fields are bitwise flags. The most common are 8-bit "byte" flags. A flags value can store boolean (true/false) values, integers, and enumerations. CF compliant NetCDF files only support booleans and enumerations. Byte flags are usually stored as unsigned integers. The most common is the uint8 (also called byte (most languages) or ubyte (NetCDF). The bigger the integer, the more information it can hold, so a uint16 holds twice as much information as a uint8. uint8 flags are examined in detail below. Note that code is given in IDL 8.4 syntax on top and ANSI c syntax on bottom.

The byte 0 has no bits set:

  0 =
76543210
00000000
1286432168421

0 = 0× 128+ 0× 64+ 0× 32+ 0× 16+ 0× 8+ 0× 4+ 0× 2+ 0× 1

The byte 255 has every bit set:

255 =
76543210
11111111
1286432168421

255 = 1× 128+ 1× 64+ 1× 32+ 1× 16+ 1× 8+ 1× 4+ 1× 2+ 1× 1

Every other number between 0 and 255 is some combination of these bits, added together.

For example, the byte 130 has bit 1 (value 2) and bit 7 (value 128) set:

130 =
76543210
10000010
1286432168421

130 = 1× 128+ 0× 64+ 0× 32+ 0× 16+ 0× 8+ 0× 4+ 1× 2+ 0× 1

All unsigned integers work this way.

Boolean Bit Flags

Instead of treating a byte as a number from 0 to 255, a byte can be thought of as 8 separate boolean (true/false) values or bits, where 1 is true and 0 is false. Using them this way, these boolean values are called boolean bit flags.

Consider the following code:

IDL:no_signal = !false all = !false aerosol = !true cloud = !true pbl = !false clear = !false prelim = !false other = !false
c:char no_signal = 0, all = 0, aerosol = 1, cloud = 1, pbl = 0, clear = 0, prelim = 0, other = 0;

These definitions are simple enough, but they take up 8 bytes of space for each time they are defined. For a single value on a modern computer, that isn't a problem. However, consider the MPLNET Vertical Feature Mask (VFM) product which is an array with many thousands of elements. Combining these properties into one value makes more sense than creating 8 separate arrays, and will save space.

To make a boolean flags value, assign each boolean to be one of the bits. Then set the bits to 1 for true and 0 for false. In practical terms, do a "bitwise and" operation on each of the true bit values, (1, 2, 4, 8, 16, 32, 64, and 128).

For readability, programmers usually assign the bit flag values to a structure (IDL), or to #define definitions (c).

Here's the code above written to take advantage of bit flags:

Preparation for Bitwise Boolean Flags:

IDL:vfm_flags = {no_signal:1B, all:2B, aerosol:4B, cloud:8B, pbl:16B, clear:32B, prelim:64B, other:128B}
c:#define VFM_NO_SIGNAL (char)1 #define VFM_ALL (char)2 #define VFM_AEROSOL (char)4 #define VFM_CLOUD (char)8 #define VFM_PBL (char)16 #define VFM_CLEAR (char)32 #define VFM_PRELIM (char)64 #define VFM_OTHER (char)128

In c, the #defines are usually in a header file. In IDL, MPLNET provides functions to simplify looking up which bit is which, and which are set.

Write Bitwise Boolean Flags:

IDL:; write a flag with aerosol and cloud set true (everything else false) vfm = vfm_flags.aerosol or vfm_flags.cloud ; set the pbl flag true (without changing other flags) vfm or= vfm_flags.pbl ; set the aerosol flag false (without changing other flags) vfm and= not vfm_flags.aerosol ; set the aerosol flag true or false depending on a boolean (without changing other flags) vfm = (vfm and not vfm_flags.aerosol) or (some_boolean ? vfm_flags.aerosol : 0B) ; if the boolean is 0B or 1B, then you can do this instead vfm = (vfm and not vfm_flags.aerosol) or (vfm_flags.aerosol * some_boolean)
c:// write a flag with aerosol and cloud set true (everything else false) vfm = VFM_AEROSOL | VFM_CLOUD; // set the pbl flag true (without changing other flags) vfm = vfm | VFM_PBL; // set the aerosol flag false (without changing other flags) vfm = vfm & !VFM_AEROSOL; // set the aerosol flag true or false depending on a boolean (without changing other flags) vfm = (vfm & !VFM_AEROSOL) | (some_boolean ? VFM_AEROSOL : 0); // if the boolean is either 0 or 1, then you can do this instead vfm = (vfm & !VFM_AEROSOL) | (VFM_AEROSOL * some_boolean);

Read Bitwise Boolean Flags:

IDL:compile_opt logical_predicate ; test if a flag is true if vfm and vfm_flags.cloud then print, "It's a cloud!" ; test if multiple flags are true if vfm and (vfm_flags.aerosol or vfm_flags.pbl) then print, "It's aerosol and PBL!" ; test if a flag is false if not vfm and vfm_flags.cloud then print, "It's NOT a cloud!" ; test if multiple flags are false if not vfm and (vfm_flags.aerosol or vfm_flags.pbl) then print, "It's neither aerosol nor PBL!" ; test for some true and false flags if vfm and (vfm_flags.cloud or vfm_flags.pbl) and (not vfm and (vfm_flags.aerosol or vfm.other)) then $ print, "CLOUD and PBL, but not AEROSOL or OTHER"
c:if (vfm & VFM_CLOUD) { // cloud-only code here } if (vfm & VFM_AEROSOL) { // aerosol-only code here }

National Aeronautics and
Space Administration
Goddard Space
Flight Center
Privacy Policy and Important Notices