next up previous contents
Next: Lecture 3: More graphics Up: Lecture 2: Programming in Previous: wheretomulti   Contents

Defining functions and procedures (and scripts)

Our examples so far have been too short to break up into sub-programs. However, any sizeable IDL project will be easier to deal with if each specific task is put into its own sub-program, which your main program can call. Sub-programs in IDL come in two flavours: functions and procedures. The main difference is that functions return a value and procedures don't. (This will be familiar to old FORTRAN hackers like me - C people are used to having only functions.) Procedures are defined like this:
pro procedure_name,arg1,arg2..... ,keyword1=keyword1....
statement
statement
.
.
.
end
and are called like this
procedure_name,argval1,arg2..... ,keyword1=value1....
They finish on the return command, or the end command.

Functions are defined like this:
function function_name,arg1,arg2..... ,keyword1=keyword1....
statement
statement
.
.
.
return, return_value
end

and are called like this:

foo = function_name(argval1,....., keyword1=value1.... )

You don't have to have any positional arguments or any keywords. If your function or procedure is called `smeg' you should put it on its own in a file called smeg.pro in the same directory from where you started IDL. As you would expect, all the variables you set up within a procedure or function are local to that sub-program. If IDL has a problem and stops within a sub-program, you will find that the variables you can look at or print are those belonging to the sub-program. You can leave the `scope' of the sub-program and return to the main level by typing

IDL> retall

Here is an example of a function. This calculates $\sin (x)/x$ - note the use of if and while.

 
function sinc,x
;+
; This idl function calculates the function sinc(x) = sin(x)/x.
; (  Beware: some authors define sinc(x) = sin(Pi x)/(Pi x)  ) 
; sinc(0)=1, but you cannot calculate this directly as sin(0)/0.
; This routine uses the power series  
; sin(x) / x = 1-(x^2)/3! + (x^4)/5! - (x^6)/7!  for small values of x 
; This function only works for scalars at the moment
; INPUT, x OUTPUT: s
; Written by: Hugh Pumphrey, Edinburgh
;-

if abs(x) gt 0.1 then begin 
    s=sin(x)/x                  ; Use obvious formula if |x| > 0.1  
endif else begin
    j=0
    s=x*0+1.0                   ;make s double if x is double
    term=s                      ;term same type as s

    ;; Calculate power series - stop after 20 terms or if term gets
    ;; very small 
    while j lt 20 and abs(term) gt 1.e-12 do begin
        j=j+2
        term=-1.0*term*x*x/(j*(j+1))
        s=s+term
    endwhile

endelse

return,s

end

To use this, put the text into a file called sinc.pro. If you type

IDL> .run sinc
IDL will inform you that it has compiled the function successfully. If you then type, for example,
IDL> print,sinc(0.05)
then the value of $\sin(0.05)/0.05$ will be printed out.

There are also things called, I think, scripts. I never use them. For example open a file called script_test.pro, somewhere where IDL can find it. Put

print,'script_test'
for i = 0,10 do print,i
in the file and save it. Type
IDL> @script_test
IDL runs it as if you had cut and pasted it into the IDL command line. As a result
print,'script_test'
for i = 0,10 do begin
  print,i
endfor
won't work, because you can't use a for ... endfor statement on a single line.

To summarise, we have learned about IDL's programming features and that we should use array operations instead of loops where that is possible. In the next lecture we will learn how to display two-dimensional data sets and how to make use of colour in IDL.


next up previous contents
Next: Lecture 3: More graphics Up: Lecture 2: Programming in Previous: wheretomulti   Contents
John Marsham 2005-04-22