4936 Rate this article:
No rating

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.