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.
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
[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
[flip@nstar temp]$ for file in *.rec ; do mv $file `echo $file | sed 's/\(.*\.\)rec/\1r18/'`; done;
[flip@nstar temp]$ perl -e 'for (@ARGV) {($nf = $_) =~ s/.rec/.r18/; `mv $_ $nf`;}' *.rec
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
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
starname #images comparison image1 image2 . . imageN starname #images comparison image1 image2 . .
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!
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
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
all commands enclosed { } are IRAF commands
all commands enclosed in ` ` are Unix commands
cl < SO90stage1.cl }
cl> flpr }
cl> prompt.
cl> task $SO90autoextall=SO90autoextall.cl }
cl> SO90autoextall }
cl> cl < make_reduclist.cl }
cl> task $SO90final = SO90final.cl }
cl> SO90final }
cl < cleanup.cl }
Copy Files:
---------
CTIOautoextall:
--------
make_CTIO_reduclist:
----------------
CTIOfinal.cl:
---------------
Rectification:
-------------
Flux Calibration
you will also notice extra directories, spectra files, and
All "relational" data for the Nstars project is held on the MySQL
This is why, as will be explained in depth later, one must specify
as the first command on the MySQL command line, or using the '-D' switch when
Starting / Stopping / Restarting the Server
The program '/usr/sbin/apachectl' it a control interface for the http server.
The program 'mysqladmin' is an extremely useful administration tool that is run from the command line.
User Accounts
All Accounts for the MySQL database server are described in an SQL database inside MySQL called 'mysql'
To bring the server down, see mysqladmin.
The interactivity between the web user and the cgi scripts come from html forms
To make this exchange a little easier, there is a function called get_form_info()
From the point of view of the web server, all it's doing is reading HTML. On a form
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
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.
------------------
Quick Instructions:
all commands enclosed { } are IRAF commands
all commands enclosed in ` ` are Unix commands
cl < CTIOstage1.cl }
cl> flpr }
cl> prompt.
cl> task $CTIOautoextall=CTIOautoextall.cl }
cl> CTIOautoextall }
cl> cl < make_CTIO_reduclist.cl }
cl> task $CTIOfinal = CTIOfinal.cl }
cl> CTIOfinal }
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.
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.
(pretty much the same as SO90)
(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
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
cd to /usr/local/CTIOout and work on the .cal files - rectify them with xmk1x
remember to rename to .ctio.rec if neccessary
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
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
database server living on stellar.phys.appstate.edu, and is stored
in the database "Nstars".
mysql> use Nstars;
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
+----------+-------------+------+-----+---------+-------+
| 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
+---------------+--------------+------+-----+---------+-------+
| 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
+------------+-------------+------+-----+---------+-------+
| 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
+-------------+--------------+------+-----+---------+-------+
| 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
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| hip | int(11) | | PRI | 0 | |
| note | text | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
Observations
+----------------+--------------+------+-----+---------+-------+
| 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
+-------------+--------------+------+-----+---------+-------+
| 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
+-------------+--------------+------+-----+---------+-------+
| 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
+-----------+--------------+------+-----+---------+-------+
| 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
+--------------+----------+------+-----+---------+-------+
| 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
+-------+--------------+------+-----+---------+-------+
| 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.
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
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 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
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
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
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.
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
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 "
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:
Perl code will be printed to the browser instead of the printed html
of strings of "name=value" format. The resultant array is returned;
for scripts that require only read access to the db and are called as cgi scripts
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
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
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)
in there own table in the Nstars database. These are the same notes that are printed
below a plotted spectrum on the spectra page.
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
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.
from the hipparcos catalog
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
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
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..)
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
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.
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);
This function finds the airmass comment in the pixel list footer and returns it
as a scalar
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.
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