Using the ASSOC function
Anonym
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:

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:

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.