This page contains an introduction to programming in IDL, and is part of a larger set of IDL tutorials. This introduction is fairly basic- while it will get you started, you will benefit greatly from reading one or more of the following books:
There are a few books on IDL programming which I have found very useful. The IDL reference manuals are quite helpful if you already have some idea of what you need. The reference manuals contain a few examples for beginners, but the first book I would recommend reading is:
"IDL Programming Techniques" by David Fanning. It has a lot of examples and is a great book!
Another excellent book is:
"Application Development with IDL" by Ron Kling. This is a somewhat more advanced book, but also has some very nice example programs that are quite useful for image analysis. I have copies of both of these books if you want to borrow them (and you work in my lab!), or you can purchase them through RSI (makers of IDL).
Table of Contents
IDL is a structured programming language that provides a complete environment for image processing. It has basic flow-control operators like if, while, and for. It supports pointers, structures, and arrays, has a vast number of built-in library functions, supports object-oriented programming, and provides a convenient image display interface. On top of that, there is a widget-builder to create complex GUIs, "Live Tools" that let you create and edit graphs and images on-the-fly, and Object Graphics which support modern complex 3D graphics displays.
The IDL language is most similar to Matlab (one of its competitors), but is also similar to Pascal and in some respects to C in structure. IDL is fundamentally an array processor; it wants to work with arrays or groups of numbers. There are many built-in routines to facilitate this; several are variations of the Numerical Recipes programs.
The basic point of IDL is to manipulate numbers. For instance, all of the image data in our lab are stored as numbers, and we need to process and display them. Knowing how to deal with numbers in IDL is the first step toward data analysis. A single number is called a value or "scalar". A number is associated with a variable "num" like:
num = 2
An image is really just a group of numbers that has some order imposed on it. This is referred to as an "array". For example:
arr = [0, 1, 2, 3, 4, 5]
is an array. You can call "arr" whatever you want, e.g. "a", "bob", etc. You can also reference a variable, like:
arr = [0, 1, num, 3, 4, 5]
IDL is a zero-index language; that is, the first element in an array has index number "0" (zero). The last element thus has an index number of (N-1). This is similar to C, but different than Matlab, which indexes from 1-N. I mention this here because in a 0-index language, you generally run a for-loop index from 0 to (N-1).
IDL is different from several other languages (C, Fortran, Pascal) in that a variable does not have to be decalred before using it. It is created the first time it is set equal to something. "Something" can be anything- a scalar, a vector, a structure, etc. Furthermore, what the variable contains can change!
a = 3
a = [4,6,8]
The variable a will change from a scalar to a vector. This is both a blessing and a curse. This can be insidious when your data get changed from e.g. a floating-point set of values to a byte (8-bit) set of values.
Line continuation:
To continue a very long line onto the nextline without breaking your statement, do:
arr = MAKE_ARRAY(num_x, $
num_y, /FLOAT)
Library Procedures and Functions
IDL has a vast collection of built-in library routines. It is this collection that forms the core of IDL. There are two tyoes of routines: Procedures and Functions. A procedure is a routine that performs a task, while a function is a routine that returns a result. Other than that, the definition between the two is pretty blurry. Both procedures and functions can accept parameters, manipulate data, and call other functions. The main distinction is in how they are called.
A procedure is called like:
TV, img, TRUE=1
The TV procedure displays an image, "img" in a window on the computer screen. The parameter, "img" is passed to the procedure. IDL uses two different syntaxes to pass parameters. The first method, as demonstrated with "img" is to simply pass the parameter into the function as part of the function call. If there are multiple parameters, the order is important. The second method uses KEYWORDS. In this example, TRUE is a keyword, and we are passing the value "1" to it. For keywords, the order within the procedure call does not matter. Keywords are generally used only for optional parameters, where a reasonable default value can be used if the keyword parameter is not invoked. Keyords are also used for binary flags that are turned on or off, and a slightly dofferent sysntax is used:
TV, img, /TRUE
Here, the leading "/" implies a value of 1 or "on" for the flag. If the keyword is not present, it is assumed to be 0 or "off".
A function is called like:
new_img = ROT(img, 60, /INTERP)
The function ROT rotates an image. In this case, we are asking it to rotate 60 degrees. The keyword /INTERP signifies that we want to use bilinear interpolation rather than the standard nearest nieghbor sampling. For a function call, there is a a returned item, "new_img" that is the result of the function. Also, the parameters are denoted by placing them inside of parenthesis.
Functions can be nested, by placing one inside of another:
TV, ROT(img, 60, /INTERP), TRUE=1
This makes for fewer lines of code, a more concise program, and sometimes may be more efficient emory-wise. However, nesting many functions together can make your code difficult to avoid and should not be taken to extremes.
Control Structures (if-then-else, for, while)
Examples of some of the basic control elements are:
if statement:
if (a GE 2) then begin
...
endif
if (a GE 2) then begin
...
endif else begin
...
endelse
while statement:
while (string EQ 'filename') do begin
...
endwhile
for statement:
for i=0, 99 do begin
...
endfor
There are variations on all of these, such as "if - then - else", a CASE structure, and allowing the counter in a for loop to decrement, but the three examples above are the elements I use for 90% of my programming. All of these elements can be nested within one another.
Programs and Functions written by you
A simple IDL program:
A basic IDL program looks like:
PRO hello, name
print, 'Hello, '+STRING(name)
END
That's it. "PRO" declares that this is a procedure that performs a task, as opposed to a function that performs a task and also returns a value. "hello" is the name of the program. "name" is the label assigned to an input parameter. The only thing this program does is print a message. "END" indicates where this program ends. To run the program, type:
IDL> hello, Terry
The program will print the message:
IDL> Hello, Terry
IDL Compiles at Run-Time.
This is a good time to talk about the fact that IDL does not normally run a precompiled program. (Although it can- this is confusingly called Run-Time mode.) The source-code is a normal text file that is read and compiled as each particular program is encountered in the calling program. This approach has several ramifications:
Precompiled IDL programs can be run using the free Virtual Machine (VM) environment which you may download from RSI. This is a very nice addition to IDL, enabling colleagues to see if a program is useful with little investment, as well as permitting the sharing of software without necessarily giving away the source code as well.
Efficient IDL Programming: Optimizing IDL performance.
IDL really shines when it can work on a large array (like a 2D or 3D image). It's performance suffers when it has to examine individual array elements one at a time, as when you have a for-loop to step through an array one element at a time. There are a host of methods for avoiding a for-loop that are beyond the scope of this brief tutorial. Suffice it to say that with good programming technique, IDL approaches the performance of compiled C for most number-crunching tasks.
Standard image display in IDL uses 256 colors. An image must be scaled from 0-255, and each value is assigned a color. Each of the 256 colors is typically referred to by the relative amounts of red, greeen, and blue (RGB). The value/color association is known as a Color Table. There are ~40 standard color tables supplied with IDL. Older graphics cards were limited to a small number of colors (2, 8, 16, or 256 were common), making a color table quite handy. Modern computer graphics can support millions of colors using an approach called True Color. This enables phot-quality images with a virtually unlimited number of colors. However, for most medical imaging applications, it is still handy to use a color table.
There are several books that discuss color tables in detail (see e.g. David Fanning's book, "IDL Programming Techniques"). I only mention color tables here because understanding how they work is critical in displaying images as well as in spotting certain types of image artifacts.
IDL has a gentle but long learning curve. I don't know an IDL programmer that considers themselves to have mastered IDL! If you want more information, refer to one of the training manuals.