Ways to compute - {Gumley 3.1-3.6} 1. interactively - that's what we've been doing so far. 2. compile and run function and procedure files (yours or IDL's) Make a file called "my_plot.pro", with a function you call "my_mean" and a procedure you call "my_plot". Place the primary procedure, which usually has the same name as the file (in this case, my_plot), last in the file. FUNCTION my_mean,arr a=TOTAL(arr)/N_ELEMENTS(arr) RETURN,a END PRO my_plot x=FINDGEN(360)*!DTOR y=SIN(x) y_mean=my_mean(y) PRINT,'the mean is',y_mean PLOT,x,y END Note that TOTAL, N_ELEMENTS, FINDGEN and SIN are IDL functions and PRINT and PLOT are IDL procedures. IDL> .R my_plot ; (or .COMPILE my_plot) IDL> my_plot You could instead add the following two lines, at the end of the file, my_plot END and then it will run when you compile it with .R but this only works if you don't need to provide parameter and keyword values for the primary procedure. Note: When writing and testing codes, it's convenient to have two windows open at the same time: one for emacs and one for IDL. Parameters and keywords: Consider a procedure called mypro that is called within another procedure: mypro,a,array,5,array[3],b+3,keyword1=keyword1,keyword2=keyword2 Here, a, array, 5, array[3], b+3 are parameters, which need to be listed in that order. Named variables are passed by reference (a, array) and could have their type, size or value changed by the procedure or function, i.e., they could be used as input or output variables or both. All others are passed by value (5, array[3], b+3) and not changed. The keywords are optional and can be listed anywhere and in any order. See page 119 for ways to check the parameters and keywords that were passed. To check if a parameter was specified and stop if it wasn't: IF(N_ELEMENTS(param1) EQ 0) THEN $ MESSAGE,'param1 not specified' To check if a keyword was specified and to set it to a default value if it wasn't: IF(N_ELEMENTS(keyword1) EQ 0) THEN keyword1=5 Note, the type and size of a keyword is determined on input. Make a file called t.pro with the following statements. PRO t,f=f PRINT,'f is type ',SIZE(f,/TNAME) PRINT,'f has ',SIZE(f,/N_DIMENSIONS),' dimensions' PRINT,'f has ',SIZE(f,/N_ELEMENTS),' elements' PRINT,f END IDL> .R t.pro IDL> t,f=7 IDL> t,f=[-9.,4.,6.32,0.,10.] IDL> t,f='hello' An alternative way to input parameters if running a procedure interactively is to read them in from the keyboard: PRINT,'how many grid points do you want?' nx=0 ; this defines nx as an integer READ,nx PRINT,'how many time steps do you want to run?' nsteps=0 READ,nsteps PRINT,'vmax ?' vmax=0. ; this defines vmax as a floating point number READ,vmax Control statements: (note: only single line statements can be done interactively) IF statements: IF (condition) THEN statement IF (condition) THEN statement1 ELSE statement2 IF (condition1) THEN IF (condition2) THEN statement For example: IDL> i=3 IDL> j=4 IDL> IF (i GT j) THEN PRINT,'i GT j' ELSE PRINT,'i LE j' You can have a block of statements in a function or procedure (but not interactively): IF (condition) THEN BEGIN statements ENDIF IF (condition) THEN BEGIN statements ENDIF ELSE BEGIN statements ENDELSE IF (condition_1) THEN BEGIN statements ENDIF ELSE IF (condition_2) THEN BEGIN statements ENDIF ELSE IF (condition_3) THEN BEGIN statements ENDIF ELSE IF (condition_4) THEN BEGIN statements ENDIF IF (condition_1) THEN BEGIN IF (condition_2) THEN BEGIN statements ENDIF ENDIF Loop statements: FOR i=istart,iend DO statement FOR i=istart,iend,inc DO statement Examples: IDL> f=FLTARR(4) Then, say you want the following: f[0]=5. f[1]=6. f[2]=7. f[3]=8. Instead of typing each one out like this, you can do the following: IDL> FOR i=0,3 DO f[i]=5.+i IDL> g=FLTARR(4,3) Then, say you want the following: g[0,2]=5. g[1,2]=6. g[2,2]=7. g[3,2]=8. Instead, do the following: IDL> FOR i=0,3 DO g[i,2]=5.+i IDL> FOR i=0,9,2 DO PRINT,i Nested FOR loops: IDL> FOR i=0,3 DO FOR j=0,5 DO PRINT,i,j Block loops in functions and procedures: FOR i=istart,iend DO BEGIN statements ENDFOR FOR i=0L,40000 DO BEGIN ; the 0L sets the type of i to LONG statements : since the largest 2-byte integer is 32,767 ENDFOR You can make the default integer be 4 bytes (instead of 2 bytes) by putting COMPILE_OPT IDL2 at the top of all the functions and procedures you write so you won't need to add the "L" to get 4-byte integers. Nested blocked FOR loops: FOR i=istart,iend DO BEGIN FOR j=jstart,jend DO BEGIN statements involving i and j ENDFOR ENDFOR WHILE statements: WHILE (condition) DO statement For example: IDL> i=10 IDL> WHILE (i GT 0) DO i=i-1 Block WHILE statements in functions and procedures: WHILE condition DO BEGIN statements ENDWHILE GOTO statements in functions and procedures: GOTO, label statements label: For example, make the following procedure file (call it test.pro): PRO test i=10 WHILE (i GT 0) DO BEGIN i=i-1 IF (i LE 0) THEN GOTO, cheryl a=1./i cheryl: PRINT,i,a ENDWHILE END The following jump statements can be used instead of a GOTO statement: A RETURN statement can be used in a procedure if continuing with the remainder of the procedure is not desired. A BREAK statement in a FOR or WHILE block will transfer control to the next statement after the block. A CONTINUE statement in a FOR or WHILE block will skip the rest of that iteration step and begin the next iteration step in the block. Example of the WHERE function: IDL> x=FINDGEN(360)*!DTOR IDL> y=SIN(x) IDL> PLOT,x,y IDL> indices = WHERE(y GT 0.5 AND y LT 0.8) IDL> HELP,indices IDL> PRINT,indices IDL> y[indices]=1. IDL> PLOT,x,y IDL> d=DIST(100,100) IDL> SURFACE,d IDL> PRINT,MAX(d) IDL> ind=WHERE(d GT 65) IDL> HELP,ind IDL> PRINT,ind IDL> d[ind]=65. IDL> SURFACE,d Common blocks: these are used to share certain variables among the functions and procedures for which the common block is included. COMMON block_name, var1, var2, var3 The variables in the COMMON block can not also be parameters passed by the procedure or function. Debugging: If an error occurs while running a job and it stops, you can use the PRINT statement to check the values of variables at the time the error occurred, which should help you figure out what the error was. You can also type RETURN, which goes back one procedure or function, or RETALL, which goes to main procedure. Before you re-compile, you need to do a IDL> .RESET to stop the current run. To track down a bug in a code, you can insert the STOP statement and print out the value of a variable and then continue execution by typing IDL> .CONT or IDL> .TRACE Do a IDL> ? STOP to see how this works. For example, replace the PRINT statement in your my_plot.pro file with a "STOP,y_mean". FUNCTION my_mean,arr a=TOTAL(arr)/N_ELEMENTS(arr) RETURN,a END PRO my_plot x=FINDGEN(360)*!DTOR y=SIN(x) y_mean=my_mean(y) STOP,y_mean PLOT,x,y END