The fitsspec library: Writing XSPEC-ready FITS files Version 0.9 Introduction ------------ The routines in fitsspec are designed to open, write, and close FITS files that contain spectral data, such as line emissivities and continua. There are 5 primary calls, one to open and initialize a FITS file, three to write the four different types of files, and one to close the files. fitsspec uses the cfitsio library extensively to write the files, and assumes that the cfitsio library is in the include-file path during compilation (see the Makefile). Currently, all integer values are int's, and all real values are double although when stored in the FITS file they are both 4 byte values. The four file types are: 0: Line emissivity. These files have one HDU for each set of parameter values. For example, a collisionally ionized plasma would have one HDU for each pair of temperature and density (T,n). Temperatures are given in Kelvin, while densities are in cm^-3. Each HDU contains rows of the line wavelength lambda, and emissivity epsilon, along with errors on each and the ion the line comes from. The upper and lower levels of the ion can also be included. 1: Binned continuum output. This file contains the continuum emissivities on a per process basis. Again, each HDU is a (T,n) pair, but this time the rows contain an evenly binned spectrum in units of photons cm^3 / s / bin, along with each of major continua stored separately: bremsstrahlung, radiative recombination, two-photon, and (optionally) the pseudo-continuum. The pseudo continuum consists of lines deemed too weak to include in the individual line list, and so the are simply binned and put here. 2: Linearly-compressed continuum output. This is the primary continuum output, and again each HDU contains one pair of (T,n). Each HDU then has a row for each atom, giving the total "true" continuum from that atom (summed over all ions of the atom and over the bremsstrahlung, two-photon, and radiative recombination continuum from each ion) and the "pseudo" continuum. When passed to the library, the continuum is in a binned format. However, in this case both the true and pseudo continua are "linearly compressed" by the library code. This means that instead of giving the emissivity in a per-bin form, the spectrum is given only at a few points, in units of photons cm^3 / s / keV. The emissivity between any two points can then be calculated by linearly interpolating between them. The maximum error induced by the interpolation is 1%; this can be set at the top of the fits_spec_write_coco.c file. 3: Similar to #2 except the emissivity is done on a per-ion format instead of per-atom. Installation ------------ In order to be compiled, the cfitsio v2.0.33 library or later is required. This can be obtained from http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html By default, fitsspec assumes that the cfitsio directory is in ../cfitsio/, but this can be changed in the Makefile. To create the library, edit the Makefile to ensure that CFITSIODIR points to the correct location, and then type make. This will compile the library, and the test program fitsspec_test. Running this program will create two files, Test_line.fits and Test_coco.fits. These files can be compared to Compare_Test_line.fits and Compare_Test_coco.fits to ensure that everything went well. NOTE: To compile on a Solaris machine, the libraries -lnsl and -lsocket are required. For Linux or Dec Alphas running whatever Compaq is calling Unix these days, these libraries must be removed from the Makefile. Procedure Calls --------------- The procedure calls are stored in the file fitsspec.h, and are as follows: void fits_spec_init(char *filehead, int filetype, int Nrows, fitsfile **fptr); void fits_spec_write_lines(fitsfile *fptr, double T, double n_e, int nlines, double lambda[], double lambda_err[], double epsilon[], double epsilon_err[], int el_Z[], int rmJ[], int UpperLev[], int LowerLev[]); void fits_spec_write_continuum(fitsfile *fptr, double T, double n_e, int nbin, double Ebin_low[], double Ebin_high[], double pseudo[], double pseudo_err[], double brems[], double brems_err[], double twoph[], double twoph_err[], double radrec[], double radrec_err[]); void fits_spec_write_coco(fitsfile *fptr, int N_Z, int list_Z[], double T, double Ne, int nbin, double E_low[], double E_high[], double pseu_arr[], double cont_arr[]); void fits_spec_close(fitsfile *fptr); Sample Use ---------- Assume we want to write two files, a line emissivity file (type 0) and a compressed continuum file (type 2). Begin by initializing both files as shown: fits_spec_init("MySpec", 0, Nrows, &fptr_line); fits_spec_init("MySpec", 2, Nrows, &fptr_coco); /* Here "MySpec" will be the first part of the filename; _line.fits and _coco.fits will be automatically appended to the name to make the new files MySpec_line.fits and MySpec_coco.fits. The Nrows variable is used if you know how many total HDUs you will be writing in advance. For example, if you'll be calcuating 40 different temperatures at 2 densities each, Nrows = 40x2 = 80. However, Nrows can be set to 0 if the proper value is not known. (Nrows is used to reserve space in the initial binary table which lists all the parameter values used; setting it to zero simply means some space will be wasted in the file.) The fptr variable is a fitsfile pointer, as defined by cfitsio. */ /* These next two routines write the line and compressed continua files. fptr_line and fptr_coco are the same fitsfile pointers from above. The T and n_e variables are the temperature and electron density, respectively. */ while (!done) { fits_spec_write_lines(fptr_line, T, n_e, nlines, lambda, lambda_err, epsilon, epsilon_err, el_Z, rmJ, UpperLev, LowerLev); /* In the line procedure, nlines gives the number of lines in the lambda and epsilon arrays. The lambda, lambda_err arrays give the wavelengths (in Angstroms) and the errors on those wavelengths, again in Angstroms. The epsilon and epsilon_err arrays give the emissivity (in photons cm^3 / s) and the error in the same units. If errors are not available, you can pass a NULL pointer instead and the errors will be set to zero. The el_Z, rmJ, UpperLev, and LowerLev arrays give the elemental Z, the ionization state (in standard roman numeral form, so 1 = I = neutral atom), and the upper and lower levels of the ion, respectively. The upper and lower levels must be defined relative to some other energy level file, and so they may also not be available. If NULL is passed, their values will be set to -1. */ fits_spec_write_coco(fptr_coco, N_Z, list_Z, T, n_e, nbin, E_low, E_high, pseu_arr, cont_arr); /* In the compressed continuum procedure, things get mildly complicated. This is due to wanting to write routines that could be called either from C or Fortran, and the difference in how 2d arrays are handled by these languages. So, here N_Z is the number of elements, and list_Z is an array of the Z values. T and n_e are the temperature and density, and nbin is the number of energy bins. The next four variables, E_low, E_high, pseu_arr, and cont_arr are actually 2d arrays of Z and Bin index. Assume iZ is such that list_Z[iZ] = Z. Then (iZ + iBin*N_Z) is the position of the (Z, BinIndex) element. So E_low[iZ + iBin*N_Z] is the lower edge of the energy bin (in keV) for element Z and position iBin, and E_high[iZ + iBin*N_Z] is the upper (also in keV). The pseudo-continuum from this element and bin is pseu_arr[iZ + iBin*N_Z] in phot cm^3 / s / bin, and the total continuum emission is cont_arr[iZ + iBin*N_Z] in the same units. */ } fits_spec_close(fptr_line); fits_spec_close(fptr_coco); /* This closes each of the files, using the cfitsio close function. */