IDL Tutorial: Reading and Writing ASCII dataThe simplest sort of data you might receive from an experiment would be simple (x, y) pairs. For example, you might have access to a weather monitoring station that records the date and time, temperature, and windspeed. Ultimately you may wish to plot the temperature vs. date, or temperature vs. windspeed, or who knows what. Often these data appear as ASCII (text) tables, the sort that you can readily view with a text editor. Here's a snippet of a data file containing the spectrum of a fluorescent lamp, coincidentally, one in my office.
There's a single header line describing the columns, in this case, wavelength in nm and signal level in detector counts per second (or something like that). How do we get these data into IDL? The Easy Way The IDLastro package maintained at NASA's Goddard Space Flight Center has a handy tool to read in columnar data; it's a procedure called readcol. Try it out. Copy the text file spectrum.txt into your workspace. readcol, 'spectrum.txt', lambda, signal Readcol seeks out columnar data and loads the data into array variables. Try, print, lambda plot, lambda, signal, xtitle='Wavelength (nm)', ytitle='Counts per second' There appears to be an overall background level in the count rate; that is, ideally "no signal" means 0 counts per second, but instead there seems to be some constant offset in the count rate. Suppose that instrumental background level were uniformly 0.002 counts per second across the spectrum. We can easily remove that background, signal = signal - 0.002 Now it might be useful to save the background-subtracted data. There's a nice tool called writecol that behaves similarly to readcol, which I believe is included in the XIDL distribution produced by Lick Observatory (try googling IDL writecol). The link will take you to my copy of it. It will not be installed by default on the system, you'll have to copy it to wherever you're working, or wherever you keep your personal IDL codes. writecol, 'spectrum_bgsub.txt', lambda, signal And now you should have saved the data for posterity. Formatted Input with Readcol Readcol, by default, looks for numbers, but sometimes you have a column filled with text, names of celestial objects, for example. You can tell readcol to look for text in a given column by including the format statement. readcol, 'data_with_text.txt', x, y, names, format='(f,f,a)' This command tells readcol to look for floating-point numbers in the first two columns, but text (ascii) in the third column. Formatted Output with Writecol Writecol behaves similarly: the expectation is that you are writing columns of numbers. To force an output column to be ascii, writecol, 'data_with_text.txt', x, y, names, fmt='(f,f,x,a)' Notice that the keyword changes from format to fmt for no good reason. The 'x' in the format statement asks writecol to put in a blank space between y and names. Try the following experiment: n = n_elements(lambda) goofy = replicate('goofy', n) writecol, 'goofy_file.txt', lambda, signal, goofy, fmt='(f,f,x,a)' Have a look at 'goofy_file.txt' with a text editor. Then try, readcol, 'goofy_file.txt', x, y, names, format='(f,f,a)' and see if you effectively copy the contents of goofy into names. (Which you could have done by the command names = goofy, but the point here is to practice reading and writing text files!) The Hard Way You will run into limitations with readcol and writecol, in which case you'll have to do things the hard way. The hard way involves writing a for loop to read and write ASCII data one element at a time. Files are handled by assigning them a "logical unit number," or LUN. Nothing to be scared of - the point here is that rather than having the input/output routines deal with filenames like "really_long_filename.txt" all the time, you just assign a number (LUN) to that file, and access it by that number. I'll just give you some simple examples, using the lambda and signal data we already have loaded. Here's an procedure that would read the spectrum from an external file. pro readspectrum, filename, LAMBDA=lambda, SIGNAL=signal Try out this procedure: readspectrum, 'spectrum.txt', x, y Exercise Try writing a similar procedure called "writespectrum.pro" to spit a spectrum out to some arbitrary filename chosen by the user. Check the documentation on openw and printf.
Final Note printf and readf can each take format= keyword arguments to clean up the reading and writing. |
Back to Index
|
Last modified by Jack Gallimore. |