Using the ASSOC function

The ASSOC function provides a basic technique for random access to data in a file. It’s particularly useful for files that have a repeating data structure, like a series of images.

For example, I have an ENVI file that holds the six multispectral bands (1-5 and 7) of a Landsat 7 ETM+ scene. ENVI, by default, uses band sequential (BSQ) interleaving, meaning the six band images are laid out in memory something like this:
The organization of multispectral Landsat 7 bands in an ENVI file
I’d like to create a normalized difference vegetation index (NDVI) image from these data, so I’ll need to read bands 3 (red) and 4 (near infrared) into IDL. One technique would be to read the entire file into IDL, then subscript the result to get bands 3 and 4. This may not be a good idea, though, because a Landsat scene can be large (I’ve used a 13000 x 12000 pixel scene in the past); it could consume all the memory available to IDL. A better approach is to read only bands 3 and 4 from the file. There are a few ways to do this, but the problem lends itself nicely to a solution with ASSOC.

Start by getting a path to the ENVI file, assuming the file is in your IDL path, with:

IDL> file = file_which('boulder-ETM.dat')

Next, open the file for reading with OPENR:

IDL> openr, u, file, /get_lun

Now, noting that each image band is 700 x 575 pixels with an 8-bit depth, use ASSOC to set up an associated variable to represent a single band in the file:

IDL> tm = assoc(u, bytarr(700, 575, /nozero))

At this step, no data have been read into IDL: file access only occurs when the associated variable tm is subscripted. (Interesting, yes?)

Calculate NDVI, using the associated variable to pull the red and near-infrared bands from the file, which, by the diagram above, are represented by indices 2 and 3 in the associated variable:

IDL> ndvi = (float(tm[3]) - tm[2]) / (float(tm[3]) + tm[2])

Again, file access only occurs when the associated variable is subscripted. After the expression on the right-hand side is evaluated, the variable ndvi resides in IDL’s memory.

Now that all file access has been performed, close the file with FREE_LUN:

IDL> free_lun, u

and do a quick check on the NDVI variable that’s been created:

IDL> help, ndvi
NDVI            FLOAT     = Array[575, 700]
IDL> print, min(ndvi), max(ndvi)
    -0.626374     0.650224

Finally, display the NDVI image with a colorbar:

IDL> g_ndvi = image(ndvi, $
>       /order, $
>       /interpolate, $
>       title='Landsat NDVI image of Boulder, Colorado')
IDL> g_cb = colorbar(target=g_ndvi, $
>       orientation=1, $
>       title='NDVI value', $
>       textpos=1, $
>       font_size=10, $
>       position=[0.80, 0.2, 0.82, 0.8], $
>       ticklen=0.1)

Here’s the result from the Windows side of my (new!) laptop:

An NDVI image of Boulder, Colorado, from Landsat 7

Note that I could have used READ_BINARY or READU + POINT_LUN to read the data from the file, but the approach with ASSOC is much easier.

About these ads

About Mark

I solve scientific programming and visualization problems with IDL.
This entry was posted in data access, language and tagged , , . Bookmark the permalink.

4 Responses to Using the ASSOC function

  1. Such a nice way to do,
    Thanks you very very much for that.

  2. Taka says:

    Mark, this is exactly what I would like to know about ASSOC function. It is very powerful and useful for data I/O.

  3. PabloM says:

    Can this be used with an offset? I think I tried something similar using shmmap, but I wanted to skip header information. Basically, I opened a file with ‘openr, u, file, /get_lun’ and used ‘point_lun’ to skip past the header information. However, this did not work with shmmap.

  4. Regner Trampedach says:

    Yes, PabloM. The assoc-function also has an off-set argument:
    IDL> Result = ASSOC( Unit, Array_Structure [, Offset] [, /PACKED] )
    with Offset in bytes.
    – Regner Trampedach

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s