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

to see the difference.

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.