6. Selected Topics

6.1. User Libraries

The IAC maintains a collection of about 1200 procedures written by users for a variety of purposes. 450 routines are in the 'astro lib', a library maintained by Wayne Landsman, NASA, which is actualized about twice a year. Other library collections typically are those maintained at other astronomical institutes.

Before beginning with an own development, it is highly recommended to have a look into these libraries. Many times there is already something available that can be used right away, or can at least be adapted.

A good way of scanning the libraries is to start with a find_pro command (which itself is a user supplied routine). Usually the name of a procedure is related by what it is doing. Suppose you need to read a file in MIDAS internal format. You imagine the corresponding routine has something like 'read' or 'midas' in its name. As 'midas' is more significant, let's search for that.

IDL>find_pro,'*midas*'
IDL>

No match. Perhaps an abbreviations for 'midas'?

IDL>find_pro,'*mds*'
IDL>find_pro,'*mid*'
/usr/rsi/idl/lib/astro/pro/disk_io/mid_rd_dirdsc.pro
/usr/rsi/idl/lib/astro/pro/disk_io/mid_rd_image.pro
/usr/rsi/idl/lib/astro/pro/disk_io/mid_rd_table.pro
/usr/rsi/idl/lib/astro/pro/disk_io/mid_up_image.pro
/usr/rsi/idl/lib/astro/pro/disk_io/mid_up_table.pro
/usr/rsi/idl/lib/varios/wue_lib/midv.pro

Bingo. Now check with the on-line help, or directly with an editor, if one of the routines is handy for you. If you have to adapt it, copy to your development directory, but modify the name to avoid duplications.

6.2. Efficient Programs

The most important thing in efficient programming is programming discipline. A program once hastily done for a special purpose is likely to be taken later as a starting point for a more general application later. If it is as clean as possible, you will have less problems. The most important rules are:

More specific programming rules in the following sub chapters.

6.2.1 Type control

Type conversion or mismatch is a frequent source of error. Look at this

IDL> a=20000
IDL> print,a/4*2
   10000
IDL> print,a*2/4
   -6384

Never use non integer variables in loops. Rounding errors may influence the number of loop executions.

If arrays are involved, type conversions can also degrade system performance. As an example for efficient programming, let us use the case of inverting a 1024 x 1024 floating point array. The problem is to avoid
divisions by zero. The naive beginner may program this like:

for i=0,1023 do for j=0,1023 do if ( a(i,j) ne 0 ) then a(i,j)=1./a(i,j)

On my Sparc-5 this command executes in 58.3 seconds. We will analyze it in the following for improving efficiency. First of all, we notice that there is an unnecessary type conversion in the if statement. Array a is float and is compared to an integer. Moreover the complete comparison is not needed, because a value differing from 0 indicates logical true. Hence:

for i=0,1023 do for j=0,1023 do if a(i,j) then a(i,j)=1./a(i,j)
and execution time goes down to 45.6 seconds (22% faster).

6.2.2. Respecting Row Major

IDL stores multidimensional variables in row major order, in each nested loop the innermost index should run on the first dimension.

for k=0,n1 do begin
    for j=0,n2 do begin
        for i=0,n3 do begin 
        a(i,j,k)=......

other ordering can greatly deteriorate program execution time. How big this effect is, depends on circumstances and machine architecture. In our example, inverting columns and rows improved execution time by 3 seconds.

6.2.3 Loops and IF's

Avoid loops and ifs with the where command. where(arg) returns a vector with the index numbers where the argument differs zero. This vector can now efficiently be used as an indexes.

IDL> a(where(a))=1./a(where(a))

Executes on my Sparc-5 in 5.8 seconds. A further look shows that we actually calculate where(a) two times, once is enough:

tmp=where(a)
a(tmp)=1./a(tmp)

and we are down to 5.5 seconds. The where command is very effective, but still compiled languages are more effective then IDL. The same operation in Fortran-77 lasts only 0.8 seconds, when compiled with optimization only 0.4 seconds.

Only in the case of direct vector operations, like a=1./a, if know that a is always non zero, IDL catches up with Fortran, both execute in 0.3 seconds.

6.2.4 Virtual memory

IDL creates temporary variables to store intermediate results of operations with arrays. Let all variables in the next example be arrays, then a statement like

amin=min(a+b) < min(c+d)

would create two intermediate arrays (a+b), (c+d), while a coding sequence

min1=min(a+b)
min2=min(c+d)
amin=min1<min2

needs only one. If the target variable in a statement also appears in the argument list, its space in memory can be used as for the temporary variable:

a=temporary(a)+1

first undefines a and does not consume extra memory.

6.3. Configuration

6.3.1. Resources

Like many other graphical applications, IDL reads the 'Xdefaults' file and apart from that looks for a proper configuration file. This has to have the name Idl (note capital I) and has to be in the users home directory or any one the the environment variable 'XAPPLRESDIR' points to.

These configurations are often used:

idl.colors: -5

Leave five colors available for other applications.

idl.background: #7300a100ff00

set the background of widget applications in this case to a dark blue. X standard color names can be used instead of hex codes.

To force each window have it's private 8bit color map

idl.gr_depth: 8
idl.gr_visual: StaticColor

6.3.2 Initialization

Upon starting up, IDL checks an environment variable called IDL_STARTUP. If it is defined, IDL will use it as a filename and execute all commands encountered in that file.

To add for instance your IDL program library to the search path, do the following: in your cshrc file add the line setenv IDL_STARTUP ${HOME}/.idl_start

and do a source ~/.cshrc, the next time to enter the system, this will not be necessary. If you use Bourne type shells, do the equivalent.

Now edit the file .idl_start in your home directory:

!path=!path+':~/idl'
print,' Hello old chap, nice to meet you again'

This will modify the search path and print a greeting message each time you enter IDL.

6.4. Animations

IDL has an high level animation tool called xinteranimate. Using it, you can quickly construct animation sequences in a standard window, that allow some user interactions. In case you do not like the standard appearance of this application, you can use the lower level routines as used in xinteranimate. It is a library procedure, the source file therefore is available.

Actually doing an animation with xinteranimate is a three step process

(various other keywords apply at each stage which influence the appearance of the animation widget.) Here is a little demo program

arr=exp(smooth(dist(100),3)/10.)   ; some sample data 100x100
arr=bytscl(arr)                    ; normalize to 8bit
xinteranimate, set=[100,100,10]    ; initialize 

for i=0,9 do xinteranimate, frame=i, image=arr*(1.+float(i)) ; store ten frames

xinteranimate,10        ; display at 10% of maximum speed

Always remember that memory consumption is quite high. For large animations you should use some other looks, like mpeg_encode and mpeg_play.