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.
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.