In this tutorial we will cover: how to write IDL programs and functions and how to properly document your IDL code.
To write your first IDL program open a file called firstpro.pro in emacs or xemacs. The .pro extension identifies this file as an IDL routine and also enables idlwave markup if it has been installed. Copy and paste or type the following bit of code into the file firstpro.pro and save it:
pro firstpro
print, 'Good morning, Arizona!'
return
end
Start idl in a terminal in the same directory where you've saved firstpro.pro and compile it with
.run firstpro
Note that you don't need to specify the .pro extension. Equivalently you can type
.r firstpro
Run your program by typing at the IDL command prompt
firstpro
There are some convenient shortcuts in IDL that you will gradually pick up. In this case .run is the same as .r. Note that .run (and all other executive commands) can only be used at the command prompt and not within programs. It is useful because if there were a bug in your code then the program would not compile. Try to sabotage your program by placing a "typo" somewhere in the code and try to re-compile. Then fix it and see what happens. You should re-compile your program whenever you make a change to it. Next let's say we want to de-bug our program. We can put in a stop and play with all the variables until we have debugged our program. Change your program to look like this:
pro firstpro
theta = 2*!pi*findgen(100)/100.0
sinewave = sin(theta)
print, interpol(sinewave,theta,!pi/2.0)
stop
return
end
Compile your routine and run it. This program generates a sine wave and then prints the value of the sine wave at pi divided by two (which should be one). But because of the stop we are still in the program firstpro.pro. To see this type
help
You will see all of the variables in the current session. You will also see that IDL knows you're in firstpro and that you've stopped at line 8. Let's make sure the sine wave looks right. Let's plot it!
window, 0, xsize=450, ysize=450 plot, theta, sinewave, xstyle=3, ystyle=3, thick=2.0, $ xtitle='Theta (Radians)', ytitle='Sin(Theta)'
We will discuss the keywords used in the call to plot in more detail in Making Plots & Postscript. You can do whatever you want here: define new variables, print existing variables, or whatever you want. To continue through the rest of the program (you can imagine having multiple stops throughout a long program) type
.continue
or, more conveniently,
.c
There are two more commands I want to discuss here. Run your program again so that it reaches the stop. If you type
return
then you will be returned to the MAIN level (or the "top" of the IDL session). This is exactly what happens when IDL sees the return in firstpro. Imagine you had multiple "nested" procedures or functions, however. For example, try this program (still call it firstpro.pro):
pro make_sine, theta, sinewave
theta = 2*!pi*findgen(100)/100.0
sinewave = sin(theta)
stop
return
end
pro firstpro
make_sine, theta, sinewave
print, interpol(sinewave,theta,!pi/2.0)
stop
return
end
The program make_sine is a sub-routine whose purpose in life is to generate a sine wave. Compile this program, run it, and then type help. You will see that IDL has successfully compiled two programs (make_sine and firstpro) and that you've stopped on line 6 in make_sine and line 13 in firstpro. As you can see you're "deeper" into the IDL session. To continue you might type return or .c but you would also stop on line 16 in firstpro which would be okay if you also need to debug firstpro. Sometimes, however, you just want to return to the MAIN level. Rerun firstpro and then type
retall
and then help to see that you're back in the MAIN level and none of your variables have been preserved. If things get really messed up then you can "reset" your IDL session by typing
.reset_session
or
.reset
This command is equivalent to exiting IDL (by typing exit) and re-starting a new session. Besides programs there are also functions. In general there is nothing functions can do that programs can't but your programs will be much more logical and shorter if you use functions for particular tasks. Type this function into a new file called firstfunc.pro:
function firstfunc, npts=npts, x=x
if n_elements(npts) eq 0L then npts = 10.0
x = findgen(npts+1)-npts/2.0
coeff = [-10.5,5.0]
model = coeff[0] + coeff[1]*x^2
return, model
end
Compile and run this routine by typing
.r firstfunc model = firstfunc()
Then plot the parabolla with
plot, model
When only one argument is passed to plot then it assumes that that argument is the ordinate and the abscissa is the index number. Note that a function is distinguished from a program by having parenthesis. In general a function takes inputs (or no inputs) and returns something, in this case the array model. But what if we wanted the x-axis variable? We can have firstfunc give it to us by using keywords. Keywords are extremely important. The best way to learn their functionality is by studying extant IDL routines. The function firstfunc has two keywords, npts and x. The first keyword is an optional input while the second keyword is an optional output. To see how they work try
model = firstfunc(x=x) plot, x, model, xstyle=3, ystyle=3
If we want to change the number of points in our parabolla we can use the npts optional input:
model = firstfunc(x=x,npts=300.0) plot, x, model, xstyle=3, ystyle=3
Note that the order of the keywords doesn't matter whereas the order of regular arguments (without an equals sign) does matter. We see that the parabolla is now more finely sampled (having 300 points rather than 10 points). Let's add one more keyword to generate a plot. Modify your program to look like this:
function firstfunc, npts=npts, x=x, doplot=doplot
if n_elements(npts) eq 0L then npts = 10.0
x = findgen(npts+1)-npts/2.0
coeff = [-10.5,5.0]
model = coeff[0] + coeff[1]*x^2
if keyword_set(doplot) then begin
window, 0, xs=450, ys=450
plot, x, model, xstyle=3, ystyle=3, thick=2.0, xthick=2.0, $
ythick=2.0, charsize=2.0, charthick=2.0, title='My Parabolla', $
xtitle='X', ytitle='Y'
endif
return, model
end
Note the extensive use of keywords in the call to plot. Now type
.r firstfunc model = firstfunc(npts=300.0,/doplot)
The final item in this tutorial is how to properly document your code. It is imperative that you consistently document routines both for yourself and if you think anybody else will ever use your programs. Let's document firstfunc the way I would document it (note that there is no standard convention about how to document an IDL program but this is how I do it). Copy and paste this into your program:
;+
; NAME:
; FIRSTFUNC()
;
; PURPOSE:
; Generate a parabolla and optionally plot it.
;
; CALLING SEQUENCE:
; model = firstfunc([npts=,x=],/doplot)
;
; INPUTS:
; None
;
; OPTIONAL INPUTS:
; npts - number of points in the parabolla (default 10)
;
; KEYWORD PARAMETERS:
; doplot - if set then generate a plot of the parabolla
;
; OUTPUTS:
; model - the parabolla
;
; OPTIONAL OUTPUTS:
; x - abscissa corresponding to MODEL
;
; COMMON BLOCKS:
; None
;
; PROCEDURES USED:
;
; COMMENTS:
;
; EXAMPLES:
; To make a parabolla with 300 points and plot it type:
;
; IDL> model = firstfunc(npts=300.0,/doplot)
;
; MODIFICATION HISTORY:
; J. Moustakas, 2003 November 17, U of A
;-
function firstfunc, npts=npts, x=x, doplot=doplot
if n_elements(npts) eq 0L then npts = 10.0
x = findgen(npts+1)-npts/2.0
coeff = [-10.5,5.0]
model = coeff[0] + coeff[1]*x^2
if keyword_set(doplot) then begin ; generate a plot
window, 0, xs=450, ys=450
plot, x, model, xstyle=3, ystyle=3, thick=2.0, xthick=2.0, $
ythick=2.0, charsize=2.0, charthick=2.0, title='My Parabolla', $
xtitle='X', ytitle='Y'
endif
return, model
end
The documentation is offset from the main program by being placed between the "+" and "-" signs. Note that you can comment your code by using a semi-colon. Now, if you want to read the documentation on your routine type
doc_library, 'firstfunc'
Last update 2003 Nov 12. Email J. Moustakas with questions or comments.