Here are some tools I wrote in the IDL language from Research Systems, Inc.
IDL recently (around version 6.2) changed how it uses and stores defaults. Things that used to be manageable no longer are. The right way to do this was to have an .Xdefaults which set the appropriate values for whatever display you were currently using (of course ssh completely breaks Xdefaults because programs don't know what display they are running on). The new IDL scheme of storing things in files in .idl means customizing settings based on display is impossible.
As far as I can tell, the only thing to do is to call a routine from .idl_startup that is full of getenv()'s and spawn,'xdpyinfo...' that figures out where it is running and has hardcoded values for graphics device type and number of colors (or reads these from environment variables).
Given that such severe changes happened in a minor release (between 6.0 and 6.2), I imagine that it will change more soon.
The routine determines what the depth of the graphics device is and defines a system variable !col that you use to specify colors. For example, plot,x,y,color=!col.green will generate a plot that is green or as close to green as possible in the current color table. All the colors defined in a normal rgb.txt are available, e.g. oplot,x,y,col=!col.darkseagreen3.
The new system variable also emulates a color table on 24-bit graphics devices. To emulate a 32-element color table using IDL's "rainbow" color table (number 39), run col_define,39,32. The color table elements are stored in a vector !col.ct. Plot using the color table like this: for i=0,31 do oplot,x[i,*],col=!col.ct[i]. The output will be identical whether you are using 8-bit or 24-bit graphics.
Here is an example.
It should now work for 16-bit graphics too. IDL with 16-bit graphics under XFree86 is very strange. Actually, it is even weirder than I thought: see comments in code. The handling of 16 bit graphics has changed IDL 5.5. I have not tested the code to see what it does now.
In IDL on 24-bit graphics devices, tvscl makes grey plots. The routine mytvscl makes color plots on a 24-bit graphics display, with the option of picking a color table and number of colors by passing options. All options and behavior of tvscl are (should be) operational.
Try
tvscl,dist(100),0
mytvscl,dist(100),1
mytvscl,dist(100),2,ct=1
mytvscl,dist(100),3,n=8
Find the phase of a complex number (oddly, atan(z) did this for
complex z in IDL 5.4; it doesn't in 5.5)
function cmphase,z,degrees=degrees
If n_params() eq 0 then begin
print," usage: cmphase(z[,/degrees]"
return,0
endif
phase = atan(imaginary(z),float(z))
if keyword_set(degrees) then $
phase=phase/!pi*180
return,phase
end
Square root of complex numbers.
function ccsqrt,z ;; This function calculates the square root of the elements in the ;; array z. Moreover, if z is approximately smooth, then the ;; returned array will be approximately smooth. This is done by ;; arbitrarily choosing which root to return. In any case, the ;; square of the value returned will equal z. r = abs(z) th = cmphase(z) nz = n_elements(z) ;; easy part is the sqare root of the amplitude sr = sqrt(r) ;; we want the phase to vary approx continuously and go above 2pi or ;; wherever it needs to go. ;; find phase jumps. p = round((th[1:nz-1]-th[0:nz-2])/(2*!pi)) pt = total(p,/cumulative) th = th-[0,pt]*2*!pi sz = sr*exp(complex(0,th/2)) return,sz end
Convert number to string padded with zeros to a certain length.
Useful for generating file names in a loop,
as in openw,unit,basename+zpstring(index,3).
function zpstring,num,lngth
;; Returns the integer num in a string with the length padded with
;; zeros on the left for a total length of lngth
if not ( (size(num))(1) eq 2 and (size(lngth))(1) eq 2 ) then begin
print,' usage: astring=zpstring(num,lngth)'
print,' e.g.: print,zpstring(2,3)'
print,' 002'
return,''
endif
ndig = floor(alog10(num))+1
if ndig gt lngth then begin
print,'zpstring: input ',strtrim(string(num),2), $
' is longer than length=',strtrim(string(lngth),2)
return,''
endif
if lngth gt ndig then begin
s1 = string(bytarr(lngth-ndig)+48B)
endif else begin
s1 = ''
endelse
s2 = strtrim(string(num),2)
return,s1+s2
end
What value of i gives array[i] closest to value?
function findindex,array,value
if n_params() eq 0 then begin
print,' usage: z=findindex(array,value)'
return,-1
endif
dummy = min(abs(array-value),indy)
return,indy
end
Make idl beep. Useful when running long analysis. IDL> LongRoutine & bleep,n=3 will make the terminal beep three times when the routine returns, letting me know that I should pay attention to it.
pro bleep,n=n
;; this beeps. Duh.
if n_elements(n) eq 0 then $
n = 1
for i=1,n do begin
print,string([7B]),format='(1A,$)'
wait,0.8
endfor
;; it is less useful if terminal is set to visual bell
return
end
Put a list in random order. This implementation is actually slightly clever. Or maybe there are just a lot of dumb ways to implement this. (OK, I just read that this is the Fisher-Yates algorithm as implemented by Durstenfeld. But I swear I thought it up myself.)
pro randomize,a
n = n_elements(a)
if n lt 1 then begin
print,' usage: randomize,SomeArray'
print,' Elements of SomeArray are placed in random order'
return
endif
for i=n-1,1,-1 do begin
;; pick at random one of the first i elements
indy = floor(randomu(seed)*(i+1))
;; move this element to the ith position
tmp = a[i]
a[i] = a[indy]
a[indy] = tmp
endfor
end
Empty the keyboard buffer. Useful to run before you wait for keypress, because get_kbrd(1) will take a key press from the buffer, if there is one; it does not necessarily wait for a new key press.
pro empty_keyboard_buffer
repeat begin
ans = get_kbrd(0)
endrep until ans eq ''
return
end
Last updated Dec 13 2007.