<<

Basic IDL tutorial

IDL is a and visualization package that is widely used in the astronomical research community, as well as in a wide variety of other scientific and technical fields. Becoming familiar with the of this will provide you the foundation necessary to gain expertise in any programming language or technical software environment.

(The symbol * denotes sections that were taken largely verbatim from the website http:// nstx.pppl.gov/nstx/Software/IDL/idl_intro.html, written by Bill Davis)

Getting Started Begin an IDL session by typing idl on the command line. Once you have started an IDL session, you can give IDL commands by interactively typing them on the IDL command line or by running a program. We will use both approaches.

When learning IDL, you should make ample use of the online searchable help website http://idlastro.gsfc.nasa.gov/idllibsrch.html (also quickly found by Googling “idl searchable help”) to search for and learn about built-in functions and procedures. You can also retrieve documentation on many IDL functions and procedures from the IDL command line. For example, if you want to learn about the readcol procedure, you would type:

IDL>doc_library, ‘readcol’

Variables and arithmetic (from the website http://nstx.pppl.gov/nstx/Software/IDL/ idl_intro.html, written by Bill Davis)* The simplest thing to work with is scalars.

IDL> x = 3 IDL> y = 2.5 IDL> z = x + y IDL> w = x^y + sin(z) IDL> print, x, y, z, w 3 2.50000 5.50000 14.8829

Square braces can be used to define vectors (1-dimensional arrays):

IDL> v1 = [1, 2, 0] IDL> v2 = [1, 0, 0] IDL> print, "v1 = ", v1 v1 = 1 2 0 IDL> print, "v2 = ", v2 v2 = 1 0 0

Vectors can be added, multiplied, etc.:

IDL> v3 = v1 + v2 IDL> print, "v3 = v1 + v2 = ", v3 v3 = v1 + v2 = 2 2 0 IDL> print, "v1 * v2 = ", v1 * v2 v1 * v2 = 1 0 0 IDL> print, "v1 * sin(v3) = ", v1 * sin(v3) v1 * sin(v3) = 0.909297 1.81859 0.00000

There are other useful operators, such as min and max:

IDL> min1 = min(v1) IDL> max1 = max(v1) IDL> print, "min(v1), max(v1) = ", min1, max1 min(v1), max(v1) = 0 2

Scalars and arrays can be allocated with specific types. Scalar examples:

IDL> x = float(1.3) IDL> sx = fix(x) IDL> lx = long(x) IDL> bx = byte(x) IDL> dx = double(x) IDL> cx = complex(x) IDL> print, x, sx, lx, bx, dx, cx 1.30000 1 1 1 1.3000000 ( 1.30000, 0.00000)

Array examples:

IDL> a = fltarr(5) IDL> for i=0, 4 do a(i) = 2*i IDL> = complex(a) IDL> print, "b = ", b b = ( 0.00000, 0.00000)( 2.00000, 0.00000) ( 4.00000, 0.00000)( 6.00000, 0.00000) ( 8.00000, 0.00000)

Be careful when doing math with integers versus with floats. See the below example of what can happen with sloppy use of integers, and how you can correct it: IDL> a = 2 IDL> b = 3 IDL> print, a/b 0 IDL> a = 2.0 IDL> b = 3.0 IDL> print, a/b 0.666667 IDL> a = 2. IDL> b = 3. IDL> print, a/b 0.666667

Reading Data in From a File There are several data formats that you can easily read in and output in IDL. Common types include columnated text files, binary tables, and fits images. readcol can be used to read in columns of data from text files. This procedure reads each column into a different vector. It works particularly easily on data that are whitespace or comma separated. Practice this with a file I have that gives the relationship between scale factor, redshift, Hubble constant, and lookback time. This file is located in /data03/beth/lookback.dat. Copy it to where you are practicing IDL. Before reading it in with IDL, look at the file by eye to see what it contains. Then read each column of data into a vector with IDL:

IDL>file = “lookback.dat” IDL>readcol, file, snap, a, z, Hz, lookback

If you use readcol as written above, each vector will be type float. Check this by typing:

IDL> help, z

To check that you’ve correctly read each column into the desired vector, you can print the vectors to the screen. You can do them one at a time, as in the examples above. [Try this]. Alternatively, you can print them all to the screen at once in nicely formatted columns:

IDL> forprint, snap, a, z, Hz, lookback, textout = 2 Making Figures You have a lot of control over the appearance of your figures with IDL. There are far too many options for me to review here, so we will cover the bare basics.

If you want to plot redshift versus lookback time from the data you just read in: plot, lookback, z

Try also: plot, lookback, z, thick = 3

You can also plot points instead of lines. The procedure plotsym makes a user defined symbol. The way I use it here creates a filled in circle. Other psyms will yield different symbols. plotsym, 0, 1.0, /fill plot, lookback, z, psym = 8, xtitle = “Lookback Time (Gyr)”, ytitle = “Redshift”, title = “A nice figure”

Try using the keywords xrange and yrange to change the axis ranges of your figure: plot, lookback, z, psym = 8, xtitle = “Lookback Time (Gyr)”, ytitle = “Redshift”, title = “A nicer figure”, xrange = [10.0,2.0], yrange = [0.,10.], /xstyle, /ystyle

Saving Figures to Postscript Files You can save your plots and other images by rendering them to a postscript file instead of to an X window. Basically, you set your plotting area to be a file, then change the device to be a postscript device, and close that device when you are done:

IDL> set_plot,'PS' IDL> device, filename='Lookback.ps’ IDL> plot, lookback, z, psym = 8, xtitle = “Lookback Time (Gyr)”, ytitle = “Redshift”, title = “Millenium II simulation snapshot times” IDL> device, /close IDL> set_plot,'X'

Great tips on IDL postscript output (as well as many other things) can be found at http://dfanning.com. You can usually view postscript files on a Linux machine by using the command “evince”:

>evince lookback.ps

Writing IDL Programs You should not use IDL interactively for most calculations. You can spend an hour typing in commands, IDL crashes, and you lose everything. Or you can spend an hour typing in commands and realize you made an error in the first step of your calculation and need to redo everything. By placing your IDL commands in a program, its easy to ask IDL to repeat the same calculation on many images of the sky. Its also easy to correct mistakes (i.e. debug your code) and then let IDL do all of the hard work of repeating your calculations for you.

We could package up the IDL commands we learned already into a program called lookback_plot.pro. We could open up a file with this name using , and edit the file to read something like: pro lookback_plot

; Read in data file = “lookback.dat” readcol, file, snap, a, z, Hz, lookback

; Check that data were read in correctly forprint, snap, a, z, Hz, lookback, textout = 2

; Make a figure showing redshift vs lookback time set_plot,'PS' ; Create user defined symbol plotsym, 0, 1.0, /fill device, filename='Lookback.ps’ plot, lookback, z, psym = 8, xtitle = “Lookback Time (Gyr)”, ytitle = “Redshift”, title = “Millenium II simulation snapshot times” device, /close set_plot,'X'

RETURN END

You can run this program when in IDL by simply:

IDL>lookback_plot If you edit your procedure, then you need to tell IDL to recompile it:

IDL>.r lookback_plot IDL>lookback_plot

Manipulating Vectors of Data

1. You can identify the maximum value of a vector using the MAX()function:

maxHubble = MAX(Hz) print, maxHubble

You can do this all on one line with: print, MAX(Hz)

You can calculate the total of all values in a vector using the TOTAL() function: totHubble = TOTAL(Hz)

(The total of that particular vector is a meaningless number; this is just a demonstration).

You can calculate the total number of elements in a vector with the function n_elements(): numvalues = n_elements(Hz)

2. The randomu function provides a convenient way to generate random numbers. For example to randomly generate a single number between 0 and 1: randN = randomu(seed,1)

To randomly generate 10 numbers between 0 and 4.5: randN = 4.5*randomu(seed,10)

To randomly select one value of the Hubble constant as f(z): randindex = numvalues*randomu(seed,1) randHubble = Hz[randindex] 3. The where function in IDL is a very powerful tool to for vector manipulation, in particular to determine which element() of a vector (for example, which of a list of dark matter halos) satisfy a particular condition.

For example, to figure out which redshifts in your data file correspond to lookback times greater than 10 Gyr: oldindices = where (lookback gt 10.0) oldredshifts = z[oldindices]

In the above example, oldindices is a list of numbers that gives the elements (indices) of the lookback vector that are greater than 10.0. Print out oldindices and check that its values make sense to you.

4. You can use a list of vector indices to investigate a subset of the data at hand. For example: plot, z[oldindices], lookback[oldindices]

5. If you’ve already started your plot with a plot statement, you can overplot additional data or lines using the procedure oplot.

Data Structures

In astronomy, we often have datasets where we have the same types of information about a large set of objects. For example:

• a long list of stars, where for each star we know the position, apparent brightness, and measurement uncertainty on the brightness • a set of dwarf galaxies, where for each dwarf galaxy we know its distance, position, luminosity, measurement uncertainty on luminosity, etc. • a list of simulation snapshots, where for each simulation snapshot we know the redshift, Hubble constant at that time, and the lookback time (much like the lookback.dat file you already have).

A is an efficient way of storing and manipulating such information. You will be using data structures extensively in your research.

Copy the MWdwarfs_2013.fits file from my /data03/beth/ MWdwarfs_2013.fits directory. This file already contains a data structure, where each element of the data structure contains a set of information about one dwarf galaxy.

MWdwarfs = MRDFITS(“MWdwarfs_2013.fits”,1)

To see what information is stored in this structure: print, TAG_NAMES(MWdwarfs)

Each piece of information, such as name of distance, is called a “tag”. A tag can contain a scalar, a vector, or even an array. For this particular structure, each tag contains a scalar value for a given element of the data structure. Try showing this using the help procedure, e.g.: help, MWdwarfs.name print, MWdwarfs.name help, MWdwarfs[0].name print, MWdwarfs[0].name help, MWdwarfs.d help, MWdwarfs[0].d

Because each element of the structure is a different dwarf galaxy, the structure itself is what gets indexed if you want to select a particular object or set of objects. Let’s say you wanted to investigate all dwarf galaxies closer than 50 kpc: close = where (MWdwarfs.d le 50.0) forprint, MWdwarfs[close].name, MWdwarfs[close].Mv, textout=2 plotsym, 0., 1.0, /fill plot, MWdwarfs[close].Mv, MWdwarfs[close].rhalf, psym = 8, $ xtitle = “M!DV!N”, ytitle = “half light radius [pc]”

Use IDL to automatically select the dwarf galaxy that you will study. Calculate the luminosity of your dwarf in units of Solar luminosities. Calculate the half-light angular size of your dwarf in units of arcminutes.

Hint: The names of the dwarf galaxies may have hidden white spaces that you need to get rid of before asking “where” MWdwarfs.name eq the name of your dwarf. The function STRCOMPRESS provides one approach to removing white spaces from a string.