Synthetic Spectrum Package for IDL

	Design, supervision, contact:
                Prof. Joseph Harrington
                Department of Physics
                University of Central Florida
                4000 Central Florida Blvd.
                Orlando, Florida 32816
                jh@alum.mit.edu

	Programmers:
		John Dermody (Cornell)	Version 0.1	2003-09-16
		John Dermody (Cornell)  Version 0.1.1	2003-12-19
		Joseph Harrington (UCF) Version 0.1.2	2009-11-18
		Joseph Harrington (UCF) Version 0.1.3	2010-06-14

OVERVIEW:
	This set of functions will create a synthetic spectrum and 
	corresponding synthetic sky frame for your use testing spectrum 
	extraction programs.  It has many available options for you to modify, 
	so you can test different aspects of your program.  Its modules 
	simulate sky lines, spatial resolution, spectral resolution, optical 
	distortions, cosmic rays, read noise, photon noise, and bad pixels 
	to an object spectrum created from a black body curve and random 
	emission and absorption lines.  The default values simulate moderate 
	levels of all effects.


The object and sky frames from a default run

INSTALLATION:
	To install, copy the synthspec directory into your idl function 
	directory, where it can been seen by the IDL program.

	To test if your installation is correct, change to a directory where
	you can write files, and run testsynthspec. If the following six lines
	appear on your screen, things are working normally:

	Creating simple test files
	Creating default test files
	PASS - Simple Object Frame
	PASS - Simple Sky Frame
	PASS - Default Object Frame
	PASS - Default Sky Frame

BASIC USE:

	  IDL> objframe = synthspec()

	Synthspec returns a 2D data array containing a computed
        spectrum that has been processed to simulate a number of sky
        and instrumental effects.  The object spectrum is the Planck
        function with random emission and absorption line superposed.
        Sky lines from an OH database appear on a flat background.
        Spectral and spatial spreading are simulated through
        convolution with a Gaussian function.  Imperfect object trace
        and bent sky lines are simulated with sine functions.  These
        data are slightly rotated to simulate imperfect chip
        alignment, and random cosmic rays, bad pixels, Poisson signal
        noise, and read noise are added.

	Each of these steps is a module that can be controlled or turned off by
	keywords to synthspec, as described below.  In addition, the user can
	specifiy certain inputs (levels, spectrum, bad pixels, etc.) and has
	access to several internal variables of the package.

SKY FRAME AND HEADERS:
	If the package is being used for infrared astronomy, the first
	argument of synthspec will contain a corresponding sky frame:

	  IDL> objframe = synthspec(skyframe)
	
	This 2D array is the same size as objframe, and contains the same
	simulations as objframe.  It does not contain the object spectrum, and
	its random cosmic rays and noise values are generated seperatly.
 
	Information from the creation of the array is saved in the FITS header
	info for the sky frame and the object frame.  To access the header,
	set a variable to SKYHEADER or OBJHEADER.
	
	  IDL> objframe = synthspec(skyframe, skyheader=skyheader)
	  IDL> print, skyheader

SIZE:
        NX and NY control the size of the resulting array.  NX defaults to 
	512 and NY defaults to whatever NX is.  For example, to make a 
	rectangular array of size 256x512 type, 

	  IDL> objframe = synthspec(skyframe, nx = 256, ny = 512)

LEVELS:
	The intensity of every element can be modified in the synthspec 
	package.  To change the background level,

	  IDL> objframe = synthspec(skyframe, bklevel = 400)

	Background, object spectrum, maximum values for bad pixels, rays, and
	spectral lines are all measure in ADUs.  The only commands measured
	in electrons are the gain (e-/ADU) and readnoise (e-).  The following
	is a brief summary of the most used level commands.  Each is discussed
	in more depth later.

		BKLEVEL:   The sky background level
		SPECLEVEL: The object's spectrum level
		SKYLVLV:   The maximum intensity of the sky lines
		EMILVLV:   The maximum intensity of the object emission lines
		EPADU:     The gain of the chip.  It impacts signal noise
		RDNOISE:   The readnoise of the chip.
		MAXBADVAL: The maximum bad pixel intensity.
		MAXRAYVAL: The maximum cosmic ray intensity.

MODULE OVERVIEW:

        Sky Lines: Sky lines can be from the OH Database or randomly generated.
		  Set RANDSKYL to randomly generate, or NOSKYL to turn off
		  sky lines. 
	Object Spectrum: A blackbody curve is used as the base of the object
		  spectrum.  Set NOBBCURVE to use a single value instead.
		  Object spectrum lines are always randomly generated; set
		  NOSPECL to not add lines to the object spectrum.
	Distort:  Frames can be distorted by bending the spatial and spectral 
		  directions and rotating the frame.  Setting the
		  keywords NOSMILE, NOTRACE, and NOTILT will turn off each
		  effect respectively.
	Bad Pixels: The same set of bad pixels are in the sky frame and object
		  frame.  Setting NOBAD will give a frame free of bad pixels.
		  Cosmic rays are generated for each frame, and NORAYS turns
		  off this module.
	Noise:	  Signal noise and read noise are added to both frames.  To 
		  turn off all noise, set NONOISE.
       
	For example, to produce a frame with no bad pixels and no noise:

	  IDL> objframe = synthspec(skyframe, /nonoise, /nobad, /norays)

INPUT:
	Four keywords are available for user input.  If a spectrum is set to
	INOBJSPEC, it will be used instead of randomly creating the spectrum.
	However, by default a blackbody curve will be used for the base of
	the object's spectrum unless otherwise noted.  Similarly, INSKYSPEC
	will take a 1D array of the sky spectrum, and will add the bklevel
	to the input spectrum.  For instance, to make a sine function be the
	only source for the object's spectrum:

	  IDL> ny = 512
	  IDL> inspec = sin(findgen(ny)/ny * !pi*20) ^ 2
	  IDL> objframe = synthspec(ny = ny, inobjspec = inspec, $
	                            /nobad, /norays)
	  IDL> tvscl, objframe

	To simulate an real CCD array, FLATFRAME and BIASFRAME accept
	2D arrays of size nx by ny.  At the last step, the frame being 
	processed is multiplied by flat frame and added to the bias frame.
	
OUTPUT:
	To assist with debugging, 2 masks, 7 frames, the object's spectrum
	can be outputted from synthspec.  The object's spectrum (before any
	loss of data from rotation, curvature, noise, or bad values) is
	saved in the SPECTRUM keyword.  To use,

	  IDL> objframe = synthspec(spectrum = spec)

	Perhaps most useful, a bad pixel mask for each frame is derived by
	setting bad pixels and cosmic rays to 0, and all other values to 1.
	The masks can be found in OBJCRMASK and SKYCRMASK.  For instance, you
	may want to see the object frame without any light from bad values.

	  IDL> objframe = synthspec(objcrmask = objcrmask)
	  IDL> tvscl, (objframe*objcrmask)

	If you wish to test your extraction's package background interpolation
	routine, get the original background from BGFRAME.  The object's 
	profile on the CDD array is saved in PROFRAME.  If you need to see
	the object spectrum alone on a frame, use the SPECFRAME keyword.  It
	contains the object frame before sky, noise, and bad pixels were added,
	but after distortions. 

SKY LINES:
	Sky lines can be derived in three ways.  Either the user inputs the
	sky lines through INSKYSPEC, tells the function to look up sky lines
	in the OH database, or randomly generates them.  The OH database
	contains information for sky lines from 10103 to 20063 Angstroms.
	The ohlines function uses the SWAVEL and EWAVEL keywords to set
	the starting and ending wavelength of the CCD chip.  The units of
	both keywords are meters, and they default to [1.5e-6, 1.6e-6]
	If the RANDSKYL keyword is set, sky lines are derived randomly.  The
	number of large sky lines is set by the NUMSKYL keyword. In
	all cases, the resulting spectrum is scaled up to SKYLLVL and 
	added to BKLEVEL.  The OHLOC keyword controls the location on the
	oh lines database.  To use a different database than the one located
	at ohsky/database.txt set the OHLOC keyword to the full path of the
	new database.

OBJECT SPECTRUM:
	Unless the NOBBCURVE keyword is set, the base of the object spectrum
	is a Planck function of temperature TEMP, and wavelengths SWAVEL 
	through	EWAVEL.  The result is then scaled up to SPECLEVEL.  The 
	object's spectrum lines are either user defined in INOBJSPEC, or 
	randomly ggenerated.  The synthspec package can generate emission and 
	absorption lines.  The number of lines is set by the NUMEMIL and 
	NUMABSL keywords respectfully.  The emission line level can also be 
	manually set using the EMILLVL keyword.  The randlines function 
	actually generates 100 times the number of lines set, but uses an 
	inverted distribution so that only 1% of the lines generated are above 
	.1, and 10% are above .01, with the ceiling set at 1.  Whether by user 
	input or randomly the spectrum is scaled so that its max value is 
	EMILLVL.  If the spectrum was randomly generated, absorption lines can
	 be added.

DISTORTIONS:
	To simulate imperfections in the geometries, curvature and tilt
	can be introduced into the frames.  The SMILE keyword controls
	the amplitude of the curve in the spacial dimension.  The TRACEAMP
	and TRACEOSC keywords control the amplitude and oscillations of the
	curve in spectral dimension.  TRACEOSC gives the number of full sine
	oscillations of the trace.  TRACEAMP and SMILE are both measured in
	pixels and give the amplitude of the sine function.  Tilting the 
	array can be used to simulate inconsistencies between the chip 
	dimensions and actual spacial and spectral dimensions.  TILT is the
	angle of this rotation, and it is measured in degrees.  TILT can also
	be used to swap the spacial and spectral dimensions, or invert the
	maximum wavelength side and minimum wavelength side of chip.  To
	do this, simply add 90, 180, or 270 to the tilt angle.
	
	  IDL> objframe = synthspec(tilt = 95)
	  IDL> tvscl, synthspec

	NX and NY still refer to the vertical and horizontal directions
	in the output.  All output frames and masks are also rotated, so
	they are correct with the output.  The package also tries to adjust
	the outputted spectrum to the tilt.  It is able to tell the difference
	between spectrum running vertical and those running horizontal, but
	if the frame is largely skewed, what is possible to get and what
	SPECTRUM shows may not be the same thing.  In these cases the
	SPECFRAME keyword might give you a more useful frame.

NOISE AND BAD VALES:
	Bad pixels are set to be pixels with the same intensity (before noise)
	in both frames.  20% of bad pixels are set to 0 before readnoise, and
	the other 80% are uniformly distributed with a max set by MAXBADVAL.
	Cosmic rays are events unique to one frame.  All cosmic rays are
	additive, with a uniform distribution less than MAXRAYVAL.  The number
	of cosmic ray and bad pixel events are set by NUMRAYS and NUMBAD
	respectfully.  Each event may impact up to 4 pixels, in one of 
	16 different shapes.  The mask is first derived, then bad values 
	calculated.  The bad pixels and cosmic rays are added after
	distortions and before noise.

	By default, signal noise and readnoise are added to the object and
	sky frames.  Signal noise is simulated to be Gaussian, with a 
	variance set to pixel intensity.  Readnoise is calculated as a Gaussian
	with mean 0 and standard deviation of the keyword RDNOISE.  RDNOISE
	defaults to 10.  Signal noise is best controlled by the EPADU keyword.
	To double the signal noise, quadruple the gain.

THE 'FAKE' PIXELS
	To make sure this synthetic data is not confused with real data, the 
	words'FAKE' are added to both the sky frame and object frame at the end
	of the program.

IDL FUNCTIONS:
	synthspec.pro  - driver routine for package
	speclines.pro  - returns a base and spectrum lines
	distort.pro    - spreads, rotates, and bends the array
	adderrors.pro  - returns a frame of bad pixels and noise
	badpixloc.pro  - returns a mask with bad pixel locations
	badpixval.pro  - returns a frame with bad pixel values at locations
	cnvlgauss.pro  - convols the input with a Gaussian
	cosrays.pro    - returns a frame with cosmic ray values at locations
	curveframe.pro - curves the frame 
	initheader.pro - initializes a string array for header information
	ohlines.pro    - returns a 1D array with OH sky lines
	planckfunc.pro - calculates the planck function for given temp and wavl
	randlines.pro  - returns a 1D array with random spectrum lines

EXAMPLE/TEST DATA: 
        In the synthspec/images directory there are four
	example.fits files.  These files provide respresentatives of
	the following four example runs.

	1) Default run:
	  IDL> objframe = synthspec(skyframe, objheader=objheader, $
				    skyheader=skyheader)
	  
	2) No noise or bad pixels or distortions:
	  IDL> objframe = synthspec(objheader=objheader, /nonoise, /nobad, $
			    /norays, /notilt, /nosmile, /notrace)

	3) Swap the spectral and spacial dimensions, make the chip read
	from 1200 to 1250 nanometers, and set the object temperature to 3000K:
	  IDL> objframe = synthspec(objheader=objheader, tiltangle=90, $
			    swavel=1.2e-6, ewavel=1.25e-6, temp=3000)

	4) Add 500 bad pixels and 400 cosmic rays to a frame with 20 e- 
	readnoise, background level at 400 ADUs, and object spectrum level
	at 4000 ADUs
	  IDL> objframe = synthspec(objheader=objheader, numbad=500, $
			    numrays=400, rdnoise=20, bklevel=400, $
			    speclevel=4000)



Examples 2, 3, and 4

OH DATABASE:
	Compiled by Kim Ennico at kennico@ast.cam.ac.uk. 
	Last modified: 4 December 1997.
	Further information can be found at ohsky/database.txt inside synthspec
	directory