Nstars Documentation

This document set should thoroughly cover all aspects of Nstars data administration, from Data reduction to web site publication.

TABLE OF CONTENTS:

The Nstars Project - Overview

The Nearby Stars 'Nstars' Project here at ASU consists of
a survey of 3597 nearby stars, as defined by parallax data from the hipparcos catalog.

The goals are to:
1) Obtain classification resolution spectra of all stars from our 4 observatories.
2) Reduce images into 'pixel list' format using IRAF
3) Flux Calibrate and or Rectify the 'pixel lists' at the UNIX command line
4) Posted onto the web site for immediate release of data to the public
5) MK Classify all stars and store data
6) Derive Fundamental Parameters using simplex and store data
7) Obtain chromospheric activity indecies and store data
8) Design and maintain a working database and webserver to provide data to the world
9) Publish

This document covers every step except Data Acquisition at the telescopes.

Data Reduction

Raw CCD images come in in FITS format, and need to be reduced into 'pixel lists'
for classification, web service and deriving other information from the spectra.

We use IRAF to perform the data reduction
and each observatory has it's own reduction routine.

Pipeline Overview

From Fits Image:
1. Stage1 reduction
Image collection and collation. Bias, Dark and Flat correction. Bad Pixel Fixing.
2. Aperture Extraction
Each spectra image has it's spectrum 'extracted' by defining the region where
the spectrum is imaged on the CCD chip and summing up across the dispersion axis.
in IRAF - these extracted data are '.ms.imh' files and are only 2-dimensional/
3. Calibration and Spectra Combining
The '.ms.imh' files are wavelength calibrated using emission line, arc-lamp spectra
to develop a function to map pixel to wavelength. This is done with IRAF's
IDENTIFY, REIDENTIFY, and DISPCOR functions. Once each .ms.imh file is
wavelength calibrated, spectra images taken of the same star (usually 3) are summed
and combined to form one spectrum of a star.
4. FITS header info collection
The '.ms.imh' file still contains FITS header information recorded at the
telescope at the time of observation. We collect the 'important' fields
(UTSTART, UTEND, AIRMASS, ST, HA, NAME, IMAGE TYPE, etc...) and store these
data to put in the pixel file in the next step.
4. Pixel file generation
The final IRAF '.ms.imh' spectrum is printed out, in ASCII format, to a file
using IRAF's LISTPIX utility. This is the raw ".cal" file. After the LISTPIX
finishes, we print the FITS header info we collected to a ".head" file. The last
step is appending this ".head" to the end of the ".cal" file.
(why is it called ".head" if it's appended to the end of the file???)
5. Rectification
Early-type stars have their .cal files rectified using xmk1x 's 'autorectify' utility
versions as early as xmk14 can rectify, but only versions later than 16 will read
and preserve the FITS info at the bottom of the pixel file. This is how the .rec
is created.
6. Flux Calibration
Late-type stars have their .cal files flux calibrated using routines specific
to the observatory and possibly an observation date. The flux routines
are C programs which utilize observations of Spectrophotometric Standards
from each observatory.

A Few Notes on IRAF

IRAF, or Image Reduction and Analysis Facility, it a tough install and has a steep
learning curve. A good start is "A Beginners Guide to IRAF" which is available
in paper copy from R.O.G. or available online at http://iraf.noao.edu

All of our work is done using a hodgepodge of IRAF scripts (*.cl files). The basic
reduction procedure within IRAF is the same for all observatories, but there are
nuances that require special scripts for each observatory. They can be identified
by the first few characters of the .cl filename. For example, doing an 'ls CTIO*.cl' will
bring up most, if not all of the .cl files for the CTIO reduction pipeline.

For a quick start in IRAF:
Log in as 'iraf2' and run (in /home/iraf2) 'startiraf'. This will open a window with a cl>
prompt - your IRAF command line, and an imtool window for image displaying.
The IRAF command 'display [filename]' will display a .fits file
The IRAF command 'help' will give help on commands - "help display" is a good thing to try
From there, good commands to learn would be implot, imhead, imstat, ccdproc, hselect, apextract...
then on to the complete NOAO package, specifically the twodspec package for apextract.

IRAF also has enabled a lot of file overwrite protection by default.
the script cleanup.cl (explained later) will take care of removing most files
that will cause a reduction script to error out trying to overwrite a file,
but every once in a while, especially if a reduction process is prematurely
terminated for one reason or another, the reduction scripts will attempt to
write out to a file that already exists and fail. Simply remove the offending
file - use IMDELETE on .imh files!! and restart the task
that errored out.

With this basic knowledge, you can try reducing a data set with the very verbose
instructions below


Rectification

All Stars with spectral types K0 and earlier get rectified using XMKxx. Currently
The newest version of XMK is xmk19 - and it is the recommended version to Rectify
Nstars. xmk19 will read in the footer at the end of the pixel list, preserve
the footer in the ".rec" files, and will also preserve any extra extensions provided
to the filename, (ie. hd123.ctio.cal -> hd123.ctio.rec.) Previous versions of xmk will
not perform these functions and your rec files, albeit scientifically correct, will
either be named improperly or have their footer truncated.

With that said, Rectification is quite easy:

Rectification is the action of taking a raw spectrum and normalizing it's wavelength-
dependent curve. Rectified spectra look "flat" and have no information about the
actual flux of the star. Rectification becomes useful during classification mostly.

To rectify, you need Dr. Gray's xmk19 program.
xmk19 should be located in a shared executable path - such as /usr/bin - so all that
is required to run the program is typing "xmk19" at the Unix shell.
xmk19 will prompt for a file name, and when given, displays the spectrum.

Rectification is performed on raw .mb, .hb, or .cal files.
Don't rectify .nor, .nfx or .flx files, although xmk19 will allow you to do so.

After your .cal (or .mb or .hb) file is loaded, clicking on "Autorectify" will give
you a good start on rectification. A few continuum points are chosen by the program
and a rough, piecewise defined curve is applied to the spectrum. The Autorectify
routine is (and will always be) rough, so care has to be taken to correct any
mistakes the algorithm may have made.

During rectification, new rectification points are placed with the mouse Left Button,
and points are removed with the right mouse button.

The most important points are the endpoints - especially
on the blue end. Placing a point on the end of the spectrum on the blue side prevents
the last couple of points from "flapping around".

After you are satisfied with the curve you have placed on the spectrum, click "<-Accept"
and the spectrum is rectified and saved with the extension ".rec".
Normally, this extension is fine, but for DSO spectra, we rename these to ".r18" and ".r36" for
rectified ".hb" and ".mb" files respectively. Without this catch, we would have
duplicate filenames.

Normally, one ends up with a directory full of .rec files that must all be renamed to
.r36 or .r18. To do this quickly, I created a script called "chngext" that lives in
/usr/local/bin. This prompts for two extensions - a from extension and a to extension-
and copies (not moves) files matching the (*.from) extension to (*.to).
For example, if you had a directory with 20 ".rec" files, one could rename these to
".r18" files with:

[flip@nstar temp]$ chngext
Enter _from_ file extension (no wildcards)>.rec
Enter _to_ file extension >.r18
cp -i file1.rec file1.r18
cp -i file2.rec file2.r18
.
.
.
[flip@nstar temp]$ rm *.rec

One could also be quite slick and do some extreme BASH:

[flip@nstar temp]$ for file in *.rec ; do mv $file `echo $file | sed 's/\(.*\.\)rec/\1r18/'`; done;

Or, one could use some perl on the command line:

[flip@nstar temp]$ perl -e 'for (@ARGV) {($nf = $_) =~ s/.rec/.r18/; `mv $_ $nf`;}' *.rec

whatever you choose.

Flux Calibration

Like rectification, Flux Calibration is done on the raw '.cal' or '.mb' files
output from IRAF reduction.

Flux calibration programs are written in C by Dr. Gray and utilize spectrophotometric
standards observed at different airmasses per observatory
The effect is to flux-calibrate the spectrum, that is, correct for atmospheric and instrumental
wavelength-dependent, low frequency features that appear in raw .cal files.
While a .cal file still has a CCD response curve and atmospheric absorption effects in the spectrum
(which is a function of both wavelength and airmass), a .nor, .nfx, or .flx has a corrected
flux density which is characteristic of the actual star itself. In the case of .flx files,
the units of the file are actual ergs/cm^2/s/Angstrom.
Each Observatory, and in some situations each observatories' run, has a different
program to flux files. All programs are located in /home/flip/FluxCalibration/ .
Here is a brief list of the current programs to use to flux a given spectrum file:
DSO:
dso5flx
acts on '.mb' files
called with Johnson photometry ( -j switch - provide V and B-V ) creates .nfx and .flx
called with Stromgren photometry (-s switch - provide v, b-y, and m1) .nfx and .flx
called with no photometry ( -n switch) creates .nor file
optional '-c' switch to incorporate 'g-band dip' correction (used on spectra observed after November 1, 2002
CTIO:
CTIOfeb01/ctio6aflx , CTIOjun01/ctiorun2, and CTIOdec02/ctiorun4
works on '.cal' files
called with Stromgren photometry or none - no switches
ctio6aflx used ONLY on CTIO's feb01 run
ctiorun2 used ONLY on CTIO's jun01 run
ctiorun4 used ONLY on CTIO's dec02 run
SO90:
SO3flx
works on '.cal' files
called with Stromgren photometry or none - no switches
There is talk of splitting up the runs, as we did for CTIO, but
currently, there is only one program - to be run on all spectra from SO

fluxall1_0

There is a Perl script "fluxall1_0" (or a newer version)
which lives in /usr/local/bin/ that is designed to create flux calibrated spectra files
given all files in the current directory having a certain extension.

The normal procedure, to flux any set of '.cal' files (or '.mb' files - for DSO) is
to change to the directory where the files live and run 'fluxall1_0'.
fluxall1_0 will prompt first for a password for the MySQL database
( see connect_readonly_to_database() in the
Nstars Perl Function Library )

Then it will prompt for an extension to match - usually '.cal'.

Then it will prompt for the COMMAND to run to flux. This is the FULL PATH
of the program to flux a file with. For example, if you are fluxing DSO data you
may enter "/home/flip/DSO/DSOflx5/dso5flx"
(although people who don't like to type may sym-link to this from the current
working directory and put in the link's name as the command to run.)

fluxall1_0 will list all the files in the directory with the specified extension
attempt to get a hipparcos # for the file - given the filename, and proceed to
look up photometry that it can use to flux with. It handles the parameter passing
and switches based solely on the name of the program used to flux with, so only
dso5flx and ctiorun4 are implemented so far.

fluxall1_0 also handles files it's not sure how to flux. Either by not finding
the star in the Nstars Database (no hip#) - either because it was named weird or not an Nstar
(in which case it lacks photometry) or for some other reason. If this happens
fluxall1_0 attempts to copy the file into a directory called './whats_left'
This directory has to be created manually before fluxall1_0 is run, and created
in the working directory.


Detailed Reduction Procedures per Observatory

Below are reduction procedures for each Observatory's data.
The general reduction procedure stays the same for all, but small
differences in the images from each observatory has required
different scripts to handle each observatory's data.

In a perfect world, there would be one script to reduce
spectroscopic data from ANY observatory, and it would
be a simple task to use "setinstrument" or some other
package parameter to decide specific courses of action
for different observatories.

DSO Reduction

FITS images from DSO are currently saved to ZIP at the observatory,
and copied to disk on campus. Reduction has primarily
been done on nstar.phys.appstate.edu - but the relevant
scripts can probably be run on another machine with IRAF with
few changes.

FITS header information is either not present in these images
or a rudimentary header is present. Storage of FITS header
information is still in development at the observatory.
There is no 'ccdtype' fitscard in the header, so the type
of image is encoded in the filename itself:

PMxxxxx.fit - 'PM' file - an image of a spectrum
ACxxxxx.fit - 'AC' file - a comparison image of the FeAr lamp (new lamp)
NCxxxxx.fit - 'NC' file - a comparison image of the old NeAr lamp (old lamp)
CPxxxx.fit - 'CP' file - a comparison image of the very old KrAr lamp - prior to 1996/7
DKxxxxx.fit - 'DK' file - dark frame (almost always a 300 sec dark)
BIxxxxx.fit - 'BI' file - bias
FLxxxxx.fit - 'FL' file - flat
DFxxxxx.fit - 'DF' file - dark frame for flat (matches flat exp time)

Data from DSO always comes from the same CCD camera - so bad pixel
masks and other CCD dependent calibration can remain the same, but
the resolution of the imaged spectrum can change and therefore
the reduction procedure - especially in wavelength calibration.

To simplify things, a naming convention was used: "mb" is "medium blue"
and "hb" is "high blue" (3.6A and 1.8A resolutions, respectively).
They can also be identified by there grating ruling factor -
(600g/mm and 1200g/mm respectively)

Since most of the reduction procedure is the same for both image
resolutions, This procedure will follow the beginning steps
(setup and stage1) that are in common with the two resolutions, then
branch off into two separate reduction procedures per resolution

Relevant Files:
unwrap.cl
n2stage1.cl, nstage1.cl(old)
autoextall.cl, bextall.cl(old)
n2wave.cl(hb), n2mbwave.cl(mb) (nwave.cl nmbwave.cl (old))
n2final(hb), n2mbfinal.cl(mb) (nfinal.cl, nmbfinal.cl (old))
fixbad2.cl, fixbad.cl(old)
DSO_BADPIX.dat
make_DSO_reduclist.cl
make_DSO_reduclist.pl
fluxall1_0
dso[12345]flx (see ~flip/FluxCalibration/DSO/*)

-----------------------
Instructions:

all commands enclosed { } are iraf commands
all commands enclosed in ` ` are unix commands

1) Log In
Using nstar.phys.appstate.edu:

a) Log in as iraf2
You can either log in an run the X-session as iraf2 or you
may 'su' to iraf2 in your current X-session - but if you
do the later, you must do an "xhost localhost" when logged in as
the same user that is currently running the X-seesion to allow
iraf2 to open windows on the X server running under your
ownership.
Simply open a shell and type "xhost localhost" before doing
an `su iraf2`.

b) If you aren't there already, cd to iraf2 's home:
`cd ~` or `cd /home/iraf2`
This needs to be done, as IRAF reads startup scripts from
iraf2's home directory.

c) type `startiraf` and IRAF should start - opening a cl> window
and an Ximtool window.
If you get an error like "Xlib: connection to ":0.0" refused by server"
- see b). You need to logout as iraf2, type "xhost localhost" and try again

2) Copy FITS files:
/usr/local/fits2 is the directory where the FITS files live that are about
to be reduced. Usuially there are files left in here from the
previous reduction - some must stay and others must be deleted.
Of course, the pm files and ac files in there now are data from
the last reduction and must be deleted; darks and biases as well
But, flats and the dark flat (df) must remain - unless a new set
is available. In that case, you can delete them and replace with
a new set of flats.

This process of cleaning out /usr/local/fits2/ for a new night's
worth of data is simple. change directory to /usr/local/fits2 and
simply type `./clean` to run the cleaning script. It deletes everything
that needs to be deleted and leaves everything that shouldn't be.
Flats need to be manually deleted if there is a new set to replace them

Copy files off of zip from night's run into /usr/local/fits2
It's good practice here to make sure ALL images are there by
checking the log for that night. Sometimes nights end up
spanning 2 zip disks, and you won't have a complete set of
images for the night.

3) cleanup.cl
Since I always forget to do it at the end (when it Should be done,
run the IRAF script cleanup.cl:
{ cl < cleanup.cl }
This cleans up temporary files left by IRAF from the previous reduction. It
will avoid many problems that can end your reduction prematurely and force
you to start over.
Again, This step is the LAST step in the process, but to run it as the first
step also is a safe bet.

4) unwrap.cl
In IRAF, run the script 'unwrap.cl'
{ cl < unwrap.cl ' }
This is a small script that fixes the PMIS 4.1 unsigned
integer representation. To see it's effect, try
displaying an image that is unfixed and compare it
to an image that has been 'unwrapped'.

This is safe to run on any image - unwrap does a check to
find the mean pixel value of the image. if it's well above
background value (say, 2000 to 3000 counts) then it assumes
that the image needs to be unwrapped.
Old images taken with PMIS 3.x need not be unwrapped, but running
this script on those files is also safe.

5) n2stage1.cl
in IRAF, run 'n2stage1.cl'
{ cl < n2stage1.cl }
This script does "stage 1" reduction on all the images:
collects biases and averages them into a master bias "BIAS.imh"
collects darks, subtracts bias from each, and averages them into a master dark "DARK.imh"
collects flats, subtracts DF (dark flat) from each,
   averages them into a combined flat,
   boxcar smooth and response correction into a master flat "FLAT.imh"
collects image files ("PM" files), scaled dark correction for each one, flat corrects each one
   and a bad pixel mask is applied to each one (fixbad2.cl is called internally)
make_DSO_reduclist.cl is called internally, interactively creating a reduce.lst file
for the 'final' script. It prompts the user for the comparison image for any set of
images. This is easy if FITS headers were gathered at the telescope, tedious and hard
if there are no headers. (see next section)

6) reduce.lst
If things went well in n2stage1.cl, you should have 2 files created automatically for you
"reduce.lst" and "reduce.[date].auto". The latter is done for backup purposes, the former
will be used in the 'final' script below. This file describes which PM files to sum together
(they are the same star) and what comparison "AC" or "NC" image to use to calibrate.

If FITS header info was present in the images for stage1, then most of this information can
be inferred from the headers themselves. If not, it's probably going to be necessary
to write this file out by hand.
Either way, a check against the logs should be done to make sure this file is correct.

reduce.lst file is in this format:

hd123456 4 ac0001
pm0001
pm0002
pm0003
pm0004
hd654321 2 ac0002
pm0005
pm0006

This is basically:

starname #images comparison
image1
image2
.
.
imageN
starname #images comparison
image1
image2
.
.

Once you are satisfied with the accuracy of this file, describing how to sum
your images and which comparisons to apply, you can move on in the reduction
process

7) autoextall.cl
autoextall.cl is an interactive script, so you must define and run it as a task:
{ task $autoextall=autoextall.cl }
(you can put this line in your login.cl script if you wish)
Then it can be run simply by typing:
{ autoextall }
at the cl> command prompt

autoextall will show a trace along one of the rows of the image,
identifying which columns the spectrum appears.
Unlike this script's earlier version - 'bextall' - This script
will pretty much automatically define a correct aperture and background
regions for your extraction of the spectrum. Occasionally (say, about 1/30 images)
autoextall will see a cosmic ray or another star on the traced row and fit the aperture to it
accidently, so care must still be taken.
For the most part, though, this script allows a human to very quickly define extraction apertures
for a large set of images.

Each pmxxxx.imh file that autoextall processes creates a matching .ms.imh file
which is the 2D image of the spectrum summed along rows (across the dispersion)
and background subtracted.
These files are now ready to be summed together (for the same star)
and wavelength calibrated.

autoextall screw-ups: how to recover
autoextall can die on you, or you could make a mistake that may cause
you to start over where you left off or re-extract a few images that
you were not satisfied with the first time you ran it.
The good news is that you do not have to duplicate work.

autoextall creates a file called PMfiles.lis which tells autoextall
which files to process. Normally, this file is created automatically, simply
populated with all the pm files available from the night's data.

To restart a died autoextall, or to re-extract a few files that weren't extracted
properly the first time (ie. cosmic ray, etc) There are a few simple steps:
1) open /home/iraf2/PMfiles.lis in your favorite editor (emacs) and, following
the same format that's there already, put the names of the pm files
you wish to re-extract and remove the names of the ones that you don't want
autoextall to re-process.
2) open /home/iraf2/autoextall.cl in your favorite editor, and TEMPORARILY
comment out these lines by placing a '#' as the first character on the line:

delete database/*
delete PMfiles.lis
files pm????.imh > PMfiles.lis

This makes sure that autoextall doesn't overwrite your PMfiles.lst file with
a pre-generated one, nor does it delete any info about successfully extracted spectra.

3) Allow yourself to replace the old .ms.imh files that were bad (if you are re-extracting)
You have a choice here - either `imdelete` the pmxxxx.ms.imh files from the cl> prompt
BEFORE running autoextall again, or type 'YES' into the prompt when the plotting window
asks if you wish to "Clobber existing file pmxxxx.ms.imh". Either way, if you
do not do this, autoextall will die from an 'overwrite protection error'
when it tries to overwrite your old, bad .ms.imh with a new one - you must
give IRAF explicit instructions to clobber files.

Now, when autoextall is run, it will use your PMfiles.lis file instead of creating
it's own.
Be sure to put the lines back into autoextall.cl after you have finished - or you may
wonder why your reduction is not working properly the next time you try to run autoextall
If all this is a bit hairy for you, you can always do an { imdelete *.ms.imh }
and re-run autoextall without any edits. You will be extracting all the files again.


This is where the procedure differs between DSO600 'mb' files and DSO1200 'hb' files!


DS600 '.mb'

8) n2mbwave.cl
like autoextall, n2mbwave must be run as a task:

{ task $n2mbwave=n2mbwave.cl }
{ n2mbwave }

n2mbwave will do a preliminary wavelength calibration to find an approximate
dispersion function
The function defined by this task will be used to
attempt to automatically identify lines in every comparison spectrum
taken throughout the night.
Running this task before n2mbfinal eliminates the tedium involved with manually identifying
the same spectral lines repeatedly for different AC files for different stars.

Running n2mbwave runs the iraf task 'identify' which brings up a trace of the first AC file in the night's data set.
Mark 3 or 4 bright lines on the image according to the printout of the "DSO600" FeAr spectrum.
(This printout should be available next to nstar.phys or in the observing briefcase)
To mark a line, center the cursor over the line and press 'm'. You will be given the pixel position
of the line and prompted to enter a wavelength. Enter the wavelength marked on the printout
. Do this for 2 or 3 more lines, then hit 'f' to see the current function fit to the points that
were marked and the scatter from the function. It should be a very tight fit - if not, one or more
of your lines were misidentified.

When you are satisfied with the 3 or 4 lines marked, hit "l" to have n2mbwave identify the rest of the
lines specified in the file /home/iraf/iraf/noao/lib/linelists/dsofear_mb.dat
bringing the total number of identified lines up to 20 to 30 - a good sample
to come up with a final dispersion function
hit 'f' once again to check the residuals - delete any extremely deviant points
with 'd' and re-fit by hitting 'f' again. Once you are satisfied with this function
hit 'q' to save dispersion function and exit.

Review of the commands to 'identify':
'm' - mark a line with a wavelength (marked by mouse cursor)
'l' - using marked lines, interpolate the rest of the lines from linelist file
'i' - delete all lines - start over
'd' - delete one line (marked by mouse cursor)
'f' - fit function to points marked (residuals)
'f,l' - ('f', followed by 'l') show actual function fit to points
'f,j' - ('f', followed by 'j') show only residuals to normalized function
'q' - quit and save dispersion function.

9) n2mbfinal.cl
Again, n2mbfinal.cl must be run as a task:

{ task $n2mbfinal=n2mbfinal.cl }
{ n2mbfinal }

n2mbfinal uses the 'reduce.lst' file created in step 3 - n2stage1.cl.
it is good practice to once again check this file and make sure it is
correct and relevant to the data being reduced.

running n2mbfinal will once again bring up the trace of the comparison image
as it does a call to IRAF's 'reidentify' task. Using the same commands
as described in n2mbwave, identify any new lines and / or delete any misidentified
lines. You will notice that the lines, for the most part, will be automatically
identified from the work done in step 7, but there will always be problems that require
human intervention.
Be prepared for this task to completely screw up line identification and for you to manually
identify all lines again for each image. But hopefully, this won't happen. Viva la IRAF.

For each comparison you check and hit 'q' on to save the dispersion function, it will calibrate
each pm file for each star (described in reduce.lst file) with the function defined by the comparison
image. It then will combine all the pm files for the star into a single .imh file named after the
'starname' field in the reduce.lst file.
as a last step, it will do a 'listpix' on the .imh file to produce an ASCII file with 2 columns:
wavelength and intensity. This file is written to /usr/local/mbout with the filename standard "starname.mb"
The task also collects any FITS header information that may have been present in the origional FITS file
(stored in the iraf .ms.imh files) and prints it out to a .head file.
This file is, as a final step, appended to the .mb file as a footer. and the .head file is removed

This task is notorious for error exits due to overwrite protection.
if the task is stopped abruptly, a .head, .mb, or starname.imh file may be present
and not deleted, causing an overwrite error in future runs.

Just remove the offending files (remember IMDELETE for IRAF .imh files!!!) and
try your script again.

After all is complete, you should have a handful of '.mb' files in /usr/local/mbout.
These are reduced files.... ready to be flux calibrated and/or rectified.
Congrats! You got through the hardest part.

Be sure to run cleanup.cl to finish the reduction


DSO1200 '.hb'

8) n2wave.cl
like autoextall, n2wave must be run as a task:

{ task $n2wave=n2wave.cl }
{ n2wave }

n2wave will do a preliminary wavelength calibration to find an approximate
dispersion function
The function defined by this task will be used to
attempt to automatically identify lines in every comparison spectrum
taken throughout the night.
Running this task before n2final eliminates the tedium involved with manually identifying
the same spectral lines repeatedly for different AC files for different stars.

Running n2wave runs the iraf task 'identify' which brings up a trace of the first AC file in the night's data set.
Mark 3 or 4 bright lines on the image according to the printout of the "DSO1200" FeAr spectrum.
(This printout should be available next to nstar.phys or in the observing briefcase)
To mark a line, center the cursor over the line and press 'm'. You will be given the pixel position
of the line and prompted to enter a wavelength. Enter the wavelength marked on the printout
. Do this for 2 or 3 more lines, then hit 'f' to see the current function fit to the points that
were marked and the scatter from the function. It should be a very tight fit - if not, one or more
of your lines were misidentified.

When you are satisfied with the 3 or 4 lines marked, hit "l" to have n2wave identify the rest of the
lines specified in the file /home/iraf/iraf/noao/lib/linelists/dsofear_hb.dat
bringing the total number of identified lines up to 15 to 20 - a good sample
to come up with a final dispersion function
hit 'f' once again to check the residuals - delete any extremely deviant points
with 'd' and re-fit by hitting 'f' again. Once you are satisfied with this function
hit 'q' to save dispersion function and exit.

Review of the commands to 'identify':
'm' - mark a line with a wavelength (marked by mouse cursor)
'l' - using marked lines, interpolate the rest of the lines from linelist file
'i' - delete all lines - start over
'd' - delete one line (marked by mouse cursor)
'f' - fit function to points marked (residuals)
'f,l' - ('f', followed by 'l') show actual function fit to points
'f,j' - ('f', followed by 'j') show only residuals to normalized function
'q' - quit and save dispersion function.

9) n2final.cl
Again, n2final.cl must be run as a task:

{ task $n2final=n2final.cl }
{ n2final }

n2final uses the 'reduce.lst' file created in step 3 - n2stage1.cl.
it is good practice to once again check this file and make sure it is
correct and relevant to the data being reduced.

running n2final will once again bring up the trace of the comparison image
as it does a call to IRAF's 'reidentify' task. Using the same commands
as described in n2wave, identify any new lines and / or delete any misidentified
lines. You will notice that the lines, for the most part, will be automatically
identified from the work done in step 7, but there will always be problems that require
human intervention.
Be prepared for this task to completely screw up line identification and for you to manually
identify all lines again for each image. But hopefully, this won't happen. Viva la IRAF.

For each comparison you check and hit 'q' on to save the dispersion function, it will calibrate
each pm file for each star (described in reduce.lst file) with the function defined by the comparison
image. It then will combine all the pm files for the star into a single .imh file named after the
'starname' field in the reduce.lst file.
as a last step, it will do a 'listpix' on the .imh file to produce an ASCII file with 2 columns:
wavelength and intensity. This file is written to /usr/local/hbout with the filename standard "starname.hb"
The task also collects any FITS header information that may have been present in the original FITS file
(stored in the iraf .ms.imh files) and prints it out to a .head file.
This file is, as a final step, appended to the .hb file as a footer. and the .head file is removed

This task is notorious for error exits due to overwrite protection.
if the task is stopped abruptly, a .head, .hb, or starname.imh file may be present
and not deleted, causing an overwrite error in future runs.

Just remove the offending files (remember IMDELETE for IRAF .imh files!!!) and
try your script again.

After all is complete, you should have a handful of '.hb' files in /usr/local/hbout.
These are reduced files.... ready to be flux calibrated and/or rectified.
Congrats! You got through the hardest part.

Be sure to run cleanup.cl to finish the reduction


Steward Observatory Reduction

As usual, all scripts for processing Steward Observatory data are located in the mess of files in /home/iraf2/ unless otherwise specified
Relevant Files:
SO90stage1.cl
SO90autoextall.cl
SO90final.cl
make_reduclist.cl
make_reduclist.pl
SO90_BADPIX_TRIM.dat
fluxall1_0 - located in /usr/bin
SO3flx - located in /home/flip/FluxCalibration/SO90/SO3flx/ (may have new version - check with ROG)
----------------------------------
Quick instructions:

all commands enclosed { } are IRAF commands
all commands enclosed in ` ` are Unix commands

1. Copy fits files from the night's run into /usr/local/fits2/Chris_90in

2. Run SO90stage1.cl at cl> prompt in IRAF.
{ cl < SO90stage1.cl }

3. relieve fixpix problem (if necessary):
when SO90stage1.cl locks while doing fixpix, go to
unix prompt, kill the process "x_proto.e", type { cl> flpr }
a couple of times into IRAF, then cut an paste remaining
fixpix lines from Script directly onto the cl> prompt.
(explained in more detail below & in comments in script)

4. define task SO90autoextall
{ cl> task $SO90autoextall=SO90autoextall.cl }

5. run SO90autoextall
{ cl> SO90autoextall }

6. run make_reduclist.cl to create rough reduce.lst file
{ cl> cl < make_reduclist.cl }

7. Review and edit reduce.lst file from that night's logs to finalize reduce.lst

8. define as task SO90final
{ cl> task $SO90final = SO90final.cl }

9. run SO90final { cl> SO90final }

11. cd to output directory where .cal files were written to
This is set in SO90final.cl as /usr/local/SO90out

12. use XMK1x to rectify any early types and make .rec files

13. run the program fluxall1_0.pl within .cal directory to make flx, nfx or nor files. (or use SO3flx manually)
` fluxall1_0.pl `
(fluxall1_0 is not yet set up to flux SO90 data... this is a "TO DO")
(if it has not been done yet, simply edit fluxall1_0 to allow SO3flx to be called,
and set up all switches appropriately. I beleve SO4flx (newer version) is implemented)
Check with ROG for best fluxing program and see the fluxall1_0 code.

14. if satisfied with reduction, clean up IRAF directory with cleanup.cl
{ cl < cleanup.cl }


Full Description:


The SO90 reduction pipeline starts with the basic "stage1" reduction
which includes BIAS, & FLAT corrections, bad pixel correction.

SO90stage1:

the script SO90stage1.cl takes care of all this in one script:
first 12 lines cleanup old files - avoids overwrite errors

(I opted NOT to subtract dark frames - they are very few counts above bias)

biases are then collected, listed and combined.

flat files are collected & listed

objects are collected & listed (obj0001.imh -> )

comparisons are collected & listed. (hear0001.imh -> )

I wish to pause here and complain about Steward Observatory's FITS headers.
when it comes to comparison images.
- This has been fixed in images after M030311
Usually, a imhead or hselect test
will pick out "imagetype" to determine type of image (dark, bias, comp, etc).
Well, both flats and comparisons have imagetype = 'comp', which confuses
ccdlist. Flats should have imagetype = 'flat' or something.
This is the reason for the strange 'hselect' line instead of an
easy 'ccdlist'
Also, comparison files have "hear" written into the OBJECT field,
which should be (in my opinion) the object name that should use
the comparison file. This makes association between object files
and their comparison easier. Right now, comp files have IMAGETYPE='comp'
and OBJECT='hear', which is redundant. You will see this problem
re-appear in "make_reduclist.cl"


First pass through 'ccdproc' removes bias, & trims flats, objects and comparisons.

Master flat is created
imcombine()'s the trimmed, bias corrected flats
Boxcar is done to create FS - a "high pass filter" over the flat - this is the response curve
Original flat is then divided by FS, to take response curve out of flat.

Second Pass through 'ccdproc' flat corrects objects & comparisions with this Master flat file.

Fixpix is run using "SO90_BADPIX_TRIM.dat" as the bad pixel mask.
I spent way too much time trying to circumvent a parser problem
in iraf with fixpix. First, one call to fixpix would not complete -
only gets about 60 lines through the @list. So I decided to try to split
the @list into 50-line chunks. fixpix still locks after the first call
finishes, so I manually kill the IRAF process "x_proto.e", and continue
by cutting and pasting the fixpix calls directly into the cl> prompt
until all the @lists are processed, and all object files are run
through fixpix. See the comments in SO90stage1.cl for more info.

Cleanup is done, and Stage1 is complete

------

SO90autoextall.cl

This is an aperture extraction routine that pretty much automatically
finds your aperture, sets backgrounds, traces, and sums up to create
2-d extracted spectra. (.ms.imh files) It must be run as a task due to being an interactive
script. (you can always define tasks in you login.cl - if you wish)

dispersion axis is defined for Steward Observatory (should be done with setinstrument)
but never hurts to double-set

database is cleaned - ready for night's data.

object files listed

variables defined

While loop extracts every object file, one at a time.

preliminary apertures are found & adjusted

using the values determined by the first calls to apfind
and apresize (lines 39 & 40), we can define the background
regions automatically. this is done by reading the database
aperture file through some brute force.

the variable "bg_sample_string" is then created and the
parameter "apdefault.bsample" is set to this.

the database file is deleted, and a new apfind and apresize
is done to create the new database file with the new background
aperture.

This complex background aperture definition is done to compensate
for variable seeing - normally backgrounds are set and left alone
for the entire night. But if the seeing gets bad, then the
spectra can bleed into the background - this avoids that.

and interactive apall is called at the end to give the user
visual conformation that the correct aperture was found and background
apertures are set correctly. I usually get about 1 object per night
that has a cosmic ray on the column I define my aperture on - and apfind
will think this is the spectrum. This is the only reason why this
task is interactive.

-------------------

make_reduclist.cl

This script attempts to use fits header information to
create what we call a "reduce.lst" file, which describes
how separate spectra are to be combined and which comparison
to use to calibrate.

a reduce.lst file usually looks like so:
(example from Steward Obs. Apr 8, 2001 run reduce.lst)

2_Hya 2 hear0001
obj0001
obj0002
Zet_Leo 2 hear0002
obj0003
obj0004
.
.
.

This means 2_Hya has 2 images to combine (obj0001 & obj0002) and
should use hear0001 to calibrate.... etc.

the reduce.lst file lives in the same directory as
all the scripts and drives the next script, SO90final.cl

This would work great in theory, but there is no way within
fits headers (other than UT or RA&DEC) to associate comparisons
with objects automatically. So this script assumes sequential
comparisons, and a unique comparison image for every series
of objects. This, of course, isn't true (double stars, for example,
are 2 diff objects with the same comparison) so it's necessary
to open it up in your favorite editor and make sure it's correct.

It is nice, though, not to have to type the entire file out
for 100+ images.

Without going into too much depth on how it works, it creates
a file called "nameinfo.dat" in which a Perl script iterates
through (make_reduclist.pl) to create reduce.lst

-----------------

SO90final.cl

This is the script that calibrates each spectra file, combines them,
fills out the .cal file footer information from the fits headers, and
creates the output .cal files.

The first thing you will notice is the mess of variable declarations..
most of these are for the footer info. This is actually quite a small
script if the code that populates the footer was taken out.

The script is well commented, mostly because I inherited the script
from Dr. Richard Gray and had to understand it myself before altering
it into the mess it is today. I will try to resolve some issues
that may cause confusion.

On line 71, you will notice a call to apfind on the first comparison "hear0001".
I use this to set a wide aperture using apedit()'s graphical interface. I just
center an aperture, and open it wide (about 1/2 to 3/4 the width of the image).
This allows me to get a better signal on low-signal comparisons.

Then (line 76) I call 'identify' to create the reference solution (refSO90)
which is the "preliminary fit".

Next is a confusing if-ladder inside a for loop inside a while loop.

The while loop controls the entire reduce.lst file and (if reduce.lst is
correctly written) the call to fscan() in the while loop will only
read a line describing the object name, comparison file, and number of images.

The for loop iterates for each image of the object (from 1 to k, where k
is the number of images taken of the object) and calibrates each one.
It also collects a running total of airmasses to average later, and a total
exposure time.

the if-ladder decides which image you are currently processing,
and handles special cases:
if it's the first image in the series:
reidentify the comparison interactively
get the start date & time of series from fits header

if it's NOT the first of the series
reidentify the image non-interactively, using solution from first image

if it's the LAST of the series:
get the end date & time of the series


Edit the fits header with the comparison info (REFSPEC1), do a dispcor to calibrate.
(line 223)

Depending on the number of images in the series, we combine with an average or sum.

Most of the data reduction is done up to now, what's left is forming
the footer. Each if-clause checks to see if a value was read from the
fits header, and if not, prompts the user to enter a value.

at line 415, the script gets interesting again.
The footer is printed out to a .head file through a series of printf()'s
the .cal file is created through the call to listpix(),
and the .head file and .cal file are concatenated. to create the final .cal file.

(.head was chosen before we realized the info goes at the end of the file.)

From here, we go back to the while loop and process the next object.

----------------------

Use of XMK19 (or whatever version you have) is out of scope of this document,
but I'll mention that rectification of the .cal files is the next step, only
for completeness.

------------------

The final step is the flux calibration, which is done at the Unix prompt, outside
of IRAF. I use a Perl script I developed called "fluxall1_0.pl" to do this.

to flux calibrate a single .cal file, we use Dr. Richard Gray's flux calibration
program for Steward Observatory called "SO3flx" which calibrates given
an airmass (for .nor output) or optional v, b-y, and m1 photometry for .flx
and .nfx output.

`SO3flx [v] [b-y] [m1]`

I couldn't find the source (SO3flx.c) on my machine - but I can
get it from Dr. Richard Gray if needed.

airmass is easy to get:
`grep "#AIRMASS" `

I wrote a small script called fluxall1_0.pl which gathers all the information
for the command line and fluxes an entire directory by itself. I am including this
file although I know it won't get photometry through the MySQL database interface.

I can open the port up for remote queries (outside appstate.edu) if necessary, though.
and you will have to edit the subroutine "connect_to_database" to put an appropriate username
in.

--------------------

I believe that's all.
Be sure to read through the .cl scripts and enjoy the comments.


CTIO Reduction

All script files for reducing CTIO data live in /home/iraf2/ unless otherwise specified.
Relevant Files:
CTIOstage1.cl
CTIOautoextall.cl
CTIOfinal.cl
CTIOcleanup.cl
make_CTIO_reduclist.cl
make_CTIO_reduclist.pl
CTIO_BADPIX_TRIM.dat
fluxall1_0 - located in /usr/bin
ctiorun[1234] - located in /home/flip/FluxCalibration/CTIO

------------------

Quick Instructions:

all commands enclosed { } are IRAF commands
all commands enclosed in ` ` are Unix commands

1. Copy fits files from the night's run into /usr/local/fits2/Chris_90in

2. Run CTIOstage1.cl at cl> prompt in IRAF.
{ cl < CTIOstage1.cl }

3. relieve fixpix problem (if necessary):
when CTIOstage1.cl locks while doing fixpix, go to
unix prompt, kill the process "x_proto.e", type { cl> flpr }
a couple of times into IRAF, then cut an paste remaining
fixpix lines from the script directly onto the cl> prompt.
(explained in more detail below & in comments in script)

4. define task CTIOautoextall
{ cl> task $CTIOautoextall=CTIOautoextall.cl }

5. run CTIOautoextall
{ cl> CTIOautoextall }

6. run make_CTIO_reduclist.cl AND make_CTIO_reduclist.pl to create rough reduce.lst file
{ cl> cl < make_CTIO_reduclist.cl }
` ./make_CTIO_reduclist.pl`

7. Review and edit reduce.lst file from that night's logs to finalize reduce.lst

8. define as task CTIOfinal
{ cl> task $CTIOfinal = CTIOfinal.cl }

9. run CTIOfinal { cl> CTIOfinal }

11. cd to output directory where .cal files were written to
This is set in CTIOfinal.cl as /usr/local/CTIOout

12. use XMK1x to rectify any early types and make .rec files

13. run the program fluxall1_0.pl within .cal directory to make flx, nfx or nor files. (or use ctiorun manually)
` fluxall1_0 `

14. if satisfied with reduction, clean up IRAF directory with cleanup.cl
{ cl < CTIOcleanup.cl }


Full Description:


The CTIO data reduction procedure varies only slightly from the SO90
procedure. This is because Steward Observatory was first to provide
us with images with FITS headers, and CTIO follows even more closely
to an NRAO 'standard' way of imaging spectra.
Therefore, the similarities in the datasets prompted a basic copy of the SO90
procedure with appropriate edits for CTIO data.

Copy Files:
Not much to be said here. Copy FITS files to reduce into /usr/local/fits2/CTIO
Be sure permissions are correct, and try renaming to .fit or .fits (lowercase)
if problems arrise reading the directory


CTIOstage1:

Stage1 reduction takes care of bias subtraction and flat correction of all the
frames, along with removing trim and biase sections

It also performs some bad pixel fixing, which is a big problem with CTIO. The
CCD entrance window (or some other part of the optical path) is quite dirty, and
there are quite a few very dark parts of the field. There has been work to correct
for these defects in the flat - by forcefully removing them from the responce flat
to better preserve them in the 'flattened flat'. Most correcton is still done in the
bad pixel mask, though. Concensus is that we would rather have falsified continum through
The dust covered area, than a flase spectral line. - Yes, these dust motes leave
a very convincing profile of a strong spectral line - one is famous for living
on or near the G-band.

Anyway, the bad pixel masks are CTIO_BADPIX*. trim means they are ment for images
that have been trimmed (so it matches the image dimentions and reference points)
and any dates on the filenames are specific for that set of data from CTIO.
If you have a new set of data from CTIO, do check the bad pixels and dust motes
manually and make a new pixel mask - but re-reducing old data with these
masks should be fine.

Since this script was inhereted from the SO90 script, it also inhereted
the 'fixpix' bug. See the SO90 reduction script above for instructions
on how to break out of a 'fixpix' lock and resume.

---------

CTIOautoextall:

(pretty much the same as SO90)

--------

make_CTIO_reduclist:

(same as SO90 except `./make_CTIO_reduclist.pl` is run afterwards manually to
create reduce.lst. Stop is in place so user can manually check intermediate file "nameinfo.dat"
Which the .pl script utilizes.
Recognize difference between .cl and .pl scripts (iraf and Perl).
Note commented out call to .pl script within .cl script

----------------

CTIOfinal.cl:

Same as SO90 - without comparision signal problem.

This script works quite well for CTIO.

Still should discuss resuming after screw-ups. Same as DSO procedure to resume

---------------

Rectification:
cd to /usr/local/CTIOout and work on the .cal files - rectify them with xmk1x
remember to rename to .ctio.rec if neccessary

-------------

Flux Calibration

Fluxall1_0 handles CTIO data. Each run should have it's own program to flux with
So far, there have been 4 runs, therefore there are 4 fluxing programs

Feb 2001 run -> /home/flip/FluxCalibration/CTIO/CTIOfeb01/ctiorun1
Aug 2001 run -> /home/flip/FluxCalibration/CTIO/CTIOaug01/ctiorun2
Jun 2002 run -> /home/flip/FluxCalibration/CTIO/CTIOjun02/ctiorun3
Dec 2002 run -> /home/flip/FluxCalibration/CTIO/CTIOdec02/ctiorun4

Use the appropriate one if re-reducing data from these runs. For new data
you really should observe a spectrphotometric standard and create a new
routine.


The SO90 reduction procedure is much more descriptive, and although it
is targeted to the SO90 data, much of the info in the documentation
is relevant to the CTIO reduction routine. Please have a look at it.


DDO Reduction


PushToServer - Putting Spectra Files up on the Web

After you have created all your .rec, .nfx, .nor, & .flx files and you
are satisfied with the set of files you have - freshly reduced, you need
to get them up to the web site so they can be seen when queried.

Manually, this step involves FTPing each one of the files into it's
proper directory on stellar, then inserting a new row into the table SpectraFiles
on the MySQL server. This can be a tedious task - even for just a few spectra files
(This is, however shown as an example in Sample SQL Commands
A Perl script called 'PushToServer.pl', (located in /usr/bin) takes care of this
for you.

First, cd into the directory where all your new spectra files are that need to go
to the web server.
Second, make a backup of all these files - easiest way is to create a temp directory
and just 'cp *' into it. The reason for this is that PushToServer deletes files off
the local directory as it FTPs them to stellar. This is done so if an error happens
in the middle of a push, then you can resume PushToServer in the current directory
and not worry about pushing the same files twice

Then, simply type "PushToServer" into the command prompt and the script begins.
It will prompt for an Observatory (with a list of possibilities) to associate
these new files with.

PushToServer simply takes the list of files in the current directory, attempts
to get a hipparcos # for each one based on the filename, and given success,
it will FTP the file to the appropriate Observatory's directory, update the
SpectraFiles table on the MySQL database, and remove the file from the current dir.

If all worked well, you can go to http://stellar.phys.appstate.edu/spectra/ and
see the newly reduced spectrum from the Nstars site.


Data Storage

Introduction

All scientific data for the Nstars Project is divided into
two groups: Spectra Files and The MySQL Database.
Spectra Files are reduced pixel lists of spectra - usually
having the extensions .cal, .mb, .hb, .rec, .nfx, etc...
The MySQL database holds all other data that's NOT
actually a spectra. This includes astrometry, photometry,
classifications, derived fundamental parameters, and many other tables
for data either derived here at ASU, or published previous to the project.

Spectra Files

Nstars

Reduced Nstars spectra files all live on the web server (stellar.phys.appstate.edu) in the directory "/var/SPECTRA", but the website is coded to use the sym-link from "/home/iraf2/public_html" which ultimately points back to the SPECTRA directory.
The SPECTRA directory is divided into sub directories for each Observatory
  1. /1200g - Dark Sky Observatory
    • /hb - DSO 'hb' files
    • /rec - DSO rectified 'hb' files
  2. /600g - Dark Sky Observatory
    • /mb - DSO 'mb' files
    • /pfx - DSO '.rec' '.nfx' '.flx' '.nor' files
  3. /SO90 - Steward Observatory 90" (VATT) "
    • /cal - raw '.cal' files
    • /proc - '.nor' '.nfx' '.flx' and '.rec' files
  4. /ctio - CTIO 1.5m
    • /raw - raw '.cal' files
    • /flx - '.nor' '.nfx' '.flx' and '.rec' files
  5. /toronto - David Dunlap Observatory
    • /4200 4200A center spectra
      • /raw - raw '.cal' files
      • /rec - '.rec' (and .nfx in the future) files.
    • /4700 - 4700A center spectra
      • /raw - raw '.cal' files
      • /rec - '.rec' (and .nfx in the future) files.

you will also notice extra directories, spectra files, and
Perl scripts laying about this directory. Most of the spectra
files you find outside this directory structure were pulled out
because they were not Nstars and most of these were put in "/others".
Most of the Perl scripts in these directories were "one time runs" and
the code should be well documented as to exactly what it does
inside the script itself.
These are the spectra which display on the web site in the "Nearby Star Spectra"
area. Having a spectrum come up for display on the web is not as simple
as copying it into it's appropriate directory - a reference to the file
must be inserted into the MySQL table 'SpectraFiles'. This can be done
manually or with the Perl script 'PushToServer' . See MySQL Basics and
MySQL Database Data - SpectraFiles for more information

Standards

All Standards are located in the general documents directory
of the website - /usr/local/apache/htdocs/Standards/. See
the website layout description for
more information.


MySQL Database Data

This section here is meant to cover the types and location of Nstars Data
within the MySQL server on stellar.phys.appstate.edu.
For more information on how to access the data on the MySQL server through
a local client - see MySQL Basics

All "relational" data for the Nstars project is held on the MySQL
database server living on stellar.phys.appstate.edu, and is stored
in the database "Nstars".

This is why, as will be explained in depth later, one must specify

mysql> use Nstars;

as the first command on the MySQL command line, or using the '-D' switch when
starting the MySQL client to connect to stellar.phys.appstate.edu:

%mysql -h stellar -u flip -p -D Nstars



The tables within the Nstars Database:

NstarsList

The Primary Table.
Holds basic Nstars data from Hipparcos catalog.
In theory (but not practice) all hip# fields in all other tables are
Foreign keys into the hip field of this table.
Basically, what this means is that you are `not supposed to' insert
hip #'s into other tables without them first existing in this table.
In practice, though, there is no restrictions against this.
 
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| hip      | int(11)     |      | PRI | 0       |       |
| HD       | varchar(10) | YES  |     | NULL    |       |
| BD       | varchar(10) | YES  |     | NULL    |       |
| RA_2000  | varchar(11) |      |     |         |       |
| DEC_2000 | varchar(11) |      |     |         |       |
| PI       | varchar(8)  | YES  |     | NULL    |       |
| hip_V    | varchar(8)  | YES  |     | NULL    |       |
| hip_BmV  | varchar(8)  | YES  |     | NULL    |       |
| SpT      | varchar(12) | YES  |     |         |       |
| pi_err   | varchar(10) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+ 

ChromAct

Holds derived Chromospheric Activity indecies
+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| hip           | int(11)      |      |     | 0       |       |
| name          | varchar(20)  | YES  |     | NULL    |       |
| DoubleFlag    | char(2)      | YES  |     | NULL    |       |
| Observatory   | varchar(20)  |      |     |         |       |
| S_mw          | varchar(6)   | YES  |     | NULL    |       |
| log_R_HK      | varchar(6)   | YES  |     | NULL    |       |
| ChromActClass | varchar(20)  | YES  |     | NULL    |       |
| Priority      | decimal(3,1) | YES  |     | NULL    |       |
+---------------+--------------+------+-----+---------+-------+  

ClassBatchInfo

Holds 'pipeline' information for each Nstar - basically, how far we've come with each star
The column "Batch" is quite important - it tells you that a hip # is included in
A classification batch, and what that batch is called.
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| hip        | int(11)     |      |     | 0       |       |
| name       | varchar(10) | YES  |     | NULL    |       |
| Classified | char(1)     |      |     | N       |       |
| Batch      | varchar(50) | YES  |     | NULL    |       |
| Published  | char(1)     |      |     | N       |       |
+------------+-------------+------+-----+---------+-------+ 

Classifications

Holds new Nstars Classification info.
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| hip         | int(11)      |      |     | 0       |       |
| name        | varchar(20)  |      |     |         |       |
| GCG_SpecTyp | varchar(50)  | YES  |     | NULL    |       |
| notes       | varchar(200) | YES  |     | NULL    |       |
| batch       | varchar(20)  |      |     |         |       |
+-------------+--------------+------+-----+---------+-------+  

Notes

Holds any notes that will appear on the web site.
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| hip   | int(11) |      | PRI | 0       |       |
| note  | text    | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

Observations

Holds information for every observation of Any Nstar
+----------------+--------------+------+-----+---------+-------+
| Field          | Type         | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| hip            | int(11)      |      |     | 0       |       |
| name           | varchar(20)  | YES  |     | NULL    |       |
| ObsvTime_Start | datetime     | YES  |     | NULL    |       |
| ObsvTime_End   | datetime     | YES  |     | NULL    |       |
| Airmass        | varchar(20)  | YES  |     | NULL    |       |
| Comments       | varchar(100) | YES  |     |         |       |
| Observatory    | varchar(20)  | YES  |     | NULL    |       |
| Project        | varchar(20)  | YES  |     | NULL    |       |
| reobserve      | int(11)      | YES  |     | 0       |       |
+----------------+--------------+------+-----+---------+-------+ 

Simplex

Holds all derived data for any one spectrum (from an observatory)
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| hip         | int(11)      |      |     | 0       |       |
| name        | varchar(20)  | YES  |     | NULL    |       |
| DoubleFlag  | char(2)      | YES  |     | NULL    |       |
| Observatory | varchar(20)  |      |     |         |       |
| T_eff       | varchar(8)   | YES  |     | NULL    |       |
| log_g       | varchar(5)   | YES  |     | NULL    |       |
| M_over_H    | varchar(5)   | YES  |     | NULL    |       |
| V_t         | varchar(5)   | YES  |     | NULL    |       |
| V_t_Fixed   | char(1)      | YES  |     | NULL    |       |
| Priority    | decimal(3,1) | YES  |     | NULL    |       |
| Fit_Qual    | varchar(15)  | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+ 

SpectraFiles

Holds filename locations for all spectra for any Nstar.
This table is queried when the web page is asked to display
a list of files associated with an Nstar. For any spectrum
to be displayed on the web page, it's filename must first
be in here, and associated with a hip #
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| hip         | int(11)      |      |     | 0       |       |
| name        | varchar(12)  | YES  |     | NULL    |       |
| Observatory | varchar(20)  |      |     |         |       |
| Filename    | varchar(50)  |      | PRI |         |       |
| priority    | decimal(6,4) | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+

Starnames

Holds names from other famous catalogs for every Nstar..
Good for finding the hip# for "VEGA" or "51 Peg"
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| hip       | int(11)      |      | PRI | -1      |       |
| hd        | varchar(12)  | YES  |     | NULL    |       |
| BD        | varchar(12)  | YES  |     | NULL    |       |
| CD        | varchar(12)  | YES  |     | NULL    |       |
| CPD       | varchar(12)  | YES  |     | NULL    |       |
| HR        | varchar(12)  | YES  |     | NULL    |       |
| GJ        | varchar(12)  | YES  |     | NULL    |       |
| Bayer     | varchar(30)  | YES  |     | NULL    |       |
| Flamstead | varchar(30)  | YES  |     | NULL    |       |
| NAME      | varchar(100) | YES  |     | NULL    |       |
| variable  | varchar(20)  | YES  |     | NULL    |       |
| LTT       | varchar(20)  | YES  |     | NULL    |       |
| SAO       | varchar(20)  | YES  |     | NULL    |       |
| GEN       | varchar(20)  | YES  |     | NULL    |       |
| uvby98    | varchar(20)  | YES  |     | NULL    |       |
| AKA1      | varchar(30)  | YES  |     | NULL    |       |
| AKA2      | varchar(30)  | YES  |     | NULL    |       |
| AKA3      | varchar(30)  | YES  |     | NULL    |       |
| AKA4      | varchar(30)  | YES  |     | NULL    |       |
| comments  | varchar(100) | YES  |     | NULL    |       |
+-----------+--------------+------+-----+---------+-------+ 

photometry

Holds All available photometry for all Nstars.
+--------------+----------+------+-----+---------+-------+
| Field        | Type     | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| hip          | int(11)  |      | PRI | 0       |       |
| HD           | int(11)  | YES  |     | NULL    |       |
| BD           | char(10) | YES  |     | NULL    |       |
| hip_V_       | char(8)  | YES  |     | NULL    |       |
| hip_BmV_     | char(8)  | YES  |     | NULL    |       |
| strom_v      | char(8)  | YES  |     | NULL    |       |
| strom_bmy    | char(8)  | YES  |     | NULL    |       |
| strom_m1     | char(8)  | YES  |     | NULL    |       |
| strom_c1     | char(8)  | YES  |     | NULL    |       |
| H_beta       | char(8)  | YES  |     | NULL    |       |
| Jon_V        | char(8)  | YES  |     | NULL    |       |
| Jon_UmB      | char(8)  | YES  |     | NULL    |       |
| Jon_BmV      | char(8)  | YES  |     | NULL    |       |
| Jon_VmR      | char(8)  | YES  |     | NULL    |       |
| Jon_VmI      | char(8)  | YES  |     | NULL    |       |
| Jon_RmI      | char(8)  | YES  |     | NULL    |       |
| Jon_J        | char(8)  | YES  |     | NULL    |       |
| Jon_H        | char(8)  | YES  |     | NULL    |       |
| Jon_K        | char(8)  | YES  |     | NULL    |       |
| Cousin_VmRc  | char(8)  | YES  |     | NULL    |       |
| Cousin_VmIc  | char(8)  | YES  |     | NULL    |       |
| Cousin_RcmIc | char(8)  | YES  |     | NULL    |       |
| tmass_J      | char(8)  | YES  |     | NULL    |       |
| tmass_H      | char(8)  | YES  |     | NULL    |       |
| tmass_K      | char(8)  | YES  |     | NULL    |       |
+--------------+----------+------+-----+---------+-------+ 

spt2code

A special-use table - a translation table to turn MK types as strings into decimal numerical values
where Early types have low values and late types have high values
Used primarily to 'sort' or 'place' spectra by type.
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| Spt   | varchar(8)   | YES  |     | NULL    |       |
| code  | decimal(6,4) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+ 


The Web Server

stellar.phys.appstate.edu runs off of the Apache Web Server.
Currently, version 1.3.26 for Debian Linux is the running
version, but apt-get update / upgrade will handle
upgrades to newer versions - so you may find you have a newer
version than this. (use /usr/sbin/apache -v to get version)

Documentation for the web server can be found in many places:
1) man apache -> the man page
2) http://httpd.apache.org/ -> home page for apache web server

Administration



Configuration

Most configuration of the web server (if not all) is done
in the file /etc/apache/httpd.conf
See the apache documentation
for more information on this file, although the configuration
file itself is quite self-documenting.


Other files in /etc/apache exist for configuration and the administrator
should be aware of these files, although documentation of these
configuration files are out of scope of this document. Refer
to apache's documentation for more information.

Starting / Stopping / Restarting the Server The program '/usr/sbin/apachectl' it a control interface for the http server.
By issuing either 'start', 'stop', or 'restart' argument to apachectl you can
perform the named action on the server
example: "/usr/bin/apachectl stop" will bring the server down
'man apachectl' for more information.

Website Layout

Not including non-nstar related domains (/SSN, /garrison, etc.) The
Webiste has 5 main areas:

Online Spectra - where you can view quick pixel plots
Nearby Star Catalog - where you can generate lists of nearby stars from a simple selection interface
Nearby Star ListQuery - where you can generate datafiles from the internal MySQL database
MK Standard Spectra - pixel lists of standards
Observation Database - for observers generating observing lists and posting observations

Online Spectra

In /var/www/spectra there is a file called spectra.html.
This is the start .html page - it only shows a query form
After a query is done, the pages shown are generated by
/usr/lib/cgi-bin/spectra/specdisplay.pl

Nearby Star Catalog

In /var/www/public_DB there are 2 html files:
Nstars.html and Nstars_Header.html

This area uses Frames - Nstars.html is the frame definition
while Nstars_Header.html is a small static .html file that prints
out the header that appears in the top frame.

The bottom frame runs /usr/lib/cgi-bin/Nstars_PubDisp_MySQL.pl
which when called with no arguments (like when the frames first load)
just shows the query form.

Nearby Star ListQuery

In /var/www/lisquery there are 2 .html files:
listquery.html and listquery_down.html

listquery_down.html is simply a message that can be put up
to say that listquery is currently broken - this is not up by default

listquery.html is the start page where a user uploads a text file list
of stars to get data on.
The 'send' action of listquery.html launches /usr/lib/cgi-bin/listquery/listquery_step1.pl
which saves the user's uploaded data to /var/tmp and proceeds to display a series of
check boxes representing data to return. "submit" goes to listquery_step2.pl
which does the query and returns the data to either the user's browser
or e-mail

MK Standard Spectra

The only site not requiring cgi scripts
In /var/www/Standards there is:
index.html - giving a description of each observatories resolution and
  links to each Observatories page.
std3_6.html - page for DSO600 standard spectra (3.6A resolution)
std1_8.html - page for DSO1200 standard spectra (1.8A resolution)
stdCTIO.html - page for CTIO standards
stdSO90.html - page for SO90 standards

and directories: CTIO/, SO90/, res36/, and res18/ which contain
the actual pixel lists of the standards.

Observation Database

Quick overview of cgi-bin


MySQL Basics

MySQL is a database server that speaks SQL - "Standard Query Language". Granted,
there are extensions and advanced parts of SQL that MySQL does not support,
but for the most part (for a free DB server) it does everything you need.

Intro

There are 2 sides to MySQL - A client and a server.

The server is running on stellar.phys.appstate.edu as the process
"mysqld". It is constantly running, awaiting connections from
clients and processing SQL queries.

The client is the program you talk to the server with. It's
simply called "mysql" and lives in /usr/bin (or /usr/local/bin) on your local machine.
It connects to the server - usually running remotely - from your desktop.
Do a "man mysql" to get complete documentation of the client.

To connect to the MySQL server, you need NOT be logged in to
stellar.phys.appstate.edu but the client must be installed on your machine.

Download and installation is done from http://www.mysql.com/downloads/mysql-3.23.html.

MySQL doesn't have a page for just 'client downloads' so be sure
that you are installing the client and not the server. After install,
you should be able to simply type 'mysql' at the shell and get the error:

"ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)"

If you get this error then the installation is complete.
(The error is caused because there is no MySQL server running on localhost (your machine))
.

logging in & the MySQL command line


To log into the MySQL server from your machine, you need to have an account
set up on the server. (a username and password). Once the administrator
has set that up, you can log in simply with:

"mysql -h stellar.phys.appstate.edu -u -p"

MySQL will prompt for a password (the -p option) and then
show you a "mysql>" prompt. This means the client is connected and
ready do pass queries to the server.

Sample Commands

Below are many samples and examples using SQL to query the database
with the pretext of creating a tutorial for using the Nstars database
Queries pertaining to the Nstars Database can (and should be) pasted into the
MySQL command line to have a real-world working example.
remember, In MySQL, all statements end in a semicolon.

USE / SHOW / DESCRIBE


The first command you must now know is USE - this selects a database to query.

"USE Nstars;" is probably what you want to type - to use the Nstars database.

http://www.mysql.com/doc/en/USE.html
Note that this is synonymous with the '-D' option to mysql - see the man page for mysql

The SHOW command is useful for providing information about databases, tables, etc...
for example:
mysql>SHOW databases;

will show all databases currently created that you can SELECT

mysql>SHOW tables;

will show all tables within the database currently selected.

http://www.mysql.com/doc/en/SHOW.html

DESCRIBE is used to get column information about a table:
As seen when you do a "SHOW tables" in the database "Nstars" you can see a table called "NstarsList".
to see what kind of data is in this table, do:

mysql>DESCRIBE NstarsList;

The output should look similar to that in the MySQL Database Data

SELECT

A SELECT statement is the most common statement in SQL. It gets data for you.
The basic form of every SELECT statement is "SELECT [columns] FROM [tables] WHERE [condition];"

see: http://www.mysql.com/doc/en/SELECT.html For complete documentation on SELECT

---
Assuming you have the Nstars Database Selected:

mysql> SELECT * FROM NstarsList;"

will select all the columns and all the data out of the table NstarsList. A LOT of data.

mysql> SELECT hip, RA_2000, DEC_2000 FROM NstarsList;

will select only the hipparcos #, the RA and the DEC of each star.

mysql> SELECT hip, RA_2000, DEC_2000 FROM NstarsList WHERE pi > 100 ;

will select out the hipparcos #, RA and DEC of only the stars within 10 parsecs of the sun....
which is a wonderful segway into "Column Name Aliases"....
The above query is quite cryptic in the Where clause - is that really 10 parsecs?
This query does the same thing.... and uses the alias DISTANCE to print out a star's distance
in parsecs by using the keyword "AS" to indicate an alias name:

mysql> SELECT hip, RA_2000, DEC_2000, pi, 1000/pi AS "Distance"
FROM NstarsList
WHERE 1000/pi < 10;


This gives slightly different output - it includes the parallax, and automatically converts it into parsecs
Also, Since the query became 'long' it has been split onto multiple lines. Usually, lines of SQL
are split into a SELECT line, a FROM line, and a WHERE line for readability.

Other neat things you can do:

mysql> SELECT hip, RA_2000, DEC_2000 FROM NstarsList ORDER BY hip DESC;
-reverse order by hip #

mysql> SELECT hip, RA_2000, DEC_2000, strom_v, strom_bmy
FROM NstarsList, photometry
WHERE NstarsList.hip=photometry.hip
AND 1000/pi < 10;

-select, along with RA and DEC, the Stromgren v and b-y magnitudes from the photometry table.
Using more than one table in a query is known as a JOIN

JOINS

There are many ways to join tables - all described at http://www.mysql.com/doc/en/JOIN.html

The simplest form is used in the last example: the INNER JOIN or (as MySQL'ers call it) "the comma join"
Which will create a Cartesian product of the two tables by printing out every combination of every row
in A with every row in B.
For Example:
TableA:              TableB:
key_a | value_a        key_b | value_b
---------------        ---------------
  1   |   a             1    |   20
  2   |   b             3    |   40
  3   |   c		

Then, The query "Select * from TableA, TableB;" will produce:
key_a | value_a | key_b | value_b
---------------------------------
  1   |   a     |  1    |  20
  1   |   a     |  3    |  40
  2   |   b     |  1    |  20 
  2   |   b     |  3    |  40
  3   |   c     |  1    |  20
  3   |   c     |  3    |  40

As you can imagine, tables formed this way can get quite large. Output size is always the product
of the size of the two tables crossed

Using a "join condition" makes this a bit more useful:
"SELECT * from TableA, TableB WHERE TableA.key_a=TableB.key_b;"

key_a | value_a | key_b | value_b
--------------------------------- 
  1   |   a     |  1    |  20   
  3   |   c     |  3    |  40


This is why most tables either have a primary key or a foreign key.
A primary key is a column that is Unique (can't contain the same value twice)
and cannot contain Null values.
In MySQL you can define a column as a primary key and it will enforce these rules for you when you
attempt to insert rows into the table.
A foreign key is a column in a table that REFERENCES a primary key in another
table. They need not be unique, but they must always reference an existing primary key in another
table. In MySQL, this is supported only under InnoDB tables, which is NOT what the Nstars Database
uses. (this would be nice to implement)
See http://www.mysql.com/doc/en/CREATE_TABLE.html for more info on column types and table types.


You can see this information about a table when you DESCRIBE it.

The two example tables above are valid tables for this design paradigm if key_a is a primary key and key_b is a foreign key
that references key_a. I could insert another row into TableB with key_b = 1, but I could not add another
row to TableA with key_a = 1 (violate uniqueness on primary key)

A LEFT JOIN is useful to join two tables where you know the second (right) table (usually the one with the foreign key)
doesn't have a row for every key in the first (left) table.

"SELECT * from TableA LEFT JOIN TableB on TableA.key_a=TableB.key_b;"
key_a | value_a | key_b | value_b
---------------------------------
  1   |   a     |  1    |  20
  2   |   b     | NULL  | NULL  
  3   |   c     |  3    |  40      

If there is no match in TableB for a key in TableA, then a row is placed with NULLS.
This becomes extremely useful to find out what DOESN'T exist in a table:

mysql> SELECT hip, HD, RA_2000, DEC_2000, Observatory
FROM NstarsList LEFT JOIN Observations on NstarsList.hip=Observations.hip
WHERE Observations.Observatory IS NULL;

Would give you a list of ALL stars out of the NstarsList (the master list of nearby stars)
that are NOT present in the Observations Table, ie. Not Observed
If you removed the WHERE clause, you would get a complete list of ALL nearby stars, with rows
from NstarsList duplicated for multiple, non unique occurrences of hip #'s in Observations
(ie. Stars observed more than once)
To get a count of how many times a star has been observed, we can Group By the hipparcos # and use the Function "count()":

mysql>SELECT hip, HD, count(hip) AS "Number Of Times Observed"
FROM NstarsList LEFT JOIN Observations on NstarsList.hip=Observations.hip
Group By NstarsList.hip;

The "Group By" collapses the table using duplicate values of column(s) specified in the
Group By clause. The above query uses the complete column name (in the table.column format)
to avoid ambiguity with the 'hip' column in Observations.

count() is one of many functions you can use in Group By clauses.
See:
http://www.mysql.com/doc/en/SELECT.html For a complete description of "Group By" and
http://www.mysql.com/doc/en/Group_by_functions.html for a list of functions available with "Group By".

There are also a number of functions for string manipulation and other useful utilities:
mysql>SELECT LEFT(RA_2000, 2) AS HOUR, count(*)
FROM NstarsList
Group By LEFT(RA_2000, 2);

This extracts the first 2 characters from the RA to get the hour portion using the LEFT() function
Then groups by the same expression and counts the result rows.
The result is a count of the number of stars in each hour of RA.

You can find a complete list of these functions in http://www.mysql.com/doc/en/Functions.html

INSERT/ UPDATE

To add a new row to an existing table, use INSERT

mysql> INSERT into SpectraFiles VALUES (9999, "VEGA", "DSO600", "/600g/mb/VEGA.mb", "99");

will insert one row into the SpectraFiles table.
This would in turn allow the file "/600g/mb/VEGA.mb" to be visible from the web site -
When someone queries for a star that matches hip 9999. (a bogus entry)

This would NOT work if Foreign Key Constraints were enforced - there is no
hip 9999 in the NstarsList table, which is conceptually what this foreign key references
But since we are not running InnoDB tables and we haven't defined this constraint, the table
will allow us to insert the row

This is part of the manual process of putting a spectra file up on the web site. Every file
than can be plotted on the "Query By Identifier" section has a row in this table, associating
a hip # with a filename. The website will query this database to find what files it can plot.

You can also do INSERT...SELECT to select out rows from one table and insert them into another
or " INSERT set [column]=[value], [column=value] " to insert when you don't want to specify every
column in a VALUES() list.
see: http://www.mysql.com/doc/en/INSERT.html

UPDATE Does a similar action, but instead of inserting a NEW row into a table it changes
the value of a column or columns in an already existing row:

mysql>UPDATE SpectraFiles SET Filename="/600g/mb/hd172167.mb" where Filename = "/600g/mb/VEGA.mb";

Would change the row we just inserted (and all other rows that match the WHERE condition to a proper filename
(hd number instead of proper name). This would be the appropriate change to the table if you renamed a pixel file
in /var/SPECTRA
Exercise caution with UPDATES. If you forget a WHERE clause, your update will be done to EVERY row in the table
which is probably not what you wanted to do. Also, LIMIT becomes useful here, as it can limit
the possibility of damage to the table from an UPDATE gone crazy:

mysql>UPDATE SpectraFiles SET Filename="/600g/mb/hd172167.mb" where Filename = "/600g/mb/VEGA.mb" LIMIT 1;

Adding the "LIMIT" would prevent more than one update to the table, even if there was more than one row that met the
WHERE condition.
This is good practice when doing updates.
see:
http://www.mysql.com/doc/en/UPDATE.html

DELETE is pretty straight forward:
mysql> DELETE from SpectraFiles where hip=9999 and name="VEGA" LIMIT 1;

This would clean up the bogus entry we placed in with INSERT and practiced with UPDATE.
Good practice in delete is also warranted - notice the "LIMIT 1" which is an extra
precaution in case the WHERE clause matches more than you want. Also, the key 'hip' is
used in the delete along with the 'name' field - insuring that we are deleting EXACTLY what
we want to. (The more fields you specify, the safer the delete).

It's also always good to try SELECTing what you are about to DELETE - whatever rows
come up after a SELECT with your WHERE clause will be the exact same set that gets deleted
with an identical WHERE clause.

LOAD DATA INFILE

This feature will do multiple inserts using a text file on the server's filesystem.
you can also do "LOAD DATA LOCAL INFILE" to use a text file on the local filesystem - you're computer
where the client is run from.
mysql> LOAD DATA INFILE "mydata.txt" into table "mytable";

will load a tab-delimited, newline ended file of single quoted ('') values. You can change the
behavior of delimiters and field encapsulators with options to LOAD DATA INFILE.
The complement of LOAD DATA INFILE is SELECT ... INTO OUTFILE
A full description of this feature can be found here: http://www.mysql.com/doc/en/LOAD_DATA.html

Useful Shell Command Line Tools

The client program, 'mysql' has many other features other than giving you a mysql> prompt
for example, you can specify a query right on the command line with the -e option:
shell% mysql -h stellar.phys.appstate.edu -u [username] -p -D Nstars -e "Select * from NstarsList;"
Will spit the results of the query "SELECT * from NstarsList" right to stdout where you can pipe it
into another process or redirect out to a file.

There are also a number of utilities in mysql's bin directory for other specific uses:

mysqlimport will do the same as LOAD DATA INFILE
mysqldump to dump out table structure and data to file (SELECT ... INTO OUTFILE)
mysqlhotcopy for copying tables
mysqladmin for administering MySQL from the Unix command line

Descriptions and more utilities can be found at http://www.mysql.com/doc/en/Client-Side_Scripts.html

Administration

/usr/bin/mysqladmin

The program 'mysqladmin' is an extremely useful administration tool that is run from the command line.
the full documentation is at
http://www.mysql.com/doc/en/mysqladmin.html
but one should at least be aware of it's existence in this document. It makes simple administration tasks
quite easy

User Accounts

All Accounts for the MySQL database server are described in an SQL database inside MySQL called 'mysql'
viewing this database is useful as a start to see how administration is done:
mysql>use mysql; #use the mysql database
mysql>SELECT * from user;

Will spit out quite a large table with each user's name, encrypted password, and permissions
they have to read/write or administer databases, tables, and even columns.

Administration can be done by INSERTing directly into this table or other tables in the MySQL
database, or through the use of GRANT statements.
see:
http://www.mysql.com/doc/en/Adding_users.html
http://www.mysql.com/doc/en/GRANT.html

Starting & Stopping the server
There are a couple of different ways to start and stop the server... all documented at
MySQL's web site. The MySQL server should come up on boot, though, if all is OK.

Manually, way to start it is to use the script 'safe_mysqld' in /usr/bin. It should be as easy
as just running the script as root to bring up the server, but in extreme circumstances
you may have to pass it some options. See
http://www.mysql.com/doc/en/safe_mysqld.html

To bring the server down, see mysqladmin.
Although it may be tempting, and the documentation on mysql.com may hint at it, be advised
against sending a kill signal to a mysqld thread. It has worked for me before, but I
have heard horror stories about corrupted tables and / or servers that won't start back up

Bringing the server up by running mysqld manually is possible though. See the manual or read
what the script 'safe_mysqld' really does!

Practical Examples Using the Database

Inserting new spectra files

Inserting Classifications

Inserting Derived Parameters

Adding Notes for Website spectra

Marking Stars for Re-Observation

Updating / Correcting data


Perl - The Glue

Perl is a scripting language that is excellent for string manipulation.
The syntax is pretty readable as-is, although some of the regular expression
matching & substitutions may be unreadable.

The website's scripts are all written in Perl. All of these scripts live in
/usr/lib/cgi-bin.

/usr/lib/cgi-bin (interface between Perl and web server)

Each one of the Perl scripts present in cgi-bin (and directories within) can be run
straight from the command line. If you do, you will see that the script simply
prints out html straight to the console. This is the same output that is sent to
the client's browser, where it looks much nicer

The interactivity between the web user and the cgi scripts come from html forms
and the ability for Perl to get environmental variables set by apache.
Apache receives the data as name/value pairs via a "POST" (opposed to GET)
where the name/value pairs are actually present in the URL.
Apache puts the length of the string of data in an environmental variable called 'CONTENT _LENGTH'
and then puts the string onto stdin for reading
See the apache documentation for more details.

To make this exchange a little easier, there is a function called get_form_info()
in the Perl Function Library that does most of this work for you - returning an
array of strings in the form "name=value". It is described in more detail below

From the point of view of the web server, all it's doing is reading HTML. On a form
there will be an ACTION option to the FORM tag which points to a .pl script to pass
the form's data to. The .pl script itself has within it the ability to logically decide
what to print to the user (in HTML form) based on the input provided from the user, via apache.
The variables passed are defined in the < FORM > < /FORM > block as < INPUT > tags.
Each one has a type, a name, a value, and a size to be defined. The name and value are the
key elements, as that is what is passed to the cgi scripts beyond. Name must always be defined
but a value is set only if a default value is needed. Without a value, the field appears
blank on the html form

'use DBI;' (interface between Perl and MySQL)

Any Perl script that requires access to the MySQL database internally - which is
most of the scripts - will include the DBI module provided by the Perl user community
(see http://www.cpan.org )
DBI stands for DataBase Interface, and is a generic SQL interface that can connect
to many types of DB systems.

Perl scripts requiring this use need only specify 'use DBI;' near the beginning of the file.
This includes a set of new functions for Perl that easily communicate to the SQL server

Here is a quick example of a simple query done from Perl. It simply prints out a list
of all stars classified in the project as A-type

#!/usr/bin/perl -w
use strict; 

use DBI; #use DBI module

#create connection handle - $dbh (DataBase Handle)
my $dbh = DBD->connect('dbi:mysql:Nstars','myusername','mypassword',{RaiseError => 1 } );

#create a SQL statement handle - $sth (StatemenT Handle) & prepare DB for query
# (let's get a list of all stars that have a spectral type that begins with "A")
my $sth = $dbh->prepare("SELECT hip, name, $GCG_SpecTyp 
                         FROM Classifications 
                         WHERE GCG_SpecTyp like \"A%\";");

#do the query
$sth->execute();

#the result is now available - the database server is holding on to it until we free it.

#first, create some variables to hold the return
#variable names can be anything, but I picked the same names as the column names for readability
my $hip, $name, $GCG_SpecTyp;

#tell the module to bind these variables to columns of the result.
# notice they are passed by-reference to bind_columns()
$sth->bind_columns(\$hip, \$name, \$GCG_SpecTyp);

#print the result - using a loop and fetch() function
while($sth->fetch()){
  print "$hip   $name    $GCG_SpecTyp\n";
}


#finish the query - free DB resources
$sth->finish();

#disconnect from database
$dbh->disconnect();


There are many other ways to do this same thing - as the motto of Perl is "There is more than
one way to do it!"
I used http://www.mysql.com/doc/en/Perl_DBI_Class.html as my reference - but others exist.
Check out http://dbi.perl.org/doc/index.html also.

Nstars Perl Function Library

As Projects evolve, so do the commonly used pieces of code. A rudimentary start has been
made to create a library of frequently used Perl functions associated with the Nstars database.

Currently, this isn't the slickest form of a Perl library. It's called Nstars_lib.pl and lives
in /cgi-bin/lib/ . It is used in many scripts in cgi-bin, to use it, simply place

Require "/Nstars_lib.pl";

near the top of your script, and precede any calls to subroutines within with a '&'. See
specdisplay.pl for an example.

This began with the rewrite of the specdisplay.pl script in /cgi-bin/spectra. This is a
beast of a script, and I functionalized many tasks within it. Noticing that these functions
were likely to be needed on other scripts, I began the placing them in a file called lib_of_subs.pl
which is currently in /home/flip/NstarsPerl_Subroutines/

Recently, it has evolved into a more dynamic library that can be included. So a change
made to a subroutine the library will in turn affect every script on the website that uses
that subroutine.
Future users of this are encouraged to add new routines or improve existing ones.
Be aware though that changing return values or input parameters of existing functions may create conflicts and break already existing code. Be sure you understand how an existing
subroutine is called, run, and every place that it is called from before changing these
properties. Optimizing or rewriting internal code should not be a problem, as long
as the parameters and return are left unchanged

Overview of functions provided in lib_of_subs.pl:
print_htm_header()
simply prints the required header info to begin printing to a browser... Without it
Perl code will be printed to the browser instead of the printed html

get_form_info()
determines method of sending form information (POST or GET) and populates an array
of strings of "name=value" format. The resultant array is returned;

connect_readonly_to_database();
function specific to connecting to MySQL Nstars Database as user 'webuser' - useful
for scripts that require only read access to the db and are called as cgi scripts

connect_readwrite_to_database();
function for connecting to the database as a privelaged user. Right now, the script
has a hard-coded username of 'flip' - but it's a good example of how to prompt for a password
. This function requires some more work to accept a username and turn off local terminal echo
when providing a password

get_hip()
An extremely useful function to get the hipparcos # given a search string of a starname.
it intelegently determines what catalog the starname belongs to (hd123 = hd catalog, etc)
then searches the Starnames table through the already defined database handle. If there are
more than zero matches, it populates an array of hip #'s that are matches to the search string, but only returns the first match. This can be modified.
Returns -1 if no match found
For example, this piece of code:

.
.
# connect to database and such
.
.
my $hip = get_hip("Vega");
print $hip;
.
.

Would output:
91262

get_nstar_name()
In a sence, does the reverse of get_hip. Given a hip #, it finds the appropriate
friendly starname to be printed. A "friendly" starname is defined as such:
If there is an HD number - use that
If not, use the BD designation
If BD not available, use the hip #
This also does a check to make sure the hip # provided is a nearby star, if it's not
it does not define the return. use the 'defined()' function in perl to check for
an empty result
(This needs to change to something a bit more standard)

get_notes()
Given a hip #, simply prints out any notes associated with the star. Notes are held
in there own table in the Nstars database. These are the same notes that are printed
below a plotted spectrum on the spectra page.

is_observed()
Given a hip #, returns the number of observations of the star.
Usuially used for a boolean test to see if a star has been observed or not, but can
be used to get a count also

get_specfiles()
Given a hip #, this returns a list of the filenames of all pixel files associated
with an observed and reduced spectrum. It returns an empty list if there are no
spectra files for the star
This is how specdisplay.pl determines what pixel files to show to the user when
a query is done from the spectra page.
The table, SpectraFiles in MySQL is where this info is stored. There is also
a priority field in the table which describes the order in which the spectra files
are displayed on the page. The file with the lowest priority is displayed first -
Notice the "order by priority asc" in the query within the function itself.

get_GCG_classification()
given a hip #, returns the GCG_spec_type stored in the Classificatons table - the NEW classification

get_hip_classification()
given a hip #, returns the hipparcos classification from the NstarsList table - the OLD classification

get_parallax()
given a hip #, returns a list containing 2 elements - the parallax and the parallax error
from the hipparcos catalog

get_photometry()
given a hip #, returns a list containing photometric data on the star in this order:
0 - hipparcos V
1 - hipparcos B-V
2 - v (stromgren)
3 - b-y(stromgren)
4 - m1 (stromgren)
5 - c1 (stromgren)
6 - H-beta
7 - Johnson V
8 - Johnson U-B
9 - Johnson B-V
10 - Johnson V-R
11 - Johnson V-I
12 - Johnson R-I
13 - Johnson J
14 - Johnson H
15 - Johnson K
16 - Cousin V-R
17 - Cousin V-I
18 - Cousin R-I

get_simplex_data()
given a hip #, returns a 2D list of simplex data currently in the list.
The array is 2D because for one hip #, there may be multuple stars of a double system
and each may have it's own data OR the star was observed at multuple observatories
and simplex values have been determined for each observation separately
Most of the time, it will only be one list wide,but propper use of this function should
check the entire result set
Remember, when passing arrays of arrays in Perl, it must be done by reference.
see specdisplay.pl for an example on how this is done and the result is traversed
The lists returned are in this format:
0 - Observatory
1 - T_eff -effective tempature
2 - log_g -log surface gravity
3 - M/H -metallicity index
4 - V_t -microturbulent velocity
5 - Fit_Qual -quality of simplex fit

get_ChromAct_data()
given a hip #, returns a 2D list of Derived Chromospheric Activity data.
much like get_simplex_data(), there may be more than one row for a given hip #
and the function will return an array of arrays for this reason.
The lists returned are in this format:
0 - Observatory
1 - S_mw - S - value on Mount Wilson Chromospheric Activity scale
2 - log_R_HK - emission strength of K and H lines
3 - ChromActClass - Chromospheric Activity Class (active, inactive, etc..)

make_spectra_gif()
This function uses ploticus to create a gif image of a spectrum plot
given a filename and a common name
The common name is used as a title on the image. The filename is the partial-path
filename of the pixel file to plot - the same as what is returned from get_spectra_file()
This function creates the ploticus 'scriptfile' that drives the creation of the
gif image and then does a call to ploticus to create the file.
It returns the filename of the new gif file created.
This function has only been implemented in specdisplay.pl, so it is still not quite
as general of a function as it should be. It currently is hard-coded to place created
gif spectra files in /htdocs/tmp and removes any .gif files that were there already
A little bit of work will make this into a nice, general function

make_spectra_jpeg()
Something broke, I can't remember exactly what it was, but gif files no longer
worked after some upgrade I made or such.... No matter... ploticus can make jpeg's too!
And so this function was created. Does the same as make_spectra_gif - but creates
a jpeg and returns the filename.

get_date()
Given a pixel list - passed as an array reference, returns the date in the
footer of the pixel list in ISO 8061 format (yyyy-mm-dd) - no matter what form
the date is within the actual footer of the pixel list.
The pixel lists are passed as arrays - by reference, not as a filename or a filehandle.
to prepare a pixel list for this function, simply OPEN the pixel list and assign
an array to the handle:

open FILEHANDLE, "my_pixel_list.hb";
my @pixellist = < FILEHANDLE>
my $date = get_date(@pixellist);

get_airmass()
Just like get_date() the input is a reference to a pixel list array.
This function finds the airmass comment in the pixel list footer and returns it
as a scalar

get_observations()
This function needs work - returns a list of observations for a hip #/
The return type is scalar - a single string - in the form
"observatory|notes|airmass/observatory|notes|airmass
where '|' is a field delimeter and "/" is a line delimiter
This return type should be fixed to be a list of lists - each list being one observation.

specfile_exsists()
Returns a count of howmany spectra files are available for a hip #
Also useful as a boolean check to see if spectra files exsist.


Data Archiving and Backup

Weekly Backup

On the webserver, there is a cron job that runs once a week to backup
all the Nstars data and webserver to a secure machine inside the network.
The script that runs is /etc/cron.weekly/Nstars_Backup.sh and it:
1) Copies, tar, and gzips database files.
2) tar and gzips spectra files.
3) tar and gzips website (/var/www/* /usr/lib/cgi-bin/* /var/log/apache*)
4) ftp all this data to barcud.phys.appstate.edu//usr/local/stellar_backup/

There are three types of files you will find on barcud after a backup:
databases.[date].tar.gz
spectra.[date].tar.gz
website.[date].tar.gz

where [date] is the date when the backup was created.

Restoring from Weekly Backup

In the worst case of a complete system failure, a new piece of hardware - preferably
running the same operating system as the failed one - could be built, and after
the install of the neccessary programs (apache, MySQL, ploticus, Perl, PHP, etc..)
all the tar files should be able to be extracted directly onto the new filesystem
and all data and funcitonality would be restored. There would most definately
be loose ends and broken parts of the website, or missing symbolic links,
but all data pretaining to the project would be saved.

The more appropriate way to restore would be to get the appropriate file from the
backup archives, unpack it, and overwrite any broken or corrupted data with the backup
data from the archive.
This is expecially useful for MySQL database data. If the database happens to be corrupted
for any reason, the .MYI, .MYD and .frm files in /var/lib/mysql/Nstars can be overwritten
by the contents of the databases.[date].tar.gz file. To do this, simply shutdown the MySQL
server, copy the files over you want to restore (each table has it's own backup), and restart
the server. All should be restored just fine.

Written by Mike McFadden
May 6, 2003