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.