1) SET_PLOT : specify the output device.
Normally it's 'X' that is screen, however, you can specify other devices such as PostScript.
Normal screen is black background. PostScript is white background.
2) DEVICE : access or control abilities a device provides.
2. Variables have be defined somewhere, whether it's in procedure/function or it's in the main program. What it mean by "defined" is that a variable needs to be assigned with a value.
You can feed less parameters to a procedure/function than what the procedure/function expects as long as you don't refer to these missing variables in your code.
eg:
PRO proc1, i1, i2, o1, o2
o1=i1 + i2 ; o1 and o2 are defined within proc1
o2=i1 * i2
END
i1=1 ; i1 and i2 are defined within main.
i2=2
proc1 i1, i2, o1 ; you don't feed o2 when calling proc1
print o1 ; and that's okay to miss o2 as long as you don't refer o2
print o2 ; This is an error because you refer to o2.
; to correct the issue, you need to define o2 either in main or in proc1.
3. multiple statements can be joined together using "&"
eg:
if deyong eq 1 then print, 1 & print , 2 & print, 3
is the same as :
if deyong eq 1 then begin
print, 1
print, 2
print, 3
endif
4. summary about "SIZE" function: return type info of a variable
t1 = size(deyong, /type)
print , "t1 is " , t1 ; undefined
deyong=3L
t1 = size(deyong, /type)
print , "t1 is " , t1 ; 3 -> long int
deyong=4.5
t1 = size(deyong, /type)
print , "t1 is " , t1 ; 4 -> float
5 "POSITION"
Allows direct specification of the plot window.
POSITION is a 4-element vector giving, in order, the coordinates [(X 0 , Y 0 ), (X 1 , Y 1 )], of the lower left and upper right corners of the data window. Coordinates are expressed in normalized units ranging from 0.0 to 1.0, unless the DEVICE keyword is present, in which case they are in actual device units. The value of POSITION is never specified in data units, even if the DATA keyword is present.
Y /\
1.0 |
|
0.0 |________________\ X
0.0 1.0 /
6. PLOT
PLOT, [X,] Y
X : A vector argument. If X is not specified,
Y
is plotted as a function of point number (starting at zero). If both arguments are provided,
Y
is plotted as a function of
X
.
Y :
A vector argument.
7. !PATH.MULTI
In IDL, the !P.Multi system variable can be used to create multiple plots in a display window. !P.Multi is a five element vector defined as follows:
!P.Multi(0) | Contains the number of plots remaining on the page. Start with this as 0 to clear the page. |
!P.Multi(1) | The number of plot columns on the page. |
!P.Multi(2) | The number of plot rows on the page. |
!P.Multi(3) | The number of plots stacked in the Z direction. |
!P.Multi(4) | If 0, plots are displayed from left to right and top to bottom, i.e., the plots are displayed in rows. If 1, plots are displayed from top to bottom and from left to right, (i.e., the plots are displayed in columns). |
To display four plots on a page in two columns and two rows, and the plots should appear in columns, the !P.Multi array should look like:
IDL> !P.Multi = [0, 2, 2, 0, 1]8. COMMON block
Common blocks are useful (a) when there are variables that need to be accessed by several IDL procedures or (b) when the value of a variable within a procedure must be preserved across calls.
Variables in a common statement have a global scope within procedures defining the same common block. Unlike local variables, variables in common blocks are not destroyed when a procedure is exited.
There are two types of common block statements:
1. definition statements
common block_name, v1, v2
2. reference statements.
dxu: duplicates the COMMON block and variable names from a previous definition.
common block_name ; same as common block_name, v1, v2
Variables in IDL COMMON blocks do not actually have names.
The number of variables appearing in the common block cannot change after the common block has been defined. ( Fixed once defined: )
The "first program unit" (the one which gets compiled first : main program, function, or procedure, NOT order who gets executed ) to define the common block sets the number of included variables;
eg:
common block_a , v1, v2, v3 ; there are 3 vars in block.
Other program units can reference the common block with any number of variables up to the number originally specified.
eg:
common block_a , v1, v2 ; number could be less than the original number.
Different program units can give the variables different names.
eg:
common block_a , M1, M2 ; name is NOT important, position IS. so M1 = v1, M2=v2.
9. Array assignment.
a=make_array(2,3, /integer, value=100)
b=make_array(2,3, /integer, value=200)
a) slice operation
b(0,0:1) = a(0, 0:1) ; copy first two element in row 0
b(0:1, 0) = a(0:1, 0) ; copy first two element in column 0
b) copy 1 row or 1 column
b(*,1) = a(*,1) ; copy column 1
b(1,*) = a(1,*) ; copy row 1
c) copy entire array
b(*,*) = a(*,*) ; copy all the rows / copy all the columns
b = a ; same as above
d) shriek array
a = a (*, 0:1) ; array shrieked to first two columns.
e) Playing an array is easy.eg:
a = a + a ; doubling all the elements in an array
a = 3* a ; tripling all the elements in an array
a= a * 3 ; same as above
a= a / 3 ; divide elements by 3
a= a ^ 3 ; square elements
f) print, a ; column-base: print column1 , then print column2, so on.
g) raise initial value of array to 1-base
eg:
a = INDGEN(3)+1
print, a
output:
1 2 3
10. Index variable used in for-statement will still incremented/decremented one more time after for-statement exits.
eg:
for i=2, 1, -1 do begin
j=i & print, i , j
endfor
print, i , j
result:
2 2 ; i, j
1 1 ; i, j
0 1 ; i, j , note : i will be decremented one more time after for-statement.
11. Conversion to string
Use strtrim or string: str
eg:
a=strtrim(" 34 ", 2) ; 2nd parameter 2 means removal of both leading and trailing spaces.
help ,a
a=strtrim(23, 2) ; convert int to string
help ,a
a=string(23.234, format='(f5.2)') ; convert float to string,
help ,a ; f5.2 : 5 digits in total including dot with 2 digits after dot.
a=string(232.232)
help ,a
output:
A STRING = '34'
A STRING = '23'
A STRING = '23.23'
A STRING = ' 232.232'
12. Catch message from IDL code when running IDL code from bash.
eg:
runIDL.sh
#!/bin/bash
idl <<EOF
.run ${mainCode}
7
1
EOF
$ ./runIDL.sh >log 2>> log2
Note: a) Normal prints from IDL commands go to log.
b) Messages from compiling IDL code go to log2.
$ tf log # to monitor the process of IDL code.
13. Logical/Mathematical operations involving array
Basically it applies an operation to each element of an array and generates a new array.
eg:
a=indgen(5)
b=a>2 ; max value (mathematical operation)
c=a ge 2 ; logical operation.
print, a
print, b
print, c
0 1 2 3 4
2 2 2 3 4
0 0 1 1 1
14. Device must close at the end of plotting, otherwise, missing data could happen because these data are not flushed into the graphics if Device is not closed.
So remember to do "DEVICE, /CLOSE" explicitly when needed.
15. Make font better in PS output
aspect_ratio=1.5 ; rectangle shape xsize=9 ysize=xsize/aspect_ratio set_plot, 'ps' !p.font=0 device, filename='fig_better.eps', encapsulated=1, /helvetica device, xsize=xsize, ysize=ysize plot, a, b, xtitle='X Title', ytitle='Y Title' device, /close set_plot, 'x' !p.font=-1
16. where
If "where" doesn't find any match, then what "where" returns is -1L, not an long array.
In this case, using the filter return from "where" actually will copy the last
element of input array to the new array.
eg:
var.a=[1,2,3,4]
fil=where(var.a gt 4) help, fil print, "filter " , fil, n_elements(fil) a.a = var.a(fil)
print , a.a
output:
FIL LONG = -1 filter -1 1 4 4 4 4
This action could be used as a trick to initialize an array with the last element
of an input array.
eg:
a = indgen(10) + 1
b = make_array(10, /int, value=-999)
filt = where ( a GT 3 )
help, b print, b
b = a(filt) ;; What this does is to copy data that satisfies the condition
;; to beginning of array b and truncate tail of b off.
help, b print, b
Output:
B INT = Array[10] -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 B INT = Array[7] 4 5 6 7 8 9 10
16. Create array as 1-based, or 2-based, etc.
Eg:
a = INDGEN(10) + 1 ; 1-based array of 10 elements.
a = INDGEN(10) + 2 ; 2-based array of 10 elements
17. Read a line as string.
; Either way, it works to read a line as string.
READF, iu, a ;READF, iu, form='(a0)', a b=strsplit(a,/extract) ; /extract to return sub-string, w/o it it returns
; an array of the position of the substrings is returned. print, b(-1) ; -1: print last element of an array
18. [] operator
; This is so wrong. Here is the reason why. ; [1, nPos] is 2-element array ; [bias(*,iChan,0), bias(*,iChan,0)] is 60-element array. ; because * represents 30 scan positions. ; What happens is it gets the two values from the first ; two scan positions. I don't know what the initial intent is for. ; but this doesn't seem to do whatever the intent is for. ;;; PLOTS,[1, nPos], [bias(*,iChan,0), bias(*,iChan,0)] ; Change to below to connect first and last ; PLOTS,[1, nPos], [bias(0,iChan,0), bias(nPos-1,iChan,0)]
19. if-else
Doing so to simplify complicated if_else_statement.
if (3 gt 4 ) then $ print, 'big ' $ ; concatenation is NOT allowed else $ print, 'small' & $ ; concatenation IS allowed in else-statement
print, 'small' & $ print, 'small' & $ print, 'small'
20. CD command
The CD procedure is used to set and/or change the current working directory.
CD, new_dir, CURRENT=old_dir ; save current directory inot var old_dir
CD, 'data'
; how to get the current working directory info
IDL> cd , current=old
IDL> print, old
/data/home001/dxu/graphic
IDL> CD, CURRENT=c & PRINT, c ; do it in one line
IDL> cd, 'graphic' ; take relative path
IDL> cd , '../../' ; take relative path
IDL> cd , '/data/home001/dxu ' ; Do NOT have whitespace in the directory string.
% CD: Unable to change current directory to /data/home001/dxu .
No such file or directory
% Execution halted at: $MAIN$
IDL> cd , '/data/home001/dxu' ; Only work when there is NO white-space.
21. Plot map with data
eg:
LOADCT, 39
MAP_SET, 0,0, charsize=1, /label, latlab=-180, lonlab = -90, latdel=30, londel=60
for i =0, num-1 do begin
OPLOT, [x(i)], [y(i)], psym=2, symsize = 5, color=y[i]
endfor
MAP_CONTINENTS, /hires, fill_continents=0, MLINESTYLE=0, MLINETHICK=1, color=210
22. index in where.
a=indgen(30)+1
print, a
print,'---------------'
ff=where(a ge 20) ; ff is index of a.
b= a(ff)
print, ff
print,'====='
print, b
print,'---------------'
ff2 = where (b ge 25) ; ff2 is index of new array b
c= b(ff2)
print, ff2
print,'====='
print, c
23. Set IDL path
Rather than having to type that !path statement every time you start IDL, you can put it in your .idlstartup file.
$ vi ~/.idl/.idlstartup
Just add:
!PATH=!PATH+':'+Expand_Path('./src/idl/coyote/')
$ cd ~/.idl/itt/pref-10-idl_8_0-unix/idl.pref
$ vi idl.pref
You add:
IDL_STARTUP : ~/.idl/.idlstartup
Maybe there's an easier way to do it, but at least you don't have to assign !PATH every time you start IDL.
If you want to access coyote from other IDL instances, then just replace that path with the absolute path.
24. Here is another way thread about setting up IDL path
Adding Programs to Your IDL Path
dxu: Note that this is only to specify the location where IDL can fine a IDL code (*.pro or *.sav). It has nothing to do with a specific subroutine/function within an IDL file.
For example, if you are calling a subroutine called "generateOutput", which is in a.pro file, then you still need to include @a.pro in your main IDL code, so the module "generateOutput" is available to your main code to use. When IDL looks for "a.pro" file, it will go through a list of directories called a '!path' to find it.
1) So to make a module (function/subroutine) available to your main code, you need to use "@" statement to include a IDL code (eg: a.pro) that contains the module.
2) To let IDL find that specific file (eg: a.pro) , you need to specify the location where that file is located in !path, which is used by IDL to find all the IDL code (*.pro and *.sav)
The easiest way to do add a folder to the path that is independent of architecture is the following:
1) Make an IDL startup file. If you have already done this then skip to step 2. You can make an IDL startup file by
a) creating a file called .idlstartup in /path/to folder.
b) within IDL type:
IDL> pref_set, 'IDL_STARTUP', '/path/to/.idlstartup',/commit
where you replace '/path/to/.idlstartup' with the path to the file you created for step 1a
2) Now edit your .idlstartup file to include the following lines to include a folder which for example is located in ~/example/
!PATH=!PATH+':'+Expand_Path('~/example/')
If I wanted to include all sub-directories I would add the following line instead (notice the + sign in front):
!PATH=!PATH+':'+Expand_Path('+~/example/')
You can also do the same actions in your bash or csh profiles without the use of the .idlstartup file as follows:
bash:
export IDL_PATH=$IDL_PATH:+'~/example/'
csh:
setenv IDL_PATH +$IDL_PATH:~/examples
where you can again include all subdirectores by leading the name with a + sign