aboutsummaryrefslogtreecommitdiff
path: root/noao/digiphot/ptools
diff options
context:
space:
mode:
Diffstat (limited to 'noao/digiphot/ptools')
-rw-r--r--noao/digiphot/ptools/README23
-rw-r--r--noao/digiphot/ptools/Revisions395
-rw-r--r--noao/digiphot/ptools/cntrplot.par21
-rw-r--r--noao/digiphot/ptools/doc/istable.hlp64
-rw-r--r--noao/digiphot/ptools/doc/pcalc.hlp86
-rw-r--r--noao/digiphot/ptools/doc/pconcat.hlp50
-rw-r--r--noao/digiphot/ptools/doc/pconvert.hlp153
-rw-r--r--noao/digiphot/ptools/doc/pdump.hlp178
-rw-r--r--noao/digiphot/ptools/doc/pexamine.hlp835
-rw-r--r--noao/digiphot/ptools/doc/prenumber.hlp59
-rw-r--r--noao/digiphot/ptools/doc/pselect.hlp130
-rw-r--r--noao/digiphot/ptools/doc/psort.hlp64
-rw-r--r--noao/digiphot/ptools/doc/pttest.hlp78
-rw-r--r--noao/digiphot/ptools/doc/tbcalc.hlp79
-rw-r--r--noao/digiphot/ptools/doc/tbconcat.hlp49
-rw-r--r--noao/digiphot/ptools/doc/tbcrename.hlp50
-rw-r--r--noao/digiphot/ptools/doc/tbdump.hlp193
-rw-r--r--noao/digiphot/ptools/doc/tbkeycol.hlp50
-rw-r--r--noao/digiphot/ptools/doc/tbrenumber.hlp54
-rw-r--r--noao/digiphot/ptools/doc/tbselect.hlp107
-rw-r--r--noao/digiphot/ptools/doc/tbsort.hlp78
-rw-r--r--noao/digiphot/ptools/doc/txcalc.hlp80
-rw-r--r--noao/digiphot/ptools/doc/txconcat.hlp45
-rw-r--r--noao/digiphot/ptools/doc/txdump.hlp167
-rw-r--r--noao/digiphot/ptools/doc/txrenumber.hlp59
-rw-r--r--noao/digiphot/ptools/doc/txselect.hlp121
-rw-r--r--noao/digiphot/ptools/doc/txsort.hlp61
-rw-r--r--noao/digiphot/ptools/histplot.par20
-rw-r--r--noao/digiphot/ptools/istable.par7
-rw-r--r--noao/digiphot/ptools/lib/strip.ptoolsx0
-rw-r--r--noao/digiphot/ptools/lib/warning.dat12
-rw-r--r--noao/digiphot/ptools/mkpkg38
-rw-r--r--noao/digiphot/ptools/pcalc.cl50
-rw-r--r--noao/digiphot/ptools/pconcat.cl56
-rw-r--r--noao/digiphot/ptools/pconvert.par8
-rw-r--r--noao/digiphot/ptools/pconvert/mkpkg14
-rw-r--r--noao/digiphot/ptools/pconvert/ptconvert.x236
-rw-r--r--noao/digiphot/ptools/pconvert/ptdeftable.x375
-rw-r--r--noao/digiphot/ptools/pconvert/ptstrwrd.x51
-rw-r--r--noao/digiphot/ptools/pconvert/t_pconvert.x53
-rw-r--r--noao/digiphot/ptools/pdump.cl83
-rw-r--r--noao/digiphot/ptools/pexamine.par20
-rw-r--r--noao/digiphot/ptools/pexamine/mkpkg21
-rw-r--r--noao/digiphot/ptools/pexamine/pexamine.h115
-rw-r--r--noao/digiphot/ptools/pexamine/pexamine.key146
-rw-r--r--noao/digiphot/ptools/pexamine/ptahgmr.x44
-rw-r--r--noao/digiphot/ptools/pexamine/ptalimr.x35
-rw-r--r--noao/digiphot/ptools/pexamine/ptcolon.x668
-rw-r--r--noao/digiphot/ptools/pexamine/ptdelete.x335
-rw-r--r--noao/digiphot/ptools/pexamine/ptgetphot.x432
-rw-r--r--noao/digiphot/ptools/pexamine/ptimplot.x940
-rw-r--r--noao/digiphot/ptools/pexamine/ptplot.x1462
-rw-r--r--noao/digiphot/ptools/pexamine/ptrddata.x125
-rw-r--r--noao/digiphot/ptools/pexamine/ptsetup.x360
-rw-r--r--noao/digiphot/ptools/pexamine/ptwtfile.x143
-rw-r--r--noao/digiphot/ptools/pexamine/t_pexamine.x188
-rw-r--r--noao/digiphot/ptools/prenumber.cl50
-rw-r--r--noao/digiphot/ptools/pselect.cl77
-rw-r--r--noao/digiphot/ptools/psort.cl42
-rw-r--r--noao/digiphot/ptools/ptools.cl50
-rw-r--r--noao/digiphot/ptools/ptools.hd34
-rw-r--r--noao/digiphot/ptools/ptools.men24
-rw-r--r--noao/digiphot/ptools/ptools.par3
-rw-r--r--noao/digiphot/ptools/pttest.cl550
-rw-r--r--noao/digiphot/ptools/ptutils/mkpkg12
-rw-r--r--noao/digiphot/ptools/ptutils/t_istable.x71
-rw-r--r--noao/digiphot/ptools/ptutils/t_tbcrename.x73
-rw-r--r--noao/digiphot/ptools/ptutils/t_tbkeycol.x140
-rw-r--r--noao/digiphot/ptools/radplot.par22
-rw-r--r--noao/digiphot/ptools/surfplot.par10
-rw-r--r--noao/digiphot/ptools/tbcalc.cl37
-rw-r--r--noao/digiphot/ptools/tbconcat.cl113
-rw-r--r--noao/digiphot/ptools/tbcrename.par6
-rw-r--r--noao/digiphot/ptools/tbdump.cl44
-rw-r--r--noao/digiphot/ptools/tbkeycol.par5
-rw-r--r--noao/digiphot/ptools/tbrenumber.cl36
-rw-r--r--noao/digiphot/ptools/tbselect.cl20
-rw-r--r--noao/digiphot/ptools/tbsort.cl21
-rw-r--r--noao/digiphot/ptools/test/gcommands.dat3
-rw-r--r--noao/digiphot/ptools/test/icommands.dat1
-rw-r--r--noao/digiphot/ptools/test/test1.dat133
-rw-r--r--noao/digiphot/ptools/test/test2.dat315
-rw-r--r--noao/digiphot/ptools/txcalc.par6
-rw-r--r--noao/digiphot/ptools/txconcat.par6
-rw-r--r--noao/digiphot/ptools/txdump.par8
-rw-r--r--noao/digiphot/ptools/txrenumber.par6
-rw-r--r--noao/digiphot/ptools/txselect.par6
-rw-r--r--noao/digiphot/ptools/txsort.par6
-rw-r--r--noao/digiphot/ptools/txtools/mkpkg23
-rw-r--r--noao/digiphot/ptools/txtools/ptqsort.x215
-rw-r--r--noao/digiphot/ptools/txtools/ptrenumb.x221
-rw-r--r--noao/digiphot/ptools/txtools/ptsortnum.x446
-rw-r--r--noao/digiphot/ptools/txtools/ptxcalc.x255
-rw-r--r--noao/digiphot/ptools/txtools/ptxdump.x421
-rw-r--r--noao/digiphot/ptools/txtools/ptxselect.x160
-rw-r--r--noao/digiphot/ptools/txtools/t_txcalc.x65
-rw-r--r--noao/digiphot/ptools/txtools/t_txconcat.x128
-rw-r--r--noao/digiphot/ptools/txtools/t_txdump.x45
-rw-r--r--noao/digiphot/ptools/txtools/t_txrenumber.x65
-rw-r--r--noao/digiphot/ptools/txtools/t_txselect.x64
-rw-r--r--noao/digiphot/ptools/txtools/t_txsort.x65
-rw-r--r--noao/digiphot/ptools/x_ptools.x11
-rw-r--r--noao/digiphot/ptools/xyplot.par20
103 files changed, 13500 insertions, 0 deletions
diff --git a/noao/digiphot/ptools/README b/noao/digiphot/ptools/README
new file mode 100644
index 00000000..2a2e5597
--- /dev/null
+++ b/noao/digiphot/ptools/README
@@ -0,0 +1,23 @@
+ The Photometry Tools Package
+ -------------------------------
+
+The ptools package contains routines which perform oerations on the
+text database files and/or ST binary tables files produced by the APPHOT
+and DAOPHOT packages, and scripts which make the fact that any given database
+is a table or a text file transparent to the user.
+
+The ptools directory structure is listed below. The .h files are all in lib
+as many of them are shared by several tasks.
+
+ |-pconvert------routines to the pconvert task
+ |-doc-----------ptools documentation
+|-ptools-----|-lib-----------ptools definitions or .h files
+ |-pexamine------routines specific to the pexamine task
+ |-ptutils-------routines specific to miscellneous utility tasks
+ |-txtools-------routines specific to the text file operators
+ |-test----------directory of test data
+
+
+Lindsey Davis
+NOAO IRAF GROUP
+August 1991
diff --git a/noao/digiphot/ptools/Revisions b/noao/digiphot/ptools/Revisions
new file mode 100644
index 00000000..14287582
--- /dev/null
+++ b/noao/digiphot/ptools/Revisions
@@ -0,0 +1,395 @@
+.help revisions Jan90 noao.digiphot.ptools
+.nf
+
+ptools$pconvert/ptdeftable.x
+ pt_kstati() was being declared pointer instead of int (7/13/09, MJF)
+
+ptools$pexamine/ptsetup.x
+ pt_getnames() was declared a pointer instead of int (7/12/09, MJF)
+
+ptools$pconvert/ptconvert.x
+ptools$pconvert/txtools/ptxcalc.x
+ptools$pconvert/txtools/ptxdump.x
+ptools$pconvert/txtools/ptxselect.x
+ Added missing xev_freeop calls to the pconvert, txcalc, txdump, and
+ txselect tasks so that memory is released if any of the input operands
+ are strings.
+
+ (Davis, March 6, 2002)
+
+
+ptools$mkpkg
+ Modified the mkpkg procedures to pick up user compile and link flags.
+
+ (Davis, June 17, 1999)
+
+ptools$ptools.cl
+ Modified the package cl script to check and see if the tables package is
+ already loaded before checking to see if it exists and then loading it.
+
+ (Davis, August 1, 1998)
+
+ptools$pdump.cl
+ Modified the way the pdump script handles the tdump pwidth parameter
+ to work around a change made to the tables.ttools.tdump task. The solution
+ is not ideal because it leaves the value of tdump.pwidth.p_max
+ modified but the parameter value is not changed.
+
+ (Davis, August 15, 1997)
+
+ptools$pconcat.cl
+ Added a missing "cache ("istable")" statement that could cause trouble
+ if the pconcat script was called from a backgroound job.
+
+ (Davis, July 28, 1997)
+
+ptools$txtools/t_txselect.x
+ Changed the maximimum size of the expression to be evaluated from
+ SZ_FNAME to SZ_LINE which is what it was supposed to be.
+
+ (Davis, May 25, 1996)
+
+ptools$tbdump.cl
+ If the input file was an ST binary table file and the expression parameter
+ was not equal to "yes", the intermediate tables file was not being deleted
+ when the tbdump and pdump tasks terminated. The problem was due to the
+ ".tab" extension that was added to the tables name but not sensed by
+ the delete command. I switched the delete command to a tdelete command
+ and everything worked fine.
+
+ (Davis, Nov 2, 1995)
+
+ptools/pexamine/pexmine.h
+ptools/pexamine/ptcolon.x
+ The rinner and router colon commands were incorrectly coded as rin and
+ rout colon commands in the pexamine.h file. The :router command was also
+ incorrectly writing back its results into the rinner parameter.
+
+ (Davis, May 1, 1995)
+
+ptools/ptutils/t_tbcrename.x
+ptools/ptutils/t_tbkeycol.x
+ Add several new checks for input text files to avoid a problem with
+ a text file being opened as a binary table. This problem prably appeared
+ when tables was modified to support simple text files (tables 1.3.3 for
+ sure, proably 1.3.2 as well, not sure before that).
+
+ (Davis, March 21, 1995)
+
+
+ptools/tbconcat.cl
+ Add a test for the existence of the ttools.keypar.silent parameter
+ for backwards compatability between tables 1.3.3 and 1.3.2.
+
+ (Davis, Feb 25, 1995)
+
+ptools/pexamine/ptplot.x
+ An off the end of the array computation error in the routine pt_hplot
+ was causing an invalid floating point operation on the Dec Alpha when
+ the user tried to plot the histogram of an array,
+
+ (Davis, Feb 23, 1995)
+
+ptools/pconvert/ptdeftable.x
+ Modified the pconvert task so that header space is preallocated rather
+ than added as needed. This significantly speeds up the task performance
+ by decreasing the number of disk writes required. This change was
+ made in response to a suggestion from PHil Hodge at ST.
+
+ (Davis, Feb 2, 1995)
+
+ptools/txtools/t_txcalc.x
+ptools/txtools/ptxcalc.x
+ptools/tbcalc.cl
+ptools/pcalc.cl
+ptools/doc/pcalc.hlp
+ptools/doc/tbcalc.hlp
+ptools/doc/txcalc.hlp
+ Added the tasks txcalc, tbcalc, and pcalc to the ptools package.
+ This tasks perform arithmetic operations on the fields or columns
+ of photometry files written with apphot or daophot tasks.
+
+ (Davis, May 31 1993)
+
+ptools/pexamine
+ Fixed numerous small bugs in the pexamine task including: 1)
+ unclear error messages if the default x-y or histogram plot columns could
+ not be found on task startup 2) initialization bug that could cause
+ the output edited catalog to be written incorrectly on the
+ second or higher run of pexamine, 3) added a 5% buffer around all
+ the plots so the user can see the plotted data better, 4) added
+ the standard deviation of the sky to the standard apphot columns, 5)
+ a misleading error message in the colon command to change the
+ default histogram column.
+
+ (Davis, May 22 1993)
+
+ptools/ptutils/t_istable.x
+ Modified the istable task, which is called by the pconcat, pdump,
+ prenumber, pselect, and psort script tasks so that it could deal
+ correctly with the fact that legal tables files might be text files.
+
+ (Davis, May 12 1993)
+
+ptools/pdump.cl
+ptools/pttest.cl
+ptools/tbdump.cl
+ptools/tbrenumber.cl
+ Added an expression parameter to the pdump task.
+
+ (Davis, Feb 25, 1993)
+
+ptools/tbrenumber.cl
+ptools/prenumber.cl
+ Modified the tbrenumber and prenumber scripts so they can use
+ the tables 1.2.1 version of tcalc as well as the 1.2 version.
+ The parameters verbose and harmless present in the 1.2 version
+ were removed from the 1.2.1 version.
+
+ (Davis, June 1, 1992)
+
+ptools$pexamine/ptplot.x
+ 1. The error message "Star not found" would persist after a star
+ was successfully found because no status line message was printed
+ out after a succesful find operation.
+
+ (Davis, April 7, 1992)
+
+ptools$tbdump.cl
+ptools$tbrenumber.cl
+ptools$prenumber.cl
+ 1. Changed the name of the pagwidth parameter to pwidth the call to the
+ ttools package task tdump because the parameter was renamed in the
+ version 1.2 of tables.
+
+ 2. Changed the value of the tcalc equals parameter from ":ROWNUM"
+ to "rownum" in calls to tcalc made by the tbrenumber and prenumber
+ tasks.
+
+ (Davis, February 28, 1992)
+
+ptools$ptools.cl
+ptools$ptools.hd
+ptools$ptools.men
+ptools$x_ptools.x
+ptools$pappend.cl
+ptools$pdump.cl
+ptools$prenumber.cl
+ptools$pselect.cl
+ptools$psort.cl
+ptools$pconvert/t_pconvert.x
+ptools$doc/pappend.hlp
+ptools$doc/pdump.hlp
+ptools$doc/prenumber.hlp
+ptools$doc/pselect.hlp
+ptools$doc/psort.hlp
+ptools$doc/pconvert.hlp
+ Changed the name of the append task to pappend.
+ Changed the name of the dump task to pdump.
+ Changed the name of the renumber task to prenumber.
+ Changed the name of the select task to pselect.
+ Changed the name of the sort task to psort.
+ Changed the name of the convert task to pconvert.
+
+ (Davis, October 8, 1991)
+
+ptools$pttest.cl
+ptools$doc/pttest.hlp
+ Added the new task pttest to the ptools package. Pttest runs basic tests
+ on the ptools package.
+
+ (Davis, October 8, 1991)
+
+ptools$pexamine/ptplot.x
+ Changed the status line message so that it is printed only when the
+ first plot is made or new data is read in.
+
+ (Davis, October 7, 1991)
+
+ *** Applied the results of spplint to the ptools package.
+
+ptools$convert/t_convert.x
+ Removed 2 extra arguments from the strupr call.
+ This could be a problem in the old testphot.
+
+ptools$convert/ptconvert.x
+ Changed an illegal logical NOT construct to an integer == NO construct.
+ This was not a problem in the old testphot.
+
+ Removed unused variable record form the pt_convert routine.
+
+ptools$convert/ptdeftable.x
+ Removed an extra argument from the pt_gnfn call. This routine has
+ changed and this bug was not a problem in the old testphot..
+
+ptools$pexamine/ptgetphot.x
+ Removed an extra argument from the pt_gnfn call. This routine has
+ changed. Pexamine did not exist in the old testphot so this was not
+ a problem.
+
+ptools$pexamine/ptplot.x
+ Removed an extra argument from the pt_gnfn call. This routine has
+ changed. Pexamine did not exist in the old testphot so this was not
+ a problem.
+
+ Removed an extra argument from pt_rxydata. This routine has changed.
+ Pexamine did not exist in the old testphot so this was not a problem.
+
+ Removed unused variables x1, y1 from the pt_gcur routine.
+
+ptools$pexamine/ptcolon.x
+ Removed an extra argument for a clgetr command.
+ Pexamine did not exist in the old testphot so this was not a problem.
+
+ptools$txtools/t_txdump.x
+ Removed two extra arguments from the call to strupr. This could have
+ been a problem in the old testphot.
+
+ptools$txtools/ptxdump.x
+ Changed an illegal logical NOT construct to an integer == NO construct.
+ This was not a problem in the old testphot.
+
+ptools$txtools/ptxselect.x
+ Changed an illegal logical NOT construct to an integer == NO construct.
+ This was not a problem in the old testphot.
+
+ptools$txtools/ptsortnum.x
+ Removed unused argument colwidth from the pt_colsort routine.
+
+ Davis, October 3, 1991
+
+
+ptools$renumber.cl
+ptools$tbrenumber.cl
+ Changed the calls to the tables tcalc task to include all the hidden
+ parameters.
+
+ Davis, October 1, 1991
+
+ptools$
+ 1. Deleted the append, dump, renumber, select and sort sub-directories
+ and consolidated then into the txtools sub-directory.
+
+ 2. Several small files were eliminated by concantenating them into other
+ existing files in txtools, pexamine, and convert.
+
+ 3. Changed the way selected keywords are stored in the text database
+ data structures. The index, instead of the pointer is stored. This removes
+ potential problems with reallocating the record structures, when the
+ test database files contain variable-sized records. All the text database
+ tools were affected, as were a couple of files in daophot.
+
+ 4. Modified txdump, txrenumber, txselect, txsort and pexamine so that they
+ could correctly deal with variable-sized records instead of crashing,
+ if a given record was larger than the first record in the file.
+
+ 5. Completely rewrote convert.
+
+ 6. Added an offset parameter to pexamine so that the user can elect
+ to read portions of an input photometry catalog into memory for plotting
+ and examining.
+
+ Davis, August 13, 1991
+
+ptools$
+ 1. Renamed the hidden tcolrename task need for the photcal preprocessors to
+ tbcrename in conformance with the new standards.
+
+ 2. Added a help page for tbcrename.
+
+ Davis, May 24, 1991
+
+ptools$
+ 1. Renamed the hidden tkeycol task need for the photcal preprocessors to
+ tbkeycol in conformance with the new standards.
+
+ Davis, May 24, 1991
+
+ptools$renumber/t_txrenumber.x
+ 1. The txrenumber task will now accept a list of images.
+
+ Davis, May 24, 1991
+
+ptools$
+ 1. The ptools package now loads the tables package on startup.
+
+ 2. The tasks tappend, tdump, trenumber, tselect, and tsort have now become
+ tbappend, tbdump, tbrenumber, tbselect and tbsort. These tasks work
+ on binary tables files. All are now scripts which call a tables
+ package task. All 5 tasks now operate on lists of tables files.
+
+ Davis, May 24, 1991
+
+ptools$pttables/ptkeywords.x
+ptools$pttables/ptconvert.x
+ 1. Fixed a problem with embedded blanks in string parameters in the
+ apphot/daophot database files. The format and units string were not being
+ correctly read because the second part of the value string was being read
+ into the units string, the units string was being read into the filter
+ string etc. This was only a problem for keywords (#K) because they
+ are read in free format. It was not a problem for columns (#N).
+ The format will now default to %-20s if it can not be decoded
+ and only the first part of the string will be kept. The units string
+ will be incorrect. There may be a more elegant solution
+ later but this fix will work for now.
+
+ Davis, Apr 2, 1991
+
+ptools$pttables/ptmkrec.x
+ 1. All of the ptools tasks which operate on text files convert, txappend,
+ txdump, txrenumber, txselect, txsort and pexamine have been modfied
+ to be more efficient. Calls to strmatch have been replaced by calls
+ to strncmp. Convert, txdump and txselect no longer call the expression
+ evaluator if the expression is a simple "yes" string.
+
+ 2. Ptmkrec has been modified to be more efficient for the simple case
+ where there is only a single aperture.
+
+ Davis, Mar 29, 1991
+
+ptools$
+ 1. Added the new hidden task tkeycol to the ptools package. Tkeycol
+ converts ST table header keywords into new ST table columns. It is not
+ intended to be seen directly by the user but will be used in some
+ of the preprocessing scripts in the photcal package.
+
+ 2. Added the new hidden task tcolrename to the ptools package. Tcolrename
+ renames selected columns in a list of ST tables. It is not intended to
+ be seen directly by the user but will be used in some of the preprocessing
+ scripts in the ptools package.
+
+ Davis, Mar 2, 1991
+
+ptools$convert/ptconvert.x
+ Convert was preallocating space for 150 columns in the output table. In
+ rare cases where the user had a large number of apertures (20 or so)
+ in a phot text file convert could overwrite memory and crash the task.
+
+ Davis, Oct 4, 1990
+
+ptools$tvmark/
+ Removed tvmark from ptools since it is duplicated in proto.
+
+ Davis, Jul 9, 1990
+
+ptools$convert/ptdeftable.x
+ Corrected a bug in the convert task wherein the code was trying to
+ load a string quantity into a boolean parameter. This caused the
+ code to crash on Orion was worked ok on the sparc station.
+
+ Davis, Jun 7, 1990
+
+ptools$pttables/tappend.cl
+ Removed two harmless debugging statements from the tappend.cl script.
+
+ Davis, Jan 8, 1989
+
+ptools$pttables/pthdrs.x
+ An off the end of the array access error was occurring for the format and
+ units string in the case where the header was duplicated in an input
+ text database file. This bug sometimes caused meomory corruption errors
+ in several of the daophot tasks and in the ptools tasks txsort, txdump,
+ txrenumber and txselect.
+
+ Davis, Jan 5, 1989
+.endhelp
diff --git a/noao/digiphot/ptools/cntrplot.par b/noao/digiphot/ptools/cntrplot.par
new file mode 100644
index 00000000..4381f07b
--- /dev/null
+++ b/noao/digiphot/ptools/cntrplot.par
@@ -0,0 +1,21 @@
+# The PEXAMINE task contour plotting parameters
+
+ncolumns,i,h,21,2,,Number of columns
+nlines,i,h,21,2,,Number of lines
+floor,r,h,INDEF,,,"Minimum value to be contoured (INDEF if none)"
+ceiling,r,h,INDEF,,,"Maximum value to be contoured (INDEF if none)"
+zero,r,h,0.,,,"Greyscale value of zero contour"
+ncontours,i,h,5,,,"Number of contours to be drawn (0 for default)"
+interval,r,h,0.,,,"Contour interval (0 for default)"
+nhi,i,h,-1,,,"Hi/low marking option: -1=omit, 0=mark h/l, 1=mark each pix"
+dashpat,i,h,528,,,"Bit pattern for generating dashed lines"
+label,b,h,no,,,"Label major contours with their values ?"
+box,b,h,yes,,,Draw box around periphery of window ?
+ticklabels,b,h,Yes,,,Label tick marks ?
+majrx,i,h,5,,,Number of major divisions along x grid
+minrx,i,h,5,,,Number of minor divisions along x grid
+majry,i,h,5,,,Number of major divisions along y grid
+minry,i,h,5,,,Number of minor divisions along y grid
+round,b,h,no,,,Round axes to nice values ?
+fill,b,h,no,,,Fill viewport vs enforce unity aspect ratio ?
+banner,b,h,yes,,,Standard banner?
diff --git a/noao/digiphot/ptools/doc/istable.hlp b/noao/digiphot/ptools/doc/istable.hlp
new file mode 100644
index 00000000..3a08376c
--- /dev/null
+++ b/noao/digiphot/ptools/doc/istable.hlp
@@ -0,0 +1,64 @@
+.help istable Aug91 noao.ptools.digiphot
+.ih
+NAME
+istable -- determine the status of a file
+
+.ih
+USAGE
+istable infile
+
+.ih
+PARAMETERS
+
+.ls infile
+The name of the input file whose status is to be determined.
+.le
+.ls table = no
+An output variable which is "yes" if \fIinfile\fR is an STSDAS table
+and "no" otherwise.
+.le
+.ls text = no
+An output variable which is "yes" if \fIinfile\fR is an APPHOT/DAOPHOT
+text database and "no" otherwise.
+.le
+.ls other = no
+An output variable which is "yes" if \fIinfile\fR is neither of the
+above and "no" otherwise.
+.le
+
+.ih
+DESCRIPTION
+ISTABLE is a very simple task which determines whether a specified
+input file is an STSDAS table, an APPHOT/DAOPHOT text database file or
+neither of the above. ISTABLE first tries to open the input file as an
+STSDAS table. If successful ISTABLE returns "yes" in the
+variable \fItable\fR and "no" in \fItext\fR and \fIother\fR. Otherwise
+ISTABLE tries to open the input file as an APPHOT/DAOPHOT text database
+file by checking for the "#K IRAF" keyword.
+If the check is positive ISTABLE return "yes" in
+the variable \fItext\fR and "no" in \fItable\fR and \fIother\fR. If the input
+file is neither an STSDAS table or an APPHOT/DAOPHOT text database
+ISTABLE returns "yes" in the variable \fIother\fR and "no" in \fItext\fR
+and \fItable\fR.
+
+.ih
+EXAMPLES
+
+1. Determine whether the file n4147.mag.1 is an STSDAS table.
+
+.nf
+ pt> istable n4147.mag
+ pt> =istable.table
+
+ ... answer will appear on the screen
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+Users should be wary of running ISTABLE in background as the output
+CL parameters may not be properly updated.
+.ih
+SEE ALSO
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pcalc.hlp b/noao/digiphot/ptools/doc/pcalc.hlp
new file mode 100644
index 00000000..36d06229
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pcalc.hlp
@@ -0,0 +1,86 @@
+.help pcalc May93 noao.digiphot.ptools
+.ih
+NAME
+pcalc - perform an arithmetic operation on a field in a list of apphot/daophot
+databases
+.ih
+USAGE
+pcalc infiles field value
+.ih
+PARAMETERS
+.ls infiles
+The APPHOT/DAOPHOT database(s) containing the field to be recomputed.
+.le
+.ls field
+The field to be recomputed. Field must be an integer or real field
+in the input file(s).
+.le
+.ls value
+The arithmetic expression used to recompute the specified field.
+Value may be an integer or real expression but must match the data
+type of field. The functions real and int may be used to do type
+conversions.
+.le
+
+.ih
+DESCRIPTION
+
+PCALC reads in the values of the \fIfield\fR keyword
+from a set of APPHOT/DAOPHOT databases, replaces the old values
+with new values equal to the value of the arithmetic expression \fIvalue\fR,
+and updates the databases(s).
+
+PCALC is script task which calls TXCALC is the input file is an
+APPHOT/DAOPHOT text database or TBCLAC if APPHOT/DAOPHOT is a tables
+database.
+If the input file is a text database, the expression \fIvalue\fR consists
+of variables which are the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords in the APPHOT/DAOPHOT text databases.
+Only keywords beginning with #N can actually be replaced.
+If the input file is an ST tables database, the expression \fIvalue\fR
+consists of the table column names.
+
+The supported
+arithmetic operators and functions are briefly described below.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Change the XCENTER and YCENTER fields to XCENTER + 5.4 and YCENTER + 10.3
+respectively in a file produced by the apphot package center task.
+
+.nf
+ pt> pcalc m92.ctr.1 xcenter "xcenter+5.4"
+ pt> pcalc m92.ctr.1 ycenter "ycenter+10.3"
+.fi
+
+2. Add a constant to the computed magnitudes produced by nstar.
+
+.nf
+ pt> pcalc n4147.nst.2 mag "mag+3.457"
+.fi
+
+.ih
+BUGS
+TXCALC does not allow arrays in the expression field.
+
+.ih
+SEE ALSO
+ptools.tbcalc,tables.tcalc,ptools.pcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pconcat.hlp b/noao/digiphot/ptools/doc/pconcat.hlp
new file mode 100644
index 00000000..f96d9bab
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pconcat.hlp
@@ -0,0 +1,50 @@
+.help pconcat Dec92 noao.digiphot.ptools
+.ih
+NAME
+pconcat -- concatenate a list of APPHOT/DAOPHOT databases
+.ih
+USAGE
+pconcat infiles outfile
+.ih
+PARAMETERS
+.ls infiles
+The list of APPHOT/DAOPHOT databases to be concatenated.
+.le
+.ls outfile
+The name of the output APPHOT/DAOPHOT database.
+.le
+.ls task = "TASK"
+The name of the keywords whose value is the name of the task which wrote
+the database.
+.le
+.ih
+DESCRIPTION
+PCONCAT is a simple task which accepts a list of APPHOT/DAOPHOT
+database files and concatenates them into one resultant output file.
+PCONCAT checks that all the file are indeed APPHOT/DAOPHOT
+database files and that they were all written by the same task before
+performing the concatenation.
+
+PCONCAT is a simple script which call TXCONCAT in the PTOOLS package
+if the input files are text database files or TBCONCAT in the PTOOLS package
+if the input files are STSDAS database files. TBCONCAT is itself a script
+which call the TABLES package task TMERGE to do the actual work.
+
+.ih
+EXAMPLES
+
+1. Concatenate a list of DAOPHOT package task GROUP output database files
+into a single output file.
+
+.nf
+ pt> pconcat m92r.grp.1,m92r.grp.2,m92r.grp.3 m92rall.grp.1
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txconcat,ptools.tbconcat,tables.tmerge,concatenate
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pconvert.hlp b/noao/digiphot/ptools/doc/pconvert.hlp
new file mode 100644
index 00000000..ca3db8e7
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pconvert.hlp
@@ -0,0 +1,153 @@
+.help pconvert Aug91 noao.digiphot.ptools
+.ih
+NAME
+pconvert -- convert an APPHOT/DAOPHOT text database into an STSDAS table
+.ih
+USAGE
+pconvert textfile table fields
+.ih
+PARAMETERS
+.ls textfile
+The APPHOT/DAOPHOT text database which is to be converted into an
+APPHOT/DAOPHOT STSDAS table database.
+.le
+.ls table
+The name of the output STSDAS table database.
+.le
+.ls fields = "*"
+Template defining the fields to be selected from each record. By default
+all the fields are output. Fields
+are specified by using the names defined in the APPHOT/DAOPHOT text
+database by the
+#N entries. Upper or lower case and minimum match abbreviations are
+permissible. For those fields which have multiple entries such as
+magnitude, an individual value can be referenced by specifying an array
+index, e.g. MAG[2] or several values can be selected by specifying a
+range of elements, e.g. MAG[1-4].
+.le
+.ls expr = yes
+The boolean expression, evaluated independently for each record,
+which serves as a selection criterion. By default all records are selected.
+.le
+.ls append = no
+If append is yes then the converted APPHOT/DAOPHOT text file is appended to an
+existing output STSDAS table database.
+.le
+.ih
+DESCRIPTION
+PCONVERT selects a subset of the fields from each record of an
+APPHOT/DAOPHOT text database and writes these into an STSDAS tabl database.
+The #K keyword parameters in the text database are
+stored as header parameters in the STSDAS table while the selected fields
+are stored in fields (columns) with the names specified by the text
+database #N keywords, units specified
+by the #U keywords, and print format specified by the #F keywords.
+
+The output records are selected on the basis of the boolean
+expression \fIexpr\fR whose variables are the field (column) names
+specified by the #N keywords in the APPHOT/DAOPHOT text database.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates to yes, that record is included in the output table.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters are described below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The boolean expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+
+If the append parameter is "yes" then the converted input text database is
+appended to the specified output table. When appending to a table each of the
+output fields must already exist in the output table.
+
+.ih
+EXAMPLES
+
+1. Convert the text output from the DAOPHOT PHOT task in the file n4147.mag.1
+to an STSDAS table, selecting only the fields ID, XCENTER, YCENTER,
+MAG,and MSKY ncessary for input to the DAOPHOT fitting routines.
+Put the output in an STSDAS table named n4147.tmag.1.
+
+.nf
+ pt> pconvert n4147.mag.1 n4147.tmag.1 "ID,XCENTER,YCENTER,MAG,MSKY"
+.fi
+
+If there were 4 magnitude fields in n4147.mag.1
+then there would be 4 columns in the output table with names of
+MAG[1], MAG[2], MAG[3] and MAG[4]
+
+
+2. Convert the same file as in example 1. but append the output to
+ n4147.tmag.1 and only select records with YCENTER <= 200.0.
+
+.nf
+ pt> pconvert n4147.mag.1 n4147.tmag.1 "ID,XCENTER,YCENTER,MAG,MSKY" \
+ expr="YCENTER < 200.0" append+
+
+.fi
+
+3. Convert all the records in the NSTAR text database n4147.nst.1 to
+ an STSDAS table.
+
+ pt> pconvert n4147.nst.1 n4147.tnst.1 "*"
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+Changes in the values of the #K keyword quantities which are permitted by
+the APPHOT/DAOPHOT text database format will be lost in the conversion to
+STSDAS table format which does not permit such changes. For example users
+who have
+set up and run PHOT interactively and changed the values of the parameters
+after writing the first record to the text database will see only the initial
+values of the #K keywords in the STSDAS table headers after conversion.
+.ih
+SEE ALSO
+images.hedit
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pdump.hlp b/noao/digiphot/ptools/doc/pdump.hlp
new file mode 100644
index 00000000..d37a87e6
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pdump.hlp
@@ -0,0 +1,178 @@
+.help pdump Feb93 noao.digiphot.ptools
+.ih
+NAME
+pdump - print fields from an APPHOT/DAOPHOT database
+.ih
+USAGE
+pdump infiles fields expr
+.ih
+PARAMETERS
+.ls infiles
+The APPHOT/DAOPHOT databases containing the fields to be dumped.
+.le
+.ls fields
+A template defining the fields to be dumped from each record.
+In the case of APPHOT/DAOPHOT text databases, the fields are specified by
+keywords defined by the
+#K and #N entries in the database. Upper or lower case and minimum match
+abbreviations are permissible. Some fields such as "mag" may have
+multiple entries. An individual entry can be referenced by specifying an
+array index, e.g. "MAG[2]" or several values can be selected by
+specifying a range of elements, e.g. "MAG[1-3]".
+In the case of STSDAS table APPHOT/DAOPHOT databases the fields are the
+column names. Names must be spelled in full but upper or lower case is allowed.
+In the case of STSDAS table databases, it may be necessary to escape the
+leading square bracket so that field "MAG[2]" would be referred to as
+"MAG\[2]". The fields are output in
+the order in which they are specified in the template.
+.le
+.ls expr
+The boolean expression to be evaluated once per record.
+Only the fields in those records for which the boolean expression
+evaluates to yes are printed.
+If \fIexpr\fR = "yes", the specified fields in all the records are
+printed.
+.le
+.ls headers = no
+Dump the APPHOT/DAOPHOT database field headers. The selected
+fields are printed on the standard output, preceded by the parameters list,
+if \fIparameters\fR = yes, and the keyword, units,
+and format information.
+.le
+.ls parameters = yes
+Print the keyword parameters records on the
+standard output if \fIheaders\fR = yes.
+.le
+
+.ih
+DESCRIPTION
+PDUMP selects a subset of fields specified by the \fIfields\fR
+parameter from an APPHOT/DAOPHOT database or a list of databases
+and prints the results on the standard output.
+If \fIheaders\fR = no, the output is in simple list format
+with adjacent fields
+separated by whitespace. The fields are printed in the order in
+which they appear in \fIields\fR. If \fIheaders\fR = yes, the
+selected fields are printed on the standard output, preceded by
+the parameter list, if \fIparameters\fR = yes, and the keyword, units,
+and format information.
+Newlines will not be inserted in the output if the input database
+was an APPHOT/DAOPHOT text file, so users should take
+care not specify so many output fields as to exceed the IRAF text file
+line limit of 161 characters.
+Newlines will be inserted if the original database was an
+STSDAS table.
+
+PDUMP is a simple CL script which calls TXDUMP if the APPHOT/DAOPHOT
+database was a text file and TBDUMP if it was an STSDAS table.
+Although the parameters of TBDUMP and TXDUMP have been tailored to
+make the two tasks appear as similar as possible each task
+offers some capabilities that the other does not. In some
+situations users may wish to use the individual tasks instead of the
+generic script.
+
+The output records are selected on the basis of an input boolean
+expression \fIexpr\fR whose variables are the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords in the APPHOT/DAOPHOT text database or the column names
+in an ST tables database.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates
+to yes, that record is included in the output table.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+.ih
+EXAMPLES
+
+1. Select the fields XCENTER and YCENTER from the output of the APPHOT
+CENTER task.
+
+.nf
+ pt> pdump image.ctr.3 "XCENTER,YCENTER" yes
+.fi
+
+2. Select the fields XCENTER and YCENTER from the output of the APPHOT
+CENTER task for all records with YCENTER > 100.0.
+
+.nf
+ pt> pdump image.ctr.3 "XCENTER,YCENTER" "YCENTER > 100.0"
+.fi
+
+3. Select the fields ID, XCENTER, YCENTER and the first three magnitudes
+from the output of the APPHOT PHOT task. In the case of STSDAS table
+databases it may be necessary to escape the leading square bracket.
+
+.nf
+ pt> pdump image.mag.3 "ID,XCEN,YCEN,MAG[1],MAG[2],MAG[3]" yes
+
+ or
+
+ pt> pdump image.mag.3 "ID,XCEN,YCEN,MAG\[1],MAG\[2],MAG\[3]" yes
+.fi
+
+
+4. Select the ID, XCENTER, YCENTER, MSKY and MAG fields from the output
+of the DAOPHOT NSTAR task. Print the headers and parameters as well.
+
+.nf
+ pt> pdump image.nst.3 "ID,XCENTER,YCENTER,MSKY,MAG" \
+ yes headers+ parameters+
+.fi
+
+.ih
+BUGS
+Users should not dump more fields than fill a 161 character textline
+as IRAF does not currently fully support longer text lines.
+.ih
+SEE ALSO
+ptools.txdump,ptools.tbdump,tables.tdump
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pexamine.hlp b/noao/digiphot/ptools/doc/pexamine.hlp
new file mode 100644
index 00000000..20289d26
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pexamine.hlp
@@ -0,0 +1,835 @@
+.help pexamine Aug91 noao.digiphot.ptools
+.ih
+NAME
+pexamine -- interactively examine or edit a photometry catalog
+.ih
+USAGE
+pexamine input output image
+.ih
+PARAMETERS
+.ls input
+The name of the input photometry catalog. \fIInput\fR may be either an
+APPHOT/DAOPHOT text database file or an STSDAS binary table database.
+.le
+.ls output
+The name of the edited output catalog. \fIOutput\fR is either an
+APPHOT/DAOPHOT text database or an STSDAS binary table database
+depending on the file type of \fIinput\fR. If \fIoutput\fR = "" no output
+catalog is written.
+.le
+.ls image
+The name of the input image corresponding to the input photometry
+catalog. If \fIimage\fR is "" no image will be attached to PEXAMINE
+and some interactive catalog examining commands will not be available.
+All the catalog editing commands however are still available.
+.le
+.ls deletions = ""
+The name of an optional output deletions photometry catalog. \fIDeletions\fR
+is either an APPHOT/DAOPHOT text database or an STSDAS binary
+table database depending on the file type of \fIinput\fR. If \fIdeletions\fR
+is "" no deletions file is written.
+.le
+.ls photcolumns = "daophot"
+The list of standard photometry columns that are loaded when pexamine is
+run. The options are listed below.
+.ls "daophot"
+The standard columns for the DAOPHOT package. The current list is GROUP, ID,
+XCENTER, YCENTER, MSKY, MAG, MERR, CHI, SHARP and NITER.
+If any of these
+columns are multi-valued, (as in the case of magnitudes measured through
+more than one aperture), the first value is selected.
+The standard list may easily be extended at user request.
+.le
+.ls "apphot"
+The standard columns for the APPHOT package. The current list is ID,
+XCENTER, YCENTER, MSKY, MAG, and MERR.
+If any of these
+columns are multi-valued, (as in the case of magnitudes measured through
+more than one aperture), the first value is selected.
+The standard list may easily be extended at user request.
+.le
+.ls user list
+A user supplied list of standard columns.
+Column names are listed in full in either upper or
+lower case letters, separated by commas. If more than one value of
+a multi-valued column is requested
+the individual values
+must be listed separately as in the following example
+ID, XCENTER, YCENTER, MAG[1], MERR[1], MAG[2], MERR[2].
+.le
+
+\fIPhotcolumns\fR can be changed interactively from within PEXAMINE at
+the cost of rereading the database.
+.le
+.ls xcolumn = "mag" (magnitude), ycolumn = "merr" (magnitude error)
+The names of the two columns which define the default X-Y plot.
+\fIXcolumn\fR and \fIycolumn\fR must be listed in \fIphotcolumns\fR or
+\fIusercolumns\fR but may be changed interactively by the user.
+If either \fIxcolumn\fR or \fIycolumn\fR is a multi-valued quantity
+and more than one value is listed in \fIphotcolumns\fR or \fIusercolumns\fR
+then the desired value number must be specified explicitly in, e.g.
+MAG[2] or MERR[2].
+.le
+.ls hcolumn = "mag" (magnitude)
+The name of the column which defines the default histogram plot.
+\fIHcolumn\fR must be listed in \fIphotcolumns\fR or
+\fIusercolumns\fR but may be changed interactively by the user.
+If \fIhcolumn\fR is a multi-valued quantity and more than one value is
+listed in \fIphotcolumns\fR or \fIusercolumns\fR then the desired value
+must be specified explicitly in \fIhcolumn\fR, e.g. MAG[2].
+.le
+.ls xposcolumn = "xcenter", yposcolumn = "ycenter"
+The names of the two columns which define the X and Y coordinates in
+\fIimage\fR of the objects in the catalog. This information is
+required if the image display and image cursor are to be used to visually
+identify objects in the image with objects in the catalog or if plots
+of image data are requested. \fIXposcolumn\fR and \fIyposcolumn\fR must
+be listed in \fIphotcolumns\fR or \fIusercolumns\fR but may
+be changed interactively by the user.
+.le
+.ls usercolumns = ""
+The list of columns loaded into memory in addition to the
+standard photometry columns \fIphotcolumns\fR. The column
+names are listed in full in upper or lower case letters and separated by
+commas.
+\fIUsercolumns\fR can be changed interactively from within PEXAMINE at
+the cost of rereading the database.
+.le
+.ls max_nstars = 3000
+The maximum number of objects that are loaded into memory at task
+startup time, beginning at object \fIfirst_star\fR. If there are more
+than \fImax_nstars\fR in the catalog only the first \fImax_nstars\fR
+objects are read in.
+.le
+.ls first_star = 1
+The index of the first object to be read out of the catalog.
+.le
+.ls match_radius = 2.0
+The tolerance in pixels to be used for matching objects in the catalog with
+objects marked on the display with the image cursor.
+.le
+.ls graphics = "stdgraph"
+The default graphics device.
+.le
+.ls gcommands = ""
+The graphics cursor. If null the standard graphics cursor is used whenever
+graphics cursor input is requested. A cursor file in the appropriate
+format may be substituted by specifying the name of the file.
+.le
+.ls icommands = ""
+The image display cursor. If null the standard image cursor is used whenever
+image cursor input is requested. A cursor file in the appropriate
+format may be substituted by specifying the name of the file.
+Also the image cursor may be changed to query the graphics device or the
+terminal by setting the environment variable "stdimcur" to "stdgraph"
+or "text" respectively.
+.le
+.ls use_display = yes
+Use the image display? Users without access to an image display should
+set \fIuse_display\fR to "no".
+.le
+
+.ih
+PLOTTING PARAMETERS
+
+PEXAMINE supports five types of plots 1) an X-Y column plot
+2) a histogram column plot 3) a radial profile plot 4) a surface
+plot and 5) a contour plot.
+Each supported plot type has its own parameter set which
+controls the appearance of the plot.
+The names of the five parameter sets are listed below.
+
+.nf
+ cntrplot Parameters for the contour plot
+ histplot Parameters for the column histogram plot
+ radplot Parameters for radial profile plot
+ surfplot Parameters for surface plot
+ xyplot Parameters for the X-Y column plot
+.fi
+
+The same parameters dealing with graph formats occur in many of the parameter
+sets while some are specific only to one parameter set. In the
+summary below those common to more than one parameter set are shown
+only once. The characters in parenthesis are the graph key prefixes
+for the parameter sets in which the parameter occurs.
+
+.ls angh = -33., angv = 25. (s)
+Horizontal and vertical viewing angles in degrees for surface plots.
+.le
+.ls axes = yes (s)
+Draw axes along the edge of surface plots?
+.le
+.ls banner = yes (chrsx)
+Add a standard banner to a graph? The standard banner includes the
+IRAF user and host identification and the date and time.
+.le
+.ls box = yes (chrx)
+Draw graph box and axes?
+.le
+.ls ceiling = INDEF (cs)
+Ceiling data value for contour and surface plots. A value of INDEF does
+not apply a ceiling. In contour plots a value of 0. also does not
+apply a ceiling.
+.le
+.ls dashpat = 528 (c)
+Dash pattern for negative contours.
+.le
+.ls fill = no (yes) (c) (hrx)
+Fill the output viewport regardless of the device aspect ratio?
+.le
+.ls floor = INDEF (cs)
+Floor data value for contour and surface plots. A value of INDEF does
+not apply a floor. In contour plots a value of 0. also does not
+apply a floor.
+.le
+.ls grid = no (rx)
+Draw grid lines at major tick marks?
+.le
+.ls interval = 0.0 (c)
+Contour interval. If 0.0, a contour interval is chosen which places 20 to 30
+contours spanning the intensity range of the image.
+.le
+.ls label= no (c)
+Label the major contours in the contour plot?
+.le
+.ls logx = no, logy = no (rx) (hrx)
+Plot the x or y axis logarithmically? The default for histogram plots is
+to plot the y axis logarithmically.
+.le
+.ls majrx=5, minrx=5, majry=5, minry=5 (chrx)
+Maximum number of major tick marks on each axis and number of minor tick marks
+between major tick marks.
+.le
+.ls marker = "box" (rx)
+Marker to be drawn. Markers are "point", "box",
+"cross", "plus", "circle", "hline", "vline" or "diamond".
+.le
+.ls nbins = 512 (h)
+The number of bins in, or resolution of, histogram plots.
+.le
+.ls ncolumns = 21, nlines = 21 (cs)
+Number of columns and lines used in contour and surface plots.
+.le
+.ls ncontours = 5 (c)
+Number of contours to be drawn. If 0, the contour interval may be specified,
+otherwise 20 to 30 nicely spaced contours are drawn. A maximum of 40 contours
+can be drawn.
+.le
+.ls nhi = -1 (c)
+If -1, highs and lows are not marked. If 0, highs and lows are marked
+on the plot. If 1, the intensity of each pixel is marked on the plot.
+.le
+.ls rinner = 0, router = 8
+The inner and outer radius of the region whose radial profile is to
+be plotted.
+.le
+.ls round = no (chrx)
+Extend the axes up to "nice" values?
+.le
+.ls szmarker = 1 (rx)
+Size of mark except for points. A positive size less than 1 specifies
+a fraction of the device size. Values of 1, 2, 3, and 4 signify
+default sizes of increasing size.
+.le
+.ls ticklabels = yes (chrx)
+Label the tick marks?
+.le
+.ls top_closed = no (h)
+Include z2 in the top histogram bin? Each bin of the histogram is a
+subinterval that is half open at the top. \fITop_closed\fR decides whether
+those pixels with values equal to z2 are to be counted in the histogram. If
+\fItop_closed\fR is yes, the top bin will be larger than the other bins.
+.le
+.ls x1 = INDEF, x2 = INDEF, y1 = INDEF, y2 = INDEF (hrx)
+Range of graph along each axis. If INDEF the range is determined from
+the data range. The default y1 for histogram plots is 0.
+.le
+.ls zero = 0. (c)
+Greyscale value of the zero contour, i.e., the value of a zero point shift
+to be applied to the image data before plotting. Does not affect the values
+of the floor and ceiling parameters.
+.le
+.ls z1 = INDEF, z2 = INDEF (h)
+Range of pixel values to be used in histogram. INDEF values default to
+the range in the region being histogrammed.
+.le
+
+.ih
+DESCRIPTION
+
+PEXAMINE is a general purpose tool for interactively examining and editing
+photometry catalogs produced by the APPHOT or DAOPHOT packages. It is
+intended to aid the user in assessing the accuracy of the photometry,
+in diagnosing problems with particular catalog objects,
+in searching the photometry data for relationships
+between the computed quantities, and in editing the catalog based on
+those observed relationships. PEXAMINE is intended to complement the
+more batch oriented editing facilities of the PSELECT task.
+
+PEXAMINE takes the input catalog \fIinput\fR and the corresponding
+image \fIimage\fR (if defined) and produces an output catalog of selected
+objects \fIoutput\fR (if defined) and an output catalog of deleted objects
+\fIdeletions\fR (if defined). The input catalog may be either an
+APPHOT/DAOPHOT text database or an ST binary table database.
+The file type of the output catalogs \fIoutput\fR and \fIdeletions\fR
+is the same as that of \fIinput\fR.
+
+READING IN THE DATA
+
+PEXAMINE reads the column data specified by \fIphotcolumns\fR and
+\fIusercolumns\fR for up to \fImax_nstars\fR into memory. If there are
+more than \fImax_nstars\fR in the input catalog only the data for the
+first \fImax_nstars\fR is read. The \fIphotcolumns\fR parameter
+defines the list of standard photometry columns to be loaded. If
+"daophot" or "apphot" is selected then the standard columns
+are GROUP, ID, XCENTER, YCENTER, MSKY, MAG, MERR, CHI, SHARP and NITER
+and ID, XCENTER, YCENTER, MSKY, MAG and MERR respectively.
+Otherwise the user must set \fIphotcolumns\fR to his or her own preferred
+list of standard photometry columns. Non-standard columns may also be
+specified using the parameter \fIusercolumns\fR.
+Valid column lists contain the full names of the specified columns
+in upper or lower case letters, separated by commas.
+Either \fIphotcolumns\fR or
+\fIusercolumns\fR may be redefined interactively by the user after
+the task has started up, but only at the
+expense of rereading the data from \fIinput\fR.
+
+PEXAMINE will fail to load a specified column if that column is
+not in the photometry database, is of a datatype other than
+integer or real, or adding that column would exceed the maximum
+number of columns limit currently set at twenty. The user can
+interactively examine the list of requested and loaded standard
+photometry columns, as well as list all the columns in the input
+after the task has started up.
+
+GRAPHICS AND IMAGE COMMAND MODE
+
+PEXAMINE accepts commands either from the graphics cursor \fIgcommands\fR
+(graphics command mode) or the image display cursor \fIicommands\fR
+if available (image command mode).
+PEXAMINE starts up in graphics command mode, but all the
+interactive commands are accessible from both modes and the user can
+switch modes at any time assuming that the \fIuse_display\fR parameter
+to "yes".
+
+PEXAMINE interprets the cursor position in graphics mode
+differently from how it interprets it in image command mode.
+In graphics command mode the cursor coordinates are the position
+of the cursor in the current plot, whereas in image command mode they
+are the x and y coordinates of the cursor in the displayed image.
+For example, if the user issues a command to PEXAMINE to locate the object
+in the catalog nearest the point in the current X-Y plot marked by
+the graphics cursor, PEXAMINE does so by searching
+the data for the object whose values of \fIxcolumn\fR and \fIycolumn\fR
+most closely match those of the current cursor position.
+If the user issues a command to PEXAMINE to locate the
+object in the catalog corresponding to the object marked on the image
+display with the image cursor,
+PEXAMINE does so by searching the data for
+the object whose values of \fIxposcolumn\fR and \fIyposcoumn\fR
+most closely match and fall within \fImatch_radius\fR of the current
+cursor position.
+
+Input to PEXAMINE is through single keystroke commands or colon
+commands. Keystroke commands are simple commands that may
+optionally use the cursor position but otherwise require no arguments.
+The PEXAMINE keystroke commands fall into three categories, basic
+commands, data examining commands and data editing commands, all
+described in detail in the following sections. Colon commands
+take an optional argument and function differently depending on
+the presence or absence of that argument. When the argument is absent
+colon commands are used to display the
+current value of a parameter or list of parameters. When the argument is
+present they change their current value to that argument.
+The basic colon commands are described in detail below.
+
+BASIC KEYSTROKE COMMANDS
+
+These keystroke commands are used to display the help page, switch from
+graphics to image command mode and quit the task.
+
+.ls ?
+Page through the help for the PEXAMINE task
+.le
+.ls :
+Execute a PEXAMINE colon command.
+.le
+.ls g
+Change to graphics command mode. Throughout PEXAMINE graphics command mode
+is the default. All PEXAMINE commands are available in graphics command
+mode.
+.le
+.ls i
+Change to image command mode.
+All the PEXAMINE commands are available in image command mode.
+However if \fIuse_display\fR is no and the image
+cursor has not been aliased to the standard input or a text file
+image command mode is disabled.
+.le
+.ls q
+Quit PEXAMINE without writing an output catalog.
+PEXAMINE queries the user for confirmation of this option.
+.le
+.ls e
+Quit PEXAMINE and write the output catalog.
+.le
+
+DATA EXAMINING COMMANDS
+
+The data examining commands fall into two categories, those that examine
+the catalog data including 'l' (catalog listing), 'o' (object listing),
+'x' (Y column versus X column plot) and 'h' (histogram column plot)
+commands, and those which examine the image data around specific catalog
+objects including 'r' (radial profile plotting), 's' (surface plotting),
+'c' (contour plotting) and 'm' (pixel dumping). The latter group
+require that \fIimage\fR be defined. A brief summary of each data
+examining command is given below.
+.ls l
+Print out the name, datatype, and units for all the columns in the input
+catalog. The list command can be used to check the contents of the input
+catalog and/or determine why a particular column was not loaded.
+.le
+.ls o
+Print out the names and values of the stored columns of the object
+nearest the cursor. In graphics mode the current plot type must be
+X-Y. In image command mode the object nearest the cursor must also be
+no more than \fImatch-radius\fR pixels away from the image cursor to be
+found. If an object is found and the current plot type is X-Y
+the graphics cursor is moved to the position of the selected object
+in the X-Y plot.
+.le
+.ls x
+Plot the data in \fIycolumn\fR versus the data in \fIxcolumn\fR excluding
+any already deleted points and identifying objects marked for deletion
+with a cross. X-Y plotting is undefined if \fIxcolumn\fR or \fIycolumn\fR
+is undefined.
+.le
+.ls h
+Plot the histogram of the data in \fIhcolumn\fR excluding any already
+deleted points and those marked for deletion. Histogram plotting is
+disabled if \fIhcolumn\fR is undefined.
+.le
+.ls r
+Plot the radial profile of the object nearest the cursor including
+only pixels within a distance of \fIrinner\fR and \fIrouter\fR of
+the object center. Radial profile plotting is disabled if \fIimage\fR
+or \fIxposcolumn\fR or \fIyposcolumn\fR is undefined.
+.le
+.ls s
+Plot the surface plot of the object nearest the cursor including
+only pixels within an image section \fIncols\fR by \fInlines\fR
+around the object center. Surface plotting is disabled if \fIimage\fR
+or \fIxposcolumn\fR or \fIyposcolumn\fR is undefined.
+.le
+.ls c
+Plot the contour plot of the object nearest the cursor including
+only pixels within an image section \fIncols\fR by \fInlines\fR
+around the object center. Contour plotting is disabled if \fIimage\fR
+or \fIxposcolumn\fR or \fIyposcolumn\fR is undefined.
+.le
+.ls m
+Dump the pixel values of a grid of 10 by 10 pixels around the object
+nearest the cursor. Pixel value dumping is disabled if \fIimage\fR
+or \fIxposcolumn\fR or \fIyposcolumn\fR is undefined.
+.le
+.ls p
+Replot the current graph.
+.le
+
+DATA EDITING COMMANDS
+
+Data points can be deleted from the catalog in either graphics command
+mode or image
+command mode. In graphics command mode the
+graphics cursor and either the X-Y or histogram plot is used to delete points.
+In image command mode the image cursor and the displayed
+image are used to delete points. A data point has three possible states
+good, marked for deletion and deleted.
+Any one of the keystroke commands 'd' (delete point), '(' (delete points
+with x less than x cursor), ')' (delete points with x greater than x cursor,
+'^' (delete points with y > y cursor), 'v' (delete points with y < y cursor)
+or 'b' (delete points in a box) can be used to mark points for deletion.
+The 'f' key is used to actually delete the points and replot the data.
+In between marking the points for deletion and actually deleting the marked
+points the 't' (toggle) key can be used to undelete the last set marked.
+The full list of the data editing keystroke commands is given below.
+
+.ls z
+Undelete not just unmark all the data points replot.
+.le
+.ls f
+Delete points marked for deletion and replot. Points marked for deletion
+but not actually deleted will be written to the output catalog and not
+written to the deletions catalog.
+.le
+.ls d
+Mark the point nearest the cursor for deletion.
+.le
+.ls u
+Undelete the marked point nearest the cursor.
+.le
+.ls (
+Mark all points with x values less than the x value of the cursor for
+deletion. In graphics command mode points can only be marked for deletion if
+the current plot type is "xyplot" or "histplot". In image command
+mode \fIxposcolumn\fR and \fIyposcolumn\fR must be defined before
+points can be marked for deletion.
+.le
+.ls )
+Mark all points with x values greater than the x value of the cursor for
+deletion. In graphics command mode points can only be marked for deletion if
+the current plot type is "xyplot" or "histplot". In image command
+mode \fIxposcolumn\fR and \fIyposcolumn\fR must be defined before
+points can be marked for deletion.
+.le
+.ls v
+Mark all points with y values less than the y value of the cursor for
+deletion. In graphics command mode points can only be marked for deletion if
+the current plot type is "xyplot". In image command
+mode \fIxposcolumn\fR and \fIyposcolumn\fR must be defined before
+points can be marked for deletion.
+.le
+.ls ^
+Mark all points with y values greater than the y value of the cursor for
+deletion. In graphics command mode points can only be marked for deletion if
+the current plot type is "xyplot". In image command
+mode \fIxposcolumn\fR and \fIyposcolumn\fR must be defined before
+points can be marked for deletion.
+.le
+.ls b
+Mark all points within a box whose lower left and upper right hand corners
+are marked by the cursor for deletion.
+In graphics mode points can only be marked for deletion if the current
+plot type is "xyplot". In image command mode \fIxposcolumn\fR and
+\fIyposcolumn\fR must be defined before points can be marked for
+deletion.
+.le
+.ls t
+Toggle between marking points for deletion or undeletion. The default
+is to mark points for deletion.
+.le
+
+BASIC COLON COMMANDS
+
+All the PEXAMINE parameters can be changed interactively with colon
+commands, including those which determine which data is read in,
+which data is plotted and the parameters of each plot. A brief description
+of the basic commands is given here. The full list is given in the
+following section.
+
+.ls :photcolumns [col1,col2,...]
+Show or set the list of requested standard photometry columns and the list
+of loaded
+photometry columns. If the user supplies a new list of columns the data will be
+reread from disk.
+.le
+.ls :usercolumns [col1,col2,...]
+Show or set the list of requested user columns and the list of loaded
+user columns. If the user supplies a new list of columns the data will be
+reread from disk.
+.le
+.ls :xcolumn [colname]
+Show or set the name of the column to be plotted along the x axis of the
+X-Y plot.
+.le
+.ls :ycolumn [colname]
+Show or set the name of the column to be plotted along the y axis of the
+X-Y plot.
+.le
+.ls :hcolumn [colname]
+Show or set the name of the column to be whose histogram is to be plotted.
+.le
+.ls :eparam [cntrplot/histplot/radplot/surfplot/xyplot]
+Review or edit the list of parameters for the various plot types.
+.le
+.ls :unlearn [cntrplot/histplot/radplot/surfplot/xyplot]
+Return the list of parameters for the various plot types to their default
+values.
+.le
+.ls :x y key cmd
+Execute any defined keystroke "key" supplying the appropriate x and y
+value in place of the cursor position. In graphics command mode the x
+and y position are assumed to be the position in the current graph.
+In image command mode the x and y position are assumed to be the x and
+y coordinate in the image display.
+.le
+
+.ih
+COMMANDS
+
+.nf
+ PEXAMINE Interactive Cursor Keystroke Commands
+
+ Basic Commands
+
+? Print help for the PEXAMINE task
+: PEXAMINE colon commands
+g Activate the graphics cursor
+i Activate the image cursor
+e Exit PEXAMINE and save the edited catalog
+q Quit PEXAMINE and discard the edited catalog
+
+ Data Examining Commands
+
+l List the name, datatype and units for all columns in the catalog
+o Print out the names and values of the stored columns for the
+ object nearest the cursor
+x Replot the current y column versus the current x column
+h Replot the current histogram
+r Plot the radial profile of the object nearest the cursor
+s Plot the surface of the object nearest the cursor
+c Plot the contour plot of the object nearest the cursor
+m Print the data values of the object nearest the cursor
+p Replot the current graph
+
+ Data Editing Commands
+
+z Reinitialize the data by removing all deletions and replot
+d Mark the point nearest the cursor for deletion
+u Undelete the marked point nearest the cursor
+t Toggle between marking points for deletion or undeletion
+( Mark points with X < X (cursor) for deletion or undeletion
+) Mark points with X > X (cursor) for deletion or undeletion
+v Mark points with Y < Y (cursor) for deletion or undeletion
+^ Mark points with Y > Y (cursor) for deletion or undeletion
+b Mark points inside a box for deletion or undeletion
+f Actually delete the marked points and replot
+
+
+ PEXAMINE Interactive Colon Commands
+
+:xcolumn [name] Show/set the X-Y plot X axis quantity
+:ycolumn [name] Show/set the X-Y plot Y axis quantity
+:hcolumn [name] Show/set the histogram plot quantity
+:photcolumns [col1,col2,...] Show/set the list of photometry columns
+:usercolumns [col1,col2,...] Show/set the list of user columns
+:delete [yes/no] Delete or undelete points
+:eparam [x/h/r/s/c] Edit/unlearn the specified plot pset
+ or
+:unlearn
+
+
+ PEXAMINE Interactive X-Y Plotting Commands
+
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:szmarker [value] Marker size
+:marker [point|box|plus|cross|circle|diamond|hline|vline] Marker type
+:logx [yes/no] Log scale the x axis?
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:grid [yes/no] Draw grid lines at major tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+
+ PEXAMINE Interactive Histogram Plotting Commands
+
+:nbins [value] Number of bins in the histogram
+:z1 [value] Minimum histogram intensity
+:z2 [value] Maximum histogram intensity
+:top_closed [y/n] Include z in the top bin?
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+ PEXAMINE Interactive Radial Profile Plotting Commands
+
+:rinner [value] Inner radius of the region to be plotted
+:router [value] Outer radius of the region to be plotted
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:szmarker [value] Marker size
+:marker [point|box|plus|cross|circle|diamond|hline|vline] Marker type
+:logx [yes/no] Log scale the x axis?
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:grid [yes/no] Draw grid lines at major tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+
+ PEXAMINE Interactive Surface Plotting Commands
+
+:ncolumns [value] Number of columns to be plotted
+:nlines [value] Number of lines to be plotted
+:axes [yes/no] Draw axes?
+:angh [value] Horizontal viewing angle
+:angv [value] Vertical viewing angle
+:floor [value] Minimum value to be plotted
+:ceiling [value] Maximum value to be plotted
+
+
+ PEXAMINE Interactive Contour Plotting Commands
+
+:ncolumns [value] Number of columns to be plotted
+:nlines [value] Number of lines to be plotted
+:floor [value] Minimum value to be plotted
+:ceiling [value] Maximum value to be plotted
+:zero [value] Greyscale value of zero contour
+:ncontours [value] Number of contours to be drawn
+:interval [value] Contour interval
+:nhi [value] Hi/low marking option
+:dashpat [value] Bit pattern for generating dashed lines
+:label [yes/no] Label major contours with their values?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+.fi
+
+.ih
+EXAMPLES
+
+1. Examine and edit an APPHOT aperture photometry catalog and a DAOPHOT
+allstar catalog without either attaching the associated image or using the
+image display.
+
+.nf
+ pt> pexamine m92.mag.1 m92.mag.ed use_display-
+
+ ... a plot of magnitude error versus magnitude appears on
+ the screen and the graphics cursor comes up ready to accept
+ commands
+
+ ... the user sees a generally smooth trend of increasing
+ magnitude error with increasing magnitude except for a
+ single deviant point at the bright end of the plot
+
+ ... the user decides to remove the deviant point using the
+ 'd' keystroke command to mark the point and the 'f'
+ keystroke command to actually delete and replot the graph
+
+ ... after examining the plot further the user decides to delete
+ all objects for which the magnitude error is > 0.1 magnitudes
+ using the '^' keystroke command, followed by the 'f'
+ keystroke command to actually replot and delete the data.
+
+ ... after deciding that this new plot is satisfactory the user
+ issues the 'e' keystroke command to exit pexamine and save
+ the good data in m92.mag.ed
+
+ pt> pexamine m92.als.1 m92.als.ed use_display-
+
+ ... a plot of magnitude error versus magnitude appears on the
+ screen and the graphics cursor comes up ready to accept
+ commands
+
+ ... after looking at the plot the user decides that what they
+ really want to see is a plot of the goodness of fit parameter
+ chi versus magnitude
+
+ ... the user issues the colon command :ycol chi followed by 'p'
+ keystroke command to replot the data
+
+ ... the user sees a generally smooth trend of increasing
+ chi with increasing magnitude
+
+ ... after examining the plot further the user decides to delete
+ all objects for which the chi value > 2.0 and the
+ magnitude is > 25 using the '^' key and ')' keystroke
+ commands followed by 'f' to save the deletions and replot
+ the data
+
+ ... after deciding that this new plot is satisfactory the user
+ issues the 'e' keystroke command to exit pexamine and save
+ the good data in m92.als.ed
+.fi
+
+2. Examine and edit a DAOPHOT allstar catalog using the subtracted image, the
+original image and the image display.
+
+.nf
+ pt> display image.sub 1
+
+ ... display the subtracted image
+
+ pt> pexamine orionk.als.1 orionk.als.ed image xcol=mag ycol=chi
+
+ ... a plot of the goodness of fit versus magnitude appears
+ on the terminal and the graphics cursor comes up ready to
+ accept commands
+
+ ... the user notices some very anomalous chi values and decides
+ to see if these correspond to objects which have poor
+ subtraction on the displayed image
+
+ ... the user switches to image command mode by tapping the 'i'
+ key, moves to the first poorly subtracted object and taps
+ the 'o' key
+
+ ... a list of the values of the loaded columns including chi
+ appears in the text window , the program switches to graphics
+ mode and places the graphics cursor on the corresponding
+ point in the X-Y plot
+
+ ... the point in question indeed has a very high chi value
+ and the user decides to try and investigate the reason for the
+ anomalous value
+
+ ... the user taps the 'r' key to get a radial profile of the
+ object in the original image
+
+ ... after carefully examining the profile it appears that the
+ object's profile is too broad and that it is not a star
+
+ ... the user switches back to the X-Y plot with the 'x' key,
+ marks the point with the 'd' key and saves the deletions
+ and replots with the 'f' key.
+
+ ... the user goes back to image command mode with the 'i' key
+ and begins investigating the next object
+
+ ... finally after examining the image and making all the changes
+ the user decides to quit and save the changes with the 'e' key
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+
+.ih
+BUGS
+If the display device is on a remote resource the first image cursor
+request will cause PEXAMINE to hang. The remote resource is expecting
+the appropriate password which the user must type in to cause the
+the image cursor to appear. The normal password prompt is
+not being issued or flushed to the terminal. The solution to the problem
+is to put the password in the .irafhosts file
+
+INDEF valued points cannot be accessed by
+PEXAMINE. INDEF valued points should be removed from the input catalog
+with PSELECT prior to entering PEXAMINE.
+
+.ih
+SEE ALSO
+ptools.pselect, ptools.txselect,ptools.tselect
+.endhelp
diff --git a/noao/digiphot/ptools/doc/prenumber.hlp b/noao/digiphot/ptools/doc/prenumber.hlp
new file mode 100644
index 00000000..1dcc4ed9
--- /dev/null
+++ b/noao/digiphot/ptools/doc/prenumber.hlp
@@ -0,0 +1,59 @@
+.help prenumber May93 noao.digiphot.ptools
+.ih
+NAME
+prenumber -- renumber an APPHOT/DAOPHOT database
+.ih
+USAGE
+renumber infile
+.ih
+PARAMETERS
+.ls infile
+The APPHOT/DAOPHOT database to be renumbered.
+.le
+.ls id = "ID"
+The name of the keyword whose value is the sequence number of the object
+.le
+.ls idoffset = 0
+An integer offset to be added to the id numbers of the stars in
+the output renumbered photometry file. If idoffset is > 0, the output
+id numbers will run from 1 + idoffset to N + idoffset instead of from 1 to N.
+in the database.
+.le
+
+.ih
+DESCRIPTION
+PRENUMBER is a simple task which accepts an APPHOT/DAOPHOT
+database file and renumbers the objects in the file from 1 + idoffset
+to N + idoffset,
+where N is the number of objects in the database. A renumber operation is
+often performed
+after an append operation to insure that the database objects have unique id
+numbers or after a sort to put the id numbers in order.
+
+PRENUMBER is a script which executes TXRENUMBER if the APPHOT/DAOPHOT
+database is a text database or TCALC if the file is an STSDAS table
+database.
+.ih
+EXAMPLES
+
+1. Renumber a sorted NSTAR database that has been sorted on magnitude.
+
+.nf
+ pt> prenumber m92r.nst.1
+.fi
+
+2. Renumber a PHOT photometry file of extra stars so as to ensure the
+stars' id numbers are greater than 4000.
+
+.nf
+ pt> prenumber m92r.mag.extra idoffset=4000
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txrenumber,ptools.tbrenumber,tables.tcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pselect.hlp b/noao/digiphot/ptools/doc/pselect.hlp
new file mode 100644
index 00000000..92d4f163
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pselect.hlp
@@ -0,0 +1,130 @@
+.help pselect Aug91 noao.digiphot.ptools
+.ih
+NAME
+pselect - select records from an APPHOT/DAOPHOT database
+.ih
+USAGE
+pselect infiles outfiles expr
+.ih
+PARAMETERS
+.ls infiles
+The APPHOT/DAOPHOT databases containing the records from which the
+selection is to be made.
+.le
+.ls outfiles
+The output APPHOT/DAOPHOT databases containing the selected records.
+.le
+.ls expr
+The boolean expression to be evaluated. The expression
+is evaluated once for each record. If \fIexpr\fR = yes,
+a copy is made of the input file.
+.le
+
+.ih
+DESCRIPTION
+PSELECT selects a subset of the records
+from an APPHOT/DAOPHOT database or a list of databases
+and writes the new records out to another database or list of
+databases.
+
+The output records are selected on the basis of an input boolean
+expression \fIexpr\fR whose variables are in the case of text
+databases the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords and in the case of an STSDAS table database the
+column names.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates
+to yes, that record is included in the output database.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters are listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The boolean expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Select the records from the output of the APPHOT CENTER task for
+which 100. <= XCENTER <= 200. and 300. <= YCENTER <= 400.
+
+.nf
+ pt> pselect m92.ctr.3 m92out \
+ "XCE >= 100. && XCE <= 200. && YCE >= 300. && YCE <= 400."
+.fi
+
+2. Select the records from the output of the APPHOT PHOT task for which
+the first magnitude is not equal to INDEF. In the case of the
+an STSDAS table database it may be necessary to escape the
+leading square bracket.
+
+.nf
+ pt> pselect n4147.mag.3 n4147out "MAG[1] != INDEF"
+
+ or
+
+ pt> pselect n4147.mag.3 n4147out "MAG\[1] != INDEF"
+.fi
+
+3. Select the records from the output of the DAOPHOT ALLSTAR task
+for which CHI <= 5.0 and MERR <= .10 magnitudes.
+
+.nf
+ pt> pselect m92b.al.2 m92out "CHI <= 5.0 && MERR <= 1.0"
+.fi
+
+.ih
+BUGS
+Array valued fields in text databases are not allowed in the expression
+field.
+
+.ih
+SEE ALSO
+images.hedit,ptools.tbselect,tables.tselect,ptools.txselect
+.endhelp
diff --git a/noao/digiphot/ptools/doc/psort.hlp b/noao/digiphot/ptools/doc/psort.hlp
new file mode 100644
index 00000000..806448c9
--- /dev/null
+++ b/noao/digiphot/ptools/doc/psort.hlp
@@ -0,0 +1,64 @@
+.help psort Aug91 noao.digiphot.ptools
+.ih
+NAME
+psort -- sort an APPHOT/DAOPHOT database file
+.ih
+USAGE
+psort infiles field
+.ih
+PARAMETERS
+.ls infiles
+The input APPHOT/DAOPHOT databases to be sorted. The sort is performed in place.
+.le
+.ls field
+The field to be sorted on. If the input file is a text database,
+\fIfield\fR may be any quantity defined by
+the APPHOT/DAOPHOT #K and #N keywords. If the input file is an STSDAS
+table database \fIfield\fR may be any column name. \fIField\fR may be
+of type integer or real, in which case a numeric sort is performed,
+boolean, in which case the boolean constant "no" is assumed to have a
+smaller value than "yes", or character in which case an alphabetic sort
+is performed.
+.le
+.ls ascend = yes
+Sort in increasing value order.
+.le
+.ih
+DESCRIPTION
+PSORT is a simple task which accepts an APPHOT/DAOPHOT database file
+and sorts it in place based on the value of the selected quantity
+\fIfield\fR. By default the sort is in increasing order of the value
+of field, but a reverse sort can be performed by
+setting \fIascend\fR = no.
+
+If \fIfield\fR is a real or integer the sort is numeric, if boolean
+the constant "no" is assumed to have a smaller value than "yes", if
+character the sort is alphabetic.
+
+PSORT is a simple CL script which call TXSORT if the input database is
+a text file and TSORT if the input database is a text file.
+.ih
+EXAMPLES
+
+1. Sort the output of the APPHOT task PHOT in increasing order of
+the y coordinate.
+
+.nf
+ pt> psort m92.mag.1 YCENTER
+.fi
+
+2. Sort the output of the DAOPHOT task ALLSTAR in increasing order of
+magnitude.
+
+.nf
+ pt> psort m92.al.1 MAG
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txsort,tables.tsort,ptools.tbsort
+.endhelp
diff --git a/noao/digiphot/ptools/doc/pttest.hlp b/noao/digiphot/ptools/doc/pttest.hlp
new file mode 100644
index 00000000..3329e017
--- /dev/null
+++ b/noao/digiphot/ptools/doc/pttest.hlp
@@ -0,0 +1,78 @@
+.help pttest Oct91 noao.digiphot.ptools
+.ih
+NAME
+pttest -- run basic tests on the ptools package tasks
+.ih
+USAGE
+pttest rootname
+.ih
+PARAMETERS
+.ls rootname
+The root name of the output test files. The actual test files are stored in
+in the PTOOLS package test directory. If the test files already exist
+PTTEST will exit with a warning message.
+.le
+.ls ptlogfile = ""
+The name of the output log file. By default all the output is logged in a file
+called \fIrootname.log"\fR. If the log file already exists PTTEST will
+exit with a warning message.
+.le
+.ls ptplotfile = ""
+The name of the output plot file. By default all the graphics output is
+logged in a file called \fIrootname.plot"\fR. If the plot file already exists
+PTTEST will exit with a warning message.
+.le
+
+.ih
+DESCRIPTION
+
+PTTEST is a simple script which exercises each of the major tasks in the
+PTOOLS package in turn. At startup PTTEST reads a small set of text files
+stored in the PTOOLS test subdirectory and creates copies of them in
+the user's working directory. PTTEST initializes the PTTOLS package by
+returning
+all the parameters to their default state, runs each of the PTOOLS
+tasks in non-interactive mode, spools the text output to the file
+\fIptlogfile\fR, and the graphics output from the PEXAMINE task to the plot
+metacode file \fIptplotfile\fR.
+
+Some of PTOOLS tasks which PTTEST attempts to test are in the STSDAS TABLES
+package. If this package is not available a warning message will appear
+on the screen and this part of the PTTEST script will be skipped.
+The TABLES external addon package is available from ST.
+
+.ih
+EXAMPLES
+
+1. Check to see that all the PTOOLS tasks are functioning correctly.
+.nf
+ da> ptools
+
+ ... load the ptools package
+
+ da> pttest testit
+
+ ... run the test script
+
+ da> lprint testit.log
+
+ ... print the text output
+
+ da> gkidir testit.plot
+
+ ... list the contents of the plot file
+
+ da> gkiextract testit.plot 1-N | stdplot
+
+ ... send the plots to the plotter
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+tables
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbcalc.hlp b/noao/digiphot/ptools/doc/tbcalc.hlp
new file mode 100644
index 00000000..9e0f83b9
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbcalc.hlp
@@ -0,0 +1,79 @@
+.help tbcalc May93 noao.digiphot.ptools
+.ih
+NAME
+tbcalc - perform an arithmetic operation on a column in a list of apphot/daophot
+ ST tables databases
+.ih
+USAGE
+tbcalc textfiles column value
+.ih
+PARAMETERS
+.ls textfiles
+The APPHOT/DAOPHOT ST tables database(s) containing the column to be recomputed.
+.le
+.ls column
+The column to be recomputed. Column must be an integer or real column
+in the input file(s).
+.le
+.ls value
+The arithmetic expression used to recompute the specified column.
+Value may be an integer or real expression but must match the data
+type of column.
+.le
+
+.ih
+DESCRIPTION
+
+TBCALC reads in the value of the \fIcolumn\fR
+from a set of APPHOT/DAOPHOT ST tables databases, replaces it with a new
+value specified by the arithmetic expression \fIvalue\fR,
+and updates the ST tables databases(s).
+
+The expression \fIvalue\fR consists of variables which are column names
+in the APPHOT/DAOPHOT ST tables database.
+TBCALC uses the TABLES package task TCALC to actually perform the
+arithmetic operation.
+
+The supported
+arithmetic operators and functions are briefly described below.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Change the XCENTER and YCENTER fields to XCENTER + 5.4 and YCENTER + 10.3
+respectively in a file produced by the daophot package allstar task.
+
+.nf
+ pt> tbcalc m92.als.1 xcenter "xcenter+5.4"
+ pt> tbcalc m92.als.1 ycenter "ycenter+10.3"
+.fi
+
+2. Add a constant to the computed magnitudes produced by the daophot
+package nstar task.
+
+.nf
+ pt> tbcalc n4147.nst.2 mag "mag+3.457"
+.fi
+
+.ih
+BUGS
+
+.ih
+SEE ALSO
+ptools.txcalc,tables.tcalc,ptools.pcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbconcat.hlp b/noao/digiphot/ptools/doc/tbconcat.hlp
new file mode 100644
index 00000000..846b8f6e
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbconcat.hlp
@@ -0,0 +1,49 @@
+.help tbconcat Dec92 noao.digiphot.ptools
+.ih
+NAME
+tbconcat -- concatenate a list of APPHOT/DAOPHOT STSDAS databases
+.ih
+USAGE
+tbconcat tables outtable
+.ih
+PARAMETERS
+.ls tables
+The list of APPHOT/DAOPHOT STSDAS databases to be concatenated.
+.le
+.ls outtable
+The name of the output APPHOT/DAOPHOT STSDAS database.
+.le
+.ls task = "TASK"
+The name of the keyword whose value is the name of the task which wrote
+the database.
+.le
+.ih
+DESCRIPTION
+TBCONCAT is a simple task which accepts a list of APPHOT/DAOPHOT STSDAS
+database files and concatenates them into one resultant database.
+TBCONCAT checks that all the file are indeed APPHOT/DAOPHOT STSDAS
+database files and that they were all written by the same task before
+performing the concatenation.
+
+TBCONCAT is a simple script built around the STSDAS TABLES package
+task TMERGE. Users should consult the manual page for TMERGE for
+more details about the inner working of the task.
+
+.ih
+EXAMPLES
+
+1. Concatenate a list of DAOPHOT package GROUP output tables into a
+single file.
+
+.nf
+ pt> tbconcat m92r.grp.1,m92r.grp.2,m92r.grp.3 m92rall.grp.1
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txconcat,ptools.pconcat,tables.tmerge,concatenate
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbcrename.hlp b/noao/digiphot/ptools/doc/tbcrename.hlp
new file mode 100644
index 00000000..47d4fd3f
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbcrename.hlp
@@ -0,0 +1,50 @@
+.help tbcrename Aug91 noao.digiphot.ptools
+.ih
+NAME
+tbcrename -- rename selected columns in a list of table
+
+.ih
+USAGE
+tbcrename tables columns names
+
+.ih
+PARAMETERS
+
+.ls table
+The list of input tables files.
+.le
+.ls columns
+The list of columns separated by commas whose names are to be changed.
+.le
+.ls names
+The list of new column names separated by commas.
+.le
+
+.ih
+DESCRIPTION
+
+TBCRENAME takes a list of ST tables \fItables\fR and changes the names
+of selected columns \fIcolumns\fR to the names specified in \fInames\fR.
+If the input file is not an ST table or the column does not exist
+no action is taken. Otherwise the specified column is renamed.
+
+.ih
+EXAMPLES
+
+1. For the list of ST tables in tablelist, rename the columns "MAG,MERR"
+to "MAG[1],MERR[1]". Note the use of '\' to escape the pattern matching
+meta-character '['.
+
+.nf
+ pt> tbcrename @tablelist "MAG,MERR" "MAG\[1],MERR\[1]"
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+Since the contents of the ST table are altered the user must have
+write permission on the table in order to run TBCRENAME.
+.ih
+SEE ALSO
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbdump.hlp b/noao/digiphot/ptools/doc/tbdump.hlp
new file mode 100644
index 00000000..3cb5eac4
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbdump.hlp
@@ -0,0 +1,193 @@
+.help tbdump Feb93 noao.digiphot.ptools
+.ih
+NAME
+tbdump -- print fields (columns) from a list of APPHOT/DAOPHOT STSDAS table
+ databases
+.ih
+USAGE
+tbdump tables columns expr
+.ih
+PARAMETERS
+.ls tables
+The name of the APPHOT/DAOPHOT table database(s) to be dumped.
+.le
+.ls columns
+The template specifying the names of the columns to be dumped.
+A null or blank string means
+dump all columns. A column template consists of a list
+of either column names or column patterns containing the usual pattern matching
+meta-characters. The names or patterns are separated by commas or white space.
+Column names must be spelled in full but may be upper or lower case.
+The columns list can be placed in a file and the name of the file preceded
+by an '@' character given in place of the column template.
+If the first non-white character in the column template
+is the negation character '~', the output will contain those columns
+NOT named in the remainder of the column template.
+.le
+.ls expr
+The boolean expression to be evaluated once per record.
+Only the fields in those records for which the boolean expression
+evaluates to yes are printed.
+If \fIexpr\fR = "yes", the specified columns in all the records are
+printed.
+.le
+.ls datafile = STDOUT
+If \fIDatafile\fR is not null ("") then the table data will be written
+to an output file with this name. By default the table data is written
+on the standard output.
+\fIDatafile\fR will not be created if the table is empty.
+.le
+.ls cdfile = ""
+If \fICdfile\fR is not null ("") then the column definitions will be written
+to an output file with this name.
+The column definitions consist of the column name, data type (R, D, I, B,
+or C), print format, and units.
+.le
+.ls pfile = ""
+If \fIPfile\fR is not null ("") then the header parameters will be written
+to an output file with this name.
+\fIPfile\fR will not be created if there are no header parameters.
+.le
+.ls rows = "-"
+\fIRows\fR is a string which may be used to specify ranges of rows which are
+to be dumped. The default of "-" means dump all rows. The first
+ten rows could be specified as \fIrows\fR = "1-10" or just \fIrows\fR = "-10".
+To dump the first ten rows and all rows from 900 through the last,
+use \fIrows\fR = "-10,900-". \fIRows\fR = "1,3,7,23" will print only
+those four rows. It is not an error to specify rows larger than the largest
+row number as they will simply be ignored.
+See the help for RANGES in XTOOLS for further information.
+.le
+.ls pagwidth = 158
+The width of the output for printing the table data. If any of the columns
+to be printed is wider than this an error message will be displayed, and
+the data will not be dumped. The width of each character column is
+increased by two to include a pair of enclosing quotes.
+.le
+.ih
+DESCRIPTION
+This task converts selected records from an APPHOT/DAOPHOT STSDAS table
+database to ASCII format
+and by default prints the result on the standard output.
+TBDUMP output does not include row numbers or column names.
+The TABLES package task TPRINT can be used for more readable output.
+
+The PTOOLS version of TBDUMP described here is
+actually a combination of the STSDAS TABLES package tasks TSELECT and TDUMP.
+
+The three primary uses for TBDUMP are to format STSDAS tables for input to
+applications
+which expect simple text input, allow editing that would be
+difficult or impossible with the TABLES package TEDIT task, such as
+global substitutions,
+and facilitate copying a table over a network to another computer.
+For the latter two applications the table can be dumped to three separate files
+containing column definitions, header parameters, and table data,
+edited, column data types changed, etc.
+The TABLES package TCREATE can be used to create a new table from the three
+ASCII files produced by TBDUMP.
+By default only the column data is dumped.
+
+TBDUMP queries for the columns to be dumped. If \fIcolumns\fR is null ("")
+then all the columns are dumped.
+All the rows are dumped by default, but ranges of
+rows may be specified with the \fIrows\fR parameter.
+If the table is wider than will fit on a page,
+the output will consist of more than one line per row of the table,
+but all the columns will be printed before moving on to the next row.
+This is in contrast to TPRINT,
+which prints all rows for those columns that will fit on a page,
+then prints all rows for the next set of columns, etc.
+Character columns with multiple words are printed with enclosing quotes.
+
+The TABLES package TLCOL task (with TLCOL.NLIST=1) may be used to generate
+a list of
+column names so there is no question about spelling or case. This list may
+be edited to rearrange the names and/or delete some, the list
+file preceded by an '@' and used as the value of the \fIcolumns\fR
+parameter.
+
+The output records are selected on the basis of an input boolean
+expression \fIexpr\fR whose variables are the tables column names.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates
+to yes, that record is included in the output table.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+.ih
+EXAMPLES
+.nf
+1. Dump the "ID", "MAG" and "MAGERR" columns of the DAOPHOT package NSTAR
+output to the standard output.
+
+ pt> tbdump n4147.nst.1 "ID,MAG,MAGERR" yes
+
+2. Dump the "ID", "MAG", and "MAGERR" columns of the above file for records
+which have "MAG <= 20.0".
+
+ pt> tbdump n4147.nst.1 "ID,MAG,MAGERR" "MAG <= 20.0"
+
+3. Dump the "MAG" and "MAGERR" columns of the above file and pipe the
+result to graph.
+
+ pt> tbdump n4147.nst.1 "MAG,MAGERR" yes | graph STDIN
+
+4. Dump all the columns in the first 100 rows of the above file.
+
+ pt> tbdump n4147.nst.1 "" yes rows="1-100"
+.fi
+.ih
+BUGS
+.ih
+SEE ALSO
+tables.tdump,tables.tprint,tables.tlcol,tables.tcreate,ptools.txdump,ptools.pdump
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbkeycol.hlp b/noao/digiphot/ptools/doc/tbkeycol.hlp
new file mode 100644
index 00000000..0c79b882
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbkeycol.hlp
@@ -0,0 +1,50 @@
+.help tbkeycol Aug91 noao.ptools.digiphot
+.ih
+NAME
+tbkeycol -- create new table columns from table header keywords
+
+.ih
+USAGE
+tbkeycol table keywords
+
+.ih
+PARAMETERS
+
+.ls table
+The list of input ST tables.
+.le
+.ls keywords
+The list of ST table header keywords, separated by commas, whose values will be
+copied into the newly created ST table columns.
+.le
+
+.ih
+DESCRIPTION
+
+TBKEYCOL takes a list of ST tables \fItable\fR and copies the values of the
+header keywords \fIkeywords\fR into newly created columns of the same name.
+If the input file is not an ST table, an output column of the same name as the
+keyword already exists, or the keyword does not exist, no action is
+taken. Otherwise a new column of the same name as the keyword is created,
+and the value of the keyword is copied into all rows of the table.
+
+.ih
+EXAMPLES
+
+1. For the list of ST tables in tablelist, copy the values of the header
+keywords "IMAGE", "ITIME", "IFILTER", and "XAIRMASS" into table columns
+of the same name.
+
+.nf
+ pt> tbkeycol @tablelist "IMAGE,ITIME,IFILTER,XAIRMASS"
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+Since the structure of the ST table is altered the user must have
+write permission on the table in order to run TBKEYCOL.
+.ih
+SEE ALSO
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbrenumber.hlp b/noao/digiphot/ptools/doc/tbrenumber.hlp
new file mode 100644
index 00000000..55c50770
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbrenumber.hlp
@@ -0,0 +1,54 @@
+.help tbrenumber May93 noao.digiphot.ptools
+.ih
+NAME
+tbrenumber -- renumber a list of APPHOT/DAOPHOT STSDAS table database(s)
+.ih
+USAGE
+tbrenumber tables
+.ih
+PARAMETERS
+.ls tables
+The list of APPHOT/DAOPHOT STSDAS table databases to be renumbered.
+.le
+.ls idoffset = 0
+An integer offset to be added to the id numbers of the stars in
+the output renumbered photometry file. If idoffset is > 0, the output
+id numbers will run from 1 + idoffset to N + idoffset instead of from 1 to N.
+.le
+.ls id = "ID"
+The name of the keyword whose value is the sequence number of the object
+in the database.
+.le
+.ih
+DESCRIPTION
+TBRENUMBER is a simple script task which accepts an APPHOT/DAOPHOT STSDAS
+table database and renumbers the objects from 1 + idoffset to N + idoffset,
+where N is the number
+of objects in the database. TBRENUMBER calls the TABLES package TCALC task
+to actually do the work.
+
+.ih
+EXAMPLES
+
+1. Renumber a concatenated NSTAR photometry file that has been written with
+TBCONCAT.
+
+.nf
+ pt> tbrenumber m92r.nst
+.fi
+
+2. Renumber a PHOT photometry file of extra stars so as to ensure the
+stars' id numbers are greater than 4000.
+
+.nf
+ pt> tbrenumber m92r.mag.extra idoffset=4000
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txrenumber,ptools.prenumber,tables.tcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbselect.hlp b/noao/digiphot/ptools/doc/tbselect.hlp
new file mode 100644
index 00000000..1a4ad6f4
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbselect.hlp
@@ -0,0 +1,107 @@
+.help tbselect Aug91 noao.digiphot.ptools
+.ih
+NAME
+tbselect -- create a new APPHOT/DAOPHOT table database from selected rows
+of an old APPHOT/DAOPHOT table database
+.ih
+USAGE
+tbselect intable outtable expr
+.ih
+PARAMETERS
+.ls intable
+The list of APPHOT/DAOPHOT STSDAS table databases from which rows are
+copied.
+.le
+.ls outtable
+The list of output APPHOT/DAOPHOT table databases to contain the copied rows.
+The number of output tables must equal the number of input tables.
+.le
+.ls expr
+The boolean expression which determines which rows are copied to the new
+table. \fIExpr\fR is evaluated once for each input row of data.
+If \fIexpr\fR is "yes" a copy is made of the old input table.
+.le
+.ih
+DESCRIPTION
+TSELECT creates a new APPHOT/DAOPHOT table database containing a subset of
+the rows in the old table database.
+The rows are selected on the basis of an input boolean expression whose
+variables are table column names.
+If after substituting the values associated
+with a particular row into the column name variables the expression evaluates
+to yes, that row is included in the output table.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters are listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+.ih
+EXAMPLES
+
+1. Extract all stars brighter than twentieth magnitude from an
+the output of the DAOPHOT ALLSTAR task and create a new database.
+
+.nf
+ pt> tbselect m92.al.1 m92out "MAG <= 20.0"
+.fi
+
+2. Create a new database from the output of the DAOPHOT NSTAR task by
+removing all INDEF valued magnitudes.
+
+.nf
+ pt> tbselect n2264b.nst.1 n2264out "MAG != INDEF"
+
+.fi
+.ih
+BUGS
+Column names must be set off from operators by blanks in the expression so
+that they can be correctly parsed by the expression evaluator.
+.ih
+SEE ALSO
+ptools.txselect,tables.tselect,ptools.tbselect
+.endhelp
diff --git a/noao/digiphot/ptools/doc/tbsort.hlp b/noao/digiphot/ptools/doc/tbsort.hlp
new file mode 100644
index 00000000..6812868a
--- /dev/null
+++ b/noao/digiphot/ptools/doc/tbsort.hlp
@@ -0,0 +1,78 @@
+.help tbsort Aug91 noao.digiphot.ptools
+.ih
+NAME
+tbsort -- sort an APPHOT/DAOPHOT STSDAS table database on one or more columns
+.ih
+USAGE
+tbsort table columns
+.ih
+PARAMETERS
+.ls table
+The list of APPHOT/DAOPHOT table databases to be sorted in-place.
+All tables are sorted on the same column or columns.
+.le
+.ls columns
+The list of columns to sort on. A column template consists of a list of
+either column names, or column patterns containing the usual pattern matching
+meta-characters. The names or patterns are separated by commas or white space.
+The list can be placed in a file and the name of the file preceeded by a
+'@' can be given in place of the column template.
+.le
+.ls ascend = yes
+If \fIascend\fR = yes, the table is sorted in ascending value order, with the
+first
+row containing the smallest value of the sorted column. Otherwise, the table
+is sorted in descending order, with the largest value first.
+.le
+.ls casesens = yes
+If \fIcasesens\fR = yes, sorts on character columns are case sensitive,
+with upper case letters preceding lower case in the sort.
+Otherwise, the sort is case insensitive.
+.le
+.ih
+DESCRIPTION
+TBSORT sorts an APPHOT/DAOPHOT STSDAS table database.
+TBSORT operates in place so
+a copy of the unsorted table must be made with the TABLES
+package TCOPY task in order to preserve the original table.
+The column or columns to sort on are specified by the parameter
+\fIcolumns\fR, which is a list of column names or column name patterns
+separated by
+commas. The most significant column name is the first in the list. Subsequent
+columns are used to break ties. There are two flags, \fIascend\fR
+and \fIcasesens\fR. If \fIascend\fR is yes,
+the first row in the output table holds the smallest value if
+the sorted column is numeric or the first string in alphabetic order if the
+sorted column is a character string. If \fIcasesens\fR is yes,
+upper case characters
+precede lower case characters in sort order. Otherwise, case is not significant
+in determining the sort order. No precedes yes when sorting a boolean column
+in ascending order. Null table elements always are last in the sort, regardless
+of whether \fIascend\fR is yes or no.
+
+TBSORT is identical to the TABLES package sort with the exception that
+it has its own copy of the default parameter set so that users
+can modify the parameters independently of the TBSORT task in TABLES.
+.ih
+EXAMPLES
+
+1. Sort the output of the DAOPHOT ALLSTAR task in increasing order of
+magnitude.
+
+.nf
+ pt> tbsort m92.al.1 MAG
+.fi
+
+2. Sort the output of the DAOPHOT task NSTAR in increasing order of
+the y position.
+
+.nf
+ pt> tbsort m92.nst.1 YCENTER
+.fi
+
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.txsort,ptools.psort,tables.tbsort
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txcalc.hlp b/noao/digiphot/ptools/doc/txcalc.hlp
new file mode 100644
index 00000000..747adabd
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txcalc.hlp
@@ -0,0 +1,80 @@
+.help txcalc May93 noao.digiphot.ptools
+.ih
+NAME
+txcalc - perform an arithmetic operation on a field in a list of apphot/daophot
+ text databases
+.ih
+USAGE
+txcalc textfiles field value
+.ih
+PARAMETERS
+.ls textfiles
+The APPHOT/DAOPHOT text database(s) containing the field to be recomputed.
+.le
+.ls field
+The field to be recomputed. Field must be an integer or real field
+in the input file(s).
+.le
+.ls value
+The arithmetic expression used to recompute the specified field.
+Value may be an integer or real expression but must match the data
+type of field. The functions real and int may be used to do type
+conversions.
+.le
+
+.ih
+DESCRIPTION
+
+TXCALC reads in the values of the \fIfield\fR keyword
+from a set of APPHOT/DAOPHOT text databases, replaces the old values
+with new values equal to the value of the arithmetic expression \fIvalue\fR,
+and updates the text databases(s).
+
+The expression \fIvalue\fR consists of variables which are the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords in the APPHOT/DAOPHOT text databases.
+Only keywords beginning with #N can actually be replaced.
+
+The supported
+arithmetic operators and functions are briefly described below.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Change the XCENTER and YCENTER fields to XCENTER + 5.4 and YCENTER + 10.3
+respectively in a file produced by the apphot package center task.
+
+.nf
+ pt> txcalc m92.ctr.1 xcenter "xcenter+5.4"
+ pt> txcalc m92.ctr.1 ycenter "ycenter+10.3"
+.fi
+
+2. Add a constant to the computed magnitudes produced by nstar.
+
+.nf
+ pt> txcalc n4147.nst.2 mag "mag+3.457"
+.fi
+
+.ih
+BUGS
+TXCALC does not allow arrays in the expression field.
+
+.ih
+SEE ALSO
+ptools.tbcalc,tables.tcalc,ptools.pcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txconcat.hlp b/noao/digiphot/ptools/doc/txconcat.hlp
new file mode 100644
index 00000000..87516f72
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txconcat.hlp
@@ -0,0 +1,45 @@
+.help txconcat Dec92 noao.digiphot.ptools
+.ih
+NAME
+txconcat -- concatenate a list of APPHOT/DAOPHOT text databases
+.ih
+USAGE
+txconcat textfiles outfile
+.ih
+PARAMETERS
+.ls textfiles
+The list of APPHOT/DAOPHOT text databases to be concatenated.
+.le
+.ls outfile
+The name of the output APPHOT/DAOPHOT text database.
+.le
+.ls task = "TASK"
+The name of the keywords whose value is the name of the task which wrote
+the database.
+.le
+.ih
+DESCRIPTION
+TXCONCAT is a simple task which accepts a list of APPHOT/DAOPHOT text
+database files and concatenates them into one resultant output file.
+TXCONCAT checks that all the file are indeed APPHOT/DAOPHOT text
+database files and that they were all written by the same task before
+performing the concatenation.
+
+.ih
+EXAMPLES
+
+1. Concatenate a list of DAOPHOT PHOT task result files into a single
+output file.
+
+.nf
+ pt> txconcat m92r.mag.1,m92r.mag.2,m92r.mag.3 m92rall.mag.1
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.tbconcat,ptools.pconcat,tables.tmerge,concatenate
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txdump.hlp b/noao/digiphot/ptools/doc/txdump.hlp
new file mode 100644
index 00000000..bd432afb
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txdump.hlp
@@ -0,0 +1,167 @@
+.help txdump Aug91 noao.digiphot.ptools
+.ih
+NAME
+txdump - print fields from selected records in an APPHOT/DAOPHOT text database
+.ih
+USAGE
+txdump textfiles fields expr
+.ih
+PARAMETERS
+.ls textfiles
+The APPHOT/DAOPHOT text database whose fields from selected records are to
+be printed.
+.le
+.ls fields
+A template defining the fields to be printed from each selected record.
+The fields are specified by keywords defined in the text database output
+files #K and #N entries. Upper or lower case and minimum match
+abbreviations are permissible. Some fields such as "mag" may have
+multiple entries. An individual entry can be referenced by specifying an
+array index, e.g. "mag[2]" or several values can be selected by
+specifying a range of elements, e.g. "mag[1-3]". The fields are output in
+the order in which they are specified in the template.
+.le
+.ls expr
+The boolean expression to be evaluated once per record.
+Only the fields in those records for which the boolean expression
+evaluates to yes are printed.
+If \fIexpr\fR = "yes", the specified fields in all the records are
+printed.
+.le
+.ls headers = no
+Preserve the APPHOT/DAOPHOT text database output format. The selected
+fields are printed on the standard output, preceded by parameters list,
+if \fIparameters\fR = yes, and the keyword, units,
+and format information, exactly as they appear in the text database.
+.le
+.ls parameters = yes
+Print the keyword parameters records in APPHOT/DAOPHOT format on the
+standard output if \fIheaders\fR = yes.
+.le
+
+.ih
+DESCRIPTION
+\fITXDUMP\fR selects a subset of fields specified by the \fIfields\fR
+parameter from an APPHOT/DAOPHOT text database or a list of databases by
+evaluating a boolean expression supplied by the user and prints the
+results on the standard output.
+If \fIheaders\fR = no, the resultant output is in simple list format
+with all the specified fields in one line of text and adjacent fields
+separated by whitespace. The fields are printed in the order in
+which they appear in \fIexpr\fR. If \fIheaders\fR = yes, the
+selected fields are printed on the standard output, preceded by
+the parameter list, if \fIparameters\fR = yes, and the keyword, units,
+and format information, exactly as they appear in the text database.
+Newlines will not be inserted in the output so users should take
+care not to exceed the IRAF text file line limit of 161 characters.
+
+The output records are selected on the basis of an input boolean
+expression \fIexpr\fR whose variables are the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords in the APPHOT/DAOPHOT text database.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates
+to yes, that record is included in the output table.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Print the fields XCENTER and YCENTER from the output of the APPHOT
+CENTER task.
+
+.nf
+ pt> txdump image.ctr.1 XCENTER,YCENTER yes
+.fi
+
+2. Select the fields ID, XCENTER, YCENTER and the first three magnitudes
+MAG{1-3] from the output of the APPHOT PHOT task.
+
+.nf
+ pt> txdump image.mag.2 "ID,XCEN,YCEN,MAG[1-3]" yes
+.fi
+
+3. Print all fields for all records in the above file with a magnitude
+through the first aperture of less than 20.0.
+
+.nf
+ pt> txdump image.mag.2 * "MAG[1] < 20.0"
+.fi
+
+4. Print the id and all magnitudes for which magnitudes 1 and 2 are < 20.0
+from a file which is the output of the APPHOT PHOT task.
+
+.nf
+ pt> txdump image.mag.3 ID,MAG "MAG[1] < 20.0 && MAG[2] < 20.0"
+.fi
+
+5. Select the ID, XCENTER, YCENTER, MSKY and MAG fields from the output
+ of the DAOPHOT NSTAR task for records where the magnitude is not
+ INDEF, while preserving the format of the text database so it
+ is suitable for input into a rerun of NSTAR.
+
+.nf
+ pt> txdump image.nst.1 "ID,XCENTER,YCENTER,MSKY,MAG" \
+ "MAG[1] != INDEF" headers+
+.fi
+
+.ih
+BUGS
+TXDUMP does not allow arrays in the expression field.
+
+Users should not dump more fields than fill a 161 character textline
+as IRAF does not currently fully support longer text lines.
+.ih
+SEE ALSO
+images.hedit,ptools.tbdump,tables.tdump,ptools.pdump
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txrenumber.hlp b/noao/digiphot/ptools/doc/txrenumber.hlp
new file mode 100644
index 00000000..67ac5a42
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txrenumber.hlp
@@ -0,0 +1,59 @@
+.help txrenumber May93 noao.digiphot.ptools
+.ih
+NAME
+txrenumber -- renumber a list of APPHOT/DAOPHOT text database
+.ih
+USAGE
+txrenumber textfiles
+.ih
+PARAMETERS
+.ls textfiles
+The APPHOT/DAOPHOT text database to be renumbered.
+.le
+.ls idoffset = 0
+An integer offset to be added to the id numbers of the stars in
+the output renumbered photometry file. If idoffset is > 0, the output
+id numbers will run from 1 + idoffset to N + idoffset instead of from 1 to N.
+.le
+.ls id = "ID"
+The name of the keyword whose value is the sequence number of the object in
+the list. After renumbering the original values of the \fIid\fR are replaced
+by numbers 1 through N, where N is the total number of objects in the list.
+The id keyword must denote an integer quantity.
+.le
+.ih
+DESCRIPTION
+TXRENUMBER is a simple task which accepts an APPHOT/DAOPHOT text
+database file and renumbers all the objects in the file beginning
+with 1 and ending with the number of objects in the file.
+The renumber operation is performed in place. The original
+values of the \fIid\fR field are replaced by numbers 1 + idoffset
+through N + idoffset
+where N is the total number of objects in the list.
+A renumber operation is typically performed after another
+list operation such as TXCONCAT or TXSORT.
+
+.ih
+EXAMPLES
+
+1. Renumber the stars in a concatenated file produced by TXCONCAT.
+
+.nf
+ pt> txrenumber m92rall.mag.1
+.fi
+
+2. Renumber a PHOT photometry file of extra stars so as to ensure the
+stars' id numbers are greater than 4000.
+
+.nf
+ pt> txrenumber m92r.mag.extra idoffset=4000
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.tbrenumber,ptools.prenumber,tables.tcalc
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txselect.hlp b/noao/digiphot/ptools/doc/txselect.hlp
new file mode 100644
index 00000000..b80357ea
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txselect.hlp
@@ -0,0 +1,121 @@
+.help txselect Aug91 noao.digiphot.ptools
+.ih
+NAME
+txselect - select records from an APPHOT/DAOPHOT text database
+.ih
+USAGE
+txselect textfiles outfiles expr
+.ih
+PARAMETERS
+.ls textfiles
+The APPHOT/DAOPHOT text database(s) containing the records from which the
+selection is to be made.
+.le
+.ls outfiles
+The output APPHOT/DAOPHOT text database(s) containing the selected records.
+.le
+.ls expr
+The boolean expression to be evaluated once for each record.
+Each input record for which \fIexpr\fR evaluates as "yes" will be
+written to the output file.
+If \fIexpr\fR = yes, a copy is made of the input file.
+.le
+
+.ih
+DESCRIPTION
+TXSELECT selects a subset of the records
+from a set of APPHOT/DAOPHOT text databases
+and writes the new records out to another set of text databases.
+
+The output records are selected on the basis of an input boolean
+expression \fIexpr\fR whose variables are the field names
+specified by the #N keywords or the parameters specified by the
+#K keywords in the APPHOT/DAOPHOT text database.
+If after substituting the values associated
+with a particular record into the field name variables the
+expression evaluates
+to yes, that record is included in the output database.
+
+The supported
+operators and functions are briefly described below. A detailed description
+of the boolean expression evaluator and its syntax can be found
+in the manual page for the IMAGES package HEDIT task.
+
+The following logical operators can be used in the boolean expression.
+
+.nf
+ equal == not equal !=
+ less than < less than or equal <=
+ greater than > greater than or equal >=
+ or || and &&
+ negation ! pattern match ?=
+ concatenation //
+.fi
+
+The pattern match character ?= takes a
+string expression as its first argument and a pattern as its second argument.
+The result is yes if the pattern is contained in the string expression.
+Patterns are strings which may contain pattern matching meta-characters.
+The meta-characters themselves can be matched by preceeding them with the escape
+character. The meta-characters listed below.
+
+.nf
+ beginning of string ^ end of string $
+ one character ? zero or more characters *
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+.fi
+
+The boolean expression may also include arithmetic operators and functions.
+The following arithmetic operators and functions are supported.
+
+.nf
+addition + subtraction -
+multiplication * division /
+negation - exponentiation **
+absolute value abs(x) cosine cos(x)
+sine sin(x) tangent tan(x)
+arc cosine acos(x) arc sine asin(x)
+arc tangent atan(x) arc tangent atan2(x,y)
+exponential exp(x) square root sqrt(x)
+natural log log(x) common log log10(x)
+minimum min(x,y) maximum max(x,y)
+convert to integer int(x) convert to real real(x)
+nearest integer nint(x) modulo mod(x)
+.fi
+
+.ih
+EXAMPLES
+
+1. Select the records from the output of the APPHOT CENTER task for
+which 100. <= XCENTER <= 200. and 300. <= YCENTER <= 400.
+
+.nf
+ pt> txselect m92.ctr.1 m92out \
+ "XCE >= 100. && XCE <= 200. && YCE >= 300. && YCE <= 400."
+.fi
+
+2. Select the records from the output of the APPHOT PHOT task for which
+the first magnitude is not equal to INDEF.
+
+.nf
+ pt> txselect n4147.mag.2 n4147out "MAG[1] != INDEF"
+.fi
+
+3. Select the records from the output of the DAOPHOT ALLSTAR task
+ for which CHI <= 5.0 and MERR <= .10 magnitudes.
+
+.nf
+ pt> txselect m92b.al.1 m92out "CHI <= 5.0 && MERR <= 1.0"
+.fi
+
+.ih
+BUGS
+TXSELECT does not allow arrays in the expression field.
+
+.ih
+SEE ALSO
+images.hselect,images.hedit,ptools.tbselect,tables.tselect,ptools.pselect
+.endhelp
diff --git a/noao/digiphot/ptools/doc/txsort.hlp b/noao/digiphot/ptools/doc/txsort.hlp
new file mode 100644
index 00000000..b9a324fd
--- /dev/null
+++ b/noao/digiphot/ptools/doc/txsort.hlp
@@ -0,0 +1,61 @@
+.help txsort Aug91 noao.digiphot.ptools
+.ih
+NAME
+txsort -- sort a list of APPHOT/DAOPHOT text database file(s)
+.ih
+USAGE
+txsort textfile field
+.ih
+PARAMETERS
+.ls textfiles
+The input APPHOT/DAOPHOT text database(s) to be sorted.
+The sort is performed in place.
+.le
+.ls field
+The field to be sorted on. \fIField\fR may be any quantity defined by
+the APPHOT/DAOPHOT #K and #N keywords. The keywords may be
+of type integer or real, in which case a numeric sort is performed,
+boolean, in which case the boolean constant "no" has a smaller value
+than "yes", or character in which case an alphabetic sort is performed.
+.le
+.ls ascend = yes
+Sort in increasing value order.
+.le
+.ih
+DESCRIPTION
+TXSORT is a simple task which accepts a list of APPHOT/DAOPHOT text
+database files
+and sorts them in place based on the value of the selected field
+specifier \fIfield\fR. By default the sort is performed in increasing order
+of the value
+of \fIfield\fR, but a reverse sort can be performed by
+setting \fIascend\fR = "no".
+
+If \fIfield\fR is a real or integer quantity the sort is numeric; if boolean
+the boolean constant "no" is assumed to have a smaller value than "yes"; if
+character the sort is alphabetic.
+.ih
+EXAMPLES
+
+1. Sort the output of the APPHOT task PHOT in increasing order of
+the y position.
+
+.nf
+ pt> txsort m92.mag.1 YCENTER
+.fi
+
+2. Sort the output of the DAOPHOT task ALLSTAR in increasing order of
+ magnitude.
+
+.nf
+ pt> txsort m92.al.1 MAG
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+ptools.tbsort,tables.tsort,ptools.psort,sort
+.endhelp
diff --git a/noao/digiphot/ptools/histplot.par b/noao/digiphot/ptools/histplot.par
new file mode 100644
index 00000000..59148ea9
--- /dev/null
+++ b/noao/digiphot/ptools/histplot.par
@@ -0,0 +1,20 @@
+# The PEXAMINE task histogram plotting task parameters
+
+nbins,i,h,10,1,,Number of bins in histogram
+z1,r,h,INDEF,,,Minimum histogram intensity
+z2,r,h,INDEF,,,Maximum histogram intensity
+top_closed,b,h,yes,,,Include z2 in the top bin?
+x1,r,h,INDEF,,,Left world X-coord if not autoscaling
+x2,r,h,INDEF,,,Right world X-coord if not autoscaling
+y1,r,h,INDEF,,,Lower world Y-coord if not autoscaling
+y2,r,h,INDEF,,,Upper world Y-coord if not autoscaling
+logy,b,h,yes,,,Log scale the y axis ?
+box,b,h,yes,,,Draw box around periphery of window ?
+ticklabels,b,h,yes,,,Label tick marks ?
+majrx,i,h,5,,,Number of major divisions along x axis
+minrx,i,h,5,,,Number of minor divisions along x axis
+majry,i,h,5,,,Number of major divisions along y axis
+minry,i,h,5,,,Number of minor divisions along y axis
+round,b,h,no,,,Round axes to nice values ?
+fill,b,h,yes,,,Fill viewport vs enforce unity aspect ratio ?
+banner,b,h,yes,,,Standard banner ?
diff --git a/noao/digiphot/ptools/istable.par b/noao/digiphot/ptools/istable.par
new file mode 100644
index 00000000..fa135764
--- /dev/null
+++ b/noao/digiphot/ptools/istable.par
@@ -0,0 +1,7 @@
+# ISTABLE Parameters
+
+infile,s,a,,,,Input file
+table,b,h,no,,,Is the file a tables file ?
+text,b,h,no,,,Is the file a text database file ?
+other,b,h,no,,,Is the file neither a tables or a text database file ?
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/lib/strip.ptoolsx b/noao/digiphot/ptools/lib/strip.ptoolsx
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/noao/digiphot/ptools/lib/strip.ptoolsx
diff --git a/noao/digiphot/ptools/lib/warning.dat b/noao/digiphot/ptools/lib/warning.dat
new file mode 100644
index 00000000..a27f7da2
--- /dev/null
+++ b/noao/digiphot/ptools/lib/warning.dat
@@ -0,0 +1,12 @@
+
+
+ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+ WARNING FROM THE PTOOLS PACKAGE LOADER
+ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+ The SDAS external package TABLES required by some of the PTOOLS
+ tasks is not available. The tasks TBAPPEND, TBDUMP, TBRENUMBER,
+ TBSELECT, and TBSORT will not run. The tasks PAPPEND, PDUMP,
+ PRENUMBER, PSELECT and PSORT will run only on APPHOT/DAOPHOT
+ output files written in the default text format, not on files
+ written in ST tables format.
diff --git a/noao/digiphot/ptools/mkpkg b/noao/digiphot/ptools/mkpkg
new file mode 100644
index 00000000..b8a75eaa
--- /dev/null
+++ b/noao/digiphot/ptools/mkpkg
@@ -0,0 +1,38 @@
+# PTOOLSX libraries
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $omake x_ptools.x
+ !mkpkg -p noao trelink XF="$(XFLAGS)" LF="$(LFLAGS)"
+ ;
+
+linkonly:
+ !mkpkg -p noao trelink XF="$(XFLAGS)" LF="$(LFLAGS)"
+ $call install
+ ;
+
+install:
+ $move xx_ptools.e noaobin$x_ptools.e
+ ;
+
+trelink:
+ $set LIBS = "-lds -lncar -lgks -lxtools -ltbtables"
+ $set XFLAGS = "$(XFLAGS) $(XF)"
+ $set LFLAGS = "$(LFLAGS) $(LF)"
+ $update libpkg.a
+ $link x_ptools.o libpkg.a ../lib/libpttables.a $(LIBS) -o xx_ptools.e
+ ;
+
+libpkg.a:
+ @pconvert
+ @pexamine
+ @ptutils
+ @txtools
+ ;
diff --git a/noao/digiphot/ptools/pcalc.cl b/noao/digiphot/ptools/pcalc.cl
new file mode 100644
index 00000000..494e7ee7
--- /dev/null
+++ b/noao/digiphot/ptools/pcalc.cl
@@ -0,0 +1,50 @@
+# PCALC - Recompute a column of an APPHOT/DAOPHOT database using an
+# arithmetic expression.
+
+procedure pcalc (infile, field, value)
+
+string infile {prompt="Input apphot/daophot databases(s)"}
+string field {prompt="Field to be edited"}
+string value {prompt="New value or expression for field"}
+
+struct *inlist
+
+begin
+ # Local variable declarations.
+ file tmpin
+ string in, tfield, tvalue, inname
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infile
+ tfield = field
+ tvalue = value
+
+ # Expand the file list names.
+ tmpin = mktemp ("tmp$")
+ files (in, sort=no, > tmpin)
+
+ # Loop over each file in the input and output lists selecting records.
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ istable (inname)
+ if (istable.table) {
+ if (defpar ("tcalc.verbose") || defpar ("tcalc.harmless")) {
+ tcalc (inname, tfield, tvalue, datatype="real",
+ colunits="", colfmt="", verbose=no, harmless=0.1)
+ } else {
+ tcalc (inname, tfield, tvalue, datatype="real",
+ colunits="", colfmt="")
+ }
+ } else if (istable.text) {
+ txcalc (inname, tfield, tvalue)
+ } else {
+ print ("Cannot run PCALC on file: " // inname)
+ }
+ }
+ inlist = ""
+
+ delete (tmpin, ver-, >& "dev$null")
+end
diff --git a/noao/digiphot/ptools/pconcat.cl b/noao/digiphot/ptools/pconcat.cl
new file mode 100644
index 00000000..7d098eee
--- /dev/null
+++ b/noao/digiphot/ptools/pconcat.cl
@@ -0,0 +1,56 @@
+# PCONCAT -- Concatenate a list of apphot/daophot databases into a single
+# output database. The input files must either be all text files or all data
+# files. PCONCAT checks that the input files were all created by the same
+# task.
+
+procedure pconcat (infiles, outfile)
+
+file infiles {prompt = "Input apphot/daophot database(s) to be concatenated"}
+file outfile {prompt = "Output apphot/daophot database"}
+string task {"TASK", prompt="Task name keyword"}
+
+struct *inlist
+
+begin
+ # Declare local variables.
+ bool table, text, other
+ file in, out
+ string tmpin, inname
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infiles
+ out = outfile
+
+ # Make a file lists.
+ tmpin = mktemp ("tmp$")
+ files (in, sort=no, > tmpin)
+
+ # Check to see whether the first file is a text database or a table.
+
+ inlist = tmpin
+ if (fscan (inlist, inname) != EOF) {
+ istable (inname)
+ table = istable.table
+ text = istable.text
+ other = istable.other
+ } else {
+ table = no
+ text = no
+ other = no
+ }
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+
+ # Do the actual appending.
+ if (table)
+ tbconcat (in, out, task=task)
+ else if (text)
+ txconcat (in, out, task=task)
+ else if (access (inname))
+ print ("File " // inname // " is not an APPHOT/DAOPHOT database")
+ else
+ print ("File " // inname // " does not exist")
+end
diff --git a/noao/digiphot/ptools/pconvert.par b/noao/digiphot/ptools/pconvert.par
new file mode 100644
index 00000000..eb3fdd0c
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert.par
@@ -0,0 +1,8 @@
+# CONVERT Parameters
+
+textfile,s,a,,,,Input apphot/daophot text database
+table,s,a,,,,Output apphot/daophot table database
+fields,s,a,"*",,,Fields to be extracted
+expr,s,h,yes,,,Boolean expression used for record selection
+append,b,h,no,,,Append to existing table ?
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/pconvert/mkpkg b/noao/digiphot/ptools/pconvert/mkpkg
new file mode 100644
index 00000000..362576cb
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert/mkpkg
@@ -0,0 +1,14 @@
+# PCONVERT task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ ptconvert.x <error.h> <evexpr.h> \
+ <tbset.h> ../../lib/ptkeysdef.h
+ ptdeftable.x ../../lib/ptkeysdef.h <tbset.h> <ctype.h>
+ ptstrwrd.x
+ t_pconvert.x <fset.h>
+ ;
diff --git a/noao/digiphot/ptools/pconvert/ptconvert.x b/noao/digiphot/ptools/pconvert/ptconvert.x
new file mode 100644
index 00000000..8ac97ac8
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert/ptconvert.x
@@ -0,0 +1,236 @@
+include <error.h>
+include <evexpr.h>
+include <tbset.h>
+include "../../lib/ptkeysdef.h"
+
+# PT_APCONVERT -- Procedure to select records from a text file in pseudo list
+# format.
+
+procedure pt_convert (fd, td, fields, expr, append)
+
+int fd # text file descriptor
+int td # table file descriptor
+char fields[ARB] # fields to be output
+char expr[ARB] # boolean expression to be evaluated
+int append # append to an existing table
+
+bool oexpr
+int nchars, nunique, uunique, funique, ncontinue, recptr, rownum
+int ntotkeys, first_rec, printall, table_defined
+pointer sp, line, colpoints, key, o
+
+bool streq()
+extern pt_getop ()
+int getline(), strncmp(), tbpsta(), pt_deftable(), pt_apptable()
+pointer evexpr(), locpr()
+real asumi()
+
+begin
+
+ # Allocate temporary working space.
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ # Initialize the keys structure.
+ call pt_kyinit (key)
+
+ # Initialize the counters.
+ nunique = 0
+ uunique = 0
+ funique = 0
+
+ # Initalize the record reading code.
+ table_defined = NO
+ first_rec = YES
+ recptr = 1
+ ncontinue = 0
+
+ # Initialize the expression evaluator.
+ o = NULL
+ if (streq (expr, "yes")) {
+ oexpr = true
+ printall = YES
+ } else {
+ oexpr = false
+ printall = NO
+ }
+
+ # Initialize the pointer for writing rows.
+ if (append == YES)
+ rownum = tbpsta (td, TBL_NROWS)
+ else
+ rownum = 0
+
+ # Loop over the text file records.
+ nchars = getline (fd, Memc[line])
+ while (nchars != EOF) {
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # skip blank lines
+
+ } else {
+
+ # Construct the table record.
+ call pt_mkrec (key, Memc[line], nchars, first_rec, recptr,
+ ncontinue)
+
+ # Construct output record when there is no continuation char.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Construct the output table if not defined.
+ if (table_defined == NO) {
+
+ # Compute the maximum number of keys.
+ ntotkeys = nint (asumi (Memi[KY_NELEMS(key)],
+ KY_NKEYS(key)))
+
+ # Allocate space for the column pointers.
+ call salloc (colpoints, ntotkeys, TY_INT)
+
+ # Initialize the table.
+ if (append == NO) {
+ if (pt_deftable (td, key, fields,
+ Memi[colpoints]) <= 0)
+ break
+ } else if (append == YES) {
+ if (pt_apptable (td, key, fields,
+ Memi[colpoints]) <= 0)
+ break
+ }
+
+ table_defined = YES
+ }
+
+ # Evaluate the expression.
+ iferr {
+ if (printall == NO) {
+ call pt_apset (key)
+ o = evexpr (expr, locpr (pt_getop), 0)
+ if (O_TYPE(o) != TY_BOOL)
+ call error (0, "Expression must be a boolean")
+ oexpr = O_VALB(o)
+ }
+ } then {
+ call erract (EA_WARN)
+ call xev_freeop (o)
+ call mfree (o, TY_STRUCT)
+ break
+ }
+
+ # Construct the output record.
+ if (oexpr) {
+ rownum = rownum + 1
+ call pt_putrec (td, Memi[colpoints], key, rownum)
+ }
+
+ # Get ready for next record.
+ ncontinue = 0
+ recptr = 1
+ first_rec = NO
+ if (o != NULL) {
+ call xev_freeop (o)
+ call mfree (o, TY_STRUCT)
+ }
+ }
+ }
+
+ # Read the next line.
+ nchars = getline (fd, Memc[line])
+ }
+
+ # Free the keys structure.
+ call pt_kyfree (key)
+ call sfree (sp)
+end
+
+
+# PT_PUTREC -- Add a row to the table.
+
+procedure pt_putrec (td, colpoints, key, rownum)
+
+pointer td # table descriptor
+pointer colpoints[ARB] # pointers for columns
+pointer key # key structure
+int rownum # row number
+
+int i, index, elem, kip, maxch, n, nk, ncols
+int number, datatype, lendata, lenfmt, ival
+pointer sp, colname, colunits, colfmt, str
+real rval
+bool streq()
+int ctor(), ctoi()
+
+begin
+ call smark (sp)
+ call salloc (colname, SZ_COLNAME+1, TY_CHAR)
+ call salloc (colunits, SZ_PARREC+1, TY_CHAR)
+ call salloc (colfmt, SZ_PARREC+1, TY_CHAR)
+ call salloc (str, SZ_LINE, TY_CHAR)
+
+ # For each selected field move into the table
+ ncols = 0
+ do i = 1, KY_NSELECT(key) {
+
+ # Get the pointer to the desired value.
+ index = Memi[KY_SELECT(key)+i-1]
+ elem = Memi[KY_ELEM_SELECT(key)+i-1]
+ maxch = Memi[KY_LEN_SELECT(key)+i-1]
+ kip = Memi[KY_PTRS(key)+index-1] + (elem - 1) * maxch
+
+ # Trim leading and trailing whitespace from the value and
+ # copy value to output buffer.
+
+ for (n = 0; Memc[kip] == ' '; n = n + 1)
+ kip = kip + 1
+ for (nk = 0; Memc[kip+nk] != ' ' && n <= maxch; nk = nk + 1)
+ n = n + 1
+ call strcpy (Memc[kip], Memc[str], nk)
+
+ # Find info about this column.
+ ncols = ncols + 1
+ call tbcinf (colpoints[ncols], number, Memc[colname],
+ Memc[colunits], Memc[colfmt], datatype, lendata, lenfmt)
+
+ # Move the selected value into the column.
+ kip = 1
+ switch (datatype) {
+ case TY_INT:
+ if (ctoi (Memc[str], kip, ival) <= 0)
+ call tbrpti (td, colpoints[ncols], INDEFI, 1, rownum)
+ else
+ call tbrpti (td, colpoints[ncols], ival, 1, rownum)
+ case TY_REAL:
+ if (ctor (Memc[str], kip, rval) <= 0)
+ call tbrptr (td, colpoints[ncols], INDEFR, 1, rownum)
+ else
+ call tbrptr (td, colpoints[ncols], rval, 1, rownum)
+ case TY_BOOL:
+ if (streq ("yes", Memc[str]))
+ call tbrptb (td, colpoints[ncols], true, 1, rownum)
+ else
+ call tbrptb (td, colpoints[ncols], false, 1, rownum)
+ default:
+ call tbrptt (td, colpoints[ncols], Memc[str], nk, 1, rownum)
+ }
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/pconvert/ptdeftable.x b/noao/digiphot/ptools/pconvert/ptdeftable.x
new file mode 100644
index 00000000..86fb2c35
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert/ptdeftable.x
@@ -0,0 +1,375 @@
+#include <ctype.h>
+include <tbset.h>
+include "../../lib/ptkeysdef.h"
+
+# PT_DEFTABLE -- Set up and create the table for the conversion of
+# the APPHOT text file.
+
+int procedure pt_deftable (td, key, fields, columns)
+
+pointer td # output table descriptor
+pointer key # key structure
+char fields[ARB] # fields to be output to the table
+int columns[ARB] # pointer to array of column pointers
+
+int ncols
+int pt_defcols()
+
+begin
+ # Define the table columns.
+ ncols = pt_defcols (td, key, fields, columns)
+ if (ncols <= 0)
+ return (0)
+
+ # Define the table header.
+ call pt_defheader (td, key)
+
+ return (ncols)
+end
+
+
+# PT_DEFHEADER -- Define the header structure.
+
+procedure pt_defheader (td, key)
+
+pointer td # table descriptor
+pointer key # pointer to the keys structure
+
+int i, index, type, len, ival, ip
+pointer sp, kname, value, ptr
+real rval
+bool streq()
+int pt_strwrd(), pt_kstati(), ctoi(), ctor()
+
+begin
+ call smark (sp)
+ call salloc (kname, SZ_KEYWORD, TY_CHAR)
+ call salloc (value, KY_SZPAR, TY_CHAR)
+
+ # Define the columns determining datatype from the format string.
+ do i = 1, KY_NPKEYS(key) {
+
+ index = pt_strwrd (i, Memc[kname], SZ_KEYWORD, Memc[KY_WORDS(key)])
+ if (index <= 0)
+ next
+
+ ptr = Memi[KY_PTRS(key)+index-1]
+ len = pt_kstati (key, Memc[kname], KY_LENGTH)
+ call strcpy (Memc[ptr], Memc[value], len)
+ type = pt_kstati (key, Memc[kname], KY_DATATYPE)
+
+ switch (type) {
+ case TY_INT:
+ ip = 1
+ if (ctoi (Memc[value], ip, ival) <= 0)
+ call tbhadi (td, Memc[kname], INDEFI)
+ else
+ call tbhadi (td, Memc[kname], ival)
+ case TY_REAL:
+ ip = 1
+ if (ctor (Memc[value], ip, rval) <= 0)
+ call tbhadr (td, Memc[kname], INDEFR)
+ else
+ call tbhadr (td, Memc[kname], rval)
+ case TY_BOOL:
+ if (streq ("yes", Memc[value]))
+ call tbhadb (td, Memc[kname], true)
+ else
+ call tbhadb (td, Memc[kname], false)
+ default:
+ call tbhadt (td, Memc[kname], Memc[value])
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+# PT_DEFCOLS -- Define the data columns to be output.
+
+int procedure pt_defcols (td, key, fields, columns)
+
+pointer td # table Descriptor
+pointer key # key structure
+char fields[ARB] # fields selected
+pointer columns[ARB] # array of pointers for columns
+
+int max_nkeys, index, ncols, element, nelems, type, len
+pointer sp, kname, aranges, ranges, rangeset, colname, colunits, colformat
+pointer list
+
+int pt_gnfn(), strdic(), pt_ranges(), get_next_number()
+int decode_ranges(), pt_kstati()
+pointer pt_ofnl()
+real asumi()
+errchk tbcdef()
+
+begin
+ # Allocate working space.
+
+ call smark (sp)
+ call salloc (kname, KY_SZPAR, TY_CHAR)
+ call salloc (aranges, SZ_FNAME, TY_CHAR)
+ call salloc (ranges, SZ_FNAME, TY_CHAR)
+ call salloc (rangeset, 3 * KY_MAXNRANGES, TY_INT)
+
+ call salloc (colname, SZ_COLNAME, TY_CHAR)
+ call salloc (colunits, SZ_COLUNITS, TY_CHAR)
+ call salloc (colformat, SZ_COLFMT, TY_CHAR)
+
+ # Initialize the select buffers. The select keyword, format
+ # and units string buffers are not necessary in this application.
+
+ max_nkeys = nint (asumi (Memi[KY_NELEMS(key)], KY_NKEYS(key)))
+ if (KY_SELECT(key) != NULL)
+ call mfree (KY_SELECT(key), TY_INT)
+ call malloc (KY_SELECT(key), max_nkeys, TY_INT)
+ if (KY_ELEM_SELECT(key) != NULL)
+ call mfree (KY_ELEM_SELECT(key), TY_INT)
+ call malloc (KY_ELEM_SELECT(key), max_nkeys, TY_INT)
+ if (KY_LEN_SELECT(key) != NULL)
+ call mfree (KY_LEN_SELECT(key), TY_INT)
+ call malloc (KY_LEN_SELECT(key), max_nkeys, TY_INT)
+
+ # Initialize the number of columns.
+ ncols = 0
+
+ # Open the list of fields.
+ list = pt_ofnl (key, fields)
+
+ # Loop over the fields.
+ while (pt_gnfn (list, Memc[kname], Memc[aranges], KY_SZPAR) != EOF) {
+
+ # Find location of the field in the keyword dictionary and
+ # expand the ranges string if it is defined.
+ index = strdic (Memc[kname], Memc[kname], KY_SZPAR,
+ Memc[KY_WORDS(key)])
+ if (pt_ranges (Memc[aranges], Memc[ranges], element, SZ_LINE) ==
+ ERR)
+ call error (0, "Cannot decode DAOPHOT range string")
+
+ # The field was not found.
+ if (index == 0) {
+ next
+
+ # Reject keyword fields.
+ } else if (index <= KY_NPKEYS (key)) {
+ next
+
+ # The field is single valued.
+ } else if (Memi[KY_NELEMS(key)+index-1] == 1) {
+
+ # Enter the pointers into the select buffer.
+ Memi[KY_SELECT(key)+ncols] = index
+ Memi[KY_ELEM_SELECT(key)+ncols] = 1
+ len = pt_kstati (key, Memc[kname], KY_LENGTH)
+ Memi[KY_LEN_SELECT(key)+ncols] = len
+ ncols = ncols + 1
+
+ # Get the column name, the units and the formats.
+ call strcpy (Memc[kname], Memc[colname], SZ_COLNAME)
+ call pt_kstats (key, Memc[kname], KY_UNITSTR, Memc[colunits],
+ SZ_COLUNITS)
+ call pt_kstats (key, Memc[kname], KY_FMTSTR, Memc[colformat],
+ SZ_COLFMT)
+
+ # Create the column determining the datatype from the
+ # format string.
+ type = pt_kstati (key, Memc[kname], KY_DATATYPE)
+ if (type != TY_CHAR)
+ call tbcdef (td, columns[ncols], Memc[colname],
+ Memc[colunits], Memc[colformat], type, 1, 1)
+ else
+ call tbcdef (td, columns[ncols], Memc[colname],
+ Memc[colunits], Memc[colformat], -len, 1, 1)
+
+ # The field is multi-valued.
+ } else {
+
+ if (Memc[ranges] == EOS) {
+ call sprintf (Memc[ranges], SZ_FNAME, "1-%d")
+ call pargi (Memi[KY_NELEMS(key)+index-1])
+ }
+ if (decode_ranges (Memc[ranges], Memi[rangeset], KY_MAXNRANGES,
+ nelems) == ERR)
+ call error (0, "Cannot decode ranges string")
+
+ nelems = 0
+ while (get_next_number (Memi[rangeset], nelems) != EOF) {
+ if (nelems < 1 || nelems > Memi[KY_NELEMS(key)+index-1])
+ break
+
+ len = pt_kstati (key, Memc[kname], KY_LENGTH)
+ Memi[KY_SELECT(key)+ncols] = index
+ Memi[KY_ELEM_SELECT(key)+ncols] = nelems
+ Memi[KY_LEN_SELECT(key)+ncols] = len
+ ncols = ncols + 1
+
+ # Get the column name, units and format.
+ call sprintf (Memc[colname], SZ_COLNAME, "%s[%d]")
+ call pargstr (Memc[kname])
+ call pargi (nelems)
+ call pt_kstats (key, Memc[kname], KY_UNITSTR,
+ Memc[colunits], SZ_COLUNITS)
+ call pt_kstats (key, Memc[kname], KY_FMTSTR,
+ Memc[colformat], SZ_COLFMT)
+
+ # Create the column determining the datatype from the
+ # format string.
+ type = pt_kstati (key, Memc[kname], KY_DATATYPE)
+ if (type != TY_CHAR)
+ call tbcdef (td, columns[ncols], Memc[colname],
+ Memc[colunits], Memc[colformat], type, 1, 1)
+ else
+ call tbcdef (td, columns[ncols], Memc[colname],
+ Memc[colunits], Memc[colformat], -len, 1, 1)
+ }
+ }
+ }
+
+ # Create the table.
+ call tbpset (td, TBL_MAXPAR, KY_NPKEYS(key))
+ call tbtcre (td)
+
+ # Free the space
+ call pt_cfnl (list)
+ call sfree (sp)
+
+ # Reallocate select buffer space
+ KY_NSELECT(key) = ncols
+ call realloc (KY_SELECT(key), KY_NSELECT(key), TY_INT)
+ call realloc (KY_ELEM_SELECT(key), KY_NSELECT(key), TY_INT)
+ call realloc (KY_LEN_SELECT(key), KY_NSELECT(key), TY_INT)
+
+ return (ncols)
+end
+
+
+# PT_APPTABLE -- Find the array of column pointers for appending to an
+# existing ST table.
+
+int procedure pt_apptable (td, key, fields, columns)
+
+pointer td # the table descriptor
+pointer key # key structure
+char fields[ARB] # string containing fields to include in table
+pointer columns[ARB] # Array of pointers for columns
+
+int max_nkeys, index, ncols, element, nelems
+pointer list, sp, kname, aranges, ranges, rangeset, colname
+int pt_gnfn(), strdic(), pt_ranges(), get_next_number(), decode_ranges()
+int pt_kstati()
+pointer pt_ofnl()
+real asumi()
+
+begin
+ # Allocate buffer space.
+ call smark (sp)
+ call salloc (kname, KY_SZPAR, TY_CHAR)
+ call salloc (aranges, SZ_FNAME, TY_CHAR)
+ call salloc (ranges, SZ_FNAME, TY_CHAR)
+ call salloc (rangeset, 3 * KY_MAXNRANGES, TY_INT)
+ call salloc (colname, SZ_COLNAME, TY_CHAR)
+
+ # Initialize the select buffers. The select keyword, format
+ # and units string buffers are not necessary in this application.
+
+ max_nkeys = nint (asumi (Memi[KY_NELEMS(key)], KY_NKEYS(key)))
+ max_nkeys = nint (asumi (Memi[KY_NELEMS(key)], KY_NKEYS(key)))
+ if (KY_SELECT(key) != NULL)
+ call mfree (KY_SELECT(key), TY_INT)
+ call malloc (KY_SELECT(key), max_nkeys, TY_INT)
+ if (KY_ELEM_SELECT(key) != NULL)
+ call mfree (KY_ELEM_SELECT(key), TY_INT)
+ call malloc (KY_ELEM_SELECT(key), max_nkeys, TY_INT)
+ if (KY_LEN_SELECT(key) != NULL)
+ call mfree (KY_LEN_SELECT(key), TY_INT)
+ call malloc (KY_LEN_SELECT(key), max_nkeys, TY_INT)
+
+ # Initialize the number of columns.
+ ncols = 0
+
+ # Initialize the list of fields.
+ ncols = 0
+ list = pt_ofnl (key, fields)
+
+ # Loop over the fields.
+ while (pt_gnfn (list, Memc[kname], Memc[aranges], KY_SZPAR) != EOF) {
+
+ # Find the column.
+ index = strdic (Memc[kname], Memc[kname], KY_SZPAR,
+ Memc[KY_WORDS(key)])
+ if (pt_ranges (Memc[aranges], Memc[ranges], element,
+ SZ_LINE) == ERR)
+ call error (0, "Cannot decode DAOPHOT range string")
+
+ # Skip if the column does exist in the text database.
+ if (index == 0)
+ next
+
+ # Skip the header keywords.
+ else if (index <= KY_NPKEYS (key))
+ next
+
+ # Convert single-valued elements.
+ else if (Memi[KY_NELEMS(key)+index-1] == 1) {
+
+ call strcpy (Memc[kname], Memc[colname], SZ_COLNAME)
+ call tbcfnd (td, Memc[colname], columns[ncols+1], 1)
+ if (columns[ncols+1] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (Memc[colname])
+ } else {
+ Memi[KY_SELECT(key)+ncols] = index
+ Memi[KY_ELEM_SELECT(key)+ncols] = 1
+ Memi[KY_LEN_SELECT(key)+ncols] = pt_kstati (key,
+ Memc[kname], KY_LENGTH)
+ ncols = ncols + 1
+ }
+
+ # Convert multivalued elements.
+ } else {
+
+ if (Memc[ranges] == EOS) {
+ call sprintf (Memc[ranges], SZ_FNAME, "1-%d")
+ call pargi (Memi[KY_NELEMS(key)+index-1])
+ }
+ if (decode_ranges (Memc[ranges], Memi[rangeset], KY_MAXNRANGES,
+ nelems) == ERR)
+ call error (0, "Cannot decode ranges string")
+
+ nelems = 0
+ while (get_next_number (Memi[rangeset], nelems) != EOF) {
+ if (nelems < 1 || nelems > Memi[KY_NELEMS(key)+index-1])
+ break
+ call sprintf (Memc[colname], SZ_COLNAME, "%s[%d]")
+ call pargstr (Memc[kname])
+ call pargi (nelems)
+ call tbcfnd (td, Memc[colname], columns[ncols+1], 1)
+ if (columns[ncols+1] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (Memc[colname])
+ } else {
+ Memi[KY_SELECT(key)+ncols] = index
+ Memi[KY_ELEM_SELECT(key)+ncols] = nelems
+ Memi[KY_LEN_SELECT(key)+ncols] = pt_kstati (key,
+ Memc[kname], KY_LENGTH)
+ ncols = ncols + 1
+ }
+
+ }
+ }
+ }
+
+ # Free the space
+ call pt_cfnl (list)
+ call sfree (sp)
+
+ # Reallocate select buffer space
+ KY_NSELECT(key) = ncols
+ call realloc (KY_SELECT(key), KY_NSELECT(key), TY_INT)
+ call realloc (KY_ELEM_SELECT(key), KY_NSELECT(key), TY_INT)
+ call realloc (KY_LEN_SELECT(key), KY_NSELECT(key), TY_INT)
+
+ return (ncols)
+end
diff --git a/noao/digiphot/ptools/pconvert/ptstrwrd.x b/noao/digiphot/ptools/pconvert/ptstrwrd.x
new file mode 100644
index 00000000..31a9974b
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert/ptstrwrd.x
@@ -0,0 +1,51 @@
+# PT_STRWRD -- Search a dictionary string for a given string index number.
+# This is the opposite function of strdic(), that returns the index for
+# given string. The entries in the dictionary string are separated by
+# a delimiter character which is the first character of the dictionary
+# string. The index of the string found is returned as the function value.
+# Otherwise, if there is no string for that index, a zero is returned.
+
+int procedure pt_strwrd (index, outstr, maxch, dict)
+
+int index # String index
+char outstr[ARB] # Output string as found in dictionary
+int maxch # Maximum length of output string
+char dict[ARB] # Dictionary string
+
+int i, len, start, count
+
+int strlen()
+
+begin
+ # Clear output string
+ outstr[1] = EOS
+
+ # Return if the dictionary is not long enough
+ if (dict[1] == EOS)
+ return (0)
+
+ # Initialize counters
+ count = 1
+ len = strlen (dict)
+
+ # Search the dictionary string. This loop only terminates
+ # successfully if the index is found. Otherwise the procedure
+ # returns with and error condition.
+ for (start = 2; count < index; start = start + 1) {
+ if (dict[start] == dict[1])
+ count = count + 1
+ if (start == len)
+ return (0)
+ }
+
+ # Extract the output string from the dictionary
+ for (i = start; dict[i] != EOS && dict[i] != dict[1]; i = i + 1) {
+ if (i - start + 1 > maxch)
+ break
+ outstr[i - start + 1] = dict[i]
+ }
+ outstr[i - start + 1] = EOS
+
+ # Return index for output string
+ return (count)
+end
diff --git a/noao/digiphot/ptools/pconvert/t_pconvert.x b/noao/digiphot/ptools/pconvert/t_pconvert.x
new file mode 100644
index 00000000..fafcbf5f
--- /dev/null
+++ b/noao/digiphot/ptools/pconvert/t_pconvert.x
@@ -0,0 +1,53 @@
+include <fset.h>
+
+# T_PCONVERT -- Procedure to convert the records within a text file into
+# an STSDAS Table.
+
+procedure t_pconvert ()
+
+pointer text # pointer to name of text file
+pointer fields # pointer list of fields
+pointer table # pointer to STSDAS table
+pointer expr # Pointer to boolean expression
+int append # open file in append mode
+
+int fd, td
+pointer sp
+bool clgetb()
+int open(), btoi(), fstati(), tbtopn()
+
+begin
+
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (text, SZ_LINE, TY_CHAR)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (table, SZ_LINE, TY_CHAR)
+ call salloc (expr, SZ_LINE, TY_CHAR)
+
+ # Get the parameters.
+ call clgstr ("textfile", Memc[text], SZ_LINE)
+ call clgstr ("table", Memc[table], SZ_LINE)
+ call clgstr ("fields", Memc[fields], SZ_LINE)
+ call strupr (Memc[fields])
+ call clgstr ("expr", Memc[expr], SZ_LINE)
+ append = btoi (clgetb ("append"))
+
+ # Open the table.
+ fd = open (Memc[text], READ_ONLY, TEXT_FILE)
+ if (append == YES)
+ td = tbtopn (Memc[table], READ_WRITE, 0)
+ else
+ td = tbtopn (Memc[table], NEW_FILE, 0)
+
+ # Select records.
+ call pt_convert (fd, td, Memc[fields], Memc[expr], append)
+
+ # Close up.
+ call close (fd)
+ call tbtclo (td)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/pdump.cl b/noao/digiphot/ptools/pdump.cl
new file mode 100644
index 00000000..5ac4b5fd
--- /dev/null
+++ b/noao/digiphot/ptools/pdump.cl
@@ -0,0 +1,83 @@
+# PDUMP - Select fields from an ST table or an APPHOT/DAOPHOT text file
+# and dump to a text file.
+
+procedure pdump (infiles, fields, expr)
+
+string infiles {prompt="Input apphot/daophot databases(s)"}
+string fields {prompt="Fields to be extracted"}
+string expr {"yes", prompt="Boolean expression"}
+bool headers {no, prompt="Print field headers?"}
+bool parameters {yes, prompt="Print parameters?"}
+
+struct *inlist
+
+begin
+ # Local variable declarations.
+ file tmpin, texpr
+ int nin, tpagwidth
+ string in, col, inname, hfile, pfile
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infiles
+ col = fields
+ texpr = expr
+
+ # Make temporary names.
+ tmpin = mktemp ("tmp$")
+
+ # Expand the file list names.
+ files (in, sort=no, > tmpin)
+
+ # Compute the length of the input list.
+ inlist = tmpin
+ for (nin = 0; fscan (inlist, inname) != EOF; nin = nin + 1)
+ ;
+ inlist = ""
+
+ # Delete the temporary files.
+ delete (tmpin, ver-, >& "dev$null")
+
+ # Expand the file list names.
+ files (in, sort=no, > tmpin)
+
+ if (headers) {
+ hfile = "STDOUT"
+ if (parameters)
+ pfile = "STDOUT"
+ else
+ pfile = ""
+ } else {
+ hfile = ""
+ pfile = ""
+ }
+
+ # Loop over each file in the input list selecting records.
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ istable (inname)
+ if (istable.table) {
+
+ # Adjust pagination for TDUMP.
+ #tpagwidth = tdump.pwidth.p_max
+ tdump.pwidth.p_max = 1023
+
+ tbdump (inname, col, texpr, cdfile=hfile, pfile=pfile,
+ datafile="STDOUT", rows="-", pagwidth=1023)
+
+ # Reset pagination for TDUMP.
+ #tdump.pwidth.p_max = tpagwidth
+
+ } else if (istable.text) {
+ txdump (inname, col, texpr, headers=headers,
+ parameters=parameters)
+ } else {
+ print ("ERROR: Cannot run PDUMP on file: " // inname)
+ }
+ }
+
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+end
diff --git a/noao/digiphot/ptools/pexamine.par b/noao/digiphot/ptools/pexamine.par
new file mode 100644
index 00000000..50dd0e75
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine.par
@@ -0,0 +1,20 @@
+# The PEXAMINE task parameter set
+
+input,s,a,,,,"Name of the input catalog"
+output,s,a,"",,,"Name of the edited output catalog"
+image,s,a,"",,,Name of the image corresponding to the input catalog
+deletions,s,h,"",,,"Name of the output catalog for deleted entries"
+photcolumns,s,h,"daophot",,,"Names of the standard photometry columns"
+xcolumn,s,h,mag,,,"Catalog column which is the X axis of X-Y plot"
+ycolumn,s,h,merr,,,"Catalog column which is the Y axis of X-Y plot"
+hcolumn,s,h,mag,,,"Catalog column which is to be binned"
+xposcolumn,s,h,"xcenter",,,"Name of the x coordinate column"
+yposcolumn,s,h,"ycenter",,,"Name of the y coordinate column"
+usercolumns,s,h,"",,,"Names of additional user selected columns"
+max_nstars,i,h,5000,1,,Maximum number of stars to load
+first_star,i,h,1,1,,First star in the catalog to load
+match_radius,r,h,2.0,,,Matching radius for positional coincidence on display
+graphics,s,h,"stdgraph",,,The graphics device
+gcommands,*gcur,h,"",,,Graphics cursor commands
+icommands,*imcur,h,"",,,Image cursor commands
+use_display,b,h,yes,,,Use the image display ?
diff --git a/noao/digiphot/ptools/pexamine/mkpkg b/noao/digiphot/ptools/pexamine/mkpkg
new file mode 100644
index 00000000..b2aa7dd8
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/mkpkg
@@ -0,0 +1,21 @@
+# The mkpkg file for the PEXAMINE task.
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ ptahgmr.x <mach.h> pexamine.h
+ ptalimr.x <mach.h>
+ ptcolon.x <gset.h> pexamine.h
+ ptdelete.x <gset.h> <mach.h> pexamine.h
+ ptgetphot.x <tbset.h> ../../lib/ptkeysdef.h pexamine.h
+ ptimplot.x <imhdr.h> <math.h> <gset.h> <mach.h>
+ ptplot.x <error.h> <fset.h> <tbset.h> <gset.h> <mach.h> \
+ <ctype.h> ../../lib/ptkeysdef.h pexamine.h
+ ptrddata.x ../../lib/ptkeysdef.h pexamine.h
+ ptsetup.x <error.h> pexamine.h <ctotok.h>
+ ptwtfile.x ../../lib/ptkeysdef.h pexamine.h
+ t_pexamine.x <error.h> <fset.h> pexamine.h
+ ;
diff --git a/noao/digiphot/ptools/pexamine/pexamine.h b/noao/digiphot/ptools/pexamine/pexamine.h
new file mode 100644
index 00000000..138ff1f4
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/pexamine.h
@@ -0,0 +1,115 @@
+# The PEXAMINE structure definitions.
+
+# Define the task termination conditions.
+
+define PX_QUIT 0
+define PX_EXIT 1
+
+# Define the delete indices
+
+define PX_GOOD 0
+define PX_DELETE 1
+define PX_MARK 2
+
+# Define some useful constants.
+
+define PX_SZCOLNAME 19 # the maximum length of a column name
+define PX_MAXNCOLS 20 # the maximum number of columns
+
+# Define the default photometry columns.
+
+define PX_DAOCOLS ",GROUP,ID,XCENTER,YCENTER,MSKY,STDEV,MAG,MERR,NITER,\
+CHI,SHARPNESS,ROUNDNESS"
+define PX_APCOLS ",ID,XCENTER,YCENTER,MSKY,STDEV,MAG,MERR,"
+
+# Define the structure.
+
+define LEN_PXSTRUCT (15 + 10 * PX_SZCOLNAME + 10)
+
+define PX_RNPHOT Memi[$1] # number of req'd photometry columns
+define PX_RNUSER Memi[$1+1] # number of req'd user columns
+define PX_RNCOLS Memi[$1+2] # total number of req'd columns
+define PX_RCOLNAMES Memi[$1+3] # ptr to list of req'd column names
+define PX_NPHOT Memi[$1+4] # number of photometry columns
+define PX_NUSER Memi[$1+5] # number of user columns
+define PX_NCOLS Memi[$1+6] # total number of stored columns
+define PX_COLNAMES Memi[$1+7] # ptr to list of stored column names
+define PX_COLPTRS Memi[$1+8] # ptr to array of stored column pointers
+
+define PX_RXCOLNAME Memc[P2C($1+10)] # the req'd x column
+define PX_RYCOLNAME Memc[P2C($1+10+PX_SZCOLNAME+1)] # the req'd y column
+define PX_XCOLNAME Memc[P2C($1+10+2*PX_SZCOLNAME+2)] # the x column
+define PX_YCOLNAME Memc[P2C($1+10+3*PX_SZCOLNAME+3)] # the y column
+define PX_RXPOSNAME Memc[P2C($1+10+4*PX_SZCOLNAME+4)] # the req'd xp column
+define PX_RYPOSNAME Memc[P2C($1+10+5*PX_SZCOLNAME+5)] # the req'd yp column
+define PX_XPOSNAME Memc[P2C($1+10+6*PX_SZCOLNAME+6)] # the x coord column
+define PX_YPOSNAME Memc[P2C($1+10+7*PX_SZCOLNAME+7)] # the y coord column
+define PX_RHCOLNAME Memc[P2C($1+10+8*PX_SZCOLNAME+8)] # the req'd hgm column
+define PX_HCOLNAME Memc[P2C($1+10+9*PX_SZCOLNAME+9)] # the hgm column
+
+# Define the colon commands arguments
+
+define PX_PCMDS "|photcolumns|usercolumns|xcolumn|ycolumn|hcolumn|xposcolumn|\
+yposcolumn|eparam|unlearn|x1|x2|y1|y2|marker|szmarker|grid|logx|logy|box|\
+ticklabels|majrx|minrx|majry|minry|round|fill|nbins|z1|z2|top_closed|rinner|\
+router|ncolumns|nlines|axes|angh|angv|floor|ceiling|zero|ncontours|interval|\
+nhi|dashpat|label|delete|"
+
+define PX_PCMD_PHOTCOLUMNS 1
+define PX_PCMD_USERCOLUMNS 2
+define PX_PCMD_XCOLUMN 3
+define PX_PCMD_YCOLUMN 4
+define PX_PCMD_HCOLUMN 5
+define PX_PCMD_XPOSCOLUMN 6
+define PX_PCMD_YPOSCOLUMN 7
+define PX_PCMD_EDIT 8
+define PX_PCMD_UNLEARN 9
+define PX_PCMD_X1 10
+define PX_PCMD_X2 11
+define PX_PCMD_Y1 12
+define PX_PCMD_Y2 13
+define PX_PCMD_MARKER 14
+define PX_PCMD_SZMARKER 15
+define PX_PCMD_GRID 16
+define PX_PCMD_LOGX 17
+define PX_PCMD_LOGY 18
+define PX_PCMD_BOX 19
+define PX_PCMD_TICKLABELS 20
+define PX_PCMD_MAJRX 21
+define PX_PCMD_MINRX 22
+define PX_PCMD_MAJRY 23
+define PX_PCMD_MINRY 24
+define PX_PCMD_ROUND 25
+define PX_PCMD_FILL 26
+define PX_PCMD_NBINS 27
+define PX_PCMD_Z1 28
+define PX_PCMD_Z2 29
+define PX_PCMD_TOP_CLOSED 30
+define PX_PCMD_RIN 31
+define PX_PCMD_ROUT 32
+define PX_PCMD_NCOLUMNS 33
+define PX_PCMD_NLINES 34
+define PX_PCMD_AXES 35
+define PX_PCMD_ANGH 36
+define PX_PCMD_ANGV 37
+define PX_PCMD_FLOOR 38
+define PX_PCMD_CEILING 39
+define PX_PCMD_ZERO 40
+define PX_PCMD_NCONTOURS 41
+define PX_PCMD_INTERVAL 42
+define PX_PCMD_NHI 43
+define PX_PCMD_DASHPAT 44
+define PX_PCMD_LABEL 45
+define PX_PCMD_DELETE 46
+
+# Define the plot types
+
+define PX_PLOTTYPES "|xyplot|histplot|radplot|surfplot|cntrplot|"
+
+define PX_XYPLOT 1
+define PX_HISTPLOT 2
+define PX_RADPLOT 3
+define PX_SURFPLOT 4
+define PX_CNTRPLOT 5
+
+define PX_MARKERS "|point|box|plus|cross|circle|hline|vline|diamond|"
diff --git a/noao/digiphot/ptools/pexamine/pexamine.key b/noao/digiphot/ptools/pexamine/pexamine.key
new file mode 100644
index 00000000..892e0542
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/pexamine.key
@@ -0,0 +1,146 @@
+ PEXAMINE Interactive Cursor Keystroke Commands
+
+ Basic Commands
+
+? Print help for the PEXAMINE task
+: PEXAMINE colon commands
+g Activate the graphics cursor
+i Activate the image cursor
+e Exit PEXAMINE and save the edited catalog
+q Quit PEXAMINE and discard the edited catalog
+
+ Data Examining Commands
+
+l List the name, datatype and units for all columns in the catalog
+o Print out the names and values of the stored columns for the
+ object nearest the cursor
+x Replot the current y column versus the current x column
+h Replot the current histogram
+r Plot the radial profile of the object nearest the cursor
+s Plot the surface of the object nearest the cursor
+c Plot the contour plot of the object nearest the cursor
+m Print the data values of the object nearest the cursor
+p Replot the current graph
+
+ Data Editing Commands
+
+z Reinitialize the data by removing all deletions and replot
+d Mark the point nearest the cursor for deletion
+u Undelete the marked point nearest the cursor
+t Toggle between marking points for deletion or undeletion
+( Mark points with X < X (cursor) for deletion or undeletion
+) Mark points with X > X (cursor) for deletion or undeletion
+v Mark points with Y < Y (cursor) for deletion or undeletion
+^ Mark points with Y > Y (cursor) for deletion or undeletion
+b Mark points inside a box for deletion or undeletion
+f Actually delete the marked points and replot
+
+
+ PEXAMINE Interactive Colon Commands
+
+:xcolumn [name] Show/set the X-Y plot X axis quantity
+:ycolumn [name] Show/set the X-Y plot Y axis quantity
+:hcolumn [name] Show/set the histogram plot quantity
+:photcolumns [col1,col2,...] Show/set the list of photometry columns
+:usercolumns [col1,col2,...] Show/set the list of user columns
+:delete [yes/no] Delete or undelete points
+:eparam [x/h/r/s/c] Edit/unlearn the specified plot pset
+ or
+:unlearn
+
+
+ PEXAMINE Interactive X-Y Plotting Commands
+
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:szmarker [value] Marker size
+:marker [point|box|plus|cross|circle|diamond|hline|vline] Marker type
+:logx [yes/no] Log scale the x axis?
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:grid [yes/no] Draw grid lines at major tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+
+ PEXAMINE Interactive Histogram Plotting Commands
+
+:nbins [value] Number of bins in the histogram
+:z1 [value] Minimum histogram intensity
+:z2 [value] Maximum histogram intensity
+:top_closed [y/n] Include z in the top bin?
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+ PEXAMINE Interactive Radial Profile Plotting Commands
+
+:rinner [value] Inner radius of the region to be plotted
+:router [value] Outer radius of the region to be plotted
+:x1 [value] Left world x-coord if not autoscaling
+:x2 [value] Right world x-coord if not autoscaling
+:y1 [value] Lower world y-coord if not autoscaling
+:y2 [value] Upper world y-coord if not autoscaling
+:szmarker [value] Marker size
+:marker [point|box|plus|cross|circle|diamond|hline|vline] Marker type
+:logx [yes/no] Log scale the x axis?
+:logy [yes/no] Log scale the y axis?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:grid [yes/no] Draw grid lines at major tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
+
+
+ PEXAMINE Interactive Surface Plotting Commands
+
+:ncolumns [value] Number of columns to be plotted
+:nlines [value] Number of lines to be plotted
+:axes [yes/no] Draw axes?
+:angh [value] Horizontal viewing angle
+:angv [value] Vertical viewing angle
+:floor [value] Minimum value to be plotted
+:ceiling [value] Maximum value to be plotted
+
+
+ PEXAMINE Interactive Contour Plotting Commands
+
+:ncolumns [value] Number of columns to be plotted
+:nlines [value] Number of lines to be plotted
+:floor [value] Minimum value to be plotted
+:ceiling [value] Maximum value to be plotted
+:zero [value] Greyscale value of zero contour
+:ncontours [value] Number of contours to be drawn
+:interval [value] Contour interval
+:nhi [value] Hi/low marking option
+:dashpat [value] Bit pattern for generating dashed lines
+:label [yes/no] Label major contours with their values?
+:box [yes/no] Draw box around periphery of window?
+:ticklabels [yes/no] Label tick marks?
+:majrx [value] Number of major divisions along x axis
+:minrx [value] Number of minor divisions along x axis
+:majry [value] Number of major divisions along y axis
+:minry [value] Number of minor divisions along y axis
+:round [yes/no] Round axes to nice values?
+:fill [yes/no] Fill viewport vs enforce unity aspect ratio?
diff --git a/noao/digiphot/ptools/pexamine/ptahgmr.x b/noao/digiphot/ptools/pexamine/ptahgmr.x
new file mode 100644
index 00000000..acf303b5
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptahgmr.x
@@ -0,0 +1,44 @@
+include <mach.h>
+include "pexamine.h"
+
+# PT_AHGMR -- Accumulate the histogram of the input vector. The output vector
+# HGM (the histogram) should be cleared prior to the first call. Delete
+# points or points marked for deletion are not included in the plot.
+
+procedure pt_ahgmr (data, delete, npix, hgm, nbins, z1, z2)
+
+real data[ARB] # data vector
+int delete[ARB] # deletions array
+int npix # number of pixels
+int hgm[ARB] # output histogram
+int nbins # number of bins in histogram
+real z1, z2 # greyscale values of first and last bins
+
+real z
+real dz
+int bin, i
+
+begin
+ dz = real (nbins - 1) / real (z2 - z1)
+ if (abs (dz - 1.0) < (EPSILONR * 2.0)) {
+ do i = 1, npix {
+ if ((delete[i] == PX_DELETE) || (delete[i] == PX_MARK))
+ next
+ z = data[i]
+ if (z >= z1 && z <= z2) {
+ bin = int (z - z1) + 1
+ hgm[bin] = hgm[bin] + 1
+ }
+ }
+ } else {
+ do i = 1, npix {
+ if ((delete[i] == PX_DELETE) || (delete[i] == PX_MARK))
+ next
+ z = data[i]
+ if (z >= z1 && z <= z2) {
+ bin = int ((z - z1) * dz) + 1
+ hgm[bin] = hgm[bin] + 1
+ }
+ }
+ }
+end
diff --git a/noao/digiphot/ptools/pexamine/ptalimr.x b/noao/digiphot/ptools/pexamine/ptalimr.x
new file mode 100644
index 00000000..614b2099
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptalimr.x
@@ -0,0 +1,35 @@
+include <mach.h>
+
+# PT_ALIMR -- Compute the limits (minimum and maximum values) of a vector
+# after rejecting any INDEF valued points.
+
+procedure pt_alimr (a, npix, minval, maxval)
+
+real a[ARB] # the input array
+int npix # the number of points
+real minval, maxval # the minimum and maximum value
+
+int i, ngood
+real value
+
+begin
+ minval = MAX_REAL
+ maxval = -MAX_REAL
+ ngood = 0
+
+ do i = 1, npix {
+ value = a[i]
+ if (IS_INDEFR(value))
+ next
+ ngood = ngood + 1
+ if (value < minval)
+ minval = value
+ if (value > maxval)
+ maxval = value
+ }
+
+ if (ngood == 0) {
+ minval = INDEFR
+ maxval = INDEFR
+ }
+end
diff --git a/noao/digiphot/ptools/pexamine/ptcolon.x b/noao/digiphot/ptools/pexamine/ptcolon.x
new file mode 100644
index 00000000..df2a29ae
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptcolon.x
@@ -0,0 +1,668 @@
+include <gset.h>
+include "pexamine.h"
+
+# PT_COLON -- Execute PEXAMINE colon commands.
+
+procedure pt_colon (px, gd, cmdstr, newdata, newxy, newhist, newcoords,
+ newplot, plottype, undelete)
+
+pointer px # pointer to the pexamine structure
+pointer gd # pointer to the graphics stream
+char cmdstr[ARB] # the colon command
+int newdata # read new columns from the input file
+int newxy # load new columns into the x and y arrays
+int newhist # load new column into the histogram array
+int newcoords # load new data into the coords array
+int newplot # replot the current plot
+int plottype # the plot type
+int undelete # delete or undelete points
+
+bool bval
+int type, ncmd, nrcols, ncols, ival, marktype
+pointer sp, cmd, str, rcols, cols
+real rval
+bool clgetb()
+int strdic(), nscan(), clgeti()
+real clgetr()
+
+errchk clgstr(), clgetb(), clgeti(), clgetr()
+errchk clpstr(), clputb(), clputi(), clputr()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+ call salloc (rcols, PX_SZCOLNAME * (PX_MAXNCOLS + 1), TY_CHAR)
+ call salloc (cols, PX_SZCOLNAME * (PX_MAXNCOLS + 1), TY_CHAR)
+
+ # Get the command.
+ call sscan (cmdstr)
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call sfree (sp)
+ return
+ }
+
+ # Define the pset type.
+ call salloc (str, SZ_LINE, TY_CHAR)
+ switch (plottype) {
+ case PX_XYPLOT:
+ call strcpy ("xyplot.", Memc[str], SZ_LINE)
+ case PX_HISTPLOT:
+ call strcpy ("histplot.", Memc[str], SZ_LINE)
+ case PX_RADPLOT:
+ call strcpy ("radplot.", Memc[str], SZ_LINE)
+ case PX_SURFPLOT:
+ call strcpy ("surfplot.", Memc[str], SZ_LINE)
+ case PX_CNTRPLOT:
+ call strcpy ("cntrplot.", Memc[str], SZ_LINE)
+ }
+
+ # Process the command.
+ ncmd = strdic (Memc[cmd], Memc[cmd], SZ_LINE, PX_PCMDS)
+ switch (ncmd) {
+
+ case PX_PCMD_PHOTCOLUMNS:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call pt_gphotcols (px, Memc[rcols], nrcols, Memc[cols],
+ ncols)
+ if (gd != NULL)
+ call gdeactivate (gd, AW_CLEAR)
+ call pt_lcols ("PHOTOMETRY COLUMNS", Memc[rcols], nrcols,
+ Memc[cols], ncols)
+ if (gd != NULL)
+ call greactivate (gd, AW_PAUSE)
+ } else {
+ call pt_gusercols (px, Memc[rcols], nrcols, Memc[cols], ncols)
+ call pt_setnames (px, Memc[cmd], Memc[rcols])
+ newdata = YES
+ newxy = YES
+ newhist = YES
+ newcoords = YES
+ newplot = YES
+ }
+
+ case PX_PCMD_USERCOLUMNS:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call pt_gusercols (px, Memc[rcols], nrcols, Memc[cols], ncols)
+ if (gd != NULL)
+ call gdeactivate (gd, AW_CLEAR)
+ call pt_lcols ("USER COLUMNS", Memc[rcols], nrcols, Memc[cols],
+ ncols)
+ if (gd != NULL)
+ call greactivate (gd, AW_PAUSE)
+ } else {
+ call pt_gphotcols (px, Memc[rcols], nrcols, Memc[cols], ncols)
+ call pt_setnames (px, Memc[rcols], Memc[cmd])
+ newdata = YES
+ newxy = YES
+ newhist = YES
+ newcoords = YES
+ newplot = YES
+ }
+
+ case PX_PCMD_XCOLUMN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call printf ("X column requested: %s stored: %s\n")
+ call pargstr (PX_RXCOLNAME(px))
+ call pargstr (PX_XCOLNAME(px))
+ } else {
+ call strupr (Memc[cmd])
+ call strcpy (Memc[cmd], PX_RXCOLNAME(px), PX_SZCOLNAME)
+ if (strdic (Memc[cmd], Memc[cmd], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) > 0) {
+ call strcpy (Memc[cmd], PX_XCOLNAME(px), PX_SZCOLNAME)
+ newxy = YES
+ newplot = YES
+ call clputr ("xyplot.x1", INDEFR)
+ call clputr ("xyplot.x2", INDEFR)
+ } else {
+ call printf ("Column %s not found\n")
+ call pargstr (PX_RXCOLNAME(px))
+ }
+ }
+
+ case PX_PCMD_YCOLUMN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call printf ("Y column requested: %s stored: %s\n")
+ call pargstr (PX_RYCOLNAME(px))
+ call pargstr (PX_YCOLNAME(px))
+ } else {
+ call strupr (Memc[cmd])
+ call strcpy (Memc[cmd], PX_RYCOLNAME(px), PX_SZCOLNAME)
+ if (strdic (Memc[cmd], Memc[cmd], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) > 0) {
+ call strcpy (Memc[cmd], PX_YCOLNAME(px), PX_SZCOLNAME)
+ newxy = YES
+ newplot = YES
+ call clputr ("xyplot.y1", INDEFR)
+ call clputr ("xyplot.y2", INDEFR)
+ } else {
+ call printf ("Column %s not found\n")
+ call pargstr (PX_RYCOLNAME(px))
+ }
+ }
+
+ case PX_PCMD_HCOLUMN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call printf ("Histogram column requested: %s stored: %s\n")
+ call pargstr (PX_RHCOLNAME(px))
+ call pargstr (PX_HCOLNAME(px))
+ } else {
+ call strupr (Memc[cmd])
+ call strcpy (Memc[cmd], PX_RHCOLNAME(px), PX_SZCOLNAME)
+ if (strdic (Memc[cmd], Memc[cmd], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) > 0) {
+ call strcpy (Memc[cmd], PX_HCOLNAME(px), PX_SZCOLNAME)
+ newhist = YES
+ newplot = YES
+ call clputr ("histplot.z1", INDEFR)
+ call clputr ("histplot.z2", INDEFR)
+ call clputr ("histplot.x1", INDEFR)
+ call clputr ("histplot.x2", INDEFR)
+ call clputr ("histplot.y1", INDEFR)
+ call clputr ("histplot.y2", INDEFR)
+ } else {
+ call printf ("Column %s not found\n")
+ call pargstr (PX_RHCOLNAME(px))
+ }
+ }
+
+ case PX_PCMD_XPOSCOLUMN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call printf ("X coord column requested: %s stored: %s\n")
+ call pargstr (PX_RXPOSNAME(px))
+ call pargstr (PX_XPOSNAME(px))
+ } else {
+ call strupr (Memc[cmd])
+ call strcpy (Memc[cmd], PX_RXPOSNAME(px), PX_SZCOLNAME)
+ if (strdic (Memc[cmd], Memc[cmd], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) > 0) {
+ call strcpy (Memc[cmd], PX_XPOSNAME(px), PX_SZCOLNAME)
+ newcoords = YES
+ } else {
+ call printf ("Column %s not found\n")
+ call pargstr (PX_RXPOSNAME(px))
+ }
+ }
+
+ case PX_PCMD_YPOSCOLUMN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call printf ("X coord column requested: %s stored: %s\n")
+ call pargstr (PX_RYPOSNAME(px))
+ call pargstr (PX_YPOSNAME(px))
+ } else {
+ call strupr (Memc[cmd])
+ call strcpy (Memc[cmd], PX_RYPOSNAME(px), PX_SZCOLNAME)
+ if (strdic (Memc[cmd], Memc[cmd], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) > 0) {
+ call strcpy (Memc[cmd], PX_YPOSNAME(px), PX_SZCOLNAME)
+ newcoords = YES
+ } else {
+ call printf ("Column %s not found\n")
+ call pargstr (PX_RXPOSNAME(px))
+ }
+ }
+
+ case PX_PCMD_EDIT:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS)
+ call printf ("The parameter set is undefined\n")
+ else {
+ type = strdic (Memc[cmd], Memc[cmd], SZ_LINE, PX_PLOTTYPES)
+ if (gd != NULL)
+ call gdeactivate (gd, 0)
+ switch (type) {
+ case PX_XYPLOT:
+ call clcmdw ("eparam xyplot")
+ case PX_HISTPLOT:
+ call clcmdw ("eparam histplot")
+ case PX_RADPLOT:
+ call clcmdw ("eparam radplot")
+ case PX_SURFPLOT:
+ call clcmdw ("eparam surfplot")
+ case PX_CNTRPLOT:
+ call clcmdw ("eparam cntrplot")
+ default:
+ call printf (
+ "The parameter set %s undefined\n")
+ call pargstr (Memc[cmd])
+ }
+ newplot = YES
+ if (gd != NULL)
+ call greactivate (gd, 0)
+ }
+
+ case PX_PCMD_UNLEARN:
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS)
+ call printf ("The parameter set is undefined\n")
+ else {
+ type = strdic (Memc[cmd], Memc[cmd], SZ_LINE, PX_PLOTTYPES)
+ switch (type) {
+ case PX_XYPLOT:
+ call clcmdw ("unlearn xyplot")
+ case PX_HISTPLOT:
+ call clcmdw ("unlearn histplot")
+ case PX_RADPLOT:
+ call clcmdw ("unlearn radplot")
+ case PX_SURFPLOT:
+ call clcmdw ("unlearn surfplot")
+ case PX_CNTRPLOT:
+ call clcmdw ("unlearn cntrplot")
+ default:
+ call printf ("The parameter set %s is undefined\n")
+ call pargstr (Memc[cmd])
+ }
+ newplot = YES
+ }
+
+ case PX_PCMD_NBINS:
+ call strcpy ("histplot.nbins", Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("nbins = %d\n")
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_Z1:
+ call strcpy ("histplot.z1", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("z1 = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_Z2:
+ call strcpy ("histplot.z2", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("z2 = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_TOP_CLOSED:
+ call strcpy ("histplot.top_closed", Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("top_closed = %b\n")
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_X1:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_X2:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_Y1:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_Y2:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_MARKER:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call clgstr (Memc[str], Memc[cmd], SZ_LINE)
+ call printf ("marker = %s\n")
+ call pargstr (Memc[cmd])
+ } else {
+ call pt_marker (Memc[cmd], SZ_LINE, marktype)
+ call clpstr (Memc[str], Memc[cmd])
+ }
+
+ case PX_PCMD_SZMARKER:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (clgetr (Memc[str]))
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_GRID:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargb (bval)
+ call pargstr (Memc[cmd])
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_LOGX:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_LOGY:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_BOX:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_TICKLABELS:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_FILL:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_ROUND:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("%s = %b\n")
+ call pargstr (Memc[cmd])
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_MAJRX:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_MINRX:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_MAJRY:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_MINRY:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_DELETE:
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("delete = %b\n")
+ if (undelete == YES)
+ call pargb (false)
+ else
+ call pargb (true)
+ } else {
+ if (bval)
+ undelete = NO
+ else
+ undelete = YES
+ }
+
+ case PX_PCMD_RIN:
+ call strcpy ("radplot.rinner", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("rinner = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_ROUT:
+ call strcpy ("radplot.router", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("router = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_NCOLUMNS:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_NLINES:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("%s = %d\n")
+ call pargstr (Memc[cmd])
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_AXES:
+ call strcpy ("surfplot.axes", Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("axes = %b\n")
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ case PX_PCMD_ANGH:
+ call strcpy ("surfplot.angh", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("angh = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_ANGV:
+ call strcpy ("surfplot.angv", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("angv = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_FLOOR:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_CEILING:
+ call strcat (Memc[cmd], Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("%s = %g\n")
+ call pargstr (Memc[cmd])
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_ZERO:
+ call strcpy ("cntrplot.zero", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("zero = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_NCONTOURS:
+ call strcpy ("cntrplot.ncontours", Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("ncontours = %d\n")
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_INTERVAL:
+ call strcpy ("cntrplot.interval", Memc[str], SZ_LINE)
+ call gargr (rval)
+ if (nscan() == 1) {
+ rval = clgetr (Memc[str])
+ call printf ("interval = %g\n")
+ call pargr (rval)
+ } else
+ call clputr (Memc[str], rval)
+
+ case PX_PCMD_NHI:
+ call strcpy ("cntrplot.nhi", Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("nhi = %d\n")
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_DASHPAT:
+ call strcpy ("cntrplot.dashpat", Memc[str], SZ_LINE)
+ call gargi (ival)
+ if (nscan() == 1) {
+ ival = clgeti (Memc[str])
+ call printf ("dashpat = %d\n")
+ call pargi (ival)
+ } else
+ call clputi (Memc[str], ival)
+
+ case PX_PCMD_LABEL:
+ call strcpy ("cntrplot.label", Memc[str], SZ_LINE)
+ call gargb (bval)
+ if (nscan() == 1) {
+ bval = clgetb (Memc[str])
+ call printf ("label = %b\n")
+ call pargb (bval)
+ } else
+ call clputb (Memc[str], bval)
+
+ default:
+ call printf ("Unknown or ambiguous colon command\7\n")
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/pexamine/ptdelete.x b/noao/digiphot/ptools/pexamine/ptdelete.x
new file mode 100644
index 00000000..f8a6581e
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptdelete.x
@@ -0,0 +1,335 @@
+include <gset.h>
+include <mach.h>
+include "pexamine.h"
+
+define MSIZE 2.0
+
+# PT_DELPT -- Mark/unmark the point nearest the cursor.
+
+procedure pt_delpt (gd, wx, wy, xpos, ypos, x, y, deleted, npix, undelete,
+ matchrad)
+
+pointer gd # pointer to the graphics stream
+real wx # X cursor position
+real wy # Y cursor position
+real xpos[ARB] # X coordinate array
+real ypos[ARB] # Y coordinate array
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int deleted[ARB] # array of delete indicators
+int npix # number of pixels
+int undelete # undelete flag
+real matchrad # matching radius
+
+int i, row
+real r2min, r2, mr2, wx0, wy0, xpos0, ypos0
+
+begin
+ # Initialize.
+ row = 0
+ r2min = MAX_REAL
+
+ # Set matching radius for the image display or graph.
+ if (IS_INDEFR(matchrad)) {
+ mr2 = MAX_REAL
+ if (gd != NULL)
+ call gctran (gd, wx, wy, wx0, wy0, 1, 0)
+ else {
+ wx0 = wx
+ wy0 = wy
+ }
+ } else {
+ mr2 = matchrad ** 2
+ wx0 = wx
+ wy0 = wy
+ }
+
+ # Search for the point nearest the cursor.
+ do i = 1 , npix {
+
+ if (deleted[i] == PX_DELETE)
+ next
+
+ if ((deleted[i] == PX_MARK && undelete == NO) ||
+ (deleted[i] == PX_GOOD && undelete == YES))
+ next
+
+ if (! IS_INDEFR(xpos[i]) && ! IS_INDEFR(ypos[i])) {
+ if (IS_INDEFR(matchrad)) {
+ if (gd != NULL)
+ call gctran (gd, xpos[i], ypos[i], xpos0, ypos0, 1, 0)
+ else {
+ xpos0 = xpos[i]
+ ypos0 = ypos[i]
+ }
+ } else {
+ xpos0 = xpos[i]
+ ypos0 = ypos[i]
+ }
+ r2 = (wx0 - xpos0) ** 2 + (wy0 - ypos0) ** 2
+ } else
+ r2 = MAX_REAL
+ if (r2 >= r2min)
+ next
+
+ r2min = r2
+ row = i
+ }
+
+ # Return if point not found.
+ if ((row == 0) || (r2min > mr2))
+ return
+
+ # Delete the point.
+ if (undelete == NO) {
+ deleted[row] = PX_MARK
+ if (gd == NULL)
+ return
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[row], y[row], GM_CROSS, MSIZE, MSIZE)
+ } else {
+ deleted[row] = PX_GOOD
+ if (gd == NULL)
+ return
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[row], y[row], GM_CROSS, MSIZE, MSIZE)
+ }
+end
+
+
+# PT_DYGTG -- Delete all points with Y > Y (cursor).
+
+procedure pt_dygtg (gd, wy, ypos, x, y, deleted, npix, undelete)
+
+pointer gd # pointer to graphics stream
+real wy # Y cursor position
+real ypos[ARB] # Y array of coordinate data
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int deleted[ARB] # array of delete indicators
+int npix # number of pixels
+int undelete # the delete or undelete flag
+
+int i
+
+begin
+ do i = 1 , npix {
+ if (ypos[i] <= wy)
+ next
+ if ((deleted[i] == PX_GOOD) && (undelete == NO)) {
+ deleted[i] = PX_MARK
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ } else if ((deleted[i] == PX_MARK) && (undelete == YES)) {
+ deleted[i] = PX_GOOD
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+ }
+end
+
+
+# PT_DYLTG -- Delete all points with Y < Y (cursor).
+
+procedure pt_dyltg (gd, wy, ypos, x, y, deleted, npix, undelete)
+
+pointer gd # pointer to graphics stream
+real wy # Y cursor position
+real ypos[ARB] # Y array of coordinate data
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int deleted[ARB] # array of delete indicators
+int npix # number of pixels
+int undelete # the delete or undelete flag
+
+int i
+
+begin
+ do i = 1 , npix {
+ if (ypos[i] >= wy)
+ next
+ if ((deleted[i] == PX_GOOD) && (undelete == NO)) {
+ deleted[i] = PX_MARK
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ } else if ((deleted[i] == PX_MARK) && (undelete == YES)) {
+ deleted[i] = PX_GOOD
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+ }
+end
+
+
+# PT_DXGTG -- Mark delete for all points with X > X (cursor)
+
+procedure pt_dxgtg (gd, wx, xpos, x, y, deleted, npix, undelete)
+
+pointer gd # pointer to graphics stream
+real wx # X cursor position
+real xpos[ARB] # X coordinate array
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int deleted[ARB] # array of delete indicators
+int npix # number of pixels
+int undelete # the delete or undelete flag
+
+int i
+
+begin
+ do i = 1 , npix {
+ if (xpos[i] <= wx)
+ next
+ if ((deleted[i] == PX_GOOD) && (undelete == NO)) {
+ deleted[i] = PX_MARK
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ } else if ((deleted[i] == PX_MARK) && (undelete == YES)) {
+ deleted[i] = PX_GOOD
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+ }
+end
+
+
+# PT_DXLTG -- Mark delete for all points with X < X (cursor).
+
+procedure pt_dxltg (gd, wx, xpos, x, y, deleted, npix, undelete)
+
+pointer gd # pointer to graphics stream
+real wx # X cursor position
+real xpos[ARB] # X coordinate array
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int deleted[ARB] # array of delete indicators
+int npix # number of pixels
+int undelete # the delete or undelete flag
+
+int i
+
+begin
+ do i = 1 , npix {
+ if (xpos[i] >= wx)
+ next
+ if ((deleted[i] == PX_GOOD) && (undelete == NO)) {
+ deleted[i] = PX_MARK
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ } else if ((deleted[i] == PX_MARK) && (undelete == YES)) {
+ deleted[i] = PX_GOOD
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+ }
+end
+
+
+# PT_DBOXG -- Delete all points inside a box
+
+procedure pt_dboxg (gd, xpos, ypos, x, y, deleted, npix, x1, y1, x2, y2,
+ undelete)
+
+pointer gd # pointer to the graphics stream
+real xpos[ARB] # x coordinate array
+real ypos[ARB] # y coordinate array
+real x[ARB] # x array of plotted data
+real y[ARB] # y array of plotted data
+int deleted[ARB] # array of deletion indicators
+int npix # number of pixels
+real x1, y1, x2, y2 # corners of the box
+int undelete # delete or undelete points
+
+int i
+real temp
+
+begin
+ # Make sure the points are in the correct order.
+ if (x2 < x1) {
+ temp = x1
+ x1 = x2
+ x2 = temp
+ }
+ if (y2 < y1) {
+ temp = y1
+ y1 = y2
+ y2 = temp
+ }
+
+ # Search for points within the box and delete.
+ do i = 1 , npix {
+ if (xpos[i] < x1 || xpos[i] > x2 || ypos[i] < y1 || ypos[i] > y2)
+ next
+ if ((deleted[i] == PX_GOOD) && (undelete == NO)) {
+ deleted[i] = PX_MARK
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ } else if ((deleted[i] == PX_MARK) && (undelete == YES)) {
+ deleted[i] = PX_GOOD
+ if (gd == NULL)
+ next
+ call gseti (gd, G_PMLTYPE, GL_CLEAR)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+ }
+end
+
+
+# PT_MDELETE -- Overplot crosses on those points which have been marked for
+# deletion.
+
+procedure pt_mdelete (gd, x, y, deleted, npix)
+
+pointer gd # pointer to the graphics stream
+real x[ARB] # the array plotted along the x axis
+real y[ARB] # the array plotted along the y axis
+int deleted[ARB] # the array of deletion indices
+int npix # the number of pixels
+
+int i
+
+begin
+ do i = 1, npix {
+ if (deleted[i] != PX_MARK)
+ next
+ call gseti (gd, G_PMLTYPE, GL_SOLID)
+ call gmark (gd, x[i], y[i], GM_CROSS, MSIZE, MSIZE)
+ }
+end
+
+
+# PT_UPDATE -- Actually delete points currently marked for deletion.
+
+procedure pt_update (deleted, npix)
+
+int deleted[ARB] # array of deletions indices
+int npix # the number of pixels
+
+int i
+
+begin
+ # Add the marked points to the deletions array.
+ do i = 1, npix {
+ if (deleted[i] != PX_MARK)
+ next
+ deleted[i] = PX_DELETE
+ }
+end
diff --git a/noao/digiphot/ptools/pexamine/ptgetphot.x b/noao/digiphot/ptools/pexamine/ptgetphot.x
new file mode 100644
index 00000000..df3b27f0
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptgetphot.x
@@ -0,0 +1,432 @@
+include <tbset.h>
+include "../../lib/ptkeysdef.h"
+include "pexamine.h"
+
+define NAPRESULT 10
+
+# PT_GETPHOT -- Read the specified columns out of the photometry catalog.
+# PT_GETPHOT works with either the "old" APPHOT files or the new ST Tables.
+
+int procedure pt_getphot (px, apd, key, max_nstars, first_star)
+
+pointer px # pointer to the pexamine structure
+int apd # input photometry file descriptor
+pointer key # pointer to key structure for text files
+int max_nstars # the maximum number of stars
+int first_star # first star to load
+
+int i, nstars
+int pt_goldap(), pt_gtabphot(), strdic()
+errchk pt_goldap(), pt_gtabphot()
+
+begin
+ # Allocate the required memory for the photometry, user and
+ # dummy columns and fill with INDEFR.
+ do i = 1, PX_MAXNCOLS {
+ call realloc (Memi[PX_COLPTRS(px)+i-1], max_nstars, TY_REAL)
+ call amovkr (INDEFR, Memr[Memi[PX_COLPTRS(px)+i-1]], max_nstars)
+ }
+
+ # Get the results.
+ if (key == NULL)
+ nstars = pt_gtabphot (apd, px, max_nstars, first_star)
+ else
+ nstars = pt_goldap (apd, px, key, max_nstars, first_star)
+
+ # Reallocate space if necessary.
+ if (nstars < max_nstars) {
+ do i = 1, PX_MAXNCOLS {
+ if (Memi[PX_COLPTRS(px)+i-1] == NULL)
+ next
+ if (i > PX_NCOLS(px)) {
+ call mfree (Memi[PX_COLPTRS(px)+i-1], TY_REAL)
+ Memi[PX_COLPTRS(px)+i-1] = NULL
+ } else
+ call realloc (Memi[PX_COLPTRS(px)+i-1], nstars, TY_REAL)
+ }
+ }
+
+ # Get the x and y columns.
+ if (strdic (PX_RXCOLNAME(px), PX_XCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ PX_XCOLNAME(px) = EOS
+ if (strdic (PX_RYCOLNAME(px), PX_YCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ PX_YCOLNAME(px) = EOS
+
+ # Get the x and y coordinate columns.
+ if (strdic (PX_RXPOSNAME(px), PX_XPOSNAME(px), PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ PX_XPOSNAME(px) = EOS
+ if (strdic (PX_RYPOSNAME(px), PX_YPOSNAME(px), PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ PX_YPOSNAME(px) = EOS
+
+ # Get the histogram column names.
+ if (strdic (PX_RHCOLNAME(px), PX_HCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ PX_HCOLNAME(px) = EOS
+
+ return (nstars)
+end
+
+
+# PT_GOLDAP -- Read in the photometry from an old style APPHOT file.
+
+int procedure pt_goldap (apd, px, apkey, max_nstars, first_star)
+
+int apd # pointer to the input file descriptor
+pointer px # pointer to the pexamine structure
+pointer apkey # pointer to the key structure
+int max_nstars # maximum number of stars
+int first_star # first star to load
+
+char lbracket
+int i, ip, index, nselect, nphot, nptr, nstars
+pointer sp, data, rcolname, colname
+int pt_photsel(), pt_getnames(), strdic(), stridx()
+data lbracket /'['/
+
+begin
+ call smark (sp)
+ call salloc (data, PX_MAXNCOLS, TY_REAL)
+ call salloc (rcolname, PX_SZCOLNAME, TY_CHAR)
+ call salloc (colname, PX_SZCOLNAME, TY_CHAR)
+
+ # Rewind the text file.
+ call seek (apd, BOF)
+
+ # Now read in the results.
+ nptr = 0
+ nstars = 0
+ while (pt_photsel (apkey, apd, Memc[PX_RCOLNAMES(px)], first_star +
+ max_nstars - 1, Memc[PX_COLNAMES(px)], Memr[data]) != EOF) {
+ nselect = KY_NSELECT(apkey)
+ if (nselect <= 0)
+ break
+ nstars = nstars + 1
+ if (nstars < first_star)
+ next
+ do i = 1, nselect
+ Memr[Memi[PX_COLPTRS(px)+i-1]+nptr] = Memr[data+i-1]
+ nptr = nptr + 1
+ }
+
+ # Count the fields.
+ ip = 1
+ nselect = 0
+ while (pt_getnames (Memc[PX_COLNAMES(px)], ip, Memc[rcolname],
+ PX_SZCOLNAME) != EOF)
+ nselect = nselect + 1
+ PX_NCOLS(px) = nselect
+
+ # Count the photometry fields.
+ ip = 1
+ nselect = 0
+ nphot = 0
+ while (pt_getnames (Memc[PX_RCOLNAMES(px)], ip, Memc[rcolname],
+ PX_SZCOLNAME) != EOF) {
+ nselect = nselect + 1
+ if (nselect > PX_RNPHOT(px))
+ break
+ if (strdic (Memc[rcolname], Memc[colname], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0) {
+ index = stridx (lbracket, Memc[rcolname])
+ if (index <= 1)
+ next
+ call strcpy (Memc[rcolname], Memc[colname], index - 1)
+ if (strdic (Memc[colname], Memc[colname], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)]) <= 0)
+ next
+ }
+ nphot = nphot + 1
+ }
+ PX_NPHOT(px) = nphot
+
+ # Count the user fields.
+ PX_NUSER(px) = PX_NCOLS(px) - PX_NPHOT(px)
+
+ call sfree (sp)
+
+ return (nptr)
+end
+
+
+# PT_GTABPHOT -- Read in the photometry from an ST table. It may be possible
+# to do this more efficiently depending on how the table ir organized.
+
+int procedure pt_gtabphot (tp, px, max_nstars, first_star)
+
+pointer tp # table descriptor
+pointer px # pointer to the pexamine structure
+int max_nstars # maximum number of stars
+int first_star # first star to load
+
+bool nullflag
+int ntot, ncount, record, ip, col, nrow, ival
+pointer sp, colname, colptrs, cptr, dptr
+int pt_getnames(), tbpsta(), tbcigi()
+
+begin
+ # Allocate working memory.
+ call smark (sp)
+ call salloc (colname, PX_SZCOLNAME, TY_CHAR)
+ call salloc (colptrs, PX_MAXNCOLS + 2, TY_POINTER)
+
+ # Define the column pointers for the preset columns.
+ ip = 1
+ ncount = 0
+ Memc[PX_COLNAMES(px)] = EOS
+ ntot = 0
+ while (pt_getnames (Memc[PX_RCOLNAMES(px)], ip, Memc[colname],
+ PX_SZCOLNAME) != EOF) {
+
+ ncount = ncount + 1
+ call tbcfnd (tp, Memc[colname], Memi[colptrs+ntot], 1)
+ if (Memi[colptrs+ntot] == NULL)
+ call strcat ("[1]", Memc[colname], PX_SZCOLNAME)
+ call tbcfnd (tp, Memc[colname], Memi[colptrs+ntot], 1)
+ if (Memi[colptrs+ntot] == NULL)
+ next
+
+ call strcat (",", Memc[PX_COLNAMES(px)], (PX_MAXNCOLS + 1) *
+ PX_SZCOLNAME)
+ call strcat (Memc[colname], Memc[PX_COLNAMES(px)],
+ (PX_MAXNCOLS + 1) * PX_SZCOLNAME)
+
+ ntot = ntot + 1
+ if (ncount <= PX_RNPHOT(px))
+ PX_NPHOT(px) = ntot
+ }
+ PX_NCOLS(px) = ntot
+ PX_NUSER(px) = PX_NCOLS(px) - PX_NPHOT(px)
+
+ # Get the results filling in any record that can not be interpreted
+ # as a real number with INDEFR.
+
+ nrow = tbpsta (tp, TBL_NROWS)
+ if (first_star > nrow) {
+ call sfree (sp)
+ return (0)
+ }
+
+ nrow = min (nrow - first_star + 1, max_nstars)
+
+ do col = 1, PX_NCOLS(px) {
+
+ cptr = Memi[colptrs+col-1]
+ if (cptr == NULL)
+ next
+ dptr = Memi[PX_COLPTRS(px)+col-1]
+ if (dptr == NULL)
+ next
+
+ if (tbcigi (cptr, TBL_COL_DATATYPE) == TY_REAL) {
+ do record = first_star, nrow + first_star - 1
+ call tbrgtr (tp, cptr, Memr[dptr+record-first_star],
+ nullflag, 1, record)
+ } else if (tbcigi (cptr, TBL_COL_DATATYPE) == TY_INT) {
+ do record = first_star, nrow + first_star - 1 {
+ call tbrgti (tp, cptr, ival, nullflag, 1, record)
+ Memr[dptr+record-first_star] = ival
+ }
+ }
+ }
+
+ call sfree (sp)
+
+ if (PX_NCOLS(px) <= 0)
+ return (0)
+ else
+ return (nrow)
+end
+
+
+# PT_PHOTSEL -- Procedure to select real records from a text file.
+
+int procedure pt_photsel (key, fd, infields, max_nrecords, outfields, data)
+
+pointer key # pointer to key structure
+int fd # text file descriptor
+char infields[ARB] # requested output fields
+int max_nrecords # maximum number of records to be read
+char outfields[ARB] # selected output field
+real data[ARB] # array of real values read from the file
+
+int nchars, nunique, uunique, funique, ncontinue, recptr
+int first_rec, record
+pointer line
+int getline(), strncmp(), pt_choose()
+
+data first_rec /YES/
+
+begin
+ # Initialize the file read.
+ if (first_rec == YES) {
+ record = 0
+ nunique = 0
+ uunique = 0
+ funique = 0
+ call malloc (line, SZ_LINE, TY_CHAR)
+ }
+
+ ncontinue = 0
+ recptr = 1
+
+ # Loop over the text file records.
+ repeat {
+
+ # Check for the maximum number of records and EOF.
+ if (record >= max_nrecords)
+ nchars = EOF
+ else
+ nchars = getline (fd, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # skip blank lines
+
+ } else {
+
+ # Construct the table record.
+ call pt_mkrec (key, Memc[line], nchars, first_rec, recptr,
+ ncontinue)
+
+ # Construct output record when there is no continuation char.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Select the appropriate records.
+ if (first_rec == YES) {
+ call pt_fields (key, infields, outfields)
+ if (pt_choose (key, outfields) <= 0) {
+ nchars = EOF
+ break
+ }
+ }
+
+ # Construct the output record by moving selected fields
+ # into the data structures.
+
+ call pt_grecord (key, data)
+ first_rec = NO
+ record = record + 1
+
+ # Record is complete so exit the loop.
+ break
+ }
+ }
+
+ }
+
+ if (nchars == EOF) {
+ first_rec = YES
+ record = 0
+ nunique = 0
+ uunique = 0
+ funique = 0
+ call mfree (line, TY_CHAR)
+ return (EOF)
+ } else
+ return (record)
+end
+
+
+# PT_FIELDS -- Check the user definitions for multiply defined entries.
+
+procedure pt_fields (key, infields, outfields)
+
+pointer key # pointer to keys strucuture
+char infields[ARB] # the list of input fields
+char outfields[ARB] # the list of input fields
+
+int ijunk, num
+pointer sp, name, aranges, ranges, rangeset, list
+int pt_gnfn(), pt_ranges(), decode_ranges(), get_next_number(), strlen()
+int pt_kstati()
+pointer pt_ofnl()
+
+begin
+ call smark (sp)
+ call salloc (name, PX_SZCOLNAME, TY_CHAR)
+ call salloc (aranges, SZ_LINE, TY_CHAR)
+ call salloc (ranges, SZ_LINE, TY_CHAR)
+ call salloc (rangeset, 3 * KY_MAXNRANGES + 1, TY_INT)
+
+ list = pt_ofnl (key, infields)
+ outfields[1] = EOS
+ while (pt_gnfn (list, Memc[name], Memc[aranges], KY_SZPAR) != EOF) {
+ if (Memc[name] == EOS)
+ next
+ num = 0
+ if (Memc[aranges] == EOS) {
+ if (pt_kstati (key, Memc[name], KY_NUMELEMS) > 1)
+ call strcat ("[1]", Memc[name], PX_SZCOLNAME)
+ } else if (pt_ranges (Memc[aranges], Memc[ranges], ijunk,
+ SZ_LINE) == ERR) {
+ call strcat ("[1]", Memc[name], PX_SZCOLNAME)
+ } else if (decode_ranges (Memc[ranges], Memi[rangeset],
+ KY_MAXNRANGES, ijunk) == ERR) {
+ call strcat ("[1]", Memc[name], PX_SZCOLNAME)
+ } else if (get_next_number (Memi[rangeset], num) > 0) {
+ call sprintf (Memc[name+strlen(Memc[name])], PX_SZCOLNAME,
+ "[%d]")
+ call pargi (num)
+ } else {
+ call strcat ("[1]", Memc[name], PX_SZCOLNAME)
+ }
+ call strcat (",", outfields, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], outfields, PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ }
+
+ call pt_cfnl (list)
+ call sfree (sp)
+end
+
+
+# PT_GRECORD -- Move selected photometry results into a real arrays.
+
+procedure pt_grecord (key, data)
+
+pointer key # pointer to keys strucuture
+real data[ARB] # output array of real selected data
+
+int i, index, elem, maxch, kip, ip
+int ctor()
+
+begin
+ do i = 1, KY_NSELECT(key) {
+
+ index = Memi[KY_SELECT(key)+i-1]
+ elem = Memi[KY_ELEM_SELECT(key)+i-1]
+ maxch = Memi[KY_LEN_SELECT(key)+i-1]
+ kip = Memi[KY_PTRS(key)+index-1] + (elem - 1) * maxch
+
+ ip = 1
+ if (kip == NULL)
+ data[i] = INDEFR
+ else if (ctor (Memc[kip], ip, data[i]) <= 0)
+ data[i] = INDEFR
+ }
+
+end
diff --git a/noao/digiphot/ptools/pexamine/ptimplot.x b/noao/digiphot/ptools/pexamine/ptimplot.x
new file mode 100644
index 00000000..8e586b97
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptimplot.x
@@ -0,0 +1,940 @@
+include <imhdr.h>
+include <gset.h>
+include <math.h>
+include <mach.h>
+
+
+# PT_RPLOT -- Plot the radial profile.
+
+procedure pt_rplot (gd, im, wx, wy)
+
+pointer gd # pointer to the graphics stream
+pointer im # pointer to the input image
+real wx, wy # radial profile coordinates
+
+int marker_type, lenbuf, npix
+pointer sp, radius, intensity, marker, longtitle
+real szmarker, rin, rout, x1, x2, y1, y2, dmin, dmax
+bool clgetb()
+int clgeti(), strlen(), pt_radpix()
+real clgetr()
+
+begin
+ # Check for undefined graphics stream.
+ if (gd == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check for undefined input image.
+ if (im == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check for an undefined center.
+ if (IS_INDEFR(wx) || IS_INDEFR(wy)) {
+ call printf ("The radial profile plot center is undefined.\n")
+ return
+ }
+
+ # Get the inner and outer radii.
+ rin = clgetr ("radplot.rinner")
+ rout = clgetr ("radplot.router")
+ if (rout <= rin) {
+ call printf (
+ "The outer radius %g is <= the inner radius %g\n")
+ call pargr (rin)
+ call pargr (rout)
+ return
+ }
+
+ # Allocate working space.
+ call smark (sp)
+
+ # Get the data.
+ lenbuf = PI * (rin + rout + 1.0) * (rout - rin + 0.5)
+ call salloc (radius, lenbuf, TY_REAL)
+ call salloc (intensity, lenbuf, TY_REAL)
+ npix = pt_radpix (im, wx, wy, rin, rout, Memr[radius], Memr[intensity])
+ if (npix <= 0) {
+ call printf ("The object at %g %g is off the image\n")
+ call pargr (wx)
+ call pargr (wy)
+ call sfree (sp)
+ return
+ }
+
+ # Clear the plotting strucuture.
+ call gclear (gd)
+
+ # Fetch the window and viewport parameters.
+ x1 = clgetr ("radplot.x1")
+ x2 = clgetr ("radplot.x2")
+ y1 = clgetr ("radplot.y1")
+ y2 = clgetr ("radplot.y2")
+ if (IS_INDEFR(x1) || IS_INDEFR(x2)) {
+ call pt_alimr (Memr[radius], npix, dmin, dmax)
+ if (IS_INDEFR(x1))
+ x1 = dmin
+ if (IS_INDEFR(x2))
+ x2 = dmax
+ }
+ if (IS_INDEFR(y1) || IS_INDEFR(y2)) {
+ call pt_alimr (Memr[intensity], npix, dmin, dmax)
+ if (IS_INDEFR(y1))
+ y1 = dmin
+ if (IS_INDEFR(y2))
+ y2 = dmax
+ }
+
+ # Set the scale of the axes.
+ call gswind (gd, x1, x2, y1, y2)
+ if (clgetb ("radplot.logx"))
+ call gseti (gd, G_XTRAN, GW_LOG)
+ else
+ call gseti (gd, G_XTRAN, GW_LINEAR)
+ if (clgetb ("radplot.logy"))
+ call gseti (gd, G_YTRAN, GW_LOG)
+ else
+ call gseti (gd, G_YTRAN, GW_LINEAR)
+
+ # Get the x and y axes parameters.
+ if (! clgetb ("radplot.fill"))
+ call gseti (gd, G_ASPECT, 1)
+ if (clgetb ("radplot.round"))
+ call gseti (gd, G_ROUND, YES)
+
+ # Get the axis drawing parameters.
+ if (clgetb ("radplot.box")) {
+
+ # Get number of major and minor tick marks.
+ call gseti (gd, G_XNMAJOR, clgeti ("radplot.majrx"))
+ call gseti (gd, G_XNMINOR, clgeti ("radplot.minrx"))
+ call gseti (gd, G_YNMAJOR, clgeti ("radplot.majry"))
+ call gseti (gd, G_YNMINOR, clgeti ("radplot.minry"))
+
+ # Label tick marks on axes.
+ if (clgetb ("radplot.ticklabels"))
+ call gseti (gd, G_LABELTICKS, YES)
+ else
+ call gseti (gd, G_LABELTICKS, NO)
+
+ # Draw grid.
+ if (clgetb ("radplot.grid"))
+ call gseti (gd, G_DRAWGRID, YES)
+ else
+ call gseti (gd, G_DRAWGRID, NO)
+
+ # Optionally draw a box around the plot.
+ call salloc (longtitle, 2 * SZ_LINE, TY_CHAR)
+ if (clgetb ("radplot.banner")) {
+ call sysid (Memc[longtitle], 2 * SZ_LINE)
+ call sprintf (Memc[longtitle+strlen(Memc[longtitle])],
+ 2 * SZ_LINE, "\n%s: xc=%g yc=%g rinner=%g router=%g\n%s")
+ call pargstr (IM_HDRFILE(im))
+ call pargr (wx)
+ call pargr (wy)
+ call pargr (rin)
+ call pargr (rout)
+ call pargstr ("Radial Profile Plot")
+ } else {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "%s: xc=%g yc=%g rinner=%g router=%g\n%s")
+ call pargstr (IM_HDRFILE(im))
+ call pargr (wx)
+ call pargr (wy)
+ call pargr (rin)
+ call pargr (rout)
+ call pargstr ("Radial Profile Plot")
+ }
+ call glabax (gd, Memc[longtitle], "Radial distance (pixels)",
+ "Intensity (counts)")
+ }
+
+ # Get the marker type, the size of the marker and the linewidth.
+ call salloc (marker, SZ_FNAME, TY_CHAR)
+ call clgstr ("radplot.marker", Memc[marker], SZ_FNAME)
+ call pt_marker (Memc[marker], SZ_FNAME, marker_type)
+ if (marker_type != GM_POINT)
+ szmarker = clgetr ("radplot.szmarker")
+ else
+ szmarker = 0.0
+ call gsetr (gd, G_PLWIDTH, 2.0)
+
+ # Draw the points in using the deletions array.
+ call gpmark (gd, Memr[radius], Memr[intensity], npix, marker_type,
+ szmarker, szmarker)
+ call gflush (gd)
+
+ call sfree (sp)
+end
+
+
+define CSIZE 24
+
+# PT_SPLOT -- Draw a perspective view of a surface. The altitude
+# and azimuth of the viewing angle are variable.
+
+procedure pt_splot (gd, im, x, y)
+
+pointer gd # pointer to the graphics stream
+pointer im # pointer to the image descriptor
+real x, y # the object center
+
+int nx, ny, x1, x2, y1, y2, npts, wkid
+pointer data, sp, sdata, work, longtitle
+real floor, ceiling, angv, angh
+bool clgetb()
+int clgeti(), strlen()
+pointer pt_gdata()
+real clgetr()
+
+int first
+real vpx1, vpx2, vpy1, vpy2
+common /frstfg/ first
+common /noaovp/ vpx1, vpx2, vpy1, vpy2
+
+begin
+ # Check for undefined graphics stream.
+ if (gd == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check for undefined input image.
+ if (im == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check for an undefined center.
+ if (IS_INDEFR(x) || IS_INDEFR(y)) {
+ call printf ("The surface plot center is undefined\n")
+ return
+ }
+
+ # Get the data.
+ ny = clgeti ("surfplot.nlines")
+ nx = clgeti ("surfplot.ncolumns")
+ x1 = x - (nx - 1) / 2 + 0.5
+ x2 = x + nx / 2 + 0.5
+ y1 = y - (ny - 1) / 2 + 0.5
+ y2 = y + ny / 2 + 0.5
+ data = pt_gdata (im, x1, x2, y1, y2)
+ if (data == NULL) {
+ call printf ("The requested image section if off the image\n")
+ return
+ }
+
+ call smark (sp)
+
+ # Set the title.
+ call salloc (longtitle, 2 * SZ_LINE, TY_CHAR)
+ if (clgetb ("surfplot.banner")) {
+ Memc[longtitle] = '\n'
+ call sysid (Memc[longtitle+1], 2 * SZ_LINE)
+ call sprintf (Memc[longtitle+strlen(Memc[longtitle])], 2 * SZ_LINE,
+ "\nObject at x: %g y: %g\nSurface plot of %s[%d:%d,%d:%d]")
+ call pargr (x)
+ call pargr (y)
+ call pargstr (IM_HDRFILE(im))
+ call pargi (x1)
+ call pargi (x2)
+ call pargi (y1)
+ call pargi (y2)
+ } else {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "\nObject at x: %g y: %g\nSurface plot of %s[%d:%d,%d:%d]")
+ call pargr (x)
+ call pargr (y)
+ call pargstr (IM_HDRFILE(im))
+ call pargi (x1)
+ call pargi (x2)
+ call pargi (y1)
+ call pargi (y2)
+ }
+
+ # Initialize the plot.
+ call gclear (gd)
+
+ # Set the viewport, turn off axes drawing.
+ call gsview (gd, 0.1, 0.9, 0.1, 0.9)
+ call gseti (gd, G_DRAWAXES, NO)
+ call glabax (gd, Memc[longtitle], "", "")
+
+ nx = x2 - x1 + 1
+ ny = y2 - y1 + 1
+ npts = nx * ny
+
+ # Take floor and ceiling if enabled (nonzero).
+ floor = clgetr ("surfplot.floor")
+ ceiling = clgetr ("surfplot.ceiling")
+ if (IS_INDEFR (floor) && IS_INDEFR (ceiling))
+ sdata = data
+ else {
+ call salloc (sdata, npts, TY_REAL)
+ call amovr (Memr[data], Memr[sdata], npts)
+ if (! IS_INDEFR (floor) && ! IS_INDEFR (ceiling)) {
+ floor = min (floor, ceiling)
+ ceiling = max (floor, ceiling)
+ }
+ if (! IS_INDEFR (floor))
+ call amaxkr (Memr[sdata], floor, Memr[sdata], npts)
+ if (! IS_INDEFR (ceiling))
+ call aminkr (Memr[sdata], ceiling, Memr[sdata], npts)
+ }
+
+ # Open graphics device and make plot.
+ call gopks (STDERR)
+ wkid = 1
+ call gopwk (wkid, 6, gd)
+ call gacwk (wkid)
+
+ first = 1
+ call srfabd()
+ call ggview (gd, vpx1, vpx2, vpy1, vpy2)
+ call set (vpx1, vpx2, vpy1, vpy2, 1.0, 1024., 1.0, 1024., 1)
+
+ angh = clgetr ("surfplot.angh")
+ angv = clgetr ("surfplot.angv")
+ call salloc (work, 2 * (2*nx*ny+nx+ny), TY_REAL)
+ call ezsrfc (Memr[sdata], nx, ny, angh, angv, Memr[work])
+
+ if (clgetb ("surfplot.axes")) {
+ call gswind (gd, real (x1), real (x2), real (y1), real (y2))
+ call gseti (gd, G_CLIP, NO)
+ call pt_perimeter (gd, Memr[sdata], nx, ny, angh, angv)
+ }
+
+ call gdawk (wkid)
+ call gclks ()
+ call sfree (sp)
+end
+
+
+# PT_CPLOT -- Contour map
+# This is an interface to the NCAR CONREC routine.
+
+procedure pt_cplot (gd, im, x, y)
+
+pointer gd # pointer to the graphics stream
+pointer im # pointer to the input image
+real x, y # center of the contour plot
+
+int nx, ny, x1, x2, y1, y2, nhi, dashpat, npts, ncontours, wkid, nset
+pointer data, sp, longtitle, data1
+real xs, xe, ys, ye, vx1, vx2, vy1, vy2
+real zero, floor, ceiling, zmin, zmax, interval, finc
+bool clgetb(), fp_equalr()
+int clgeti(), btoi(), strlen()
+pointer pt_gdata()
+real clgetr()
+
+int isizel, isizem, isizep, nrep, ncrt, ilab, nulbll, ioffd
+int ioffm, isolid, nla, nlm, first
+real xlt, ybt, side, ext, hold[5]
+common /conflg/ first
+common /conre4/ isizel, isizem , isizep, nrep, ncrt, ilab, nulbll,
+ ioffd, ext, ioffm, isolid, nla, nlm, xlt, ybt, side
+common /noaolb/ hold
+
+begin
+ # Check for undefined graphics stream.
+ if (gd == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check for undefined input image.
+ if (im == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Check fo an undefined center.
+ if (IS_INDEFR(x) || IS_INDEFR(y)) {
+ call printf ("The center of the contour plot is undefined\n")
+ return
+ }
+
+ # Get the data.
+ ny = clgeti ("cntrplot.nlines")
+ nx = clgeti ("cntrplot.ncolumns")
+ x1 = x - (nx - 1) / 2 + 0.5
+ x2 = x + nx / 2 + 0.5
+ y1 = y - (ny - 1) / 2 + 0.5
+ y2 = y + ny / 2 + 0.5
+ data = pt_gdata (im, x1, x2, y1, y2)
+ if (data == NULL) {
+ call printf ("The image section to be contoured is off the image\n")
+ return
+ }
+
+ call smark (sp)
+
+ # Intialize the plot
+ call gclear (gd)
+
+ # Set the WCS.
+ xs = x1
+ xe = x2
+ ys = y1
+ ye = y2
+ call gswind (gd, xs, xe, ys, ye)
+
+ nx = x2 - x1 + 1
+ ny = y2 - y1 + 1
+ if (! clgetb ("cntrplot.fill"))
+ call gsetr (gd, G_ASPECT, real (ny-1) / real (nx-1))
+ call gseti (gd, G_ROUND, btoi (clgetb ("cntrplot.round")))
+
+ if (clgetb ("cntrplot.box")) {
+
+ # Get number of major and minor tick marks.
+ call gseti (gd, G_XNMAJOR, clgeti ("cntrplot.majrx"))
+ call gseti (gd, G_XNMINOR, clgeti ("cntrplot.minrx"))
+ call gseti (gd, G_YNMAJOR, clgeti ("cntrplot.majry"))
+ call gseti (gd, G_YNMINOR, clgeti ("cntrplot.minry"))
+
+ # Label tick marks on axes ?
+ call gseti (gd, G_LABELTICKS, btoi (clgetb ("cntrplot.ticklabels")))
+
+ # Construct the title.
+ call salloc (longtitle, 2 * SZ_LINE, TY_CHAR)
+ if (clgetb ("cntrplot.banner")) {
+ call sysid (Memc[longtitle], 2 * SZ_LINE)
+ call sprintf (Memc[longtitle+strlen(Memc[longtitle])],
+ 2 * SZ_LINE,
+ "\nObject at x: %g y: %g\n\nContour plot of %s[%d:%d,%d:%d]\n")
+ call pargr (x)
+ call pargr (y)
+ call pargstr (IM_HDRFILE(im))
+ call pargi (x1)
+ call pargi (x2)
+ call pargi (y1)
+ call pargi (y2)
+ } else {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "\nObject at x: %g y: %g\n\nContour plot of %s[%d:%d,%d:%d]\n")
+ call pargr (x)
+ call pargr (y)
+ call pargstr (IM_HDRFILE(im))
+ call pargi (x1)
+ call pargi (x2)
+ call pargi (y1)
+ call pargi (y2)
+ }
+
+ call glabax (gd, Memc[longtitle], "", "")
+ }
+
+ # First of all, intialize conrec's block data before altering any
+ # parameters in common.
+ first = 1
+ call conbd
+
+ # Set the contouring parameters.
+ zero = clgetr ("cntrplot.zero")
+ floor = clgetr ("cntrplot.floor")
+ ceiling = clgetr ("cntrplot.ceiling")
+ nhi = clgeti ("cntrplot.nhi")
+ dashpat = clgeti ("cntrplot.dashpat")
+
+ # Resolve INDEF limits.
+ npts = nx * ny
+ if (IS_INDEFR (floor) || IS_INDEFR (ceiling)) {
+ call alimr (Memr[data], npts, zmin, zmax)
+ if (IS_INDEFR (floor))
+ floor = zmin
+ if (IS_INDEFR (ceiling))
+ ceiling = zmax
+ }
+
+ # Apply the zero point shift.
+ if (abs (zero) > EPSILON) {
+ call salloc (data1, npts, TY_REAL)
+ call asubkr (Memr[data], zero, Memr[data1], npts)
+ floor = floor - zero
+ ceiling = ceiling - zero
+ } else
+ data1 = data
+
+ # Avoid conrec's automatic scaling.
+ if (fp_equalr (floor, 0.0))
+ floor = EPSILON
+ if (fp_equalr (ceiling, 0.0))
+ ceiling = EPSILON
+
+ # The user can suppress the contour labelling by setting the common
+ # parameter "ilab" to zero.
+ if (btoi (clgetb ("cntrplot.label")) == NO)
+ ilab = 0
+ else
+ ilab = 1
+
+ # User can specify either the number of contours or the contour
+ # interval, or let conrec pick a nice number. Get params and
+ # encode the FINC param expected by conrec.
+
+ ncontours = clgeti ("cntrplot.ncontours")
+ if (ncontours <= 0) {
+ interval = clgetr ("cntrplot.interval")
+ if (interval <= 0.0)
+ finc = 0
+ else
+ finc = interval
+ } else
+ finc = - abs (ncontours)
+
+ # Open device and make contour plot.
+ call gopks (STDERR)
+ wkid = 1
+ call gopwk (wkid, 6, gd)
+ call gacwk (wkid)
+
+ # Make the contour plot.
+ nset = 1 # No conrec viewport
+ ioffm = 1 # No conrec box
+ call gswind (gd, 1., real (nx), 1., real (ny))
+ call ggview (gd, vx1, vx2, vy1, vy2)
+ call set (vx1, vx2, vy1, vy2, 1.0, real (nx), 1.0, real (ny), 1)
+ call conrec (Memr[data1], nx, nx, ny, floor, ceiling, finc, nset,
+ nhi, -dashpat)
+
+ call gdawk (wkid)
+ call gclks ()
+
+ call gswind (gd, xs, xe, ys, ye)
+ if (fp_equalr (hold[5], 1.0)) {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "\n\nContoured from %g to %g, interval = %g\n\n")
+ call pargr (hold[1])
+ call pargr (hold[2])
+ call pargr (hold[3])
+ } else {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "\n\nContoured from %g to %g, interval = %g, labels scaled by %g\n\n")
+ call pargr (hold[1])
+ call pargr (hold[2])
+ call pargr (hold[3])
+ call pargr (hold[5])
+ }
+
+ call gseti (gd, G_DRAWAXES, NO)
+ call glabax (gd, Memc[longtitle], "", "")
+
+ call sfree (sp)
+end
+
+
+# PT_PERIMETER -- Draw and label axes around the surface plot.
+
+procedure pt_perimeter (gd, z, ncols, nlines, angh, angv)
+
+pointer gd # graphics pointer
+int ncols # number of image columns
+int nlines # number of image lines
+real z[ncols, nlines] # array of intensity values
+real angh # angle of horizontal inclination
+real angv # angle of vertical inclination
+
+char tlabel[10]
+int i, j
+pointer sp, x_val, y_val, kvec
+real xmin, ymin, delta, fact1, flo, hi, xcen, ycen
+real x1_perim, x2_perim, y1_perim, y2_perim, z1, z2
+real wc1, wc2, wl1, wl2, del
+int itoc()
+
+data fact1 /2.0/
+real vpx1, vpx2, vpy1, vpy2
+common /noaovp/ vpx1, vpx2, vpy1, vpy2
+
+begin
+ call smark (sp)
+ call salloc (x_val, ncols + 2, TY_REAL)
+ call salloc (y_val, nlines + 2, TY_REAL)
+ call salloc (kvec, max (ncols, nlines) + 2, TY_REAL)
+
+ # Get window coordinates set up calling procedure.
+ call ggwind (gd, wc1, wc2, wl1, wl2)
+
+ # Set up window, viewport for output. The coordinates returned
+ # from trn32s are in the range [1-1024].
+ call set (vpx1, vpx2, vpy1, vpy2, 1.0, 1024., 1.0, 1024., 1)
+
+ # Find range of z for determining perspective.
+ flo = MAX_REAL
+ hi = -flo
+ do j = 1, nlines {
+ call alimr (z[1,j], ncols, z1, z2)
+ flo = min (flo, z1)
+ hi = max (hi, z2)
+ }
+
+ # Set up linear endpoints and spacing as used in surface.
+ delta = (hi-flo) / (max (ncols, nlines) -1.) * fact1
+ xmin = -(real (ncols/2) * delta + real (mod (ncols+1, 2)) * delta)
+ ymin = -(real (nlines/2) * delta + real (mod (nlines+1, 2)) * delta)
+ del = 2.0 * delta
+
+ # The perimeter is separated from the surface plot by the
+ # width of delta.
+ x1_perim = xmin - delta
+ y1_perim = ymin - delta
+ x2_perim = xmin + (real (ncols) * delta)
+ y2_perim = ymin + (real (nlines) * delta)
+
+ # Set up linear arrays over full perimeter range.
+ do i = 1, ncols + 2
+ Memr[x_val+i-1] = x1_perim + (i-1) * delta
+ do i = 1, nlines + 2
+ Memr[y_val+i-1] = y1_perim + (i-1) * delta
+
+ # Draw and label axes and tick marks.
+ # It is important that frame has not been called after calling srface.
+ # First to draw the perimeter. Which axes get drawn depends on the
+ # values of angh and angv. Get angles in the range [-180, 180].
+
+ if (angh > 180.)
+ angh = angh - 360.
+ else if (angh < -180.)
+ angh = angh + 360.
+ if (angv > 180.)
+ angv = angv - 360.
+ else if (angv < -180.)
+ angv = angv + 360.
+
+ # Calculate positions for the axis labels.
+ xcen = 0.5 * (x1_perim + x2_perim)
+ ycen = 0.5 * (y1_perim + y2_perim)
+
+ if (angh >= 0.0) {
+
+ # Case 1: xy rotation positive, looking down from above mid z.
+ if (angv >= 0.0) {
+
+ # First draw x axis.
+ call amovkr (y2_perim, Memr[kvec], ncols + 2)
+ call pt_draw_axis (Memr[x_val+1], Memr[kvec], flo, ncols + 1)
+ call pt_label_axis (xcen, y2_perim+del, flo, "X-AXIS", -1, -2)
+ call pt_draw_ticksx (Memr[x_val+1], y2_perim, y2_perim+delta,
+ flo, ncols)
+ if (itoc (int (wc1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (xmin, y2_perim+del, flo, tlabel, -1, -2)
+ if (itoc (int (wc2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (Memr[x_val+ncols], y2_perim+del, flo,
+ tlabel, -1, -2)
+
+ # Now draw y axis.
+ call amovkr (x2_perim, Memr[kvec], nlines + 2)
+ call pt_draw_axis (Memr[kvec], Memr[y_val+1], flo, nlines + 1)
+ call pt_label_axis (x2_perim+del, ycen, flo, "Y-AXIS", 2, -1)
+ call pt_draw_ticksy (x2_perim, x2_perim+delta, Memr[y_val+1],
+ flo, nlines)
+ if (itoc (int (wl1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x2_perim+del, ymin, flo, tlabel, 2, -1)
+ if (itoc (int (wl2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x2_perim+del, Memr[y_val+nlines], flo,
+ tlabel, 2, -1)
+
+ # Case 2: xy rotation positive, looking up from below mid z.
+ } else {
+
+ # First draw x axis.
+ call amovkr (y1_perim, Memr[kvec], ncols + 2)
+ call pt_draw_axis (Memr[x_val], Memr[kvec], flo, ncols + 1)
+ call pt_label_axis (xcen, y1_perim-del, flo, "X-AXIS", -1, 2)
+ call pt_draw_ticksx (Memr[x_val+1], y1_perim, y1_perim-delta,
+ flo, ncols)
+ if (itoc (int (wc1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (xmin, y1_perim-del, flo, tlabel, -1, 2)
+ if (itoc (int (wc2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (Memr[x_val+ncols], y1_perim-del, flo,
+ tlabel, -1, 2)
+
+ # Now draw y axis.
+ call amovkr (x1_perim, Memr[kvec], nlines + 2)
+ call pt_draw_axis (Memr[kvec], Memr[y_val], flo, nlines + 1)
+ call pt_label_axis (x1_perim-del, ycen, flo, "Y-AXIS", 2, 1)
+ call pt_draw_ticksy (x1_perim, x1_perim-delta, Memr[y_val+1],
+ flo, nlines)
+ if (itoc (int (wl1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x1_perim-del, ymin, flo, tlabel, 2, 1)
+ if (itoc (int (wl2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x1_perim-del, Memr[y_val+nlines], flo,
+ tlabel, 2, 1)
+ }
+ }
+
+ if (angh < 0.0) {
+
+ # Case 3: xy rotation negative, looking down from above mid z
+ # (default).
+ if (angv > 0.0) {
+
+ # First draw x axis.
+ call amovkr (y1_perim, Memr[kvec], ncols + 2)
+ call pt_draw_axis (Memr[x_val+1], Memr[kvec], flo, ncols + 1)
+ call pt_label_axis (xcen, y1_perim-del, flo, "X-AXIS", 1, 2)
+ call pt_draw_ticksx (Memr[x_val+1], y1_perim, y1_perim-delta,
+ flo, ncols)
+ if (itoc (int (wc1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (xmin, y1_perim-del, flo, tlabel, 1, 2)
+ if (itoc (int (wc2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (Memr[x_val+ncols], y1_perim-del, flo,
+ tlabel, 1, 2)
+
+ # Now draw y axis.
+ call amovkr (x2_perim, Memr[kvec], nlines + 2)
+ call pt_draw_axis (Memr[kvec], Memr[y_val], flo, nlines + 1)
+ call pt_label_axis (x2_perim+del, ycen, flo, "Y-AXIS", 2, -1)
+ call pt_draw_ticksy (x2_perim, x2_perim+delta, Memr[y_val+1],
+ flo, nlines)
+ if (itoc (int (wl1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x2_perim+del, ymin, flo, tlabel, 2, -1)
+ if (itoc (int (wl2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x2_perim+del, Memr[y_val+nlines], flo,
+ tlabel, 2, -1)
+
+ # Case 4: xy rotation negative, looking up from below mid Z.
+ } else {
+
+ # First draw x axis.
+ call amovkr (y2_perim, Memr[kvec], ncols + 2)
+ call pt_draw_axis (Memr[x_val], Memr[kvec], flo, ncols + 1)
+ call pt_label_axis (xcen, y2_perim+del, flo, "X-AXIS", 1, -2)
+ call pt_draw_ticksx (Memr[x_val+1], y2_perim, y2_perim+delta,
+ flo, ncols)
+ if (itoc (int (wc1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (xmin, y2_perim+del, flo, tlabel, 1, -2)
+ if (itoc (int (wc2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (Memr[x_val+ncols], y2_perim+del, flo,
+ tlabel, 1, -2)
+
+ # Now draw y axis.
+ call amovkr (x1_perim, Memr[kvec], nlines + 2)
+ call pt_draw_axis (Memr[kvec], Memr[y_val+1], flo, nlines + 1)
+ call pt_label_axis (x1_perim-del, ycen, flo, "Y-AXIS", 2, 1)
+ call pt_draw_ticksy (x1_perim, x1_perim-delta, Memr[y_val+1],
+ flo, nlines)
+ if (itoc (int (wl1), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x1_perim-del, ymin, flo, tlabel, 2, 1)
+ if (itoc (int (wl2), tlabel, 10) <= 0)
+ tlabel[1] = EOS
+ call pt_label_axis (x1_perim-del, Memr[y_val+nlines], flo,
+ tlabel, 2, 1)
+ }
+ }
+
+ # Flush plotit buffer before returning.
+ call plotit (0, 0, 2)
+ call sfree (sp)
+end
+
+
+# PT_DRAW_AXIS -- Draw the axes around the plot.
+
+procedure pt_draw_axis (xvals, yvals, zval, nvals)
+
+real xvals[nvals]
+real yvals[nvals]
+real zval
+int nvals
+
+int i
+pointer sp, xt, yt
+real dum
+
+begin
+ call smark (sp)
+ call salloc (xt, nvals, TY_REAL)
+ call salloc (yt, nvals, TY_REAL)
+
+ do i = 1, nvals
+ call trn32s (xvals[i], yvals[i], zval, Memr[xt+i-1], Memr[yt+i-1],
+ dum, 1)
+
+ call gpl (nvals, Memr[xt], Memr[yt])
+ call sfree (sp)
+end
+
+
+# PT_LABEL_AXIS -- Label the axes.
+
+procedure pt_label_axis (xval, yval, zval, sppstr, path, up)
+
+real xval
+real yval
+real zval
+char sppstr[SZ_LINE]
+int path
+int up
+
+int nchars
+int strlen()
+% character*64 fstr
+
+begin
+ nchars = strlen (sppstr)
+% call f77pak (sppstr, fstr, 64)
+ call pwrzs (xval, yval, zval, fstr, nchars, CSIZE, path, up, 0)
+end
+
+
+# PT_DRAW_TICKSX -- Draw the x tick marks.
+
+procedure pt_draw_ticksx (x, y1, y2, zval, nvals)
+
+real x[nvals]
+real y1, y2
+real zval
+int nvals
+
+int i
+real tkx[2], tky[2], dum
+
+begin
+ do i = 1, nvals {
+ call trn32s (x[i], y1, zval, tkx[1], tky[1], dum, 1)
+ call trn32s (x[i], y2, zval, tkx[2], tky[2], dum, 1)
+ call gpl (2, tkx[1], tky[1])
+ }
+end
+
+
+# PT_DRAW_TICKSY -- Draw the y tick marks.
+
+procedure pt_draw_ticksy (x1, x2, y, zval, nvals)
+
+real x1, x2
+real y[nvals]
+real zval
+int nvals
+
+int i
+real tkx[2], tky[2], dum
+
+begin
+ do i = 1, nvals {
+ call trn32s (x1, y[i], zval, tkx[1], tky[1], dum, 1)
+ call trn32s (x2, y[i], zval, tkx[2], tky[2], dum, 1)
+ call gpl (2, tkx[1], tky[1])
+ }
+end
+
+
+# PT_GDATA -- Get image data with boundary checking.
+
+pointer procedure pt_gdata (im, x1, x2, y1, y2)
+
+pointer im # pointer to the input image
+int x1, x2, y1, y2 # subraster limits both input and output
+
+int i, nc, nl
+pointer imgs2r()
+errchk imgs2r
+
+begin
+ nc = IM_LEN(im,1)
+ nl = IM_LEN(im,2)
+ if (IS_INDEFI (x1))
+ x1 = 1
+ if (IS_INDEFI (x2))
+ x2 = nc
+ if (IS_INDEFI (y1))
+ y1 = 1
+ if (IS_INDEFI (y2))
+ y2 = nl
+
+ i = max (x1, x2)
+ x1 = min (x1, x2)
+ x2 = i
+ i = max (y1, y2)
+ y1 = min (y1, y2)
+ y2 = i
+
+ if (x2 < 1 || x1 > nc || y2 < 1 || y1 > nl)
+ return (NULL)
+
+ x1 = max (1, x1)
+ x2 = min (nc, x2)
+ y1 = max (1, y1)
+ y2 = min (nl, y2)
+
+ return (imgs2r (im, x1, x2, y1, y2))
+end
+
+
+# PT_RADPIX -- Procedure to fetch the image pixels in an annulus around
+# a given center.
+
+int procedure pt_radpix (im, wx, wy, rin, rout, rcoords, pix)
+
+pointer im # pointer to IRAF image
+real wx, wy # center of sky annulus
+real rin, rout # inner and outer radius of sky annulus
+real rcoords[ARB] # radial coordinate array
+real pix[ARB] # pixel array
+
+int i, j, ncols, nlines, c1, c2, l1, l2, npix
+pointer buf
+real xc1, xc2, xl1, xl2, rin2, rout2, rj2, r2
+pointer imgs2r()
+
+begin
+ if (rout <= rin)
+ return (0)
+
+ # Test for out of bounds sky regions.
+ ncols = IM_LEN(im,1)
+ nlines = IM_LEN(im,2)
+ xc1 = wx - rout
+ xc2 = wx + rout
+ xl1 = wy - rout
+ xl2 = wy + rout
+ if (xc2 < 1.0 || xc1 > real (ncols) || xl2 < 1.0 || xl1 > real (nlines))
+ return (0)
+
+ # Compute the column and line limits.
+ c1 = max (1.0, min (real (ncols), wx - rout)) + 0.5
+ c2 = min (real (ncols), max (1.0, wx + rout)) + 0.5
+ l1 = max (1.0, min (real (nlines), wy - rout)) + 0.5
+ l2 = min (real (nlines), max (1.0, wy + rout)) + 0.5
+
+ # Fetch the sky pixels.
+ rin2 = rin ** 2
+ rout2 = rout ** 2
+ npix = 0
+
+ do j = l1, l2 {
+ buf = imgs2r (im, c1, c2, j, j)
+ rj2 = (wy - j) ** 2
+ do i = c1, c2 {
+ r2 = (wx - i) ** 2 + rj2
+ if (r2 > rin2 && r2 <= rout2) {
+ rcoords[npix+1] = sqrt (r2)
+ pix[npix+1] = Memr[buf+i-c1]
+ npix = npix + 1
+ }
+ }
+ }
+
+ return (npix)
+end
diff --git a/noao/digiphot/ptools/pexamine/ptplot.x b/noao/digiphot/ptools/pexamine/ptplot.x
new file mode 100644
index 00000000..beeb9fec
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptplot.x
@@ -0,0 +1,1462 @@
+include <error.h>
+include <mach.h>
+include <ctype.h>
+include <gset.h>
+include <fset.h>
+include <tbset.h>
+include "../../lib/ptkeysdef.h"
+include "pexamine.h"
+
+define GHELPFILE "ptools$pexamine/pexamine.key"
+define FRACTION 0.05
+
+int procedure pt_plot (gd, px, apd, apkey, im, deleted, npix, max_npix,
+ first_star, match_radius, use_display)
+
+pointer gd # pointer to the graphics stream
+pointer px # pointer to the pexamine structure
+pointer apd # the input catalog descriptor
+pointer apkey # pointer to the text file structure
+pointer im # pointer to the input image
+int deleted[ARB] # array of deleted values
+int npix # number of points
+int max_npix # maximum number of points
+int first_star # first object read in
+real match_radius # tolerance in pixels for cursor positioning
+int use_display # use the image display
+
+int newdata, newxy, xyinvalid, newhist, hinvalid, plottype, newplot
+int firstplot, newcoo, cooinvalid, undelete, status, key, starno, curtype
+pointer sp, title, xlabel, ylabel, cmd, x, y, h, xpos, ypos
+real wx, wy, twx, twy
+
+bool fp_equalr()
+int pt_rxydata(), pt_rhdata(), pt_rcoodata(), pt_getphot(), pt_fstarg()
+int pt_gcur(), pt_gldata()
+
+define replot_ 91
+
+begin
+ # Allocate working stack space.
+ call smark (sp)
+ call salloc (title, SZ_LINE, TY_CHAR)
+ call salloc (xlabel, SZ_LINE, TY_CHAR)
+ call salloc (ylabel, SZ_LINE, TY_CHAR)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Initialize some parameters.
+ twx = INDEFR
+ twy = INDEFR
+ newdata = NO
+ newxy = YES
+ newhist = YES
+ newcoo = YES
+ newplot = YES
+ firstplot = YES
+ curtype = 'g'
+ plottype = PX_XYPLOT
+ call amovki (PX_GOOD, deleted, npix)
+
+ undelete = NO
+
+replot_
+ if (newdata == YES) {
+ if (apkey != NULL) {
+ call pt_kyfree (apkey)
+ call pt_kyinit (apkey)
+ }
+ npix = pt_getphot (px, apd, apkey, npix, first_star)
+ }
+
+ if (newxy == YES)
+ xyinvalid = pt_rxydata (px, x, y)
+ if (newhist == YES)
+ hinvalid = pt_rhdata (px, h)
+ if (newcoo == YES)
+ cooinvalid = pt_rcoodata (px, xpos, ypos)
+
+ switch (plottype) {
+ case PX_XYPLOT:
+ call pt_xyinfo (px, apd, apkey, Memc[title], SZ_LINE,
+ Memc[xlabel], Memc[ylabel], SZ_LINE)
+ if (xyinvalid == NO) {
+ if (newplot == YES) {
+ call pt_xyplot (gd, Memr[x], Memr[y], deleted, npix,
+ Memc[title], Memc[xlabel], Memc[ylabel])
+ }
+ } else {
+ call printf ("Cannot plot X: %s versus Y: %s\n")
+ call pargstr (Memc[xlabel])
+ call pargstr (Memc[ylabel])
+ }
+
+ case PX_HISTPLOT:
+ call pt_hinfo (px, apd, apkey, Memc[title], SZ_LINE,
+ Memc[xlabel], Memc[ylabel], SZ_LINE)
+ if (hinvalid == NO) {
+ if (newplot == YES) {
+ call pt_hplot (gd, Memr[h], deleted, npix, Memc[title],
+ Memc[xlabel], Memc[ylabel])
+ }
+ } else {
+ call printf ("Cannot plot histogram of %s\n")
+ call pargstr (Memc[xlabel])
+ }
+
+ case PX_RADPLOT:
+ if (im != NULL) {
+ if (newplot == YES)
+ call pt_rplot (gd, im, twx, twy)
+ } else
+ call printf ("The input image is undefined\n")
+
+ case PX_SURFPLOT:
+ if (im != NULL) {
+ if (newplot == YES)
+ call pt_splot (gd, im, twx, twy)
+ } else
+ call printf ("The input image is undefined\n")
+
+ case PX_CNTRPLOT:
+ if (im != NULL) {
+ if (newplot == YES)
+ call pt_cplot (gd, im, twx, twy)
+ } else
+ call printf ("The input image is undefined\n")
+
+ default:
+ call printf ("Invalid plot type\n")
+ }
+
+ if ((firstplot == YES || newdata == YES) && (xyinvalid == NO)) {
+ call printf ("nstars read: %d first_star: %d max_nstars: %d\n")
+ call pargi (npix)
+ call pargi (first_star)
+ call pargi (max_npix)
+ }
+
+ newdata = NO
+ newxy = NO
+ newcoo = NO
+ newhist = NO
+ newplot = NO
+ firstplot = NO
+
+ while (pt_gcur (curtype, wx, wy, key, Memc[cmd], SZ_LINE) != EOF) {
+
+ switch (key) {
+
+ # Quit and do not make changes.
+ case 'q':
+ call printf ("Type 'q' to confirm quit without saving edits\n")
+ if (pt_gcur (curtype, wx, wy, key, Memc[cmd], SZ_LINE) == EOF)
+ next
+ if (key != 'q')
+ next
+ status = PX_QUIT
+ break
+
+ # Exit and do the changes.
+ case 'e':
+ status = PX_EXIT
+ break
+
+ # Print the help page.
+ case '?':
+ call gpagefile (gd, GHELPFILE, "")
+
+ # Activate the graphics cursor.
+ case 'g':
+ curtype = 'g'
+
+ # Activate the image cursor.
+ case 'i':
+ if (use_display == YES)
+ curtype = 'i'
+ else
+ call printf ("The image display is not available\n")
+
+ # Plot the current y column versus the current x column.
+ case 'x':
+ if (plottype != PX_XYPLOT) {
+ newplot = YES
+ plottype = PX_XYPLOT
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Plot the current histogram.
+ case 'h':
+ if (plottype != PX_HISTPLOT) {
+ newplot = YES
+ plottype = PX_HISTPLOT
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Print a matrix of points around the cursor.
+ case 'm':
+ if (im == NULL) {
+ call printf ("The input image is undefined\n")
+ next
+ } else if (cooinvalid == YES) {
+ call printf ("The x or y coordinate data is undefined\n")
+ next
+ } else if (curtype == 'i') {
+ starno = pt_fstarg (gd, wx, wy, Memr[xpos], Memr[ypos],
+ npix, match_radius)
+ } else if (xyinvalid == YES) {
+ call printf ("The x or y column data is undefined\n")
+ next
+ } else if (plottype != PX_XYPLOT) {
+ call printf ("Points must be marked on an X-Y plot\n")
+ next
+ } else {
+ starno = pt_fstarg (gd, wx, wy, Memr[x], Memr[y], npix,
+ INDEFR)
+ }
+
+ if (starno > 0)
+ call pt_print (gd, im, Memr[xpos+starno-1],
+ Memr[ypos+starno-1])
+
+ # Plot the the radial profile of the point nearest the graphics
+ # cursor.
+ case 'r', 's', 'c':
+
+ if (im == NULL) {
+ call printf ("The input image is undefined\n")
+ next
+ }
+ if (cooinvalid == YES) {
+ call printf ("The x or y coordinate data is undefined\n")
+ next
+ }
+
+ if (curtype == 'i') {
+ starno = pt_fstarg (gd, wx, wy, Memr[xpos], Memr[ypos],
+ npix, match_radius)
+ } else if (xyinvalid == YES) {
+ call printf ("The x or y column data is undefined\n")
+ next
+ } else if (plottype != PX_XYPLOT) {
+ call printf ("Points must be marked on the X-Y plot\n")
+ next
+ } else {
+ starno = pt_fstarg (gd, wx, wy, Memr[x], Memr[y], npix,
+ INDEFR)
+ }
+
+ if (starno > 0) {
+ switch (key) {
+ case 'r':
+ if (plottype != PX_RADPLOT)
+ newplot = YES
+ plottype = PX_RADPLOT
+ case 'c':
+ if (plottype != PX_CNTRPLOT)
+ newplot = YES
+ plottype = PX_CNTRPLOT
+ case 's':
+ if (plottype != PX_SURFPLOT)
+ newplot = YES
+ plottype = PX_SURFPLOT
+ }
+ wx = Memr[xpos+starno-1]
+ wy = Memr[ypos+starno-1]
+ if (! fp_equalr (wx, twx) && ! fp_equalr (wy, twy)) {
+ newplot = YES
+ twx = wx
+ twy = wy
+ }
+ } else
+ call printf ("Cannot find selected star in the catalog\n")
+
+ if (newplot == YES)
+ goto replot_
+
+ # Replot the current plot.
+ case 'p':
+ newplot = YES
+ goto replot_
+
+ # Print out the names, types and units of all defined columns.
+ case 'l':
+ call pt_colinfo (gd, apd, apkey)
+
+ # Print out the names, values and units of the stored columns
+ # for the object nearest the cursor.
+ case 'o':
+ if (curtype == 'g') {
+ if (xyinvalid == YES)
+ call printf ("The x or y column data is undefined\n")
+ else if (plottype != PX_XYPLOT)
+ call printf ("Points must be marked on an x-y plot\n")
+ else {
+ starno = pt_gldata (gd, px, apd, apkey, wx, wy,
+ Memr[x], Memr[y], npix, INDEFR)
+ if (starno > 0)
+ call printf ("Star found\n")
+ else
+ call printf ("Star not found\n")
+ }
+ } else if (curtype == 'i') {
+ if (cooinvalid == NO) {
+ starno = pt_gldata (gd, px, apd, apkey, wx, wy,
+ Memr[xpos], Memr[ypos], npix, match_radius)
+ if ((gd != NULL) && (starno > 0) && (xyinvalid == NO) &&
+ (plottype == PX_XYPLOT)) {
+ call gscur (gd, Memr[x+starno-1], Memr[y+starno-1])
+ call printf ("Star found\n")
+ curtype = 'g'
+ } else
+ call printf ("Star not found\n")
+ } else
+ call printf (
+ "The x or y coordinate data is undefined\n")
+ }
+
+ # Undelete everything.
+ case 'z':
+ call amovki (PX_GOOD, deleted, npix)
+ newplot = YES
+ goto replot_
+
+ # Delete points and replot.
+ case 'f':
+ call pt_update (deleted, npix)
+ newplot = YES
+ goto replot_
+
+ # Mark a point for deletion.
+ case 'd':
+ if (curtype == 'g') {
+ if ((xyinvalid == YES) || (plottype != PX_XYPLOT))
+ call printf (
+ "Invalid plot type for deleting points\n")
+ else
+ call pt_delpt (gd, wx, wy, Memr[x], Memr[y], Memr[x],
+ Memr[y], deleted, npix, NO, INDEFR)
+ } else if (curtype == 'i') {
+ if (cooinvalid == NO) {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_delpt (gd, wx, wy, Memr[xpos], Memr[ypos],
+ Memr[x], Memr[y], deleted, npix, NO,
+ match_radius)
+ else
+ call pt_delpt (NULL, wx, wy, Memr[xpos], Memr[ypos],
+ Memr[x], Memr[y], deleted, npix, NO,
+ match_radius)
+ } else
+ call printf (
+ "The x or y coordinate data is undefined\n")
+ }
+
+ # Undelete a point marked for deletion.
+ case 'u':
+ if (curtype == 'g') {
+ if ((xyinvalid == YES) || (plottype != PX_XYPLOT))
+ call printf (
+ "Invalid plot type for undeleting points\n")
+ else
+ call pt_delpt (gd, wx, wy, Memr[x], Memr[y], Memr[x],
+ Memr[y], deleted, npix, YES, INDEFR)
+ } else if (curtype == 'i') {
+ if (cooinvalid == NO) {
+ if (xyinvalid == NO && plottype == PX_XYPLOT)
+ call pt_delpt (gd, wx, wy, Memr[xpos], Memr[ypos],
+ Memr[x], Memr[y], deleted, npix, YES,
+ match_radius)
+ else
+ call pt_delpt (NULL, wx, wy, Memr[xpos], Memr[ypos],
+ Memr[x], Memr[y], deleted, npix, YES,
+ match_radius)
+ } else
+ call printf (
+ "The x and y coordinate data is undefined\n")
+ }
+
+ # Toggle the delete/undelete function
+ case 't':
+ if (undelete == NO) {
+ call printf ("Now undeleting points\n")
+ undelete = YES
+ } else if (undelete == YES) {
+ call printf ("Now deleting points\n")
+ undelete = NO
+ }
+
+ # Mark for deletion points with X < X (cursor).
+ case '(':
+ if (curtype == 'g') {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT)) {
+ call pt_dxltg (gd, wx, Memr[x], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ } else if ((hinvalid == NO) && plottype == PX_HISTPLOT) {
+ call pt_dxltg (NULL, wx, Memr[h], Memr[h], Memr[h],
+ deleted, npix, undelete)
+ newplot = YES
+ } else
+ call printf (
+ "Invalid plot type for (un)deleting points\n")
+ } else if (curtype == 'i') {
+ if (cooinvalid == YES) {
+ call printf (
+ "The x or y coordinate data is undefined\n")
+ } else if ((xyinvalid == NO) && (plottype == PX_XYPLOT)) {
+ call pt_dxltg (gd, wx, Memr[xpos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ } else {
+ call pt_dxltg (NULL, wx, Memr[xpos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ if (plottype == PX_XYPLOT || plottype == PX_HISTPLOT)
+ newplot = YES
+ else
+ call printf (
+ "Replot x-y or histogram to show (un)deletions\n")
+ }
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Mark for deletion points with X > X (cursor).
+ case ')':
+ if (curtype == 'g') {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT)) {
+ call pt_dxgtg (gd, wx, Memr[x], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ } else if ((hinvalid == NO) && (plottype == PX_HISTPLOT)) {
+ call pt_dxgtg (NULL, wx, Memr[h], Memr[h], Memr[h],
+ deleted, npix, undelete)
+ newplot = YES
+ } else
+ call printf (
+ "Invalid plot type for (un)deleting points\n")
+ } else if (curtype == 'i') {
+ if (cooinvalid == YES) {
+ call printf (
+ "The x and y coordinate data is undefined\n")
+ } else if ((xyinvalid == NO) && (plottype == PX_XYPLOT)) {
+ call pt_dxgtg (gd, wx, Memr[xpos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ } else {
+ call pt_dxgtg (NULL, wx, Memr[xpos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ if (plottype == PX_XYPLOT || plottype == PX_HISTPLOT)
+ newplot = YES
+ else
+ call printf (
+ "Replot x-y or histogram to show (un)deletions\n")
+ }
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Mark for deletion points with Y > Y (cursor).
+ case '^':
+ if (curtype == 'g') {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_dygtg (gd, wy, Memr[y], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ else
+ call printf (
+ "Invalid plot type for (un)deleting points\n")
+ } else if (curtype == 'i') {
+ if (cooinvalid == YES)
+ call printf (
+ "The x and y coordinate data is undefined\n")
+ else if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_dygtg (gd, wy, Memr[ypos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ else {
+ call pt_dygtg (NULL, wy, Memr[ypos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ if (plottype == PX_XYPLOT || plottype == PX_HISTPLOT)
+ newplot = YES
+ else
+ call printf (
+ "Replot x-y or histogram to show (un)deletions\n")
+ }
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Mark for deletion points with Y < Y (cursor).
+ case 'v':
+ if (curtype == 'g') {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_dyltg (gd, wy, Memr[y], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ else
+ call printf (
+ "Invalid plot type for (un)deleting points\n")
+ } else if (curtype == 'i') {
+ if (cooinvalid == YES)
+ call printf (
+ "The x and y coordinate data is undefined\n")
+ else if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_dyltg (gd, wy, Memr[ypos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ else {
+ call pt_dyltg (NULL, wy, Memr[ypos], Memr[x], Memr[y],
+ deleted, npix, undelete)
+ if (plottype == PX_XYPLOT || plottype == PX_HISTPLOT)
+ newplot = YES
+ else
+ call printf (
+ "Replot x-y or histogram to show (un)deletions\n")
+ }
+ }
+ if (newplot == YES)
+ goto replot_
+
+ # Mark points for deletion inside a box.
+ case 'b':
+ if (curtype == 'g') {
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT)) {
+ twx = wx; twy = wy
+ call printf ("again:\n")
+ if (pt_gcur (curtype, wx, wy, key, Memc[cmd],
+ SZ_LINE) == EOF)
+ next
+ call pt_dboxg (gd, Memr[x], Memr[y], Memr[x], Memr[y],
+ deleted, npix, twx, twy, wx, wy, undelete)
+ } else
+ call printf (
+ "Invalid plot type for (un)deleting points\n")
+ } else if (curtype == 'i') {
+ if (cooinvalid == YES)
+ call printf (
+ "The x or y coordinate data is undefined\n")
+ else {
+ twx = wx; twy = wy
+ call printf ("again:\n")
+ if (pt_gcur (curtype, wx, wy, key, Memc[cmd],
+ SZ_LINE) == EOF)
+ next
+ if ((xyinvalid == NO) && (plottype == PX_XYPLOT))
+ call pt_dboxg (gd, Memr[xpos], Memr[ypos], Memr[x],
+ Memr[y], deleted, npix, twx, twy, wx, wy,
+ undelete)
+ else {
+ call pt_dboxg (NULL, Memr[xpos], Memr[ypos],
+ Memr[x], Memr[y], deleted, npix, twx, twy,
+ wx, wy, undelete)
+ if ((plottype == PX_XYPLOT) ||
+ (plottype == PX_HISTPLOT))
+ newplot = YES
+ else
+ call printf (
+ "Replot x-y or histogram to show (un)deletions\n")
+ }
+ }
+ }
+
+ # Colon commands:
+ case ':':
+ iferr (call pt_colon (px, gd, Memc[cmd], newdata, newxy,
+ newhist, newcoo, newplot, plottype, undelete))
+ call erract (EA_WARN)
+ if (newplot == YES)
+ goto replot_
+
+ default:
+ call printf ("Unknown or ambiguous keystroke command\007\n")
+ }
+ }
+
+ call sfree (sp)
+
+ return (status)
+end
+
+
+# PT_PRINT -- Print a 10 by 10 box of pixel values around the star.
+
+procedure pt_print (gd, im, x, y)
+
+pointer gd # pointer to the graphics stream
+pointer im # pointer to the input image
+real x, y # center of box
+
+int i, j, x1, x2, y1, y2, nx
+pointer data
+pointer pt_gdata()
+
+begin
+ if (gd != NULL)
+ call gdeactivate (gd, 0)
+
+ # Check that the image is defined.
+ if (im == NULL) {
+ call printf ("The input image is undefined\n")
+ return
+ }
+
+ # Check that the center is defined.
+ if (IS_INDEFR(x) || IS_INDEFR(y)) {
+ call printf ("The box center is undefined\n")
+ return
+ }
+
+ x1 = x - 5 + 0.5
+ x2 = x + 5 + 0.5
+ y1 = y - 5 + 0.5
+ y2 = y + 5 + 0.5
+ data = pt_gdata (im, x1, x2, y1, y2)
+ if (data == NULL) {
+ call printf ("The requested image section is off the image\n")
+ return
+ }
+ nx = x2 - x1 + 1
+
+ call printf ("\n%4w")
+ do i = x1, x2 {
+ call printf (" %4d ")
+ call pargi (i)
+ }
+ call printf ("\n")
+
+ do j = y2, y1, -1 {
+ call printf ("%4d")
+ call pargi (j)
+ do i = x1, x2 {
+ call printf (" %5g")
+ call pargr (Memr[data+(j-y1)*nx+(i-x1)])
+ }
+ call printf ("\n")
+ }
+ call printf ("\n")
+
+ if (gd != NULL)
+ call greactivate (gd, 0)
+end
+
+
+define LEN_TYPESTR 9
+
+# PT_COLINFO -- Print the name, type and units of all the columns in the
+# input catalog.
+
+procedure pt_colinfo (gd, apd, key)
+
+pointer gd # pointer to the graphics stream
+pointer apd # the file descriptor for the input catalog
+int key # the key structure for text catalogs
+
+int len_colname, i, datatype, numelems
+pointer tty, sp, name, units, type, junk, colptr
+int tbpsta(), tbcigi(), pt_gnfn(), pt_kstati()
+pointer ttyodes(), tbcnum(), pt_ofnl()
+
+begin
+ if (gd != NULL)
+ call gdeactivate (gd, AW_CLEAR)
+ else {
+ tty = ttyodes ("terminal")
+ call ttyclear (STDOUT, tty)
+ }
+
+ len_colname = max (SZ_COLNAME, KY_SZPAR)
+ call printf ("\n%*.*s %*.*s %s\n\n")
+ call pargi (-len_colname)
+ call pargi (len_colname)
+ call pargstr ("COLUMN")
+ call pargi (-LEN_TYPESTR)
+ call pargi (LEN_TYPESTR)
+ call pargstr ("TYPE")
+ call pargstr ("UNITS")
+
+ call smark (sp)
+ call salloc (name, len_colname, TY_CHAR)
+ call salloc (units, max (SZ_COLUNITS, KY_SZPAR), TY_CHAR)
+ call salloc (type, LEN_TYPESTR, TY_CHAR)
+
+ if (key == NULL) {
+
+ do i = 1, tbpsta (apd, TBL_NCOLS) {
+
+ colptr = tbcnum (apd, i)
+ call tbcigt (colptr, TBL_COL_NAME, Memc[name], SZ_COLNAME)
+ call tbcigt (colptr, TBL_COL_UNITS, Memc[units], SZ_COLUNITS)
+ datatype = tbcigi (colptr, TBL_COL_DATATYPE)
+ switch (datatype) {
+ case TY_BOOL:
+ call strcpy ("boolean", Memc[type], LEN_TYPESTR)
+ case TY_SHORT, TY_INT, TY_LONG:
+ call strcpy ("integer", Memc[type], LEN_TYPESTR)
+ case TY_REAL:
+ call strcpy ("real", Memc[type], LEN_TYPESTR)
+ case TY_DOUBLE:
+ call strcpy ("double", Memc[type], LEN_TYPESTR)
+ default:
+ if (datatype < 0)
+ call strcpy ("character", Memc[type], LEN_TYPESTR)
+ else
+ call strcpy ("undefined", Memc[type], LEN_TYPESTR)
+ }
+
+ call printf ("%*.*s %*.*s %s\n")
+ call pargi (-len_colname)
+ call pargi (len_colname)
+ call pargstr (Memc[name])
+ call pargi (-LEN_TYPESTR)
+ call pargi (LEN_TYPESTR)
+ call pargstr (Memc[type])
+ call pargstr (Memc[units])
+ }
+
+ } else {
+
+ call salloc (junk, SZ_LINE, TY_CHAR)
+ colptr = pt_ofnl (key, "*")
+ while (pt_gnfn (colptr, Memc[name], Memc[junk], KY_SZPAR) != EOF) {
+ #if (pt_kstati (key, Memc[name], KY_INDEX) <= KY_NOKEYS(key))
+ if (pt_kstati (key, Memc[name], KY_INDEX) <= KY_NPKEYS(key))
+ next
+ numelems = pt_kstati (key, Memc[name], KY_NUMELEMS)
+ call pt_kstats (key, Memc[name], KY_UNITSTR, Memc[units],
+ KY_SZPAR)
+ datatype = pt_kstati (key, Memc[name], KY_DATATYPE)
+ switch (datatype) {
+ case TY_BOOL:
+ call strcpy ("boolean", Memc[type], LEN_TYPESTR)
+ case TY_CHAR:
+ call strcpy ("character", Memc[type], LEN_TYPESTR)
+ case TY_INT:
+ call strcpy ("integer", Memc[type], LEN_TYPESTR)
+ case TY_REAL:
+ call strcpy ("real", Memc[type], LEN_TYPESTR)
+ default:
+ call strcpy ("undefined", Memc[type], LEN_TYPESTR)
+ }
+
+ do i = 1, numelems {
+ if (numelems == 1)
+ call strcpy (Memc[name], Memc[junk], KY_SZPAR)
+ else {
+ call sprintf (Memc[junk], KY_SZPAR, "%s[%d]")
+ call pargstr (Memc[name])
+ call pargi (numelems)
+ }
+ call printf ("%*.*s %*.*s %s\n")
+ call pargi (-len_colname)
+ call pargi (len_colname)
+ call pargstr (Memc[junk])
+ call pargi (-LEN_TYPESTR)
+ call pargi (LEN_TYPESTR)
+ call pargstr (Memc[type])
+ call pargstr (Memc[units])
+ }
+
+ }
+ call pt_cfnl (colptr)
+
+ }
+ call printf ("\n")
+
+ call sfree (sp)
+
+ if (gd != NULL)
+ call greactivate (gd, AW_PAUSE)
+ else
+ call ttycdes (tty)
+end
+
+
+# PT_GLDATA -- List the values of the loaded columns for this point.
+
+int procedure pt_gldata (gd, px, apd, key, wx, wy, x, y, npix, matchrad)
+
+pointer gd # pointer to the graphics stream
+pointer px # pointer to the pexamine structure
+int apd # file descriptor for catalog
+pointer key # pointer to the key structure for text files
+real wx # the graphics cursor x coordinate
+real wy # the graphics cursor y coordinate
+real x[ARB] # the array of x plotted data
+real y[ARB] # the array of y plotted data
+int npix # the number of points
+real matchrad # matching radius
+
+int row, ip, ncol
+pointer sp, name, units, colptr
+int pt_getnames(), pt_fstarg()
+
+begin
+ if (gd != NULL)
+ call gdeactivate (gd, 0)
+
+ # Find the star.
+ row = pt_fstarg (gd, wx, wy, x, y, npix, matchrad)
+
+ # List the values of the loaded columns.
+ if (row != 0) {
+
+ call smark (sp)
+ call salloc (name, PX_SZCOLNAME, TY_CHAR)
+ call salloc (units, max (KY_SZPAR, SZ_COLUNITS), TY_CHAR)
+
+ call printf ("\n%*.*s %s (%s)\n\n")
+ call pargi (-PX_SZCOLNAME)
+ call pargi (PX_SZCOLNAME)
+ call pargstr ("COLUMN")
+ call pargstr ("VALUE")
+ call pargstr ("UNITS")
+
+ ip = 1
+ ncol = 0
+ while (pt_getnames (Memc[PX_COLNAMES(px)], ip, Memc[name],
+ PX_SZCOLNAME) != EOF) {
+ if (PX_COLPTRS(px) == NULL)
+ next
+ if (key == NULL) {
+ call tbcfnd (apd, Memc[name], colptr, 1)
+ call tbcigt (colptr, TBL_COL_UNITS, Memc[units],
+ SZ_COLUNITS)
+ } else
+ call pt_kstats (key, Memc[name], KY_UNITSTR, Memc[units],
+ KY_SZPAR)
+ call printf ("%*.*s %g (%s)\n")
+ call pargi (-PX_SZCOLNAME)
+ call pargi (PX_SZCOLNAME)
+ call pargstr (Memc[name])
+ call pargr (Memr[Memi[PX_COLPTRS(px)+ncol]+row-1])
+ call pargstr (Memc[units])
+ ncol = ncol + 1
+ }
+ call printf ("\n")
+
+ call sfree (sp)
+ }
+
+ if (gd != NULL)
+ call greactivate (gd, 0)
+
+ return (row)
+end
+
+
+# PT_XYPLOT -- Plot the x and y points.
+
+procedure pt_xyplot (gd, x, y, deleted, npix, title, xlabel, ylabel)
+
+pointer gd # pointer to the graphics stream
+real x[ARB] # array of x coordinates
+real y[ARB] # array of y coordinates
+int deleted[ARB] # deletions array
+int npix # number of points
+char title[ARB] # title of the plot
+char xlabel[ARB] # x axis label
+char ylabel[ARB] # y axis label
+
+int i, marker_type
+pointer sp, marker, longtitle
+real szmarker, x1, x2, y1, y2, dmin, dmax
+bool clgetb()
+int clgeti(), strlen()
+real clgetr()
+
+begin
+ # Check for undefined graphis stream.
+ if (gd == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (marker, SZ_FNAME, TY_CHAR)
+ call salloc (longtitle, 2 * SZ_LINE, TY_CHAR)
+
+ # Clear the plotting strucuture.
+ call gclear (gd)
+
+ # Fetch the window and viewport parameters.
+ x1 = clgetr ("xyplot.x1")
+ x2 = clgetr ("xyplot.x2")
+ y1 = clgetr ("xyplot.y1")
+ y2 = clgetr ("xyplot.y2")
+ if (IS_INDEFR(x1) || IS_INDEFR(x2)) {
+ call pt_alimr (x, npix, dmin, dmax)
+ if (IS_INDEFR(x1))
+ x1 = dmin - FRACTION * (dmax - dmin)
+ if (IS_INDEFR(x2))
+ x2 = dmax + FRACTION * (dmax - dmin)
+ }
+ if (IS_INDEFR(y1) || IS_INDEFR(y2)) {
+ call pt_alimr (y, npix, dmin, dmax)
+ if (IS_INDEFR(y1))
+ y1 = dmin - FRACTION * (dmax - dmin)
+ if (IS_INDEFR(y2))
+ y2 = dmax + FRACTION * (dmax - dmin)
+ }
+
+ # Set the scale of the axes.
+ call gswind (gd, x1, x2, y1, y2)
+ if (clgetb ("xyplot.logx"))
+ call gseti (gd, G_XTRAN, GW_LOG)
+ else
+ call gseti (gd, G_XTRAN, GW_LINEAR)
+ if (clgetb ("xyplot.logy"))
+ call gseti (gd, G_YTRAN, GW_LOG)
+ else
+ call gseti (gd, G_YTRAN, GW_LINEAR)
+
+ # Get the x and y axes parameters.
+ if (! clgetb ("xyplot.fill"))
+ call gseti (gd, G_ASPECT, 1)
+ if (clgetb ("xyplot.round"))
+ call gseti (gd, G_ROUND, YES)
+
+ # Get the axis drawing parameters.
+ if (clgetb ("xyplot.box")) {
+
+ # Get number of major and minor tick marks.
+ call gseti (gd, G_XNMAJOR, clgeti ("xyplot.majrx"))
+ call gseti (gd, G_XNMINOR, clgeti ("xyplot.minrx"))
+ call gseti (gd, G_YNMAJOR, clgeti ("xyplot.majry"))
+ call gseti (gd, G_YNMINOR, clgeti ("xyplot.minry"))
+
+ # Label tick marks on axes.
+ if (clgetb ("xyplot.ticklabels"))
+ call gseti (gd, G_LABELTICKS, YES)
+ else
+ call gseti (gd, G_LABELTICKS, NO)
+
+ # Draw grid.
+ if (clgetb ("xyplot.grid"))
+ call gseti (gd, G_DRAWGRID, YES)
+ else
+ call gseti (gd, G_DRAWGRID, NO)
+
+ # Optionally draw a box around the plot.
+ if (clgetb ("xyplot.banner")) {
+ call sysid (Memc[longtitle], 2 * SZ_LINE)
+ call sprintf (Memc[longtitle+strlen(Memc[longtitle])],
+ 2 * SZ_LINE, "\n%s")
+ call pargstr (title)
+ } else
+ call strcpy (title, Memc[longtitle], 2 * SZ_LINE)
+ call glabax (gd, Memc[longtitle], xlabel, ylabel)
+
+ }
+
+ # Get the marker type, the size of the marker and the linewidth.
+ call clgstr ("xyplot.marker", Memc[marker], SZ_FNAME)
+ call pt_marker (Memc[marker], SZ_FNAME, marker_type)
+ if (marker_type != GM_POINT)
+ szmarker = clgetr ("xyplot.szmarker")
+ else
+ szmarker = 0.0
+ call gsetr (gd, G_PLWIDTH, 2.0)
+
+ # Draw the points in using the deletions array.
+ do i = 1, npix {
+ if (deleted[i] == PX_DELETE)
+ next
+ call gmark (gd, x[i], y[i], marker_type, szmarker, szmarker)
+ }
+
+ # Overplot crosses for those new points marked for deletion.
+ call pt_mdelete (gd, x, y, deleted, npix)
+
+ call gflush (gd)
+ call sfree (sp)
+end
+
+
+# PT_HPLOT -- Compute and plot histogram.
+
+procedure pt_hplot (gd, x, deleted, npix, title, xlabel, ylabel)
+
+pointer gd # pointer to the graphics stream
+real x[ARB] # array of points to be made into a histogram
+int deleted[ARB] # deletions array
+int npix # number of pixels
+char title[ARB] # the title of the plot
+char xlabel[ARB] # the x axis label
+char ylabel[ARB] # the y axis label
+
+int i, j, nbins, nbins1
+pointer sp, hgm, xp, yp, longtitle
+real z1, z2, dz, x1, x2, y1, y2, dmin, dmax
+bool clgetb(), fp_equalr()
+int clgeti(), strlen()
+real clgetr()
+
+begin
+ # Check for undefined graphis stream.
+ if (gd == NULL) {
+ call printf ("The graphics device is undefined\n")
+ return
+ }
+
+ # Get default histogram resolution and range.
+ nbins = clgeti ("histplot.nbins")
+ z1 = clgetr ("histplot.z1")
+ z2 = clgetr ("histplot.z2")
+
+ # Use data limits for INDEF limits.
+ if (IS_INDEFR(z1) || IS_INDEFR(z2)) {
+ call pt_alimr (x, npix, dmin, dmax)
+ if (IS_INDEFR(z1))
+ z1 = dmin
+ if (IS_INDEFR(z2))
+ z2 = dmax
+ }
+ if (z1 > z2) {
+ dz = z1
+ z1 = z2
+ z2 = dz
+ }
+
+ # Test for constant valued image, which causes zero divide in ahgm.
+ if (fp_equalr (z1, z2)) {
+ call printf ("Warning: Histogram has no data range.\n")
+ return
+ }
+
+ # The extra bin counts the pixels that equal z2 and shifts the
+ # remaining bins to evenly cover the interval [z1,z2].
+ # Note that real numbers could be handled better - perhaps
+ # adjust z2 upward by ~ EPSILONR (in ahgm itself).
+
+ nbins1 = nbins + 1
+
+ # Initialize the histogram buffer and image line vector.
+ call smark (sp)
+ call salloc (hgm, nbins1, TY_INT)
+ call aclri (Memi[hgm], nbins1)
+
+ # Accumulate the histogram. Add the ability to use the deletions
+ # array in future.
+ call pt_ahgmr (x, deleted, npix, Memi[hgm], nbins1, z1, z2)
+
+ # "Correct" the topmost bin for pixels that equal z2. Each
+ # histogram bin really wants to be half open.
+
+ if (clgetb ("histplot.top_closed"))
+ Memi[hgm+nbins-1] = Memi[hgm+nbins-1] + Memi[hgm+nbins1-1]
+
+ # List or plot the histogram. In list format, the bin value is the
+ # z value of the left side (start) of the bin.
+
+ dz = (z2 - z1) / real (nbins)
+
+ # Plot the histogram in box mode.
+ nbins1 = 2 * nbins + 2
+ call salloc (xp, nbins1, TY_REAL)
+ call salloc (yp, nbins1, TY_REAL)
+ Memr[xp] = z1
+ Memr[yp] = 0.0
+ j = 1
+ do i = 0, nbins - 1 {
+ Memr[xp+j] = Memr[xp+j-1]
+ Memr[yp+j] = Memi[hgm+i]
+ j = j + 1
+ Memr[xp+j] = Memr[xp+j-1] + dz
+ Memr[yp+j] = Memr[yp+j-1]
+ j = j + 1
+ }
+ Memr[xp+j] = Memr[xp+j-1]
+ Memr[yp+j] = 0.0
+
+ # Construct the title.
+ call salloc (longtitle, 2 * SZ_LINE, TY_CHAR)
+ if (clgetb ("histplot.banner")) {
+ call sysid (Memc[longtitle], 2 * SZ_LINE)
+ call sprintf (Memc[longtitle+strlen(Memc[longtitle])], 2 * SZ_LINE,
+ "\nHistogram from z1=%g to z2=%g, nbins=%d\n%s")
+ call pargr (z1)
+ call pargr (z2)
+ call pargi (nbins)
+ call pargstr (title)
+ } else {
+ call sprintf (Memc[longtitle], 2 * SZ_LINE,
+ "Histogram from z1=%g to z2=%g, nbins=%d\n%s")
+ call pargr (z1)
+ call pargr (z2)
+ call pargi (nbins)
+ call pargstr (title)
+ }
+
+ # Clear the screen.
+ call gclear (gd)
+
+ # Compute the data window to be plotted.
+ x1 = clgetr ("histplot.x1")
+ x2 = clgetr ("histplot.x2")
+ if (IS_INDEFR(x1) || IS_INDEFR(x2)) {
+ call alimr (Memr[xp], nbins1, dmin, dmax)
+ if (IS_INDEFR(x1))
+ x1 = dmin
+ if (IS_INDEFR(x2))
+ x2 = dmax
+ }
+ y1 = clgetr ("histplot.y1")
+ y2 = clgetr ("histplot.y2")
+ if (IS_INDEFR(y1) || IS_INDEFR(y2)) {
+ call alimr (Memr[yp], nbins1, dmin, dmax)
+ if (IS_INDEFR(y1))
+ y1 = dmin
+ if (IS_INDEFR(y2))
+ y2 = dmax
+ }
+
+ # Set the scale of the axes.
+ call gswind (gd, x1, x2, y1, y2)
+ call gseti (gd, G_XTRAN, GW_LINEAR)
+ if (clgetb ("histplot.logy"))
+ call gseti (gd, G_YTRAN, GW_LOG)
+ else
+ call gseti (gd, G_YTRAN, GW_LINEAR)
+
+ if (! clgetb ("xyplot.fill"))
+ call gseti (gd, G_ASPECT, 1)
+ if (clgetb ("xyplot.round"))
+ call gseti (gd, G_ROUND, YES)
+ call gsetr (gd, G_PLWIDTH, 2.0)
+
+ # Draw a box around the axes.
+ if (clgetb ("histplot.box")) {
+
+ # Label tick marks on axes.
+ if (clgetb ("histplot.ticklabels"))
+ call gseti (gd, G_LABELTICKS, YES)
+ else
+ call gseti (gd, G_LABELTICKS, NO)
+
+ # Get number of major and minor tick marks.
+ call gseti (gd, G_XNMAJOR, clgeti ("histplot.majrx"))
+ call gseti (gd, G_XNMINOR, clgeti ("histplot.minrx"))
+ call gseti (gd, G_YNMAJOR, clgeti ("histplot.majry"))
+ call gseti (gd, G_YNMINOR, clgeti ("histplot.minry"))
+
+ # Draw the axes.
+ call glabax (gd, Memc[longtitle], xlabel, ylabel)
+
+ }
+
+ # Draw the historgram.
+ call gseti (gd, G_PLTYPE, GL_SOLID)
+ call gpline (gd, Memr[xp], Memr[yp], nbins1)
+ call gflush (gd)
+
+ call sfree (sp)
+end
+
+
+# PT_XYINFO -- Get the title and axes labels for the X-Y plot.
+
+procedure pt_xyinfo (px, tp, key, title, max_sztitle, xlabel, ylabel,
+ max_szlabel)
+
+pointer px # pointer to the pexamine strcuture
+pointer tp # input catalog file descriptor
+pointer key # pointer to key structure for text files
+char title[ARB] # title for the plot
+int max_sztitle # maximum length of the title
+char xlabel[ARB] # X axis label
+char ylabel[ARB] # Y axis label
+int max_szlabel # maximum size of the label
+
+pointer sp, label, units, cd
+
+begin
+ call smark (sp)
+ call salloc (label, max_szlabel, TY_CHAR)
+ call salloc (units, max_szlabel, TY_CHAR)
+
+ # Get the title.
+
+ # Get the x and y labels for the columns.
+ if (key == NULL) {
+
+ call tbtnam (tp, title, max_sztitle)
+
+ call tbcfnd (tp, PX_XCOLNAME(px), cd, 1)
+ if (cd != NULL) {
+ call strcpy (PX_XCOLNAME(px), Memc[label], max_szlabel)
+ call tbcigt (cd, TBL_COL_UNITS, Memc[units], SZ_COLUNITS)
+ } else {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ }
+ call sprintf (xlabel, max_szlabel, "%s in %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ call tbcfnd (tp, PX_YCOLNAME(px), cd, 1)
+ if (cd != NULL) {
+ call strcpy (PX_YCOLNAME(px), Memc[label], max_szlabel)
+ call tbcigt (cd, TBL_COL_UNITS, Memc[units], SZ_COLUNITS)
+ } else {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ }
+ call sprintf (ylabel, max_szlabel, "%s in %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ } else {
+
+ call fstats (tp, F_FILENAME, title, max_sztitle)
+
+ if (PX_XCOLNAME(px) == EOS) {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ } else {
+ call strcpy (PX_XCOLNAME(px), Memc[label], max_szlabel)
+ call pt_kstats (key, PX_XCOLNAME(px), KY_UNITSTR, Memc[units],
+ max_szlabel)
+ }
+ call sprintf (xlabel, max_szlabel, "%s %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ if (PX_YCOLNAME(px) == EOS) {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ } else {
+ call strcpy (PX_YCOLNAME(px), Memc[label], max_szlabel)
+ call pt_kstats (key, PX_YCOLNAME(px), KY_UNITSTR, Memc[units],
+ max_szlabel)
+ }
+ call sprintf (ylabel, max_szlabel, "%s %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ }
+
+ call sfree (sp)
+end
+
+
+# PT_HINFO -- Get the title and axes labels for the histogram plot.
+
+procedure pt_hinfo (px, tp, key, title, max_sztitle, xlabel, ylabel,
+ max_szlabel)
+
+pointer px # pointer to the pexamine strcuture
+pointer tp # input catalog file descriptor
+pointer key # pointer to key structure for text files
+char title[ARB] # title for the plot
+int max_sztitle # maximum length of the title
+char xlabel[ARB] # X axis label
+char ylabel[ARB] # Y axis label
+int max_szlabel # maximum size of the label
+
+pointer sp, label, units, cd
+
+begin
+ call smark (sp)
+ call salloc (label, max_szlabel, TY_CHAR)
+ call salloc (units, max_szlabel, TY_CHAR)
+
+ # Get the title.
+
+ # Get the x and y labels for the columns.
+ if (key == NULL) {
+
+ call tbtnam (tp, title, max_sztitle)
+
+ call tbcfnd (tp, PX_HCOLNAME(px), cd, 1)
+ if (cd != NULL) {
+ call strcpy (PX_HCOLNAME(px), Memc[label], max_szlabel)
+ call tbcigt (cd, TBL_COL_UNITS, Memc[units], SZ_COLUNITS)
+ } else {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ }
+ call sprintf (xlabel, max_szlabel, "%s in %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ call sprintf (ylabel, max_szlabel, "N(%s)")
+ call pargstr (Memc[label])
+
+ } else {
+
+ call fstats (tp, F_FILENAME, title, max_sztitle)
+
+ if (PX_HCOLNAME(px) == EOS) {
+ call strcpy ("UNDEFINED", Memc[label], max_szlabel)
+ Memc[units] = EOS
+ } else {
+ call strcpy (PX_HCOLNAME(px), Memc[label], max_szlabel)
+ call pt_kstats (key, PX_HCOLNAME(px), KY_UNITSTR, Memc[units],
+ max_szlabel)
+ }
+ call sprintf (xlabel, max_szlabel, "%s %s")
+ call pargstr (Memc[label])
+ call pargstr (Memc[units])
+
+ call sprintf (ylabel, max_szlabel, "N(%s)")
+ call pargstr (Memc[label])
+
+ }
+
+ call sfree (sp)
+end
+
+
+# PT_GCUR -- Get PEXAMINE cursor value.
+# This is an interface between the standard cursor input and PEXAMINE.
+# It reads the appropriate cursor, makes the appropriate default
+# coordinate conversions when using graphics cursor input, and gets any
+# further cursor reads needed. Missing coordinates default to the last
+# coordinates.
+
+int procedure pt_gcur (curtype, x, y, key, strval, maxch)
+
+int curtype # cursor type
+real x, y # cursor position
+int key # keystroke value of cursor event
+char strval[ARB] # string value, if any
+int maxch # max chars out
+
+char ch
+int nitems, wcs, ip
+int clgcur(), ctor(), cctoc()
+errchk clgcur
+
+begin
+ # Initialize.
+ strval[1] = EOS
+
+ # Get a cursor values from the desired cursor parameter.
+ switch (curtype) {
+ case 'i':
+ nitems = clgcur ("icommands", x, y, wcs, key, strval, maxch)
+ case 'g':
+ nitems = clgcur ("gcommands", x, y, wcs, key, strval, maxch)
+ }
+
+ call flush (STDOUT)
+
+ # Map numeric colon sequences (: x [y] key strval) to make them appear
+ # as ordinary "x y key" type cursor reads. This makes it possible for
+ # the user to access any command using typed in rather than positional
+ # cursor coordinates. Special treatment is also given to the syntax
+ # ":lN" and ":cN", provided for compatibility with IMPLOT for simple
+ # line and column plots.
+
+ if (key == ':') {
+ for (ip=1; IS_WHITE(strval[ip]); ip=ip+1)
+ ;
+ if (IS_DIGIT(strval[ip])) {
+ if (ctor (strval, ip, x) <= 0)
+ ;
+ if (ctor (strval, ip, y) <= 0)
+ y = x
+ for (; IS_WHITE(strval[ip]); ip=ip+1)
+ ;
+ if (cctoc (strval, ip, ch) > 0)
+ key = ch
+ call strcpy (strval[ip], strval, maxch)
+
+ }
+ }
+
+ return (nitems)
+end
+
+
+# PT_FSTARG -- Find the the point data point nearest the input position.
+
+int procedure pt_fstarg (gd, wx, wy, x, y, npix, matchrad)
+
+pointer gd # pointer to the graphics descriptor
+real wx # X cursor position
+real wy # Y cursor position
+real x[ARB] # X array of plotted data
+real y[ARB] # Y array of plotted data
+int npix # number of pixels
+real matchrad # the matching radius
+
+int i, row
+real r2min, r2, mr2, wx0, wy0, x0, y0
+
+begin
+ row = 0
+ r2min = MAX_REAL
+ if (IS_INDEFR(matchrad)) {
+ mr2 = MAX_REAL
+ if (gd != NULL)
+ call gctran (gd, wx, wy, wx0, wy0, 1, 0)
+ else {
+ wx0 = wx
+ wy0 = wy
+ }
+ } else {
+ mr2 = matchrad ** 2
+ wx0 = wx
+ wy0 = wy
+ }
+
+ # Search for the nearest point.
+ do i = 1 , npix {
+ if (! IS_INDEFR(x[i]) && ! IS_INDEFR(y[i])) {
+ if (IS_INDEFR(matchrad)) {
+ if (gd != NULL)
+ call gctran (gd, x[i], y[i], x0, y0, 1, 0)
+ else {
+ x0 = x[i]
+ y0 = y[i]
+ }
+ } else {
+ x0 = x[i]
+ y0 = y[i]
+ }
+ r2 = (wx0 - x0) ** 2 + (wy0 - y0) ** 2
+ } else
+ r2 = MAX_REAL
+ if (r2 >= r2min)
+ next
+ r2min = r2
+ row = i
+ }
+
+ if ((row != 0) && (r2min <= mr2))
+ return (row)
+ else
+ return (0)
+end
+
+
+# PT_MARKER -- Return an integer code for the marker type string.
+
+procedure pt_marker (marker, maxch, imark)
+
+char marker[ARB] # string defining the marker type
+int maxch # maximum length of the marker name
+int imark # the integer code for the marker
+
+int i
+int strdic()
+
+begin
+ i = strdic (marker, marker, maxch, PX_MARKERS)
+ switch (i) {
+ case 1:
+ imark = GM_POINT
+ case 2:
+ imark = GM_BOX
+ case 3:
+ imark = GM_PLUS
+ case 4:
+ imark = GM_CROSS
+ case 5:
+ imark = GM_CIRCLE
+ case 6:
+ imark = GM_HLINE
+ case 7:
+ imark = GM_VLINE
+ case 8:
+ imark = GM_DIAMOND
+ default:
+ imark = GM_BOX
+ call strcpy ("box", marker, maxch)
+ }
+end
diff --git a/noao/digiphot/ptools/pexamine/ptrddata.x b/noao/digiphot/ptools/pexamine/ptrddata.x
new file mode 100644
index 00000000..ff0864b9
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptrddata.x
@@ -0,0 +1,125 @@
+include "../../lib/ptkeysdef.h"
+include "pexamine.h"
+
+# PT_RXYDATA -- Load the data for the input columns from the structure.
+
+int procedure pt_rxydata (px, xptr, yptr)
+
+pointer px # pointer to the pexamine structure
+pointer xptr # pointer to the X coordinate array
+pointer yptr # pointer to the Y coordinate array
+
+int data_invalid, field
+pointer sp, str
+int strdic()
+
+begin
+ data_invalid = NO
+
+ # Allocate some temporary memory
+ call smark (sp)
+ call salloc (str, PX_SZCOLNAME, TY_CHAR)
+
+ # Load the x column.
+ field = strdic (PX_XCOLNAME(px), Memc[str], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)])
+ if (field > 0)
+ xptr = Memi[PX_COLPTRS(px)+field-1]
+ else {
+ xptr = NULL
+ data_invalid = YES
+ }
+
+ # Load the y column.
+ field = strdic (PX_YCOLNAME(px), Memc[str], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)])
+ if (field > 0)
+ yptr = Memi[PX_COLPTRS(px)+field-1]
+ else {
+ yptr = NULL
+ data_invalid = YES
+ }
+
+ call sfree (sp)
+
+ return (data_invalid)
+end
+
+
+# PT_RHDATA -- Load the data for the histogram column from the structure.
+
+int procedure pt_rhdata (px, xptr)
+
+pointer px # pointer to the pexamine structure
+pointer xptr # array containing the x points
+
+int data_invalid, field
+pointer sp, str
+int strdic()
+
+begin
+ data_invalid = NO
+
+ # Allocate some temporary memory
+ call smark (sp)
+ call salloc (str, PX_SZCOLNAME, TY_CHAR)
+
+ # Load the x column.
+ field = strdic (PX_HCOLNAME(px), Memc[str], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)])
+ if (field > 0)
+ xptr = Memi[PX_COLPTRS(px)+field-1]
+ else {
+ xptr = NULL
+ data_invalid = YES
+ }
+
+ call sfree (sp)
+
+ return (data_invalid)
+end
+
+
+# PT_RCOODATA -- Load the coordinate data from the structure.
+
+int procedure pt_rcoodata (px, xptr, yptr)
+
+pointer px # pointer to the pexamine structure
+pointer xptr # pointer to x coordinates array
+pointer yptr # pointer to y coordinates array
+
+int data_invalid, field
+pointer sp, str
+int strdic()
+
+begin
+ data_invalid = NO
+
+ # Allocate some temporary memory
+ call smark (sp)
+ call salloc (str, PX_SZCOLNAME, TY_CHAR)
+
+ # Load the x coordinate.
+ field = strdic (PX_XPOSNAME(px), Memc[str], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)])
+ if (field > 0)
+ xptr = Memi[PX_COLPTRS(px)+field-1]
+ else {
+ data_invalid = YES
+ xptr = NULL
+ }
+
+ # Load the y coordinate.
+ field = strdic (PX_YPOSNAME(px), Memc[str], PX_SZCOLNAME,
+ Memc[PX_COLNAMES(px)])
+ if (field > 0)
+ yptr = Memi[PX_COLPTRS(px)+field-1]
+ else {
+ data_invalid = YES
+ yptr = NULL
+ }
+
+ call sfree (sp)
+
+ return (data_invalid)
+end
diff --git a/noao/digiphot/ptools/pexamine/ptsetup.x b/noao/digiphot/ptools/pexamine/ptsetup.x
new file mode 100644
index 00000000..5a8bc832
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptsetup.x
@@ -0,0 +1,360 @@
+include <error.h>
+include <ctotok.h>
+include "pexamine.h"
+
+# PT_INIT - Initialize the pexamine structure.
+
+pointer procedure pt_init (photcols, usercols, xcol, ycol, xpos, ypos, hcol)
+
+char photcols[ARB] # the list of photometry columns
+char usercols[ARB] # the list of user columns
+char xcol[ARB] # the name of the x column
+char ycol[ARB] # the name of the y column
+char xpos[ARB] # the name of the x coord column
+char ypos[ARB] # the name of the y coord column
+char hcol[ARB] # the name of the histogram column
+
+pointer px
+bool streq()
+int strdic()
+
+begin
+ # Preload the daophot and apphot photometry fields.
+ if (streq ("DAOPHOT", photcols) || streq ("daophot", photcols))
+ call strcpy (PX_DAOCOLS, photcols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ else if (streq ("APPHOT", photcols) || streq ("apphot", photcols))
+ call strcpy (PX_APCOLS, photcols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+
+ # Allocate space for the pexamine structure and the column lists.
+ call malloc (px, LEN_PXSTRUCT, TY_STRUCT)
+
+ # Initialize the requested column information.
+ PX_RNPHOT(px) = 0; PX_RNUSER(px) = 0; PX_RNCOLS(px) = 0
+ call malloc (PX_RCOLNAMES(px), PX_SZCOLNAME * (PX_MAXNCOLS + 1),
+ TY_CHAR)
+ Memc[PX_RCOLNAMES(px)] = EOS
+
+ # Initialize the stored column information.
+ PX_NPHOT(px) = 0; PX_NUSER(px) = 0; PX_NCOLS(px) = 0
+ call malloc (PX_COLNAMES(px), PX_SZCOLNAME * (PX_MAXNCOLS + 1),
+ TY_CHAR)
+ Memc[PX_COLNAMES(px)] = EOS
+
+ # Decode the column strings. Check that the number of columns
+ # does not exceed the maximum number permitted, by extracting
+ # the column names one by one from the photometry and user column
+ # strings.
+
+ call pt_setnames (px, photcols, usercols)
+
+ # Convert all the input column name specifications to upper case.
+ call strupr (xcol)
+ call strupr (ycol)
+ call strupr (xpos)
+ call strupr (ypos)
+ call strupr (hcol)
+
+ # Decode the x and y columns.
+ if (strdic (xcol, PX_RXCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_RCOLNAMES(px)]) <= 0)
+ call strcpy (xcol, PX_RXCOLNAME(px), PX_SZCOLNAME)
+ if (strdic (ycol, PX_RYCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_RCOLNAMES(px)]) <= 0)
+ call strcpy (ycol, PX_RYCOLNAME(px), PX_SZCOLNAME)
+
+ # Decode the y and y coordinate column names.
+ if (strdic (xpos, PX_RXPOSNAME(px), PX_SZCOLNAME,
+ Memc[PX_RCOLNAMES(px)]) <= 0)
+ call strcpy (xpos, PX_RXPOSNAME(px), PX_SZCOLNAME)
+ if (strdic (ypos, PX_RYPOSNAME(px), PX_SZCOLNAME,
+ Memc[PX_RCOLNAMES(px)]) <= 0)
+ call strcpy (ypos, PX_RYPOSNAME(px), PX_SZCOLNAME)
+
+ # Decode the histogram column name.
+ if (strdic (hcol, PX_RHCOLNAME(px), PX_SZCOLNAME,
+ Memc[PX_RCOLNAMES(px)]) <= 0)
+ call strcpy (hcol, PX_RHCOLNAME(px), PX_SZCOLNAME)
+
+ # Allocate space for the pointers and initialize them to NULL.
+ call malloc (PX_COLPTRS(px), PX_MAXNCOLS, TY_POINTER)
+ call amovki (NULL, Memi[PX_COLPTRS(px)], PX_MAXNCOLS)
+
+ return (px)
+end
+
+
+# PT_FREE -- Free memory used by the pexamine task.
+
+procedure pt_free (px)
+
+pointer px
+
+int i
+
+begin
+ # Free the column lists.
+ if (PX_RCOLNAMES(px) != NULL)
+ call mfree (PX_RCOLNAMES(px), TY_CHAR)
+ if (PX_COLNAMES(px) != NULL)
+ call mfree (PX_COLNAMES(px), TY_CHAR)
+
+ # Free the column pointers.
+ do i = 1, PX_MAXNCOLS {
+ if (Memi[PX_COLPTRS(px)+i-1] != NULL)
+ call mfree (Memi[PX_COLPTRS(px)+i-1], TY_REAL)
+ }
+ if (PX_COLPTRS(px) != NULL)
+ call mfree (PX_COLPTRS(px), TY_POINTER)
+
+ # Free the pexamine structure.
+ call mfree (px, TY_STRUCT)
+end
+
+
+# PT_SETNAMES -- Decode the photometry and user columns.
+
+procedure pt_setnames (px, photcols, usercols)
+
+pointer px # pointer to the pexamine strucuture
+char photcols[ARB] # list of photometry columns
+char usercols[ARB] # list of user columns
+
+int ip, nphot
+pointer sp, name
+int pt_getnames()
+
+begin
+ call smark (sp)
+ call salloc (name, PX_SZCOLNAME, TY_CHAR)
+
+ call strupr (photcols)
+ call strupr (usercols)
+ Memc[PX_RCOLNAMES(px)] = EOS
+
+ ip = 1
+ nphot = 0
+ while (pt_getnames (photcols, ip, Memc[name], PX_SZCOLNAME) != EOF) {
+ if (nphot >= PX_MAXNCOLS)
+ break
+ #if (Memc[name] == EOS)
+ #next
+ call strcat (",", Memc[PX_RCOLNAMES(px)], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], Memc[PX_RCOLNAMES(px)], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ nphot = nphot + 1
+ }
+ PX_RNPHOT(px) = nphot
+
+ # Decode the user columns.
+ ip = 1
+ while (pt_getnames (usercols, ip, Memc[name], PX_SZCOLNAME) != EOF) {
+ if (nphot >= PX_MAXNCOLS)
+ break
+ #if (Memc[name] == EOS)
+ #next
+ call strcat (",", Memc[PX_RCOLNAMES(px)], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], Memc[PX_RCOLNAMES(px)], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ nphot = nphot + 1
+ }
+ PX_RNUSER(px) = nphot - PX_RNPHOT(px)
+
+ PX_RNCOLS(px) = nphot
+
+ call sfree (sp)
+end
+
+
+# PT_GPHOTCOLS -- Extract the requested and stored photometric columns
+# from the pexamine structure.
+
+procedure pt_gphotcols (px, rphotcols, rnphot, photcols, nphot)
+
+pointer px # pointer to the pexamine structure
+char rphotcols[ARB] # list of requested photometric columns
+int rnphot # number of requested photometric columns
+char photcols[ARB] # list of photometric columns
+int nphot # number of photometric columns
+
+int ip, ncols
+pointer sp, name
+int pt_getnames()
+
+begin
+ call smark (sp)
+ call salloc (name, PX_SZCOLNAME, TY_CHAR)
+
+ ip = 1
+ ncols = 0
+ rphotcols[1] = EOS
+ while (pt_getnames (Memc[PX_RCOLNAMES(px)], ip, Memc[name],
+ PX_SZCOLNAME) != EOF) {
+ #if (Memc[name] == EOS)
+ #next
+ ncols = ncols + 1
+ if (ncols > PX_RNPHOT(px))
+ break
+ call strcat (",", rphotcols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], rphotcols, PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ }
+ rnphot = PX_RNPHOT(px)
+
+ ip = 1
+ ncols = 0
+ photcols[1] = EOS
+ while (pt_getnames (Memc[PX_COLNAMES(px)], ip, Memc[name],
+ PX_SZCOLNAME) != EOF) {
+ #if (Memc[name] == EOS)
+ #next
+ ncols = ncols + 1
+ if (ncols > PX_NPHOT(px))
+ break
+ call strcat (",", photcols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], photcols, PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ }
+ nphot = PX_NPHOT(px)
+
+ call sfree (sp)
+end
+
+
+# PT_GUSERCOLS -- Extract the requested and stored user columns
+# from the pexamine structure.
+
+procedure pt_gusercols (px, rusercols, rnuser, usercols, nuser)
+
+pointer px # pointer to the pexamine structure
+char rusercols[ARB] # list of requested user columns
+int rnuser # number of requested user columns
+char usercols[ARB] # list of user columns
+int nuser # number of user columns
+
+int ip, ncols
+pointer sp, name
+int pt_getnames()
+
+begin
+ call smark (sp)
+ call salloc (name, PX_SZCOLNAME, TY_CHAR)
+
+ ip = 1
+ ncols = 0
+ rusercols[1] = EOS
+ while (pt_getnames (Memc[PX_RCOLNAMES(px)], ip, Memc[name],
+ PX_SZCOLNAME) != EOF) {
+ #if (Memc[name] == EOS)
+ #next
+ ncols = ncols + 1
+ if (ncols <= PX_RNPHOT(px))
+ next
+ call strcat (",", rusercols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], rusercols, PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ }
+ rnuser = PX_RNUSER(px)
+
+ ip = 1
+ ncols = 0
+ usercols[1] = EOS
+ while (pt_getnames (Memc[PX_COLNAMES(px)], ip, Memc[name],
+ PX_SZCOLNAME) != EOF) {
+ #if (Memc[name] == EOS)
+ #next
+ ncols = ncols + 1
+ if (ncols <= PX_NPHOT(px))
+ next
+ call strcat (",", usercols, PX_SZCOLNAME * (PX_MAXNCOLS + 1))
+ call strcat (Memc[name], usercols, PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ }
+ nuser = PX_NUSER(px)
+
+ call sfree (sp)
+end
+
+
+# PT_LCOLS -- List the requested and stored columns with an optional
+# title string.
+
+procedure pt_lcols (title, rcols, rncols, cols, ncols)
+
+char title[ARB] # title string for column listing
+char rcols[ARB] # list of requested columns
+int rncols # the number of requested columns
+char cols[ARB] # list of stored columns
+int ncols # the number of stored columns
+
+int ip1, ip2, i
+pointer sp, name1, name2
+int pt_getnames()
+
+begin
+ call smark (sp)
+ call salloc (name1, PX_SZCOLNAME, TY_CHAR)
+ call salloc (name2, PX_SZCOLNAME, TY_CHAR)
+
+ call printf ("\n%s\n\n")
+ call pargstr (title)
+
+ ip1 = 1
+ ip2 = 1
+ do i = 1, max (rncols, ncols) {
+ if (pt_getnames (rcols, ip1, Memc[name1], PX_SZCOLNAME) == EOF)
+ Memc[name1] = EOS
+ if (pt_getnames (cols, ip2, Memc[name2], PX_SZCOLNAME) == EOF)
+ Memc[name2] = EOS
+ call printf (" requested: %*.*s stored: %*.*s\n")
+ call pargi (-PX_SZCOLNAME)
+ call pargi (PX_SZCOLNAME)
+ call pargstr (Memc[name1])
+ call pargi (-PX_SZCOLNAME)
+ call pargi (PX_SZCOLNAME)
+ call pargstr (Memc[name2])
+ }
+
+ call sfree (sp)
+end
+
+
+# PT_GETNAMES -- Decode the list of column names into list of column names.
+
+int procedure pt_getnames (colnames, ip, name, maxch)
+
+char colnames[ARB] # list of column names
+int ip # pointer in to the list of names
+char name[ARB] # the output column name
+int maxch # maximum length of a column name
+
+int op, token
+int ctotok(), strlen()
+
+begin
+ # Decode the column labels.
+ op = 1
+ while (colnames[ip] != EOS) {
+
+ token = ctotok (colnames, ip, name[op], maxch)
+ if (name[op] == EOS)
+ next
+ if ((token == TOK_UNKNOWN) || (token == TOK_CHARCON))
+ break
+ if ((token == TOK_PUNCTUATION) && (name[op] == ',')) {
+ if (op == 1)
+ next
+ else
+ break
+ }
+
+ op = op + strlen (name[op])
+ }
+
+ name[op] = EOS
+ if ((colnames[ip] == EOS) && (op == 1))
+ return (EOF)
+ else
+ return (op - 1)
+end
diff --git a/noao/digiphot/ptools/pexamine/ptwtfile.x b/noao/digiphot/ptools/pexamine/ptwtfile.x
new file mode 100644
index 00000000..02f5f282
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/ptwtfile.x
@@ -0,0 +1,143 @@
+include "../../lib/ptkeysdef.h"
+include "pexamine.h"
+
+# PT_WTFILE -- Write out the catalogs of selected and rejected objects.
+
+procedure pt_wtfile (apd, key, apout, aprej, deleted, nstars)
+
+int apd # input catalog file descriptor
+pointer key # key structure for textfiles
+int apout # output catalog file descriptor
+int aprej # rejections catalog file descriptor
+int deleted[ARB] # deletions array
+int nstars # number of stars in the catalog
+
+int i, nselect, ndelete
+int pt_selrej()
+
+begin
+ # ST tables format.
+ if (key == NULL) {
+
+ # Write out the good data.
+ if (apout != NULL) {
+ call tbtcre (apout)
+ call tbhcal (apd, apout)
+ nselect = 0
+ do i = 1, nstars {
+ if (deleted[i] == PX_DELETE)
+ next
+ nselect = nselect + 1
+ call tbrcpy (apd, apout, i, nselect)
+ }
+ }
+
+ # Write out the deletions.
+ if (aprej != NULL) {
+ call tbtcre (aprej)
+ call tbhcal (apd, aprej)
+ ndelete = 0
+ do i = 1, nstars {
+ if (deleted[i] != PX_DELETE)
+ next
+ ndelete = ndelete + 1
+ call tbrcpy (apd, aprej, i, ndelete)
+ }
+ }
+
+ # Write out a text file.
+ } else {
+ if (pt_selrej (apd, apout, aprej, deleted, nstars) < nstars)
+ ;
+ }
+end
+
+
+define LEN_LONGLINE 10
+
+# PT_SELREJ -- Select and/or reject records based on evaluating a logical
+# expression.
+
+int procedure pt_selrej (tp_in, tp_out, tp_rej, deleted, nstars)
+
+int tp_in # the input catalog file descriptor
+int tp_out # the output catalog file descriptor
+int tp_rej # the rejections catalog file descriptor
+int deleted[ARB] # the deletions array
+int nstars # maximum number of stars
+
+int record, nchars, buflen, lenrecord
+pointer line, lline
+int getline()
+
+begin
+ # Check that output has been requested.
+ if (tp_out == NULL && tp_rej == NULL)
+ return (0)
+
+ # Rewind the input file.
+ call seek (tp_in, BOF)
+
+ # Initialize the file read.
+ record = 0
+ lenrecord = 0
+ buflen = LEN_LONGLINE * SZ_LINE
+ call malloc (line, SZ_LINE, TY_CHAR)
+ call malloc (lline, buflen, TY_CHAR)
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ nchars = getline (tp_in, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND || Memc[line] == KY_CHAR_NEWLINE) {
+
+ if (tp_out != NULL)
+ call putline (tp_out, Memc[line])
+ if (tp_rej != NULL)
+ call putline (tp_rej, Memc[line])
+
+ } else {
+
+ # Reallocate the temporary record space.
+ if (lenrecord > buflen) {
+ buflen = buflen + SZ_LINE
+ call realloc (lline, buflen, TY_CHAR)
+ }
+
+ # Store the record.
+ call amovc (Memc[line], Memc[lline+lenrecord], nchars)
+ lenrecord = lenrecord + nchars
+ Memc[lline+lenrecord] = EOS
+
+ # Do the record bookkeeping.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Increment the record counter.
+ record = record + 1
+
+ # Write out the expression.
+ if ((tp_out != NULL) && (deleted[record] != PX_DELETE))
+ call putline (tp_out, Memc[lline])
+ if ((tp_rej != NULL) && (deleted[record] == PX_DELETE))
+ call putline (tp_rej, Memc[lline])
+ if (record >= nstars)
+ break
+
+ # Reinitialize the record read.
+ lenrecord = 0
+ }
+ }
+
+ }
+
+ # Cleanup.
+ call mfree (line, TY_CHAR)
+ call mfree (lline, TY_CHAR)
+
+ return (record)
+end
diff --git a/noao/digiphot/ptools/pexamine/t_pexamine.x b/noao/digiphot/ptools/pexamine/t_pexamine.x
new file mode 100644
index 00000000..10db0747
--- /dev/null
+++ b/noao/digiphot/ptools/pexamine/t_pexamine.x
@@ -0,0 +1,188 @@
+include <fset.h>
+include <error.h>
+include "pexamine.h"
+
+# T_PEXAMINE -- Interactively examine and edit APPHOT and DAOPHOT output.
+
+procedure t_pexamine()
+
+pointer input # pointer to the name of the catalog
+pointer output # pointer to the name of the edited catalog
+pointer xcolumn # pointer to the name of the X column
+pointer ycolumn # pointer to the name of the Y column
+pointer xposcolumn # pointer to the name of the X coord column
+pointer yposcolumn # pointer to the name of the Y coord column
+pointer hcolumn # pointer to the name of the histogram column
+pointer photcolumns # pointer to the photometry columns
+pointer usercolumns # pointer to the user columns
+pointer graphics # pointer to the name of the graphics device
+pointer image # pointer to the name of the input image
+pointer reject # pointer to the name of the deletions catalog
+real match_radius # the matching radius
+
+int numrows, max_nstars, first_star, status
+int apd, apout, aprej, use_display
+pointer sp, key, px, gd, im, deleted
+
+bool clgetb()
+int fstati(), access(), clgeti(), pt_getphot(), pt_plot(), open(), btoi()
+pointer gopen(), tbtopn(), pt_init(), immap()
+real clgetr()
+
+begin
+ # Flush on a newline if the standard output is not redirected.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (input, SZ_FNAME, TY_CHAR)
+ call salloc (output, SZ_FNAME, TY_CHAR)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (reject, SZ_FNAME, TY_CHAR)
+ call salloc (photcolumns, PX_SZCOLNAME * (PX_MAXNCOLS + 1), TY_CHAR)
+ call salloc (xcolumn, PX_SZCOLNAME, TY_CHAR)
+ call salloc (ycolumn, PX_SZCOLNAME, TY_CHAR)
+ call salloc (hcolumn, PX_SZCOLNAME, TY_CHAR)
+ call salloc (xposcolumn, PX_SZCOLNAME, TY_CHAR)
+ call salloc (yposcolumn, PX_SZCOLNAME, TY_CHAR)
+ call salloc (usercolumns, PX_SZCOLNAME * (PX_MAXNCOLS + 1), TY_CHAR)
+ call salloc (graphics, SZ_FNAME, TY_CHAR)
+
+ # Fetch the input and output file parameters and the column
+ # definition parameters.
+ call clgstr ("input", Memc[input], SZ_FNAME)
+ call clgstr ("output", Memc[output], SZ_FNAME)
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("deletions", Memc[reject], SZ_FNAME)
+ call clgstr ("photcolumns", Memc[photcolumns], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+ call clgstr ("xcolumn", Memc[xcolumn], PX_SZCOLNAME)
+ call clgstr ("ycolumn", Memc[ycolumn], PX_SZCOLNAME)
+ call clgstr ("hcolumn", Memc[hcolumn], PX_SZCOLNAME)
+ call clgstr ("xposcolumn", Memc[xposcolumn], PX_SZCOLNAME)
+ call clgstr ("yposcolumn", Memc[yposcolumn], PX_SZCOLNAME)
+ call clgstr ("usercolumns", Memc[usercolumns], PX_SZCOLNAME *
+ (PX_MAXNCOLS + 1))
+
+ match_radius = clgetr ("match_radius")
+ max_nstars = clgeti ("max_nstars")
+ first_star = clgeti ("first_star")
+
+ # Get the graphics and display parameters.
+ call clgstr ("icommands.p_filename", Memc[graphics], SZ_FNAME)
+ if (Memc[graphics] != EOS)
+ use_display = YES
+ else
+ use_display = btoi (clgetb ("use_display"))
+ call clgstr ("graphics", Memc[graphics], SZ_FNAME)
+
+ # Initialize the pexamine struture.
+ px = pt_init (Memc[photcolumns], Memc[usercolumns], Memc[xcolumn],
+ Memc[ycolumn], Memc[xposcolumn], Memc[yposcolumn], Memc[hcolumn])
+
+ # Open the input catalog.
+ if (access (Memc[input], 0, TEXT_FILE) == YES) {
+ apd = open (Memc[input], READ_ONLY, TEXT_FILE)
+ call pt_kyinit (key)
+ } else {
+ apd = tbtopn (Memc[input], READ_ONLY, 0)
+ key = NULL
+ }
+
+ # Open the input image.
+ if (Memc[image] == EOS)
+ im = NULL
+ else
+ im = immap (Memc[image], READ_ONLY, 0)
+
+ # Allocate buffer space.
+ iferr {
+ numrows = min (max_nstars, pt_getphot (px, apd, key, max_nstars,
+ first_star))
+ call malloc (deleted, numrows, TY_INT)
+ } then
+ call erract (EA_FATAL)
+
+ # Plot the data and enter the interactive cursor loop.
+ gd = gopen (Memc[graphics], NEW_FILE, STDGRAPH)
+ status = pt_plot (gd, px, apd, key, im, Memi[deleted], numrows,
+ max_nstars, first_star, match_radius, use_display)
+ call gclose (gd)
+
+ if (status == PX_EXIT) {
+
+ # Open the output file.
+ if (Memc[output] != EOS) {
+ if (access (Memc[output], 0, 0) == YES) {
+ call printf ("The catalog %s already exists\n")
+ call pargstr (Memc[output])
+ call mktemp ("out", Memc[output], SZ_FNAME)
+ call printf ("The new output catalog is %s\n")
+ call pargstr (Memc[output])
+ }
+ if (key == NULL)
+ apout = tbtopn (Memc[output], NEW_COPY, apd)
+ else
+ apout = open (Memc[output], NEW_FILE, TEXT_FILE)
+ } else
+ apout = NULL
+
+ # Open a reject points catalog if required.
+ if (Memc[reject] != EOS) {
+ if (access (Memc[reject], 0, 0) == YES) {
+ call printf ("The catalog %s already exists.\n")
+ call pargstr (Memc[reject])
+ call mktemp ("rej", Memc[reject], SZ_FNAME)
+ call printf ("The new rejections catalog is %s\n")
+ call pargstr (Memc[reject])
+ }
+ if (key == NULL)
+ aprej = tbtopn (Memc[reject], NEW_COPY, apd)
+ else
+ aprej = open (Memc[reject], NEW_FILE, TEXT_FILE)
+ } else
+ aprej = NULL
+
+ # Write the output catalog file.
+ call pt_wtfile (apd, key, apout, aprej, Memi[deleted], numrows)
+
+ # Close the output file.
+ if (apout != NULL) {
+ if (key == NULL)
+ call tbtclo (apout)
+ else
+ call close (apout)
+ }
+
+ # Close the rejected points file.
+ if (aprej != NULL) {
+ if (key == NULL)
+ call tbtclo (aprej)
+ else
+ call close (aprej)
+ }
+
+ } else if (status == ERR)
+ call fseti (STDOUT, F_CANCEL, OK)
+
+ # Close the input file.
+ if (key != NULL) {
+ call pt_kyfree (key)
+ call close (apd)
+ } else if (apd != NULL)
+ call tbtclo (apd)
+
+ # Close the image.
+ if (im != NULL)
+ call imunmap(im)
+
+ # Return the buffer space.
+ call mfree (deleted, TY_INT)
+
+ # Free the program structures.
+ call pt_free (px)
+ call sfree (sp)
+ if (status == ERR)
+ call erract (EA_ERROR)
+end
diff --git a/noao/digiphot/ptools/prenumber.cl b/noao/digiphot/ptools/prenumber.cl
new file mode 100644
index 00000000..2a174275
--- /dev/null
+++ b/noao/digiphot/ptools/prenumber.cl
@@ -0,0 +1,50 @@
+# PRENUMBER - Renumber the ID column of an APPHOT/DAOPHOT database from 1 to
+# N where N is the number of objects in the database. The renumbering is
+# done in place.
+
+procedure prenumber (infile)
+
+string infile {prompt="Input apphot/daophot databases(s) to be renumbered"}
+int idoffset {0, min=0, prompt="Id number offset"}
+string id {"ID", prompt="Id name keyword"}
+
+struct *inlist
+
+begin
+ # Local variable declarations.
+ file tmpin
+ string in, inname, expr
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infile
+ expr = "rownum + " // idoffset
+
+ # Expand the file list names.
+ tmpin = mktemp ("tmp$")
+ files (in, sort=no, > tmpin)
+
+ # Loop over each file in the input and output lists selecting records.
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ istable (inname)
+ if (istable.table) {
+ if (defpar ("tcalc.verbose") || defpar ("tcalc.harmless")) {
+ tcalc (inname, id, expr, datatype="real", colunits="",
+ colfmt="", verbose=no, harmless=0.1)
+ } else {
+ tcalc (inname, id, expr, datatype="real", colunits="",
+ colfmt="")
+ }
+ } else if (istable.text) {
+ txrenumber (inname, idoffset=idoffset, id=id)
+ } else {
+ print ("Cannot run PRENUMBER on file: " // inname)
+ }
+ }
+ inlist = ""
+
+ delete (tmpin, ver-, >& "dev$null")
+end
diff --git a/noao/digiphot/ptools/pselect.cl b/noao/digiphot/ptools/pselect.cl
new file mode 100644
index 00000000..86ebb9bf
--- /dev/null
+++ b/noao/digiphot/ptools/pselect.cl
@@ -0,0 +1,77 @@
+# PSELECT - Select records from an ST table of an APPHOT/DAOPHOT text file
+# based on the value of a boolean expression.
+
+procedure pselect (infiles, outfiles, expr)
+
+string infiles {prompt="Input apphot/daophot database(s)"}
+string outfiles {prompt="Output apphot/daophot database(s)"}
+string expr {prompt="Boolean expression for record selection"}
+
+struct *inlist, *outlist
+
+begin
+ # Local variable declarations.
+ file tmpin, tmpout
+ int nin, nout
+ string in, out, ex, inname, outname
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infiles
+ out = outfiles
+ ex = expr
+
+ # Make temporary names.
+ tmpin = mktemp ("tmp$")
+ tmpout = mktemp ("tmp$")
+
+ # Expand the file list names.
+ files (in, sort=no, > tmpin)
+ files (out, sort=no, > tmpout)
+
+ # Compute the lengths of the input and output lists.
+ inlist = tmpin
+ for (nin = 0; fscan (inlist, inname) != EOF; nin = nin + 1)
+ ;
+ inlist = ""
+ outlist = tmpout
+ for (nout = 0; fscan (outlist, outname) != EOF; nout = nout + 1)
+ ;
+ outlist = ""
+
+ # Delete the temporary files.
+ delete (tmpin, ver-, >& "dev$null")
+ delete (tmpout, ver-, >& "dev$null")
+
+ # Quit if the number of input and output files is different.
+ if (nin != nout) {
+ print ("ERROR: Input and output file lists are different lengths")
+ return
+ }
+
+ # Expand the file list names.
+ files (in, sort=no, > tmpin)
+ files (out, sort=no, > tmpout)
+
+ # Loop over each file in the input and output lists selecting records.
+ inlist = tmpin
+ outlist = tmpout
+ while (fscan (inlist, inname) != EOF && fscan (outlist, outname) !=
+ EOF) {
+ istable (inname)
+ if (istable.table) {
+ tselect (inname, outname, ex)
+ } else if (istable.text) {
+ txselect (inname, outname, ex)
+ } else {
+ print ("ERROR: Cannot run PSELECT on file: " // inname)
+ }
+ }
+
+ delete (tmpin, ver-, >& "dev$null")
+ delete (tmpout, ver-, >& "dev$null")
+ inlist = ""
+ outlist = ""
+end
diff --git a/noao/digiphot/ptools/psort.cl b/noao/digiphot/ptools/psort.cl
new file mode 100644
index 00000000..d99d55c6
--- /dev/null
+++ b/noao/digiphot/ptools/psort.cl
@@ -0,0 +1,42 @@
+# PSORT - Sort an ST or APPHOT/DAOPHOT file based on a single column.
+
+procedure psort (infiles, field)
+
+string infiles {prompt="Input Apphot/daophot database(s) to be sorted"}
+string field {prompt="Field to be sorted on"}
+bool ascend {yes, prompt="Sort in increasing value order?"}
+
+struct *inlist
+
+begin
+ # Local variable declarations.
+ file tmpin
+ string in, col, inname
+
+ # Cache the istable parameters.
+ cache ("istable")
+
+ # Get the positional parameters.
+ in = infiles
+ col = field
+
+ # Expand the file list names.
+ tmpin = mktemp ("tmp$")
+ files (in, sort=no, > tmpin)
+
+ # Loop over each file in the input and output lists selecting records.
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ istable (inname)
+ if (istable.table) {
+ tsort (inname, col, ascend=ascend, casesens=yes)
+ } else if (istable.text) {
+ txsort (inname, col, ascend=ascend)
+ } else {
+ print ("Cannot run PSORT on file: " // inname)
+ }
+ }
+ inlist = ""
+
+ delete (tmpin, ver-, >& "dev$null")
+end
diff --git a/noao/digiphot/ptools/ptools.cl b/noao/digiphot/ptools/ptools.cl
new file mode 100644
index 00000000..72cacab5
--- /dev/null
+++ b/noao/digiphot/ptools/ptools.cl
@@ -0,0 +1,50 @@
+# Package script task for the PTOOLSX package.
+#{ PTOOLSX -- Photometry tools package.
+
+
+package ptools
+
+# Define the ptools executable tasks.
+
+task pconvert,
+ istable,
+ pexamine,
+ tbcrename,
+ tbkeycol,
+ txconcat,
+ txcalc,
+ txdump,
+ txrenumber,
+ txselect,
+ txsort = "ptools$x_ptools.e"
+
+# Define the tasks which are CL scripts.
+
+task tbconcat = "ptools$tbconcat.cl"
+task tbdump = "ptools$tbdump.cl"
+task tbcalc = "ptools$tbcalc.cl"
+task tbrenumber = "ptools$tbrenumber.cl"
+task tbselect = "ptools$tbselect.cl"
+task tbsort = "ptools$tbsort.cl"
+
+task pconcat = "ptools$pconcat.cl"
+task pcalc = "ptools$pcalc.cl"
+task pdump = "ptools$pdump.cl"
+task prenumber = "ptools$prenumber.cl"
+task pselect = "ptools$pselect.cl"
+task psort = "ptools$psort.cl"
+
+task pttest = "ptools$pttest.cl"
+
+# Pset tasks.
+
+task xyplot = "ptools$xyplot.par"
+task histplot = "ptools$histplot.par"
+task radplot = "ptools$radplot.par"
+task surfplot = "ptools$surfplot.par"
+task cntrplot = "ptools$cntrplot.par"
+
+hidetask tbkeycol, tbcrename
+hidetask xyplot, histplot, radplot, surfplot, cntrplot
+
+clbye()
diff --git a/noao/digiphot/ptools/ptools.hd b/noao/digiphot/ptools/ptools.hd
new file mode 100644
index 00000000..344197a7
--- /dev/null
+++ b/noao/digiphot/ptools/ptools.hd
@@ -0,0 +1,34 @@
+# Help directory for the PTOOLS package
+
+$doc = "./doc/"
+
+$pconvert = "ptools$pconvert/"
+$ptutils = "ptools$ptutils/"
+$pexamine = "ptools$pexamine/"
+$txtools = "ptools$txtools/"
+
+pcalc hlp=doc$pcalc.hlp, src=ptools$pcalc.cl
+pconcat hlp=doc$pconcat.hlp, src=ptools$pconcat.cl
+pconvert hlp=doc$pconvert.hlp, src=pconvert$t_pconvert.x
+pdump hlp=doc$pdump.hlp, src=ptools$pdump.cl
+istable hlp=doc$istable.hlp, src=ptutils$t_istable.x
+prenumber hlp=doc$prenumber.hlp, src=ptools$prenumber.cl
+pexamine hlp=doc$pexamine.hlp, src=pexamine$t_pexamine.x
+pttest hlp=doc$pttest.hlp, src=ptools$pttest.cl
+pselect hlp=doc$pselect.hlp, src=ptools$pselect.cl
+psort hlp=doc$psort.hlp, src=ptools$psort.cl
+tbcalc hlp=doc$tbcalc.hlp, src=ptools$tbcalc.cl
+tbconcat hlp=doc$tbconcat.hlp, src=ptools$tbconcat.cl
+tbcrename hlp=doc$tbcrename.hlp, src=ptutils$t_tbcrename.x
+tbdump hlp=doc$tbdump.hlp, src=ptools$t_tbdump.cl
+tbkeycol hlp=doc$tbkeycol.hlp, src=ptutils$t_tbkeycol.x
+tbrenumber hlp=doc$tbrenumber.hlp, src=ptools$tbrenumber.cl
+tbselect hlp=doc$tbselect.hlp, src=ptools$tbselect.cl
+tbsort hlp=doc$tbsort.hlp, src=ptools$tbsort.cl
+txconcat hlp=doc$txconcat.hlp, src=txtools$t_txconcat.x
+txcalc hlp=doc$txcalc.hlp, src=txtools$t_txcalc.x
+txdump hlp=doc$txdump.hlp, src=txtools$t_txdump.x
+txrenumber hlp=doc$txrenumber.hlp, src=txtools$t_txrenumber.x
+txselect hlp=doc$txselect.hlp, src=txtools$t_txselect.x
+txsort hlp=doc$txsort.hlp, src=txtools$t_txsort.x
+revisions sys=ptoolsx$Revisions
diff --git a/noao/digiphot/ptools/ptools.men b/noao/digiphot/ptools/ptools.men
new file mode 100644
index 00000000..2e13df00
--- /dev/null
+++ b/noao/digiphot/ptools/ptools.men
@@ -0,0 +1,24 @@
+ istable - Is a file a table or text database file ?
+ pconcat - Concatenate a list of apphot/daophot databases
+ pconvert - Convert from an apphot/daophot text to tables database
+ pcalc - Do arithmetic on a list of apphot/daophot tables databases
+ pdump - Print selected columns of a list of daophot/apphot databases
+ prenumber - Renumber a list of apphot/daophot databases
+ pexamine - Interactively examine and edit an apphot/daophot database
+ pselect - Select records from a list of apphot/daophot databases
+ psort - Sort a list of apphot/daophot databases
+ pttest - Run basic tests on the ptoolsx package tasks
+
+ tbconcat - Concatenate a list of apphot/daophot tables databases
+ tbcalc - Do arithmetic on a list of apphot/daophot tables databases
+ tbdump - Print selected columns of a list of tables databases
+ tbrenumber - Renumber a list of apphot/daophot tables databases
+ tbselect - Select records from a list of apphot/daophot tables databases
+ tbsort - Sort a list of apphot/daophot tables databases
+
+ txconcat - Concatenate a list of apphot/daophot text databases
+ txcalc - Do arithmetic on a list of apphot/daophot text databases
+ txdump - Print selected columns of a list of apphot/daophot text databases
+ txrenumber - Renumber a list of apphot/daophot text databases
+ txselect - Select records from a list of apphot/daophot text databases
+ txsort - Sort a list of apphot/daophot text databases
diff --git a/noao/digiphot/ptools/ptools.par b/noao/digiphot/ptools/ptools.par
new file mode 100644
index 00000000..cf641f88
--- /dev/null
+++ b/noao/digiphot/ptools/ptools.par
@@ -0,0 +1,3 @@
+# PTOOLSX package parameter file
+
+version,s,h,"Aug91"
diff --git a/noao/digiphot/ptools/pttest.cl b/noao/digiphot/ptools/pttest.cl
new file mode 100644
index 00000000..a601a17e
--- /dev/null
+++ b/noao/digiphot/ptools/pttest.cl
@@ -0,0 +1,550 @@
+# PTTEST - Self testing procedure for the PTOOLS package.
+
+procedure pttest (rootname)
+
+string rootname {prompt="Root name of the output test files"}
+string ptlogfile {"", prompt="Name of the output log file"}
+string ptplotfile {"", prompt="Name of the output plot file"}
+
+begin
+ # Declare local variables.
+ string root, txtfile1, txtfile2, tblfile1, ptlog, ptplot
+
+ # Check that the user truly wants to proceed.
+ s1 = ""
+ print ("")
+ print ("PTTEST INITIALIZES THE PTOOLS TASK PARAMETERS")
+ print ("TYPE 'q' or 'Q' TO QUIT, ANY OTHER KEY TO PROCEED")
+ if (scan (s1) != EOF) {
+ if (s1 == "q" || s1 == "Q") {
+ print ("TERMINATING THE PTTEST TASK")
+ bye
+ }
+ }
+ print ("")
+
+ # Define the image name and the log and plot file names.
+ root = rootname
+ ptlog = ptlogfile
+ if (ptlog == "") {
+ ptlog = root // ".log"
+ }
+ ptplot = ptplotfile
+ if (ptplot == "") {
+ ptplot = root // ".plot"
+ }
+
+ # Read in the FITS file and check for the existance of the log and
+ # plot files.
+
+ txtfile1 = root // ".txt.1"
+ if (! access (txtfile1)) {
+ copy ("ptools$test/test1.dat", txtfile1, verbose-)
+ } else {
+ error (0, "Error: The first test text file already exists on disk")
+ }
+ txtfile2 = root // ".txt.2"
+ if (! access (txtfile2)) {
+ copy ("ptools$test/test2.dat", txtfile2, verbose-)
+ } else {
+ error (0, "Error: The second test text file already exists on disk")
+ }
+ tblfile1 = root // ".tbl.1"
+ if (! access (tblfile1)) {
+ ;
+ } else {
+ error (0, "Error: The test tables file already exists on disk")
+ }
+ if (access (ptlog)) {
+ error (0, "Error: The log file already exists on disk")
+ }
+ if (access (ptplot)) {
+ error (0, "Error: The plot file already exists on disk")
+ }
+
+ # Initialize the PTOOLS package.
+
+ print ("INITIALIZE THE PTOOLS PACKAGE", >> ptlog)
+ print ("", >> ptlog)
+ print ("")
+ print ("INITIALIZE THE PTOOLS PACKAGE")
+ print ("")
+
+ unlearn ("txconcat")
+ unlearn ("txdump")
+ unlearn ("txrenumber")
+ unlearn ("txselect")
+ unlearn ("txsort")
+ unlearn ("pconvert")
+
+ unlearn ("tbconcat")
+ unlearn ("tbdump")
+ unlearn ("tbrenumber")
+ unlearn ("tbselect")
+ unlearn ("tbsort")
+ unlearn ("tbkeycol")
+ unlearn ("tbcrename")
+
+ unlearn ("pconcat")
+ unlearn ("pdump")
+ unlearn ("prenumber")
+ unlearn ("pselect")
+ unlearn ("psort")
+ unlearn ("pexamine")
+ unlearn ("xyplot")
+ unlearn ("histplot")
+ unlearn ("radplot")
+ unlearn ("surfplot")
+ unlearn ("cntrplot")
+ unlearn ("istable")
+
+ # Copy the first test file to the log file.
+
+ print ("COPY THE FIRST TEST FILE TO THE LOG FILE", >> ptlog)
+ print ("COPY THE FIRST TEST FILE TO THE LOG FILE")
+ print ("", >> ptlog)
+
+ concatenate (txtfile1, ptlog, append=yes)
+
+ # Testing the TXCONCAT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXCONCAT TASK (FIRST TEXT FILE)", >> ptlog)
+ print (" APPENDING THE FIRST TEXT FILE TO ITSELF", >> ptlog)
+ print ("TESTING THE TXCONCAT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ txconcat (txtfile1 // "," // txtfile1, root // ".app.1", task="TASK")
+ concatenate (root // ".app.1", ptlog, append=yes)
+ delete (root // ".app.1", ver-, >& "dev$null")
+
+ # Testing the PCONCAT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PCONCAT TASK (FIRST TEXT FILE)", >> ptlog)
+ print (" APPENDING THE FIRST TEXT FILE TO ITSELF", >> ptlog)
+ print ("TESTING THE PCONCAT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ pconcat (txtfile1 // "," // txtfile1, root // ".app.1", task="TASK")
+ concatenate (root // ".app.1", ptlog, append=yes)
+ delete (root // ".app.1", ver-, >& "dev$null")
+
+ # Testing the TXDUMP task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXDUMP TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("DUMPING FIELDS ID, XCENTER, YCENTER, MSKY AND MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TXDUMP TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ txdump (txtfile1, "id,xcenter,ycenter,msky,mag[1]", "yes", headers-,
+ parameters+, >> ptlog)
+
+ # Testing the PDUMP task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PDUMP TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("DUMPING FIELDS ID, XCENTER, YCENTER, MSKY AND MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PDUMP TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ pdump (txtfile1, "id,xcenter,ycenter,msky,mag[1]", yes, headers-,
+ parameters+, >> ptlog)
+
+ # Testing the TXSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXSELECT TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] <= 18.0", >> ptlog)
+ print ("TESTING THE TXSELECT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ txselect (txtfile1, root // ".sel.1", "mag[1] <= 18.0")
+ concatenate (root // ".sel.1", ptlog, append=yes)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the PSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSELECT TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] <= 18.0", >> ptlog)
+ print ("TESTING THE PSELECT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ pselect (txtfile1, root // ".sel.1", "mag[1] <= 18.0")
+ concatenate (root // ".sel.1", ptlog, append=yes)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the TXSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXSORT TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("TESTING THE TXSORT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ copy (txtfile1, root // ".srt.1", verbose-)
+ txsort (root // ".srt.1", "MAG[1]", ascend+)
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the PSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSORT TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("TESTING THE PSORT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ copy (txtfile1, root // ".srt.2", verbose-)
+ psort (root // ".srt.2", "MAG[1]", ascend+)
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the TXRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXRENUMBER TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("TESTING THE TXRENUMBER TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ txrenumber (root // ".srt.1", idoffset=0, id="ID")
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the PRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PRENUMBER TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("TESTING THE PRENUMBER TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ prenumber (root // ".srt.2", idoffset=0, id="ID")
+ concatenate (root // ".srt.2", ptlog, append=yes)
+
+ delete (root // ".srt.1", ver-, >& "dev$null")
+ delete (root // ".srt.2", ver-, >& "dev$null")
+
+ # Copy the second test file to the log file.
+
+ print ("")
+ print ("", >> ptlog)
+ print ("COPY THE SECOND TEST FILE TO THE LOG FILE", >> ptlog)
+ print ("COPY THE SECOND TEST FILE TO THE LOG FILE")
+ print ("", >> ptlog)
+
+ concatenate (txtfile2, ptlog, append=yes)
+
+ # Testing the TXDUMP task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXDUMP TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("DUMPING FIELDS ID, XCENTER, YCENTER, MSKY AND MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TXDUMP TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ txdump (txtfile2, "id,xcenter,ycenter,msky,mag[1]", "yes", headers-,
+ parameters+, >> ptlog)
+
+ # Testing the PDUMP task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PDUMP TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("DUMPING FIELDS ID, XCENTER, YCENTER, MSKY AND MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PDUMP TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ pdump (txtfile2, "id,xcenter,ycenter,msky,mag[1]", yes, headers-,
+ parameters+, >> ptlog)
+
+ # Testing the TXSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXSELECT TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] >= 11.5", >> ptlog)
+ print ("TESTING THE TXSELECT TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ txselect (txtfile2, root // ".sel.1", "mag[1] >= 11.5")
+ concatenate (root // ".sel.1", ptlog, append=yes)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the PSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSELECT TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] >= 11.5", >> ptlog)
+ print ("TESTING THE PSELECT TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ pselect (txtfile2, root // ".sel.1", "mag[1] >= 11.5")
+ concatenate (root // ".sel.1", ptlog, append=yes)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the TXSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXSORT TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("TESTING THE TXSORT TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ copy (txtfile2, root // ".srt.1", verbose-)
+ txsort (root // ".srt.1", "MAG[1]", ascend+)
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the PSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSORT TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("TESTING THE PSORT TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ copy (txtfile2, root // ".srt.2", verbose-)
+ psort (root // ".srt.2", "MAG[1]", ascend+)
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the TXRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TXRENUMBER TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("TESTING THE TXRENUMBER TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ txrenumber (root // ".srt.1", id="ID")
+ concatenate (root // ".srt.1", ptlog, append=yes)
+
+ # Testing the PRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PRENUMBER TASK (SECOND TEXT FILE)", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("TESTING THE PRENUMBER TASK (SECOND TEXT FILE)")
+ print ("", >> ptlog)
+
+ prenumber (root // ".srt.2", id="ID")
+ concatenate (root // ".srt.2", ptlog, append=yes)
+
+ delete (root // ".srt.1", ver-, >& "dev$null")
+ delete (root // ".srt.2", ver-, >& "dev$null")
+
+ # Testing the PCONVERT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PCONVERT TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("CREATING TABLE FILE BY CONVERTING ALL COLUMNS", >> ptlog)
+ print ("")
+ print ("TESTING THE PCONVERT TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ pconvert (txtfile1, tblfile1, "*", expr+, append-)
+
+ # Check to see if the tables package is loaded.
+
+ if (! defpac ("nttools")) {
+
+ print ("THE NTTOOLS PACKAGE IS NOT LOADED: TERMINATING PTTEST")
+
+ } else {
+
+ # Testing the TBCONCAT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TBCONCAT/TBDUMP TASKS", >> ptlog)
+ print ("APPENDING TABLE FILE TO ITSELF", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TBCONCAT/TBDUMP TASKS")
+ print ("", >> ptlog)
+
+ tbconcat (tblfile1 // "," // tblfile1, root // ".app.1",
+ task="TASK")
+ tbdump (root // ".app.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ "yes", datafile="STDOUT", cdfile="", pfile="", rows="-",
+ pagwidth=158, >> ptlog)
+ delete (root // ".app.1", ver-, >& "dev$null")
+
+ # Testing the PCONCAT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PCONCAT/PDUMP TASKS", >> ptlog)
+ print ("APPENDING TABLE FILE TO ITSELF", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PCONCAT/PDUMP TASKS")
+ print ("", >> ptlog)
+
+ pconcat (tblfile1 // "," // tblfile1, root // ".app.1",
+ task="TASK")
+ pdump (root // ".app.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ yes, headers-, parameters+, >> ptlog)
+ delete (root // ".app.1", ver-, >& "dev$null")
+
+ # Testing the TBSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TBSELECT/TBDUMP TASKS", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] <= 18.0", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TBSELECT/TBDUMP TASKS")
+ print ("", >> ptlog)
+
+ tbselect (tblfile1, root // ".sel.1", "mag[1] <= 18.0")
+ tbdump (root // ".sel.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ "yes", datafile="STDOUT", cdfile="", pfile="", rows="-",
+ pagwidth=158, >> ptlog)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the PSELECT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSELECT/PDUMP TASKS", >> ptlog)
+ print ("SELECTING RECORDS WITH MAG[1] <= 18.0", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PSELECT/PDUMP TASKS")
+ print ("", >> ptlog)
+
+ pselect (tblfile1, root // ".sel.1", "mag[1] <= 18.0")
+ pdump (root // ".sel.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ yes, headers-, parameters+, >> ptlog)
+ delete (root // ".sel.1", ver-, >& "dev$null")
+
+ # Testing the TBSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TBSORT/TBDUMP TASKS", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TBSORT/TBDUMP TASKS")
+ print ("", >> ptlog)
+
+ copy (tblfile1, root // ".srt.1", verbose-)
+ tbsort (root // ".srt.1", "MAG\[1]", ascend+, casesens+)
+ tbdump (root // ".srt.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ "yes", datafile="STDOUT", cdfile="", pfile="", rows="-",
+ pagwidth=158, >> ptlog)
+
+ # Testing the PSORT task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PSORT/PDUMP TASKS", >> ptlog)
+ print ("SORTING ON COLUMN MAG[1]", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PSORT/PDUMP TASK")
+ print ("", >> ptlog)
+
+ copy (tblfile1, root // ".srt.2", verbose-)
+ psort (root // ".srt.2", "MAG\[1]", ascend+)
+ pdump (root // ".srt.2", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ yes, headers-, parameters+, >> ptlog)
+
+ # Testing the TBRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE TBRENUMBER/TBDUMP TASKS", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE TBRENUMBER/PDUMP TASKS")
+ print ("", >> ptlog)
+
+ tbrenumber (root // ".srt.1", idoffset=0, id="ID")
+ tbdump (root // ".srt.1", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ "yes", datafile="STDOUT", cdfile="", pfile="", rows="-",
+ pagwidth=158, >> ptlog)
+
+ # Testing the PRENUMBER task.
+
+ print ("", >> ptlog)
+ print ("TESTING THE PRENUMBER/PDUMP TASKS", >> ptlog)
+ print ("RENUMBERING ON COLUMN ID", >> ptlog)
+ print ("DUMPING COLUMNS ID, XCENTER, YCENTER, MKSKY, and MAG[1]",
+ >> ptlog)
+ print ("TESTING THE PRENUMBER/PDUMP TASKS")
+ print ("", >> ptlog)
+
+ prenumber (root // ".srt.2", id="ID")
+ pdump (root // ".srt.2", "ID,XCENTER,YCENTER,MSKY,MAG\[1]",
+ yes, headers-, parameters+, >> ptlog)
+
+ delete (root // ".srt.1", ver-, >& "dev$null")
+ delete (root // ".srt.2", ver-, >& "dev$null")
+ }
+
+ # Testing the PEXAMINE task.
+
+ xyplot.x1=16.0
+ xyplot.x2=20.0
+ xyplot.y1=0.0
+ xyplot.y2=0.5
+
+ histplot.z1=16.0
+ histplot.z2=20.0
+ histplot.nbins=8
+
+ print ("")
+ print ("", >> ptlog)
+ print ("TESTING THE PEXAMINE TASK (FIRST TEXT FILE)", >> ptlog)
+ print ("DUMPING THE RESULTS TO THE PLOT FILE", >> ptlog)
+ print ("TESTING THE PEXAMINE TASK (FIRST TEXT FILE)")
+ print ("", >> ptlog)
+
+ pexamine (txtfile1, "", "", gcommands="ptools$test/gcommands.dat",
+ icommands="ptools$test/icommands.dat", >>G ptplot, >& "dev$null")
+
+ print ("", >> ptlog)
+ print ("TESTING THE PEXAMINE TASK (TABLE FILE)", >> ptlog)
+ print ("DUMPING THE RESULTS TO THE PLOT FILE", >> ptlog)
+ print ("TESTING THE PEXAMINE TASK (TABLE FILE)")
+ print ("", >> ptlog)
+
+ pexamine (tblfile1, "", "", gcommands="ptools$test/gcommands.dat",
+ icommands="ptools$test/icommands.dat", >>G ptplot, >& "dev$null")
+
+ # Clean up.
+ delete (txtfile1, ver-, >& "dev$null")
+ delete (txtfile2, ver-, >& "dev$null")
+ delete (tblfile1, ver-, >& "dev$null")
+
+ unlearn ("txconcat")
+ unlearn ("txdump")
+ unlearn ("txrenumber")
+ unlearn ("txselect")
+ unlearn ("txsort")
+ unlearn ("pconvert")
+
+ unlearn ("tbconcat")
+ unlearn ("tbdump")
+ unlearn ("tbrenumber")
+ unlearn ("tbselect")
+ unlearn ("tbsort")
+ unlearn ("tbkeycol")
+ unlearn ("tbcrename")
+
+ unlearn ("pconcat")
+ unlearn ("pdump")
+ unlearn ("prenumber")
+ unlearn ("pselect")
+ unlearn ("psort")
+ unlearn ("pexamine")
+
+ unlearn ("xyplot")
+ unlearn ("histplot")
+ unlearn ("radplot")
+ unlearn ("surfplot")
+ unlearn ("cntrplot")
+
+ unlearn ("istable")
+
+ bye
+end
diff --git a/noao/digiphot/ptools/ptutils/mkpkg b/noao/digiphot/ptools/ptutils/mkpkg
new file mode 100644
index 00000000..3c3dc1bb
--- /dev/null
+++ b/noao/digiphot/ptools/ptutils/mkpkg
@@ -0,0 +1,12 @@
+# miscellaneous useful tasks
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ t_istable.x ../../lib/ptkeysdef.h
+ t_tbkeycol.x <tbset.h>
+ t_tbcrename.x <tbset.h>
+ ;
diff --git a/noao/digiphot/ptools/ptutils/t_istable.x b/noao/digiphot/ptools/ptutils/t_istable.x
new file mode 100644
index 00000000..b8cbf5db
--- /dev/null
+++ b/noao/digiphot/ptools/ptutils/t_istable.x
@@ -0,0 +1,71 @@
+include "../../lib/ptkeysdef.h"
+
+# T_ISTABLE -- Decide whether an input file is an ST Table, an APPHOT style
+# text file or neither.
+
+procedure t_istable ()
+
+pointer infile # name of the input file
+
+bool table, text, other
+int fd, type
+pointer sp, line
+int access(), tbtopn(), open(), getline(), strmatch()
+errchk tbtopn(), open()
+
+begin
+ # Get some working space.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ # Fetch the name of the input file
+ call clgstr ("infile", Memc[infile], SZ_FNAME)
+ if (access (Memc[infile], READ_ONLY, TEXT_FILE) == YES)
+ type = TEXT_FILE
+ else
+ type = BINARY_FILE
+
+ if (type == BINARY_FILE) {
+ iferr {
+ fd = tbtopn (Memc[infile], READ_ONLY, 0)
+ } then {
+ table = false
+ text = false
+ other = true
+ } else {
+ table = true
+ text = false
+ other = false
+ call tbtclo (fd)
+ }
+ } else {
+ table = false
+ iferr {
+ fd = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ } then {
+ text = false
+ other = true
+ } else {
+ Memc[line] = EOS
+ if (getline (fd, Memc[line]) != EOF) {
+ if (strmatch (Memc[line], KY_CHAR_IRAF) != 0) {
+ text = true
+ other = false
+ } else {
+ text = false
+ other = true
+ }
+ }
+ call close (fd)
+ }
+ }
+
+ # Store the results in the istable parameter file.
+ call clputb ("table", table)
+ call clputb ("text", text)
+ call clputb ("other", other)
+
+ # Free memory.
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/ptutils/t_tbcrename.x b/noao/digiphot/ptools/ptutils/t_tbcrename.x
new file mode 100644
index 00000000..8f54e9d5
--- /dev/null
+++ b/noao/digiphot/ptools/ptutils/t_tbcrename.x
@@ -0,0 +1,73 @@
+include <tbset.h>
+
+# T_TBCRENAME -- Rename a list of columns in an ST table.
+
+procedure t_tbcrename ()
+
+int tlist # the tables list descriptor
+int columns # the input columns list descriptor
+int names # the output column names list descriptor
+
+pointer sp, table, incname, outcname, tp, colptr
+int clpopnu(), clplen(), clgfil(), access(), tbpsta()
+pointer tbtopn()
+
+begin
+ # Open the lists of tables and keywords.
+ tlist = clpopnu ("table")
+ if (clplen (tlist) <= 0)
+ return
+ columns = clpopnu ("columns")
+ names = clpopnu ("names")
+ if (clplen (columns) != clplen (names))
+ call error (0,
+ "The number of new names does not equal the number of columns")
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+ call salloc (incname, SZ_COLNAME, TY_CHAR)
+ call salloc (outcname, SZ_COLNAME, TY_CHAR)
+
+ # Loop over the list of ST tables.
+ while (clgfil (tlist, Memc[table], SZ_FNAME) != EOF) {
+
+ # If the file is not an ST table go to the next file in the list.
+ if (access (Memc[table], 0, TEXT_FILE) == YES)
+ next
+ iferr (tp = tbtopn (Memc[table], READ_WRITE, 0))
+ next
+ if (tbpsta (tp, TBL_WHTYPE) == TBL_TYPE_TEXT)
+ next
+
+ # Loop over the input column list.
+ while (clgfil (columns, Memc[incname], SZ_COLNAME) != EOF &&
+ clgfil (names, Memc[outcname], SZ_COLNAME) != EOF) {
+
+ # If the output column already exists in the table skip
+ # to the next input column.
+ call tbcfnd (tp, Memc[outcname], colptr, 1)
+ if (colptr != NULL)
+ next
+
+ # If the input column does not exist in the table skip to the
+ # next column.
+
+ call tbcfnd (tp, Memc[incname], colptr, 1)
+ if (colptr == NULL)
+ next
+
+ # Rename the column.
+ call tbcnam (tp, colptr, Memc[outcname])
+ }
+
+ call tbtclo (tp)
+ call clprew (columns)
+ call clprew (names)
+ }
+
+ call clpcls (columns)
+ call clpcls (names)
+ call clpcls (tlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/ptutils/t_tbkeycol.x b/noao/digiphot/ptools/ptutils/t_tbkeycol.x
new file mode 100644
index 00000000..47923ca6
--- /dev/null
+++ b/noao/digiphot/ptools/ptutils/t_tbkeycol.x
@@ -0,0 +1,140 @@
+include <tbset.h>
+
+# T_TBKEYCOL -- For all the rows of a list of ST tables, copy the values of
+# selected table keywords into new columns of the same name. If the columns
+# already exist no action is taken.
+
+procedure t_tbkeycol ()
+
+int tlist # the tables list descriptor
+int klist # the keywords list descriptor
+
+bool bval
+double dval
+int i, keytype, keyptr, nrows, keylength, ival
+pointer sp, table, keyword, keyvalue, format, tp, colptr
+real rval
+
+bool itob()
+int clpopnu(), clgfil(), clplen(), tbpsta(), strlen(), access()
+int ctoi(), ctor(), ctod()
+pointer tbtopn()
+errchk tbtopn()
+
+begin
+ # Open the lists of tables and keywords.
+ tlist = clpopnu ("tables")
+ if (clplen (tlist) <= 0)
+ return
+ klist = clpopnu ("keywords")
+ if (clplen (klist) <= 0)
+ return
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+ call salloc (keyword, SZ_KEYWORD, TY_CHAR)
+ call salloc (keyvalue, SZ_PARREC, TY_CHAR)
+ call salloc (format, SZ_COLFMT, TY_CHAR)
+
+ # Loop over the list of ST tables.
+ while (clgfil (tlist, Memc[table], SZ_FNAME) != EOF) {
+
+ # If the file is not an ST table go to the next file in the list.
+ if (access(Memc[table], 0, TEXT_FILE) == YES)
+ next
+ iferr (tp = tbtopn (Memc[table], READ_WRITE, 0))
+ next
+ if (tbpsta (tp, TBL_WHTYPE) == TBL_TYPE_TEXT)
+ next
+
+
+ # Loop over the keywords.
+ while (clgfil (klist, Memc[keyword], SZ_FNAME) != EOF) {
+
+ # If a column named keyword already exists in the table
+ # skip to the next keyword.
+ call tbcfnd (tp, Memc[keyword], colptr, 1)
+ if (colptr != NULL)
+ next
+
+ # If keyword does not exist in the table skip to the
+ # next keyword.
+ call tbhfkr (tp, Memc[keyword], keytype, Memc[keyvalue],
+ keyptr)
+ if (keyptr == 0)
+ next
+
+ nrows = tbpsta (tp, TBL_NROWS)
+
+ # Decode the header value and copy it into all the rows
+ # of the table.
+ i = 1
+ switch (keytype) {
+ case TY_BOOL:
+ call tbcdef (tp, colptr, Memc[keyword], "undefined",
+ "%-3.3b", keytype, 1, 1)
+ if (ctoi (Memc[keyvalue], i, ival) <= 0)
+ ival = NO
+ bval = itob (ival)
+ do i = 1, nrows
+ call tbrptb (tp, colptr, bval, 1, i)
+ case TY_CHAR:
+ keylength = strlen (Memc[keyvalue])
+ call sprintf (Memc[format], SZ_COLFMT, "%*.*s")
+ call pargi (-keylength)
+ call pargi (keylength)
+ call tbcdef (tp, colptr, Memc[keyword], "undefined",
+ Memc[format], -keylength, 1, 1)
+ do i = 1, nrows
+ call tbrptt (tp, colptr, Memc[keyvalue], keylength,
+ 1, i)
+ case TY_INT:
+ keylength = ctoi (Memc[keyvalue], i, ival)
+ if (keylength <= 0) {
+ ival = INDEFI
+ keylength = 6
+ }
+ call sprintf (Memc[format], SZ_COLFMT, "%%%d.%dd")
+ call pargi (-keylength)
+ call pargi (keylength)
+ call tbcdef (tp, colptr, Memc[keyword], "undefined",
+ Memc[format], keytype, 1, 1)
+ do i = 1, nrows
+ call tbrpti (tp, colptr, ival, 1, i)
+ case TY_REAL:
+ keylength = ctor (Memc[keyvalue], i, rval)
+ if (keylength <= 0) {
+ rval = INDEFR
+ keylength = 6
+ }
+ call sprintf (Memc[format], SZ_COLFMT, "%%%dg")
+ call pargi (-keylength)
+ call tbcdef (tp, colptr, Memc[keyword], "undefined",
+ Memc[format], keytype, 1, 1)
+ do i = 1, nrows
+ call tbrptr (tp, colptr, rval, 1, i)
+ case TY_DOUBLE:
+ keylength = ctod (Memc[keyvalue], i, dval)
+ if (keylength <= 0) {
+ dval = INDEFD
+ keylength = 6
+ }
+ call sprintf (Memc[format], SZ_COLFMT, "%%%dg")
+ call pargi (-keylength)
+ call tbcdef (tp, colptr, Memc[keyword], "undefined",
+ Memc[format], keytype, 1, 1)
+ do i = 1, nrows
+ call tbrptd (tp, colptr, dval, 1, i)
+ }
+
+ }
+
+ call tbtclo (tp)
+ call clprew (klist)
+ }
+
+ call clpcls (klist)
+ call clpcls (tlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/radplot.par b/noao/digiphot/ptools/radplot.par
new file mode 100644
index 00000000..0d579463
--- /dev/null
+++ b/noao/digiphot/ptools/radplot.par
@@ -0,0 +1,22 @@
+# The PEXAMINE task radial profile plotting parameters
+
+rinner,r,h,0.0,,,Inner radius of the region to be plotted in pixels
+router,r,h,8.0,,,Outer radius of the region to be plotted in pixels
+x1,r,h,INDEF,,,Left world x-coord if not autoscaling
+x2,r,h,INDEF,,,Right world x-coord if not autoscaling
+y1,r,h,INDEF,,,Lower world y-coord if not autoscaling
+y2,r,h,INDEF,,,Upper world y-coord if not autoscaling
+marker,s,h,"box","point|box|plus|cross|circle|diamond|hline|vline",,Marker type
+szmarker,r,h,1.0,0.0,,Marker size
+logx,b,h,no,,,Log scale the x axis?
+logy,b,h,no,,,Log scale the y axis?
+box,b,h,yes,,,Draw box around periphery of window?
+ticklabels,b,h,yes,,,Label tick marks?
+majrx,i,h,5,,,Number of major divisions along x axis
+minrx,i,h,5,,,Number of minor divisions along x axis
+majry,i,h,5,,,Number of major divisions along y axis
+minry,i,h,5,,,Number of minor divisions along y axis
+round,b,h,no,,,Round axes to nice values?
+fill,b,h,yes,,,Fill viewport vs enforce unity aspect ratio?
+grid,b,h,no,,,Draw grid lines at major tick marks?
+banner,b,h,yes,,,Standard banner?
diff --git a/noao/digiphot/ptools/surfplot.par b/noao/digiphot/ptools/surfplot.par
new file mode 100644
index 00000000..1d94e5cc
--- /dev/null
+++ b/noao/digiphot/ptools/surfplot.par
@@ -0,0 +1,10 @@
+# The PEXAMINE task surface plotting parameters
+
+ncolumns,i,h,21,2,,"Number of columns"
+nlines,i,h,21,2,,"Number of lines"
+axes,b,h,yes,,,Draw axes?
+angh,r,h, -33.,,,Horizontal viewing angle (degrees)
+angv,r,h,25.,,,Vertical viewing angle (degrees)
+floor,r,h,INDEF,,,Minimum value to be plotted
+ceiling,r,h,INDEF,,,Maximum value to be plotted
+banner,b,h,yes,,,Standard banner?
diff --git a/noao/digiphot/ptools/tbcalc.cl b/noao/digiphot/ptools/tbcalc.cl
new file mode 100644
index 00000000..25f1ee60
--- /dev/null
+++ b/noao/digiphot/ptools/tbcalc.cl
@@ -0,0 +1,37 @@
+# TBCALC -- Perform arithmetic operations on a column column of an
+# APPHOT/DAOPHOT STSDAS table database.
+
+procedure tbcalc (tables, column, value)
+
+file tables {prompt="Input apphot/daophot tables databases to be renumbered"}
+string column {prompt="Column to be edited"}
+string value {prompt="New value or expression for column"}
+
+struct *inlist
+
+begin
+ # Declare local variables.
+ file ttables, tcolumn, tvalue
+ string tmpin, inname
+
+ # Get the positional parameters.
+ ttables = tables
+ tcolumn = column
+ tvalue = value
+
+ tmpin = mktemp ("tmp$")
+ files (ttables, sort=no, > tmpin)
+
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ if (defpar ("tcalc.verbose") || defpar ("tcalc.harmless")) {
+ tcalc (inname, tcolumn, tvalue, datatype="real", colunits="",
+ colfmt="", verbose=no, harmless=0.1)
+ } else {
+ tcalc (inname, tcolumn, tvalue, datatype="real", colunits="",
+ colfmt="")
+ }
+ }
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+end
diff --git a/noao/digiphot/ptools/tbconcat.cl b/noao/digiphot/ptools/tbconcat.cl
new file mode 100644
index 00000000..d9e5c429
--- /dev/null
+++ b/noao/digiphot/ptools/tbconcat.cl
@@ -0,0 +1,113 @@
+# TBCONCAT -- Concatenate a list of apphot/daophot STSDAS table databases
+# into a single output database. All the input files must of been written
+# by the same task.
+
+procedure tbconcat (tables, outtable)
+
+file tables {prompt="Input apphot/daophot tables databases to be concatenated"}
+file outtable {prompt="Output apphot/daophot STSDAS table database"}
+string task {"TASK", prompt="Task name keyword"}
+
+struct *inlist
+
+begin
+ # Declare local variables.
+ bool stat, first_tab
+ file in, out
+ int npars, first_npars, ncols, first_ncols
+ string tmpin, inname, first_inname, tkname, first_tkname
+
+ # Cache the parameters.
+ cache ("istable", "keypar", "tinfo")
+
+ # Get the positional parameters.
+ in = tables
+ out = outtable
+
+ # Make a file lists.
+ tmpin = mktemp ("tmp$")
+ files (in, sort=no, > tmpin)
+
+ # Loop through the list checking that all the files are
+ # tables that they were created with the same task and
+ # that they have the same number of parameters and columns
+
+ stat = yes
+ first_tab = yes
+
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+
+ # Check that the input file is an STSDAS table.
+ istable (inname)
+ if (! istable.table) {
+ print ("ERROR: File " // inname // " is not an ST table")
+ stat = no
+ break
+ }
+
+
+ # Check that all the input files were written by the same task.
+ if (defpar ("keypar.silent")) {
+ keypar (inname, task, silent=no)
+ } else {
+ keypar (inname, task)
+ }
+ if (first_tab) {
+ first_inname = inname
+ first_tkname = keypar.value
+ } else {
+ tkname = keypar.value
+ if (tkname != first_tkname) {
+ print ("ERROR:")
+ print (" File" // first_inname // " written by task " //
+ first_tkname)
+ print (" File" // inname // " written by task " //
+ tkname)
+ stat = no
+ break
+ }
+ }
+
+ # Check that the number of parameters and columns is the same.
+ tinfo (inname, ttout=no)
+ if (first_tab) {
+ first_npars = tinfo.npar
+ first_ncols = tinfo.ncols
+ } else {
+ npars = tinfo.npar
+ ncols = tinfo.ncols
+ if (npars != first_npars) {
+ print ("ERROR:")
+ print (" File " // first_inname // " has " //
+ first_npars // "parameters")
+ print (" File " // inname // " has " // npars //
+ "parameters")
+ stat = no
+ break
+ }
+ if (ncols != first_ncols) {
+ print ("ERROR:")
+ print (" File " // first_inname // " has " //
+ first_ncols // "columns")
+ print (" File " // inname // " has " // ncols //
+ "columns")
+ stat = no
+ break
+ }
+ }
+
+ first_tab = no
+ }
+
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+
+ # Return if status is not ok.
+ if (! stat)
+ return
+
+ # Do the actual append.
+ tmerge (in, out, option="append", allcols=no, tbltype="row",
+ allrows=100, extracol=0)
+end
diff --git a/noao/digiphot/ptools/tbcrename.par b/noao/digiphot/ptools/tbcrename.par
new file mode 100644
index 00000000..c466c337
--- /dev/null
+++ b/noao/digiphot/ptools/tbcrename.par
@@ -0,0 +1,6 @@
+# TBCRENAME Parameters
+
+tables,s,a,,,,Input apphot/daophot tables databases
+columns,s,a,"",,,List of column names to be changed
+names,s,a,"",,,List of new column names
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/tbdump.cl b/noao/digiphot/ptools/tbdump.cl
new file mode 100644
index 00000000..f3482a5f
--- /dev/null
+++ b/noao/digiphot/ptools/tbdump.cl
@@ -0,0 +1,44 @@
+# TBDUMP -- Dump selected columns of an APPHOT/DAOPHOT STSDAS table database.
+
+procedure tbdump (tables, fields, expr)
+
+file tables {prompt = "Input apphot/daophot tables database(s)"}
+string fields {"", prompt = "Fields to be extracted"}
+string expr {"yes", prompt = "Boolean expression for record selection"}
+file datafile {"STDOUT", prompt = "Output file for table data"}
+file cdfile {"", prompt = "Output file for table column definitions"}
+file pfile {"", prompt = "Output file for table header parameters"}
+string rows {"-", prompt = "Range of rows to dump"}
+int pagwidth {158, prompt = "Output page width"}
+
+struct *inlist
+
+begin
+ # Declare local variables
+ file ttables
+ string tfields, texpr, tmpin, tmpout, inname
+
+ # Get the positional parameters.
+ ttables = tables
+ tfields = fields
+ texpr = expr
+
+ tmpin = mktemp ("tmp$")
+ files (ttables, sort=no, > tmpin)
+
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ if (texpr != "yes") {
+ tmpout = mktemp ("tmp$")
+ tselect (inname, tmpout, texpr)
+ tdump (tmpout, cdfile=cdfile, pfile=pfile, datafile=datafile,
+ columns=tfields, rows=rows, pwidth=pagwidth)
+ tdelete (tmpout, ver-, >& "dev$null")
+ } else {
+ tdump (inname, cdfile=cdfile, pfile=pfile, datafile=datafile,
+ columns=tfields, rows=rows, pwidth=pagwidth)
+ }
+ }
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+end
diff --git a/noao/digiphot/ptools/tbkeycol.par b/noao/digiphot/ptools/tbkeycol.par
new file mode 100644
index 00000000..bc6bc159
--- /dev/null
+++ b/noao/digiphot/ptools/tbkeycol.par
@@ -0,0 +1,5 @@
+# TKEYCOL Parameters
+
+tables,s,a,,,,Input apphot/daophot tables databases
+keywords,s,a,"",,,Table keywords to be copied to table columns
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/tbrenumber.cl b/noao/digiphot/ptools/tbrenumber.cl
new file mode 100644
index 00000000..75778ac6
--- /dev/null
+++ b/noao/digiphot/ptools/tbrenumber.cl
@@ -0,0 +1,36 @@
+# TBRENUMBER -- Renumber the ID column of an APPHOT/DAOPHOT STSDAS table
+# database.
+
+procedure tbrenumber (tables)
+
+file tables {prompt="Input apphot/daophot tables databases to be renumbered"}
+int idoffset {0, min=0, prompt="Id number offset"}
+string id {"ID", prompt="Id name keyword"}
+
+struct *inlist
+
+begin
+ # Declare local variables.
+ file ttables
+ string tmpin, inname, expr
+
+ # Get the positional parameters.
+ ttables = tables
+ expr = "rownum + " // idoffset
+
+ tmpin = mktemp ("tmp$")
+ files (ttables, sort=no, > tmpin)
+
+ inlist = tmpin
+ while (fscan (inlist, inname) != EOF) {
+ if (defpar ("tcalc.verbose") || defpar ("tcalc.harmless")) {
+ tcalc (inname, id, expr, datatype="real", colunits="",
+ colfmt="", verbose=no, harmless=0.1)
+ } else {
+ tcalc (inname, id, expr, datatype="real", colunits="",
+ colfmt="")
+ }
+ }
+ delete (tmpin, ver-, >& "dev$null")
+ inlist = ""
+end
diff --git a/noao/digiphot/ptools/tbselect.cl b/noao/digiphot/ptools/tbselect.cl
new file mode 100644
index 00000000..2ba294f8
--- /dev/null
+++ b/noao/digiphot/ptools/tbselect.cl
@@ -0,0 +1,20 @@
+# TBSELECT -- Select records from an APPHOT/DAOPHOT STSDAS table based
+# on the value of an expression.
+
+procedure tbselect (intable, outtable, expr)
+
+file intable {"", prompt = "Input apphot/daophot tables database(s)"}
+file outtable {"", prompt = "Output apphot/daophot tables database(s)"}
+string expr {"", prompt = "Boolean expression for record selection"}
+
+begin
+ # Declare the local variables.
+ string tintable, touttable, texpr
+
+ # Get the positional parameters.
+ tintable = intable
+ touttable = outtable
+ texpr = expr
+
+ tselect (tintable, touttable, texpr)
+end
diff --git a/noao/digiphot/ptools/tbsort.cl b/noao/digiphot/ptools/tbsort.cl
new file mode 100644
index 00000000..c5d10f24
--- /dev/null
+++ b/noao/digiphot/ptools/tbsort.cl
@@ -0,0 +1,21 @@
+# TBSORT -- Sort an APPHOT/DAOPHOT STSDAS table using the values in the
+# selected columns.
+
+procedure tbsort (table, fields)
+
+file table {"", prompt="Input apphot/daophot tables database(s)to be sorted"}
+string fields {"", prompt = "Fields to be sorted on"}
+bool ascend {yes, prompt = "Sort in ascending value order ?"}
+bool casesens {yes, prompt = "Case sensitive sort ?"}
+
+begin
+ # Decalre the local variables.
+ string ttable, tfields
+
+ # Get the positional parameters.
+ ttable = table
+ tfields = fields
+
+ # Sort the table.
+ tsort (ttable, tfields, ascend=ascend, casesens=casesens)
+end
diff --git a/noao/digiphot/ptools/test/gcommands.dat b/noao/digiphot/ptools/test/gcommands.dat
new file mode 100644
index 00000000..1ec5ac13
--- /dev/null
+++ b/noao/digiphot/ptools/test/gcommands.dat
@@ -0,0 +1,3 @@
+h
+i
+e
diff --git a/noao/digiphot/ptools/test/icommands.dat b/noao/digiphot/ptools/test/icommands.dat
new file mode 100644
index 00000000..01058d84
--- /dev/null
+++ b/noao/digiphot/ptools/test/icommands.dat
@@ -0,0 +1 @@
+g
diff --git a/noao/digiphot/ptools/test/test1.dat b/noao/digiphot/ptools/test/test1.dat
new file mode 100644
index 00000000..7f2e9dc5
--- /dev/null
+++ b/noao/digiphot/ptools/test/test1.dat
@@ -0,0 +1,133 @@
+#K IRAF = NOAO/IRAFV2.10BETA version %-23s
+#K USER = davis name %-23s
+#K HOST = tucana computer %-23s
+#K DATE = 10-04-91 mm-dd-yr %-23s
+#K TIME = 07:57:32 hh:mm:ss %-23s
+#K PACKAGE = apphot name %-23s
+#K TASK = phot name %-23s
+#
+#K SCALE = 1. units %-23.7g
+#K FWHMPSF = 2. scaleunit %-23.7g
+#K EMISSION = yes switch %-23b
+#K DATAMIN = INDEF counts %-23.7g
+#K DATAMAX = INDEF counts %-23.7g
+#K EXPOSURE = "" keyword %-23s
+#K AIRMASS = "" keyword %-23s
+#K FILTER = "" keyword %-23s
+#K OBSTIME = "" keyword %-23s
+#
+#K NOISE = poisson model %-23s
+#K THRESHOLD = 30. counts %-23.7g
+#K CTHRESHOLD = 0. counts %-23.7g
+#K SIGMA = 10. counts %-23.7g
+#K GAIN = "" keyword %-23s
+#K EPADU = 1. e-/adu %-23.7g
+#K CCDREAD = "" keyword %-23s
+#K READNOISE = 0. e- %-23.7g
+#
+#K CALGORITHM = none algorithm %-23s
+#K CBOXWIDTH = 5. scaleunit %-23.7g
+#K MAXSHIFT = 1. scaleunit %-23.7g
+#K CMAXITER = 10 number %-23d
+#K MINSNRATIO = 1. number %-23.7g
+#K CLEAN = no switch %-23b
+#K RCLEAN = 1. scaleunit %-23.7g
+#K RCLIP = 2. scaleunit %-23.7g
+#K KCLEAN = 3. sigma %-23.7g
+#
+#K SALGORITHM = mode algorithm %-23s
+#K ANNULUS = 6. scaleunit %-23.7g
+#K DANNULUS = 12. scaleunit %-23.7g
+#K SMAXITER = 10 number %-23d
+#K SKREJECT = 3. sigma %-23.7g
+#K SNREJECT = 50 number %-23d
+#K KHIST = 3. sigma %-23.7g
+#K BINSIZE = 0.1 sigma %-23.7g
+#K SMOOTH = no switch %-23b
+#K RGROW = 0. scaleunit %-23.7g
+#K SKYVALUE = 0. counts %-23.7g
+#
+#K WEIGHTING = constant model %-23s
+#K APERTURES = 3.0,5.0 scaleunit %-23s
+#K ZMAG = 25. zeropoint %-23.7g
+#
+#N IMAGE XINIT YINIT ID COORDS LID \
+#U imagename pixels pixels ## filename ## \
+#F %-23s %-10.2f %-10.2f %-5d %-23s %-5d
+#
+#N XCENTER YCENTER XSHIFT YSHIFT XERR YERR CIER CERROR \
+#U pixels pixels pixels pixels pixels pixels ## cerrors \
+#F %-12.2f %-11.2f %-8.2f %-8.2f %-8.2f %-8.2f %-5d %-13s
+#
+#N MSKY STDEV SSKEW NSKY NSREJ SIER SERROR \
+#U counts counts counts npix npix ## serrors \
+#F %-18.7g %-15.7g %-15.7g %-7d %-6d %-5d %-13s
+#
+#N ITIME XAIRMASS IFILTER OTIME \
+#U timeunit number name timeunit \
+#F %-18.7g %-15.7g %-23s %-23s
+#
+#N RAPERT SUM AREA MAG MERR PIER PERROR \
+#U scale counts pixels mag mag ## perrors \
+#F %-12.2f %-15.7f %-15.7f %-7.3f %-6.3f %-5d %-13s
+#
+testim 41.05 4.01 1 testim.coo.1 1 \
+ 41.05 4.01 0.00 0.00 INDEF INDEF 0 No_error \
+ 101.2498 10.10408 3.265505 422 10 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 4177.432 28.38464 17.212 0.055 0 No_error *\
+ 5.00 0. 0. INDEF INDEF 302 Out_of_bounds *
+testim 23.05 7.01 2 testim.coo.1 2 \
+ 23.05 7.01 0.00 0.00 INDEF INDEF 0 No_error \
+ 100.046 10.3039 5.156589 599 26 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 3729.583 28.38464 17.627 0.078 0 No_error *\
+ 5.00 9275.692 79.08551 17.163 0.083 0 No_error *
+testim 18.01 7.98 3 testim.coo.1 3 \
+ 18.01 7.98 0.00 0.00 INDEF INDEF 0 No_error \
+ 99.18147 9.960084 4.406289 624 27 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 3848.674 28.38741 17.465 0.066 0 No_error *\
+ 5.00 9254.844 79.12583 17.129 0.078 0 No_error *
+testim 25.99 22.00 4 testim.coo.1 4 \
+ 25.99 22.00 0.00 0.00 INDEF INDEF 0 No_error \
+ 100.8048 10.62133 5.339536 839 57 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 4807.073 28.38794 16.777 0.040 0 No_error *\
+ 5.00 10242.03 79.1264 16.612 0.053 0 No_error *
+testim 35.99 22.00 5 testim.coo.1 5 \
+ 35.99 22.00 0.00 0.00 INDEF INDEF 0 No_error \
+ 101.8237 10.81446 5.27525 836 32 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 5733.314 28.38794 16.366 0.030 0 No_error *\
+ 5.00 11055.33 79.12638 16.308 0.041 0 No_error *
+testim 8.00 22.96 6 testim.coo.1 6 \
+ 8.00 22.96 0.00 0.00 INDEF INDEF 0 No_error \
+ 98.55382 9.745545 -1.86605 642 15 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 5121.953 28.38596 16.584 0.033 0 No_error *\
+ 5.00 10346.71 79.10844 16.484 0.045 0 No_error *
+testim 30.96 25.04 7 testim.coo.1 7 \
+ 30.96 25.04 0.00 0.00 INDEF INDEF 0 No_error \
+ 101.0168 10.24696 1.970369 865 39 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 4406.198 28.38385 17.032 0.048 0 No_error *\
+ 5.00 10425.96 79.07048 16.532 0.048 0 No_error *
+testim 21.06 26.07 8 testim.coo.1 8 \
+ 21.06 26.07 0.00 0.00 INDEF INDEF 0 No_error \
+ 100.5127 10.64676 6.194943 841 65 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 3008.981 28.37686 19.512 0.409 0 No_error *\
+ 5.00 8254.723 78.98734 18.753 0.346 0 No_error *
+testim 28.96 33.93 9 testim.coo.1 9 \
+ 28.96 33.93 0.00 0.00 INDEF INDEF 0 No_error \
+ 101.6732 10.37004 5.42453 845 61 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 3637.463 28.37949 17.809 0.090 0 No_error *\
+ 5.00 8691.696 79.00822 17.953 0.164 0 No_error *
+testim 35.99 41.97 10 testim.coo.1 10 \
+ 35.99 41.97 0.00 0.00 INDEF INDEF 0 No_error \
+ 101.5544 10.21878 4.627132 673 19 0 No_error \
+ 1. INDEF INDEF INDEF \
+ 3.00 5199.237 28.38675 16.588 0.034 0 No_error *\
+ 5.00 10383.58 79.12172 16.573 0.050 0 No_error *
diff --git a/noao/digiphot/ptools/test/test2.dat b/noao/digiphot/ptools/test/test2.dat
new file mode 100644
index 00000000..20ecab5c
--- /dev/null
+++ b/noao/digiphot/ptools/test/test2.dat
@@ -0,0 +1,315 @@
+#K IRAF = NOAO/IRAF V2.9.version %-15s
+#K USER = cmartin name %-15s
+#K HOST = kepler computer %-15s
+#K DATE = 05-24-91 mm-dd-yr %-15s
+#K TIME = 15:13:50 hh:mm:ss %-15s
+#K PACKAGE = apphot name %-15s
+#K TASK = polyphot name %-15s
+#
+#K SCALE = 1. units %-15.7g
+#K FWHMPSF = 1. scaleunit %-15.7g
+#K EMISSION = yes switch %-15b
+#K DATAMIN = INDEF counts %-15.7g
+#K DATAMAX = INDEF counts %-15.7g
+#K EXPOSURE = "" keyword %-15s
+#K AIRMASS = "" keyword %-15s
+#K FILTER = "" keyword %-15s
+#
+#K NOISE = poisson model %-15s
+#K THRESHOLD = 0. counts %-15.7g
+#K CTHRESHOLD = 0. counts %-15.7g
+#K SIGMA = INDEF counts %-15.7g
+#K GAIN = "" keyword %-15s
+#K EPADU = 1. e-/adu %-15.7g
+#K CCDREAD = "" keyword %-15s
+#K READNOISE = 0. e- %-15.7g
+#
+#K CALGORITHM = centroid algorithm %-15s
+#K CBOXWIDTH = 5. scaleunit %-15.7g
+#K MAXSHIFT = 1. scaleunit %-15.7g
+#K CMAXITER = 10 number %-15d
+#K MINSNRATIO = 1. number %-15.7g
+#K CLEAN = no switch %-15b
+#K RCLEAN = 1. scaleunit %-15.7g
+#K RCLIP = 2. scaleunit %-15.7g
+#K KCLEAN = 3. sigma %-15.7g
+#
+#K SALGORITHM = mode algorithm %-15s
+#K ANNULUS = 10. scaleunit %-15.7g
+#K DANNULUS = 10. scaleunit %-15.7g
+#K SMAXITER = 10 number %-15d
+#K SKREJECT = 3. sigma %-15.7g
+#K SNREJECT = 50 number %-15d
+#K KHIST = 3. sigma %-15.7g
+#K BINSIZE = 0.1 sigma %-15.7g
+#K SMOOTH = no switch %-15b
+#K RGROW = 0. scaleunit %-15.7g
+#K SKYVALUE = 0. counts %-15.7g
+#
+#K WEIGHTING = constant model %-15s
+#K ZMAG = 26. zeropoint %-15.7g
+#
+#N IMAGE XINIT YINIT ID COORDS LID \
+#U imagename pixels pixels ## filename ## \
+#F %-23s %-10.2f %-10.2f %-5d %-20s %-5d
+#
+#N XCENTER YCENTER XSHIFT YSHIFT XERR YERR CIER CERROR \
+#U pixels pixels pixels pixels pixels pixels ## cerrors \
+#F %-12.2f %-9.2f %-7.2f %-7.2f %-7.2f %-7.2f %-5d %-13s
+#
+#N MSKY STDEV SSKEW NSKY NSREJ SIER SERROR \
+#U counts counts counts npix npix ## serrors \
+#F %-18.7g %-15.7g %-15.7g %-7d %-6d %-5d %-13s
+#
+#N ITIME XAIRMASS IFILTER \
+#U timeunit number name \
+#F %-18.7g %-15.7g %-23s
+#
+#N SUM AREA MAG MERR PIER PERROR \
+#U counts pixels mag mag ## perrors \
+#F %-18.7g %-15.7g %-9.3f %-8.3f %-7d %-13s
+#
+#N POLYGONS PID OLDXMEAN OLDYMEAN XMEAN YMEAN MINRAD NVER \
+#U filename ## pixels pixels pixels pixels pixels ## \
+#F %-23s %-5d %-9.2f %-9.2f %-9.2f %-9.2f %-9.2f %-5d
+#
+#N XVERTEX YVERTEX \
+#U pixels pixels \
+#F %-12.2f %-9.2f
+#
+rot.N2903 186.64 195.51 1 nullfile 1 \
+ 187.70 198.05 1.06 2.54 0.00 0.01 27 Shift_too_big \
+ 11.29906 43.04229 33.70715 702 243 0 No_error \
+ 1. INDEF INDEF \
+ 412419.6 404.0344 11.974 0.003 0 No_error \
+ ell.N2903 1 186.64 195.51 187.70 198.05 17.77 14 \
+ 171.03 198.06 *\
+ 176.03 203.81 *\
+ 181.03 205.44 *\
+ 186.03 206.08 *\
+ 191.03 205.96 *\
+ 196.03 205.04 *\
+ 201.03 202.89 *\
+ 204.37 198.05 *\
+ 199.37 192.30 *\
+ 194.37 190.66 *\
+ 189.37 190.03 *\
+ 184.37 190.15 *\
+ 179.37 191.07 *\
+ 174.37 193.22 *
+rot.N2903 186.64 195.51 2 nullfile 2 \
+ 187.70 198.05 1.06 2.54 0.00 0.01 27 Shift_too_big \
+ 11.29906 43.04229 33.70715 702 243 0 No_error \
+ 1. INDEF INDEF \
+ 491112.9 1657.524 11.814 0.008 0 No_error \
+ ell.N2903 2 186.64 195.51 187.70 198.05 34.43 28 \
+ 154.37 198.06 *\
+ 159.37 206.55 *\
+ 164.37 209.57 *\
+ 169.37 211.52 *\
+ 174.37 212.83 *\
+ 179.37 213.67 *\
+ 184.37 214.10 *\
+ 189.37 214.16 *\
+ 194.37 213.86 *\
+ 199.37 213.16 *\
+ 204.37 212.02 *\
+ 209.37 210.31 *\
+ 214.37 207.73 *\
+ 219.37 203.09 *\
+ 221.03 198.05 *\
+ 216.03 189.56 *\
+ 211.03 186.54 *\
+ 206.03 184.59 *\
+ 201.03 183.27 *\
+ 196.03 182.44 *\
+ 191.03 182.01 *\
+ 186.03 181.95 *\
+ 181.03 182.25 *\
+ 176.03 182.95 *\
+ 171.03 184.09 *\
+ 166.03 185.80 *\
+ 161.03 188.38 *\
+ 156.03 193.02 *
+rot.N2903 186.64 195.51 3 nullfile 3 \
+ 187.70 198.05 1.06 2.54 0.00 0.01 27 Shift_too_big \
+ 11.29906 43.04229 33.70715 702 243 0 No_error \
+ 1. INDEF INDEF \
+ 692970.2 3752.306 11.467 0.011 0 No_error \
+ ell.N2903 3 186.64 195.51 187.70 198.05 51.10 42 \
+ 137.70 198.05 *\
+ 142.70 208.60 *\
+ 147.70 212.57 *\
+ 152.70 215.33 *\
+ 157.70 217.41 *\
+ 162.70 219.00 *\
+ 167.70 220.23 *\
+ 172.70 221.13 *\
+ 177.70 221.76 *\
+ 182.70 222.12 *\
+ 187.70 222.24 *\
+ 192.70 222.12 *\
+ 197.70 221.76 *\
+ 202.70 221.13 *\
+ 207.70 220.23 *\
+ 212.70 219.00 *\
+ 217.70 217.41 *\
+ 222.70 215.33 *\
+ 227.70 212.57 *\
+ 232.70 208.60 *\
+ 237.70 198.05 *\
+ 237.70 198.05 *\
+ 232.70 187.51 *\
+ 227.70 183.54 *\
+ 222.70 180.78 *\
+ 217.70 178.70 *\
+ 212.70 177.11 *\
+ 207.70 175.88 *\
+ 202.70 174.98 *\
+ 197.70 174.35 *\
+ 192.70 173.99 *\
+ 187.70 173.87 *\
+ 182.70 173.99 *\
+ 177.70 174.35 *\
+ 172.70 174.98 *\
+ 167.70 175.88 *\
+ 162.70 177.11 *\
+ 157.70 178.70 *\
+ 152.70 180.78 *\
+ 147.70 183.54 *\
+ 142.70 187.51 *\
+ 137.70 198.05 *
+rot.N2903 186.64 195.51 4 nullfile 4 \
+ 187.70 198.05 1.06 2.55 0.00 0.01 27 Shift_too_big \
+ 11.29906 43.04229 33.70715 702 243 0 No_error \
+ 1. INDEF INDEF \
+ 1187322. 6709.435 10.885 0.011 0 No_error \
+ ell.N2903 4 186.64 195.51 187.70 198.05 67.77 54 \
+ 121.03 198.06 *\
+ 126.03 210.31 *\
+ 131.03 215.05 *\
+ 136.03 218.44 *\
+ 141.03 221.09 *\
+ 146.03 223.23 *\
+ 151.03 224.99 *\
+ 156.03 226.44 *\
+ 161.03 227.62 *\
+ 166.03 228.56 *\
+ 171.03 229.28 *\
+ 176.03 229.81 *\
+ 181.03 230.15 *\
+ 186.03 230.30 *\
+ 191.03 230.27 *\
+ 196.03 230.05 *\
+ 201.03 229.66 *\
+ 206.03 229.06 *\
+ 211.03 228.27 *\
+ 216.03 227.25 *\
+ 221.03 225.99 *\
+ 226.03 224.44 *\
+ 231.03 222.57 *\
+ 236.03 220.27 *\
+ 241.03 217.41 *\
+ 246.03 213.67 *\
+ 251.03 208.13 *\
+ 254.37 198.04 *\
+ 249.37 185.80 *\
+ 244.37 181.06 *\
+ 239.37 177.67 *\
+ 234.37 175.02 *\
+ 229.37 172.88 *\
+ 224.37 171.12 *\
+ 219.37 169.67 *\
+ 214.37 168.50 *\
+ 209.37 167.55 *\
+ 204.37 166.83 *\
+ 199.37 166.30 *\
+ 194.37 165.96 *\
+ 189.37 165.81 *\
+ 184.37 165.84 *\
+ 179.37 166.06 *\
+ 174.37 166.45 *\
+ 169.37 167.05 *\
+ 164.37 167.84 *\
+ 159.37 168.86 *\
+ 154.37 170.12 *\
+ 149.37 171.67 *\
+ 144.37 173.55 *\
+ 139.37 175.84 *\
+ 134.37 178.70 *\
+ 129.37 182.44 *\
+ 124.37 187.98 *
+rot.N2903 186.64 195.51 5 nullfile 5 \
+ 187.70 198.05 1.06 2.54 0.00 0.01 27 Shift_too_big \
+ 11.29906 43.04229 33.70715 702 243 0 No_error \
+ 1. INDEF INDEF \
+ 1607853. 10511.2 10.568 0.013 0 No_error \
+ ell.N2903 5 186.64 195.51 187.70 198.05 84.43 68 \
+ 104.37 198.05 *\
+ 109.37 211.81 *\
+ 114.37 217.20 *\
+ 119.37 221.13 *\
+ 124.37 224.26 *\
+ 129.37 226.85 *\
+ 134.37 229.03 *\
+ 139.37 230.90 *\
+ 144.37 232.49 *\
+ 149.37 233.85 *\
+ 154.37 235.00 *\
+ 159.37 235.97 *\
+ 164.37 236.76 *\
+ 169.37 237.38 *\
+ 174.37 237.85 *\
+ 179.37 238.17 *\
+ 184.37 238.34 *\
+ 189.37 238.36 *\
+ 194.37 238.24 *\
+ 199.37 237.97 *\
+ 204.37 237.56 *\
+ 209.37 236.98 *\
+ 214.37 236.25 *\
+ 219.37 235.35 *\
+ 224.37 234.26 *\
+ 229.37 232.97 *\
+ 234.37 231.46 *\
+ 239.37 229.69 *\
+ 244.37 227.61 *\
+ 249.37 225.17 *\
+ 254.37 222.24 *\
+ 259.37 218.63 *\
+ 264.37 213.86 *\
+ 269.37 206.08 *\
+ 271.03 198.05 *\
+ 266.03 184.30 *\
+ 261.03 178.91 *\
+ 256.03 174.98 *\
+ 251.03 171.85 *\
+ 246.03 169.26 *\
+ 241.03 167.08 *\
+ 236.03 165.21 *\
+ 231.03 163.62 *\
+ 226.03 162.26 *\
+ 221.03 161.10 *\
+ 216.03 160.14 *\
+ 211.03 159.35 *\
+ 206.03 158.73 *\
+ 201.03 158.26 *\
+ 196.03 157.94 *\
+ 191.03 157.77 *\
+ 186.03 157.75 *\
+ 181.03 157.87 *\
+ 176.03 158.14 *\
+ 171.03 158.55 *\
+ 166.03 159.13 *\
+ 161.03 159.86 *\
+ 156.03 160.76 *\
+ 151.03 161.85 *\
+ 146.03 163.14 *\
+ 141.03 164.65 *\
+ 136.03 166.42 *\
+ 131.03 168.49 *\
+ 126.03 170.94 *\
+ 121.03 173.87 *\
+ 116.03 177.48 *\
+ 111.03 182.25 *\
+ 106.03 190.03 *
diff --git a/noao/digiphot/ptools/txcalc.par b/noao/digiphot/ptools/txcalc.par
new file mode 100644
index 00000000..d557d988
--- /dev/null
+++ b/noao/digiphot/ptools/txcalc.par
@@ -0,0 +1,6 @@
+# TXCALC Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text database(s)
+field,s,a,,,,Field to be edited
+value,s,a,,,,New value or expression for field
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txconcat.par b/noao/digiphot/ptools/txconcat.par
new file mode 100644
index 00000000..57249639
--- /dev/null
+++ b/noao/digiphot/ptools/txconcat.par
@@ -0,0 +1,6 @@
+# TXCONCAT Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text databases to be concatenated
+outfile,s,a,,,,Output apphot/daophot text database
+task,s,h,"TASK",,,Task name keyword
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txdump.par b/noao/digiphot/ptools/txdump.par
new file mode 100644
index 00000000..ce400817
--- /dev/null
+++ b/noao/digiphot/ptools/txdump.par
@@ -0,0 +1,8 @@
+# TXDUMP Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text database(s)
+fields,s,a,,,,Fields to be extracted
+expr,s,a,yes,,,Boolean expression for record selection
+headers,b,h,no,,,Print the field headers ?
+parameters,b,h,yes,,,Print the parameters if headers is yes ?
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txrenumber.par b/noao/digiphot/ptools/txrenumber.par
new file mode 100644
index 00000000..a9140216
--- /dev/null
+++ b/noao/digiphot/ptools/txrenumber.par
@@ -0,0 +1,6 @@
+# TXRENUMBER Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text database(s) to be renumbered
+idoffset,i,h,0,,,Id number offset
+id,s,h,ID,,,Id name keyword
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txselect.par b/noao/digiphot/ptools/txselect.par
new file mode 100644
index 00000000..080bc6d7
--- /dev/null
+++ b/noao/digiphot/ptools/txselect.par
@@ -0,0 +1,6 @@
+# TXSELECT Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text database(s)
+outfiles,s,a,,,,Output apphot/daophot text databases(s)
+expr,s,a,"yes",,,Boolean expression for record selection
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txsort.par b/noao/digiphot/ptools/txsort.par
new file mode 100644
index 00000000..95cc14e4
--- /dev/null
+++ b/noao/digiphot/ptools/txsort.par
@@ -0,0 +1,6 @@
+# TXSORT Parameters
+
+textfiles,s,a,,,,Input apphot/daophot text database(s) to be sorted
+field,s,a,MAG,,,Field to be sorted on
+ascend,b,h,yes,,,Sort in increasing value order?
+mode,s,h,"ql",,,Mode of task
diff --git a/noao/digiphot/ptools/txtools/mkpkg b/noao/digiphot/ptools/txtools/mkpkg
new file mode 100644
index 00000000..55485e70
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/mkpkg
@@ -0,0 +1,23 @@
+# TXTOOLS tasks
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ t_txconcat.x ../../lib/ptkeysdef.h <fset.h> <error.h>
+ t_txdump.x
+ ptxdump.x <fset.h> <error.h> <evexpr.h> ../../lib/ptkeysdef.h
+ t_txcalc.x <fset.h>
+ ptxcalc.x ../../lib/ptkeysdef.h <error.h> \
+ <ctype.h> <evexpr.h>
+ t_txrenumber.x <fset.h>
+ ptrenumb.x ../../lib/ptkeysdef.h
+ t_txsort.x <fset.h>
+ ptsortnum.x <ctype.h> ../../lib/ptkeysdef.h
+ ptqsort.x
+ t_txselect.x <fset.h>
+ ptxselect.x ../../lib/ptkeysdef.h <error.h> \
+ <ctype.h> <evexpr.h>
+ ;
diff --git a/noao/digiphot/ptools/txtools/ptqsort.x b/noao/digiphot/ptools/txtools/ptqsort.x
new file mode 100644
index 00000000..3883424f
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptqsort.x
@@ -0,0 +1,215 @@
+define LOGPTR 20 # log2(maxpts) (1e6)
+
+# PT_QSORT -- Vector Quicksort. In this version the index array is
+# sorted.
+
+procedure pt_qsortr (data, a, b, npix)
+
+real data[ARB] # data array
+int a[ARB], b[ARB] # index array
+int npix # number of pixels
+
+int i, j, lv[LOGPTR], p, uv[LOGPTR], temp
+real pivot
+
+begin
+ # Initialize the indices for an inplace sort.
+ do i = 1, npix
+ a[i] = i
+ call amovi (a, b, npix)
+
+ p = 1
+ lv[1] = 1
+ uv[1] = npix
+ while (p > 0) {
+
+ # If only one elem in subset pop stack otherwise pivot line.
+ if (lv[p] >= uv[p])
+ p = p - 1
+ else {
+ i = lv[p] - 1
+ j = uv[p]
+ pivot = data[b[j]]
+
+ while (i < j) {
+ for (i=i+1; data[b[i]] < pivot; i=i+1)
+ ;
+ for (j=j-1; j > i; j=j-1)
+ if (data[b[j]] <= pivot)
+ break
+ if (i < j) { # out of order pair
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+ }
+ }
+
+ j = uv[p] # move pivot to position i
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+
+ if (i-lv[p] < uv[p] - i) { # stack so shorter done first
+ lv[p+1] = lv[p]
+ uv[p+1] = i - 1
+ lv[p] = i + 1
+ } else {
+ lv[p+1] = i + 1
+ uv[p+1] = uv[p]
+ uv[p] = i - 1
+ }
+
+ p = p + 1 # push onto stack
+ }
+ }
+end
+
+
+# PT_QSORT -- Vector Quicksort. In this version the index array is
+# sorted.
+
+procedure pt_qsorti (data, a, b, npix)
+
+int data[ARB] # data array
+int a[ARB], b[ARB] # index array
+int npix # number of pixels
+
+int i, j, lv[LOGPTR], p, uv[LOGPTR], temp
+int pivot
+
+begin
+ # Initialize the indices for an inplace sort.
+ do i = 1, npix
+ a[i] = i
+ call amovi (a, b, npix)
+
+ p = 1
+ lv[1] = 1
+ uv[1] = npix
+ while (p > 0) {
+
+ # If only one elem in subset pop stack otherwise pivot line.
+ if (lv[p] >= uv[p])
+ p = p - 1
+ else {
+ i = lv[p] - 1
+ j = uv[p]
+ pivot = data[b[j]]
+
+ while (i < j) {
+ for (i=i+1; data[b[i]] < pivot; i=i+1)
+ ;
+ for (j=j-1; j > i; j=j-1)
+ if (data[b[j]] <= pivot)
+ break
+ if (i < j) { # out of order pair
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+ }
+ }
+
+ j = uv[p] # move pivot to position i
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+
+ if (i-lv[p] < uv[p] - i) { # stack so shorter done first
+ lv[p+1] = lv[p]
+ uv[p+1] = i - 1
+ lv[p] = i + 1
+ } else {
+ lv[p+1] = i + 1
+ uv[p+1] = uv[p]
+ uv[p] = i - 1
+ }
+
+ p = p + 1 # push onto stack
+ }
+ }
+end
+
+
+# PT_QSORT -- Vector Quicksort. In this version the index array is
+# sorted.
+
+procedure pt_qsortb (data, a, b, npix)
+
+bool data[ARB] # data array
+int a[ARB], b[ARB] # index array
+int npix # number of pixels
+
+int i, j, lv[LOGPTR], p, uv[LOGPTR], temp
+bool pivot
+int pt_compareb()
+
+begin
+ # Initialize the indices for an inplace sort.
+ do i = 1, npix
+ a[i] = i
+ call amovi (a, b, npix)
+
+ p = 1
+ lv[1] = 1
+ uv[1] = npix
+ while (p > 0) {
+
+ # If only one elem in subset pop stack otherwise pivot line.
+ if (lv[p] >= uv[p])
+ p = p - 1
+ else {
+ i = lv[p] - 1
+ j = uv[p]
+ pivot = data[b[j]]
+
+ while (i < j) {
+ #for (i=i+1; data[b[i]] != pivot; i=i+1)
+ for (i=i+1; pt_compareb (data[b[i]], pivot) < 0; i=i+1)
+ ;
+ for (j=j-1; j > i; j=j-1)
+ #if (data[b[j]] != pivot)
+ if (pt_compareb (data[b[j]], pivot) <= 0)
+ break
+ if (i < j) { # out of order pair
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+ }
+ }
+
+ j = uv[p] # move pivot to position i
+ temp = b[j] # interchange elements
+ b[j] = b[i]
+ b[i] = temp
+
+ if (i-lv[p] < uv[p] - i) { # stack so shorter done first
+ lv[p+1] = lv[p]
+ uv[p+1] = i - 1
+ lv[p] = i + 1
+ } else {
+ lv[p+1] = i + 1
+ uv[p+1] = uv[p]
+ uv[p] = i - 1
+ }
+
+ p = p + 1 # push onto stack
+ }
+ }
+end
+
+
+# PT_COMPAREB -- Compare to booleans for the sort routine.
+
+int procedure pt_compareb (a, b)
+
+bool a # first boolean
+bool b # second boolean
+
+begin
+ if (! a && b)
+ return (-1)
+ else if (a && ! b)
+ return (1)
+ else
+ return (0)
+end
diff --git a/noao/digiphot/ptools/txtools/ptrenumb.x b/noao/digiphot/ptools/txtools/ptrenumb.x
new file mode 100644
index 00000000..85fee34a
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptrenumb.x
@@ -0,0 +1,221 @@
+include "../../lib/ptkeysdef.h"
+
+# PT_RENUMBER -- Renumber the input file.
+
+int procedure pt_renumber (tp_in, tp_out, idoffset, id)
+
+int tp_in # the input text file descriptor
+int tp_out # the output text file descriptor
+int idoffset # the id number offset
+char id[ARB] # the name of the id column
+
+int first_rec, nunique, uunique, funique, record
+int ncontinue, recptr, nchars, field
+pointer key, line
+int getline(), strncmp(), pt_kstati()
+
+begin
+ # Initialize keyword structure.
+ call pt_kyinit (key)
+
+ # Initialize the file read.
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ record = 0
+ call malloc (line, SZ_LINE, TY_CHAR)
+
+ # Initilize the record read.
+ ncontinue = 0
+ recptr = 1
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ nchars = getline (tp_in, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ call putline (tp_out, Memc[line])
+ } else {
+ # skip lines beginning with # sign
+ call putline (tp_out, Memc[line])
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+
+ # skip blank lines
+ call putline (tp_out, Memc[line])
+
+ } else {
+
+ # Check that the ID column exists and its datatype is
+ # integer.
+
+ if (first_rec == YES) {
+ field = pt_kstati (key, id, KY_INDEX)
+ if (field <= 0)
+ break
+ if (pt_kstati (key, id, KY_DATATYPE) != TY_INT)
+ break
+ }
+
+ # Replace the ID string.
+ call pt_idreplace (key, field, 1, Memc[line], nchars,
+ record + idoffset + 1, first_rec, recptr, ncontinue)
+
+ # Write the output record.
+ call putline (tp_out, Memc[line])
+
+ # Do the record book-keeping.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Increment the record counter.
+ record = record + 1
+ first_rec = NO
+
+ # Reinitialize the record read.
+ ncontinue = 0
+ recptr = 1
+ }
+ }
+
+ }
+
+ # Cleanup.
+ call mfree (line, TY_CHAR)
+ call pt_kyfree (key)
+
+ return (record)
+end
+
+
+# PT_IDREPLACE -- Replace the id with the current record number.
+
+procedure pt_idreplace (key, field, element, line, nchars, record, first_rec,
+ recptr, ncontinue)
+
+pointer key # pointer to record structure
+int field # field to be fetched
+int element # field array element
+char line[ARB] # input line
+int nchars # length of line array
+int record # current record number
+int first_rec # first record
+int recptr # line per record index
+int ncontinue # number of unique lines per record
+
+int len, i, cip, nper_line, nokeys, nckeys, nkeys
+pointer sp, str
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # The number of header columns defined by #K at the beginning of
+ # the file is nokeys.
+ if (recptr == 1)
+ nokeys = KY_NPKEYS(key)
+
+ # Increment the continuation statement counter or reset to 0.
+ if (line[nchars-2] == '*')
+ ncontinue = ncontinue + 1
+ else
+ ncontinue = 0
+
+ # Replace the current id with the record number.
+ cip = 1
+ if (ncontinue < 1) {
+
+ nper_line = Memi[KY_NPLINE(key)+recptr-1]
+ nkeys = nokeys + nper_line
+ call amovki (int(1), Memi[KY_NELEMS(key)+nokeys], nper_line)
+
+ do i = nokeys + 1, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if (i == field) {
+ call sprintf (Memc[str], SZ_FNAME, "%*s")
+ call pargi (-len)
+ call pargi (record)
+ call amovc (Memc[str], line[cip], len)
+ }
+ cip = cip + len
+ }
+
+ recptr = recptr + 1
+ nokeys = nkeys
+
+ } else if (ncontinue == 1) {
+
+ nckeys = nokeys + 1
+ nkeys = nokeys + Memi[KY_NPLINE(key)+recptr-1]
+
+ if (first_rec == YES) {
+ Memi[KY_NCONTINUE(key)+recptr-1] = KY_NLINES
+ do i = nckeys, nkeys
+ call malloc (Memi[KY_PTRS(key)+i-1], KY_NLINES *
+ Memi[KY_KINDICES(key)+i-1], TY_CHAR)
+ }
+
+ do i = nckeys, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if ((i == field) && (element == 1)) {
+ call sprintf (Memc[str], SZ_FNAME, "%*s")
+ call pargi (-len)
+ call pargi (record)
+ call amovc (Memc[str], line[cip], len)
+ }
+ cip = cip + len
+ }
+
+ nokeys = nkeys
+ recptr = recptr + 1
+
+ } else {
+
+ if (ncontinue > Memi[KY_NCONTINUE(key)+recptr-2]) {
+ Memi[KY_NCONTINUE(key)+recptr-2] =
+ Memi[KY_NCONTINUE(key)+recptr-2] + KY_NLINES
+ do i = nckeys, nkeys
+ call realloc (Memi[KY_PTRS(key)+i-1],
+ Memi[KY_NCONTINUE(key)+recptr-2] *
+ Memi[KY_KINDICES(key)+i-1], TY_CHAR)
+ }
+
+ do i = nckeys, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if ((i == field) && (element == ncontinue)) {
+ call sprintf (Memc[str], SZ_FNAME, "%*s")
+ call pargi (-len)
+ call pargi (record)
+ call amovc (Memc[str], line[cip], len)
+ }
+ Memi[KY_NELEMS(key)+i-1] = ncontinue
+ cip = cip + len
+ }
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/ptsortnum.x b/noao/digiphot/ptools/txtools/ptsortnum.x
new file mode 100644
index 00000000..463b2f38
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptsortnum.x
@@ -0,0 +1,446 @@
+include <ctype.h>
+include "../../lib/ptkeysdef.h"
+
+# PT_SORTNUM -- Decode the column used for the sort, compute the file
+# record structure map, sort on the extracted column, reorder the
+# input file and write the output file.
+
+int procedure pt_sortnum (tp_in, tp_out, column, ascend)
+
+pointer tp_in # input Table descriptor
+pointer tp_out # output Table descriptor
+char column[ARB] # column name for sort
+int ascend # forward sort
+
+int coltype, colwidth, nrecs
+pointer key, colptr, colindex, recmap
+int pt_colmap()
+
+begin
+ # Initialize.
+ call pt_kyinit (key)
+ colptr = NULL
+ colindex = NULL
+ recmap = NULL
+
+ # Decode the sort column and map the record structure.
+ nrecs = pt_colmap (key, tp_in, tp_out, column, colptr, colindex,
+ coltype, colwidth, recmap)
+
+ # Sort the column and write the output file.
+ if (nrecs > 0) {
+ call pt_colsort (colptr, Memi[colindex], nrecs, coltype)
+ if (ascend == NO)
+ call pt_flipi (Memi[colindex], nrecs)
+ call pt_reorder (tp_in, tp_out, Memi[recmap], Memi[colindex], nrecs)
+ }
+
+ # Free space.
+ if (colptr != NULL)
+ call mfree (colptr, coltype)
+ if (colindex != NULL)
+ call mfree (colindex, TY_INT)
+ if (recmap != NULL)
+ call mfree (recmap, TY_INT)
+ call pt_kyfree (key)
+
+ return (nrecs)
+end
+
+
+define BUFSIZE 1000
+
+# PT_COLMAP -- Decode the column to be sorted and compute the record
+# structure of the file.
+
+int procedure pt_colmap (key, tp_in, tp_out, column, colptr, colindex, coltype,
+ bufwidth, recmap)
+
+pointer key # pointer to the database structure
+int tp_in # the input text file descriptor
+int tp_out # the output text file descriptor
+char column[ARB] # column to be sorted
+pointer colptr # pointer to extracted column array
+pointer colindex # pointer to index array for extracted column
+int coltype # data type of the column to be sorted
+int bufwidth # column width if chars
+pointer recmap # pointer to the record structure map
+
+int first_rec, nunique, uunique, funique, record
+int ncontinue, recptr, nchars, szbuf, colwidth, field, element
+long loffset, roffset
+pointer sp, line, name, value
+int getline(), strncmp(), pt_kstati()
+long note()
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+ call salloc (value, SZ_FNAME, TY_CHAR)
+
+ # Initialize the file read.
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ record = 0
+ szbuf = 0
+
+ # Initilize the record read.
+ ncontinue = 0
+ recptr = 1
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ loffset = note (tp_in)
+ nchars = getline (tp_in, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ if (first_rec == YES)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ call putline (tp_out, Memc[line])
+ } else {
+ # skip lines beginning with # sign
+ call putline (tp_out, Memc[line])
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # skip blank lines
+ call putline (tp_out, Memc[line])
+
+ } else {
+
+ # Get the variable index.
+ if (first_rec == YES) {
+ call pt_kid (column, Memc[name], element)
+ field = pt_kstati (key, Memc[name], KY_INDEX)
+ if (field <= 0)
+ break
+ }
+
+ # Save the offset of the beginning of the current record.
+ if (recptr == 1)
+ roffset = loffset
+
+ # Construct the data record.
+ call pt_kgfield (key, field, element, Memc[line], nchars,
+ Memc[value], first_rec, recptr, ncontinue)
+
+ # Decode the selected fields.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Select the appropriate column, get its datatype and
+ # allocate the appropriate space.
+
+ if (first_rec == YES) {
+ element = pt_kstati (key, column, KY_ELEMENT)
+ if (IS_INDEFI(element))
+ break
+ coltype = pt_kstati (key, column, KY_DATATYPE)
+ if (IS_INDEFI(coltype))
+ break
+ colwidth = pt_kstati (key, column, KY_LENGTH)
+ if (coltype == TY_CHAR)
+ bufwidth = colwidth + 1
+ else
+ bufwidth = 1
+ }
+
+ # Reallocate buffer space if necessary.
+ if (record >= szbuf) {
+ szbuf = szbuf + BUFSIZE
+ if (coltype == TY_CHAR)
+ call realloc (colptr, szbuf * bufwidth, TY_CHAR)
+ else
+ call realloc (colptr, szbuf, coltype)
+ call realloc (colindex, szbuf, TY_INT)
+ call realloc (recmap, szbuf, TY_INT)
+ }
+
+ # Decode the selected column.
+ record = record + 1
+ Memi[colindex+record-1] = 1 + (record - 1) * bufwidth
+ Memi[recmap+record-1] = roffset
+ call pt_gsrt (Memc[value], colptr, coltype, bufwidth,
+ record)
+ first_rec = NO
+
+ # Reinitialize the record read.
+ ncontinue = 0
+ recptr = 1
+ }
+ }
+
+ }
+
+ # Cleanup.
+ call sfree (sp)
+ return (record)
+end
+
+
+# PT_KGFIELD -- Fetch a single fields from the input file.
+
+procedure pt_kgfield (key, field, element, line, nchars, value, first_rec,
+ recptr, ncontinue)
+
+pointer key # pointer to record structure
+int field # field to be fetched
+int element # field array element
+char line[ARB] # input line
+int nchars # length of line array
+char value[ARB] # the field value
+int first_rec # first record
+int recptr # line per record index
+int ncontinue # number of unique lines per record
+
+int len, i, cip, nper_line, nokeys, nckeys, nkeys
+
+begin
+ # Fetch the value if it is a #K parameter as this will already
+ # be sorted in the key structure.
+
+ if ((recptr == 1) && (field <= KY_NPKEYS(key))) {
+ len = Memi[KY_KINDICES(key)+field-1]
+ call amovc (Memc[Memi[KY_PTRS(key)+field-1]], value, len)
+ value[len+1] = EOS
+ }
+
+ # The number of header columns defined by #K at the beginning of
+ # the file is nokeys.
+ if (recptr == 1)
+ nokeys = KY_NPKEYS(key)
+
+ # Increment the continuation statement counter or reset to 0.
+ if (line[nchars-2] == '*')
+ ncontinue = ncontinue + 1
+ else
+ ncontinue = 0
+
+ # Fill in the record.
+ cip = 1
+ if (ncontinue < 1) {
+
+ nper_line = Memi[KY_NPLINE(key)+recptr-1]
+ nkeys = nokeys + nper_line
+ call amovki (int(1), Memi[KY_NELEMS(key)+nokeys], nper_line)
+
+ do i = nokeys + 1, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if (i == field) {
+ call amovc (line[cip], value, len)
+ value[len+1] = EOS
+ }
+ cip = cip + len
+ }
+
+ recptr = recptr + 1
+ nokeys = nkeys
+
+ } else if (ncontinue == 1) {
+
+ nckeys = nokeys + 1
+ nkeys = nokeys + Memi[KY_NPLINE(key)+recptr-1]
+
+ if (first_rec == YES) {
+ Memi[KY_NCONTINUE(key)+recptr-1] = KY_NLINES
+ do i = nckeys, nkeys
+ call malloc (Memi[KY_PTRS(key)+i-1], KY_NLINES *
+ Memi[KY_KINDICES(key)+i-1], TY_CHAR)
+ }
+
+ do i = nckeys, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if ((i == field) && (element == 1)) {
+ call amovc (line[cip], value, len)
+ value[len+1] = EOS
+ }
+ cip = cip + len
+ }
+
+ nokeys = nkeys
+ recptr = recptr + 1
+
+ } else {
+
+ if (ncontinue > Memi[KY_NCONTINUE(key)+recptr-2]) {
+ Memi[KY_NCONTINUE(key)+recptr-2] =
+ Memi[KY_NCONTINUE(key)+recptr-2] + KY_NLINES
+ do i = nckeys, nokeys
+ call realloc (Memi[KY_PTRS(key)+i-1],
+ Memi[KY_NCONTINUE(key)+recptr-2] *
+ Memi[KY_KINDICES(key)+i-1], TY_CHAR)
+ }
+
+ do i = nckeys, nkeys {
+ len = Memi[KY_KINDICES(key)+i-1]
+ if ((i == field) && (element == ncontinue)) {
+ call amovc (line[cip], value, len)
+ value[len+1] = EOS
+ }
+ Memi[KY_NELEMS(key)+i-1] = ncontinue
+ cip = cip + len
+ }
+ }
+end
+
+
+# PT_COLSORT -- Sort the column.
+
+procedure pt_colsort (colptr, colindex, nrecs, coltype)
+
+pointer colptr # array of column pointers
+int colindex[ARB] # column indices
+int nrecs # number of records
+int coltype # column type
+
+begin
+ # Sort the column.
+ switch (coltype) {
+ case TY_INT:
+ call pt_qsorti (Memi[colptr], colindex, colindex, nrecs)
+ case TY_REAL:
+ call pt_qsortr (Memr[colptr], colindex, colindex, nrecs)
+ case TY_CHAR:
+ call strsrt (colindex, Memc[colptr], nrecs)
+ case TY_BOOL:
+ call pt_qsortb (Memb[colptr], colindex, colindex, nrecs)
+ }
+end
+
+
+# PT_REORDER -- Reorder the input file and write it to the output file.
+
+procedure pt_reorder (tp_in, tp_out, recmap, colindex, nrecs)
+
+int tp_in # input table file descriptor
+int tp_out # output file descriptor
+int recmap[ARB] # record strucuture map
+int colindex[ARB] # column index
+int nrecs # number of records
+
+int i
+long lptr
+pointer sp, line
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ do i = 1, nrecs {
+ lptr = recmap[colindex[i]]
+ call seek (tp_in, lptr)
+ call pt_rwrecord (tp_in, tp_out, Memc[line])
+ }
+
+ call sfree (sp)
+end
+
+
+# PT_GSRT -- Decode the column to be sorted.
+
+procedure pt_gsrt (value, colptr, coltype, colwidth, record)
+
+char value[ARB] # value to be decoded
+pointer colptr # pointer to the decode column
+int coltype # the data type of the sort column
+int colwidth # width of the column
+int record # the current record number
+
+int ip
+int ctoi(), ctor(), ctowrd()
+
+begin
+ # Decode the output value.
+ ip = 1
+ switch (coltype) {
+ case TY_INT:
+ if (ctoi (value, ip, Memi[colptr+record-1]) <= 0)
+ Memi[colptr+record-1] = INDEFI
+ case TY_REAL:
+ if (ctor (value, ip, Memr[colptr+record-1]) <= 0)
+ Memr[colptr+record-1] = INDEFR
+ case TY_BOOL:
+ while (IS_WHITE(value[ip]))
+ ip = ip + 1
+ switch (value[ip]) {
+ case 'Y', 'y':
+ Memb[colptr+record-1] = true
+ case 'N', 'n':
+ Memb[colptr+record-1] = false
+ default:
+ Memb[colptr+record-1] = false
+ }
+ case TY_CHAR:
+ if (ctowrd (value, ip, Memc[colptr+(record-1)*colwidth],
+ colwidth) <= 0)
+ Memc[colptr+(record-1)*colwidth] = EOS
+ default:
+ ;
+ }
+end
+
+
+# PT_FLIPI -- Filp an integer array in place.
+
+procedure pt_flipi (a, npix)
+
+int a[ARB] # array to be flipped
+int npix # number of pixels
+
+int i, nhalf, ntotal, itemp
+
+begin
+ nhalf = npix / 2
+ ntotal = npix + 1
+ do i = 1, nhalf {
+ itemp = a[i]
+ a[i] = a[ntotal-i]
+ a[ntotal-i] = itemp
+ }
+end
+
+
+# PT_RWRECORD -- Read a text record and write it out to the output file.
+
+procedure pt_rwrecord (tp_in, tp_out, line)
+
+int tp_in # input file descriptor
+int tp_out # output file descriptor
+char line[ARB] # line buffer
+
+int nchars
+int getline()
+
+begin
+ nchars = getline (tp_in, line)
+ while (nchars != EOF) {
+ call putline (tp_out, line)
+ if (line[nchars-1] != KY_CHAR_CONT)
+ break
+ nchars = getline (tp_in, line)
+ }
+end
diff --git a/noao/digiphot/ptools/txtools/ptxcalc.x b/noao/digiphot/ptools/txtools/ptxcalc.x
new file mode 100644
index 00000000..5e3d07ac
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptxcalc.x
@@ -0,0 +1,255 @@
+include <ctype.h>
+include <error.h>
+include <evexpr.h>
+include "../../lib/ptkeysdef.h"
+
+define LEN_LONGLINE 10
+
+# PT_XCALC -- Edit a field in a record using a value expression and a
+# a selection expression.
+
+int procedure pt_xcalc (tp_in, tp_out, field, value, expr)
+
+int tp_in # the input text file descriptor
+int tp_out # the output text file descriptor
+char field[ARB] # field to be edited
+char value[ARB] # the new value expression
+char expr[ARB] # the expression to be evaluated
+
+bool oexpr
+int first_rec, nunique, uunique, funique, fieldno, fieldtype, fieldlen
+int elem, record, editall, ncontinue, recptr, nchars, buflen, lenrecord
+int offset, fieldptr
+pointer key, lline, o, v, sp, line, name, newvalue, fmtstr
+
+bool streq()
+extern pt_getop()
+int getline(), strncmp(), pt_kstati(), pt_fmkrec()
+pointer evexpr(), locpr()
+errchk evexpr(), locpr(), pt_getop()
+
+begin
+ # Get some working space.
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+ call salloc (newvalue, SZ_FNAME, TY_CHAR)
+ call salloc (fmtstr, SZ_FNAME, TY_CHAR)
+
+ # Initialize keyword structure.
+ call pt_kyinit (key)
+
+ # Initialize the file read.
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ record = 0
+
+ # Initialize the buffers.
+ buflen = LEN_LONGLINE * SZ_LINE
+ call malloc (lline, buflen, TY_CHAR)
+
+ # Initilize the record read.
+ ncontinue = 0
+ recptr = 1
+ fieldptr = 0
+
+ # Initialize the expression decoding.
+ o = NULL
+ if (streq (expr, "yes") || streq (expr, "YES"))
+ editall = YES
+ else
+ editall = NO
+ v = NULL
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ nchars = getline (tp_in, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ call putline (tp_out, Memc[line])
+ } else {
+ # skip lines beginning with # sign
+ call putline (tp_out, Memc[line])
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # skip blank lines
+ call putline (tp_out, Memc[line])
+
+ } else {
+
+ # Set the record size and set the column to be altered.
+ if (recptr == 1) {
+ lenrecord = nchars
+ if (first_rec == YES) {
+ call pt_kid (field, Memc[name], elem)
+ fieldno = pt_kstati (key, Memc[name], KY_INDEX)
+ if (fieldno <= 0) {
+ call eprintf (
+ "Cannot find field %s in input file\n")
+ call pargstr (Memc[name])
+ break
+ }
+ fieldtype = pt_kstati (key, Memc[name], KY_DATATYPE)
+ if (fieldtype != TY_INT && fieldtype != TY_REAL) {
+ call eprintf ("Field %s is not numeric\n")
+ call pargstr (Memc[name])
+ break
+ }
+ fieldlen = pt_kstati (key, Memc[name], KY_LENGTH)
+ call pt_kstats (key, Memc[name], KY_FMTSTR,
+ Memc[fmtstr], SZ_FNAME)
+ }
+ } else
+ lenrecord = lenrecord + nchars
+
+ # Build the record.
+ offset = pt_fmkrec (key, fieldno, elem, Memc[line],
+ nchars, first_rec, recptr, ncontinue)
+ if (offset > 0)
+ fieldptr = lenrecord - nchars + offset
+
+ # Reallocate the temporary record space if necessary.
+ if (lenrecord > buflen) {
+ buflen = buflen + SZ_LINE
+ call realloc (lline, buflen, TY_CHAR)
+ }
+
+ # Store the record.
+ call amovc (Memc[line], Memc[lline+lenrecord-nchars], nchars)
+ Memc[lline+lenrecord] = EOS
+
+ # Do the record bookkeeping.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Evaluate the value and selection expression.
+ iferr {
+
+ if (editall == NO) {
+ call pt_apset (key)
+ o = evexpr (expr, locpr (pt_getop), 0)
+ if (O_TYPE(o) != TY_BOOL)
+ call error (0,
+ "Selection expression must be a boolean")
+ oexpr = O_VALB(o)
+ } else
+ oexpr = true
+
+ if (oexpr) {
+ call pt_apset (key)
+ v = evexpr (value, locpr (pt_getop), 0)
+ switch (fieldtype) {
+ case TY_BOOL:
+ if (O_TYPE(v) != TY_BOOL) {
+ call error (0,
+ "Value must be a boolean expression")
+ } else if (fieldptr > 0) {
+ call sprintf (Memc[newvalue], fieldlen,
+ Memc[fmtstr])
+ call pargb (O_VALB(v))
+ call amovc (Memc[newvalue],
+ Memc[lline+fieldptr-1], fieldlen)
+ }
+ case TY_INT:
+ if (O_TYPE(v) != TY_INT) {
+ call error (0,
+ "Value must be an integer expression")
+ } else if (fieldptr > 0) {
+ call sprintf (Memc[newvalue], fieldlen,
+ Memc[fmtstr])
+ call pargi (O_VALI(v))
+ call amovc (Memc[newvalue],
+ Memc[lline+fieldptr-1], fieldlen)
+ }
+ case TY_REAL:
+ if (O_TYPE(v) != TY_REAL) {
+ call error (0,
+ "Value must be a real expression")
+ } else if (fieldptr > 0) {
+ call sprintf (Memc[newvalue], fieldlen,
+ Memc[fmtstr])
+ call pargr (O_VALR(v))
+ call amovc (Memc[newvalue],
+ Memc[lline+fieldptr-1], fieldlen)
+ }
+ case TY_CHAR:
+ if (O_TYPE(v) != TY_CHAR) {
+ call error (0,
+ "Value must be a string expression")
+ } else if (fieldptr > 0) {
+ call sprintf (Memc[newvalue], fieldlen,
+ Memc[fmtstr])
+ call pargstr (O_VALC(v))
+ call amovc (Memc[newvalue],
+ Memc[lline+fieldptr-1], fieldlen)
+ }
+ default:
+ call error (0,
+ "Value expression is undefined")
+ }
+ }
+
+ } then {
+ call erract (EA_WARN)
+ call error (0,
+ "Error evaluating the value expression")
+ }
+
+ # Write out the record.
+ call putline (tp_out, Memc[lline])
+
+ # Increment the record counter.
+ record = record + 1
+ first_rec = NO
+
+ # Reinitialize the record read.
+ ncontinue = 0
+ recptr = 1
+ fieldptr = 0
+ if (o != NULL) {
+ call xev_freeop (o)
+ call mfree (o, TY_STRUCT)
+ }
+ o = NULL
+ if (v != NULL) {
+ call xev_freeop (v)
+ call mfree (v, TY_STRUCT)
+ }
+ v = NULL
+ }
+ }
+
+ }
+
+ # Cleanup.
+ call mfree (lline, TY_CHAR)
+ call sfree (sp)
+ call pt_kyfree (key)
+
+ return (record)
+end
diff --git a/noao/digiphot/ptools/txtools/ptxdump.x b/noao/digiphot/ptools/txtools/ptxdump.x
new file mode 100644
index 00000000..5d98f1e3
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptxdump.x
@@ -0,0 +1,421 @@
+include <fset.h>
+include <error.h>
+include <evexpr.h>
+include "../../lib/ptkeysdef.h"
+
+# PT_XDUMP -- Procedure to select records from a text file in apphot/daophot
+# format. This procedure reads through an apphot/daophot output file line by
+# line. The lines preceded by #K define the task parameters. These are
+# fields which do not often change during the execution of an apphot/daophot
+# task. The lines beginning with #N describe the fields in the output
+# record which change for each star. The lines beginning with #U describe
+# the units of each field, while those beginning with #F describe the format
+# of each field. Blank lines and lines beginning with # are ignored.
+
+procedure pt_xdump (fd, fields, expr, headers, parameters)
+
+int fd # text file descriptor
+char fields[ARB] # fields to be output
+char expr[ARB] # boolean expression to be evaluated
+int headers # format the output file ?
+int parameters # dump the parameters ?
+
+bool oexpr
+int nchars, nunique, uunique, funique, ncontinue, first_rec, recptr
+int nselect, szbuf, nmove, printall
+pointer sp, line, key, outline, o
+
+bool streq()
+extern pt_getop()
+int fstati(), getline(), strncmp(), pt_kszselbuf, pt_fmt(), pt_ffmt()
+pointer pt_choose(), evexpr(), locpr()
+errchk evexpr (), pt_getop()
+
+begin
+ # If the output has been redirected do not flush on a newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Allocate temporary space and space for the keyword structure.
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call pt_kyinit (key)
+
+ # Initialize counters.
+ nunique = 0
+ uunique = 0
+ funique = 0
+
+ # Setup the record counters. First_rec is set to NO after the first
+ # record is read. A record usually consists of several lines of text.
+ # A '\' in column 80 indicats that the current line is a part of
+ # the previous record. If there is a blank in column 80 the current
+ # line terminates the current record. In some cases the fields of a
+ # record may have more than one value, for example the magnitude field.
+ # These lines are marked by a '*\' in columns 79 and 80 respectively.
+
+ # The variable first_rec is set to NO after the first record is read.
+ # The variable recptr maintains a counter of the number of unique
+ # lines there are in a given record while ncontinue maintains a count
+ # of the number of times a given portion of the record is repeated.
+
+ # Initialize the record reading.
+ outline = NULL
+ first_rec = YES
+ recptr = 1
+ ncontinue = 0
+
+ # Initialize the expression decoding.
+ o = NULL
+ if (streq (expr, "yes")) {
+ oexpr = true
+ printall = YES
+ } else {
+ oexpr = false
+ printall = NO
+ }
+
+ # Loop over the text file records.
+ nchars = getline (fd, Memc[line])
+ while (nchars != EOF) {
+
+ # Determine the type of record. Add keywords to the database.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ if (headers == YES && parameters == YES)
+ call putline (STDOUT, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ } else if (headers == YES && parameters == YES) {
+ if (nunique == 0 || nunique != uunique || nunique !=
+ funique)
+ call putline (STDOUT, Memc[line])
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # Skip lines beginning with a newline
+
+ } else {
+
+ # Construct the record. This routine is called repeatedly
+ # until a record without the continuation character is
+ # encountered.
+
+ call pt_mkrec (key, Memc[line], nchars, first_rec, recptr,
+ ncontinue)
+
+ # Construct the output record when there is no terminating
+ # continuation char.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Select the appropriate records and compute the size of
+ # the output buffer. This routine only needs to be called
+ # once.
+
+ if (outline == NULL) {
+ nselect = pt_choose (key, fields)
+ if (nselect <= 0)
+ break
+ szbuf = pt_kszselbuf (key)
+ call malloc (outline, szbuf, TY_CHAR)
+ } else
+ Memc[outline] = EOS
+
+ # Evaluate the expression.
+ iferr {
+ if (printall == NO) {
+ call pt_apset (key)
+ o = evexpr (expr, locpr (pt_getop), 0)
+ if (O_TYPE(o) != TY_BOOL)
+ call error (0, "Expression must be a boolean")
+ oexpr = O_VALB(o)
+ }
+ } then {
+ call erract (EA_WARN)
+ call error (0, "Error evaluating selection expression")
+ }
+
+ if (first_rec == YES && headers == YES) {
+ call pt_fnstr (key, Memc[outline], szbuf)
+ call putline (STDOUT, Memc[outline])
+ call pt_fustr (key, Memc[outline], szbuf)
+ call putline (STDOUT, Memc[outline])
+ call pt_ffstr (key, Memc[outline], szbuf)
+ call putline (STDOUT, Memc[outline])
+ call putline (STDOUT, "#\n")
+ }
+
+ # Construct the output record.
+ if (oexpr) {
+ if (headers == YES)
+ nmove = pt_fmt (key, Memc[outline], szbuf)
+ else
+ nmove = pt_ffmt (key, Memc[outline], szbuf)
+ if (nmove > 0)
+ call putline (STDOUT, Memc[outline])
+ }
+
+ # Get ready for next record.
+ first_rec = NO
+ recptr = 1
+ ncontinue = 0
+ if (o != NULL) {
+ call xev_freeop (o)
+ call mfree (o, TY_STRUCT)
+ }
+ }
+ }
+
+ # Read the next line.
+ nchars = getline (fd, Memc[line])
+ }
+
+ # Free space.
+ call pt_kyfree (key)
+ if (outline != NULL)
+ call mfree (outline, TY_CHAR)
+ call sfree (sp)
+end
+
+
+# PT_FMT -- Procedure to format an apphot/daophot output record.
+
+int procedure pt_fmt (key, line, szbuf)
+
+pointer key # pointer to keys strucuture
+char line[ARB] # output line
+int szbuf # maximum buffer size
+
+char blank
+int i, op, kip, nk, index, elem, maxch
+data blank /' '/
+
+begin
+ # Add leading three blanks.
+ call strcpy (" ", line[1], 3)
+
+ # Move records.
+ op = 4
+ do i = 1, KY_NSELECT(key) {
+
+ # Find the key.
+ index = Memi[KY_SELECT(key)+i-1]
+ elem = Memi[KY_ELEM_SELECT(key)+i-1]
+ maxch = Memi[KY_LEN_SELECT(key)+i-1]
+ kip = Memi[KY_PTRS(key)+index-1] + (elem - 1) * maxch
+
+ # Trim leading whitespace.
+ for (nk = 0; Memc[kip] == ' ' && nk < maxch; nk = nk + 1)
+ kip = kip + 1
+
+ # Check the buffer size.
+ if ((op + maxch) >= szbuf)
+ break
+
+ # Copy value to output buffer.
+ call amovc (Memc[kip], line[op], maxch - nk)
+ op = op + maxch - nk
+ call amovkc (blank, line[op], nk)
+ op = op + nk
+ }
+
+ line[op] = '\n'
+ line[op+1] = EOS
+ return (op)
+end
+
+
+# PT_FFMT -- Procedure to free format an apphot output record.
+
+int procedure pt_ffmt (key, line, szbuf)
+
+pointer key # pointer to keys strucuture
+char line[ARB] # output line
+int szbuf # size of the output buffer
+
+int i, op, kip, nk, index, elem, maxch
+
+begin
+ op = 1
+ do i = 1, KY_NSELECT(key) {
+
+ # Find the key.
+ index = Memi[KY_SELECT(key)+i-1]
+ elem = Memi[KY_ELEM_SELECT(key)+i-1]
+ maxch = Memi[KY_LEN_SELECT(key)+i-1]
+ kip = Memi[KY_PTRS(key)+index-1] + (elem - 1) * maxch
+
+ # Trim leading whitespace.
+ for (nk = 0; Memc[kip] == ' ' && nk < maxch; nk = nk + 1)
+ kip = kip + 1
+
+ # Trim trailing whitesapce.
+ for (nk = 0; Memc[kip+nk] != ' ' && nk < maxch; nk = nk + 1)
+ ;
+
+ # Check buffer space.
+ if ((op + nk + 2) >= szbuf)
+ break
+
+ # Copy value to output buffer.
+ call amovc (Memc[kip], line[op], nk)
+ op = op + nk
+ line[op] = ' '
+ op = op + 1
+ line[op] = ' '
+ op = op + 1
+ }
+
+ if (op > 1) {
+ line[op-2] = '\n'
+ line[op-1] = EOS
+ return (op - 2)
+ } else {
+ line[1] = EOS
+ return (0)
+ }
+end
+
+
+# PT_FNSTR -- Format an apphot/daophot selected name string.
+
+procedure pt_fnstr (key, line, maxline)
+
+pointer key # pointer to keys strucuture
+char line[ARB] # output line
+int maxline # add new line every max lines
+
+int op, nchars
+int gstrcpy()
+
+begin
+ # Add leading three characters.
+ call strcpy (KY_CHAR_NAME, line[1], KY_LEN_STR)
+
+ # Copy the selected name string.
+ op = KY_LEN_STR + 1
+ nchars = gstrcpy (Memc[KY_NAME_SELECT(key)], line[op], maxline -
+ KY_LEN_STR)
+
+ # Add the newline and EOS character.
+ op = op + nchars
+ line[op] = '\n'
+ line[op+1] = EOS
+end
+
+
+# PT_FUSTR -- Format an apphot/daophot selected units string.
+
+procedure pt_fustr (key, line, maxline)
+
+pointer key # pointer to keys strucuture
+char line[ARB] # output line
+int maxline # add new line every max lines
+
+int op, nchars
+int gstrcpy()
+
+begin
+ # Add leading three blanks.
+ op = 1
+ call strcpy (KY_CHAR_UNITS, line[op], KY_LEN_STR)
+
+ # Copy the selected name string.
+ op = KY_LEN_STR + 1
+ nchars = gstrcpy (Memc[KY_UNIT_SELECT(key)], line[op], maxline -
+ KY_LEN_STR)
+
+ # Add the newline and EOS character.
+ op = op + nchars
+ line[op] = '\n'
+ line[op+1] = EOS
+end
+
+
+# PT_FFSTR -- Format an apphot selected format string.
+
+procedure pt_ffstr (key, line, maxline)
+
+pointer key # pointer to keys strucuture
+char line[ARB] # output line
+int maxline # add new line every max lines
+
+char ctype
+int fwidth, prec, type, op, nchars
+pointer sp, format
+int pt_kyfstr(), gstrcpy()
+
+begin
+ fwidth = Memi[KY_LEN_SELECT(key)]
+ call smark (sp)
+ call salloc (format, fwidth, TY_CHAR)
+
+ # Adjust the format of the first field to correct for the three
+ # blanks.
+ call strcpy (Memc[KY_FMT_SELECT(key)], Memc[format], fwidth)
+ if (pt_kyfstr (Memc[format], fwidth, prec, type, ctype) != ERR) {
+ if (type == TY_REAL) {
+ Memc[format] = '%'
+ call sprintf (Memc[format+1], fwidth - 1, "%d.%d%c%*t")
+ call pargi (-(fwidth+KY_LEN_STR))
+ call pargi (prec)
+ call pargc (ctype)
+ call pargi (fwidth)
+ } else {
+ Memc[format] = '%'
+ call sprintf (Memc[format+1], fwidth - 1, "%d%c%*t")
+ call pargi (-(fwidth+KY_LEN_STR))
+ call pargc (ctype)
+ call pargi (fwidth)
+ }
+ call amovc (Memc[format], Memc[KY_FMT_SELECT(key)], fwidth)
+ }
+
+ # Add leading three blanks.
+ op = 1
+ call strcpy (KY_CHAR_FORMAT, line[op], KY_LEN_STR)
+
+ # Copy the selected name string.
+ op = KY_LEN_STR + 1
+ nchars = gstrcpy (Memc[KY_FMT_SELECT(key)], line[op], maxline -
+ KY_LEN_STR)
+
+ # Add the newline and EOS character.
+ op = op + nchars
+ line[op] = '\n'
+ line[op+1] = EOS
+
+ call sfree (sp)
+end
+
+
+# PT_KSZSELBUF -- Compute the buffer size required to hold the output selected
+# line.
+
+int procedure pt_kszselbuf (key)
+
+pointer key # pointer to the keyword structure
+
+int i, szbuf
+
+begin
+ szbuf = 0
+
+ do i = 1, KY_NSELECT(key)
+ szbuf = szbuf + Memi[KY_LEN_SELECT(key)+i-1] + 2
+ szbuf = szbuf + 4
+
+ return (szbuf)
+end
diff --git a/noao/digiphot/ptools/txtools/ptxselect.x b/noao/digiphot/ptools/txtools/ptxselect.x
new file mode 100644
index 00000000..77990909
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/ptxselect.x
@@ -0,0 +1,160 @@
+include <ctype.h>
+include <error.h>
+include <evexpr.h>
+include "../../lib/ptkeysdef.h"
+
+define LEN_LONGLINE 10
+
+# PT_XSELECT -- Select records based on evaluating a logical expression.
+
+int procedure pt_xselect (tp_in, tp_out, expr)
+
+int tp_in # the input text file descriptor
+int tp_out # the output text file descriptor
+char expr[ARB] # the expression to be evaluated
+
+bool oexpr
+int first_rec, nunique, uunique, funique, record, printall
+int ncontinue, recptr, nchars, buflen, lenrecord
+pointer key, line, lline, o
+
+bool streq()
+extern pt_getop()
+int getline(), strncmp()
+pointer evexpr(), locpr()
+errchk evexpr(), pt_getop()
+
+begin
+ # Initialize keyword structure.
+ call pt_kyinit (key)
+
+ # Initialize the file read.
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ record = 0
+
+ # Initialize the buffers.
+ buflen = LEN_LONGLINE * SZ_LINE
+ call malloc (line, SZ_LINE, TY_CHAR)
+ call malloc (lline, buflen, TY_CHAR)
+
+ # Initilize the record read.
+ ncontinue = 0
+ recptr = 1
+
+ # Initialize the expression decoding.
+ o = NULL
+ if (streq (expr, "yes")) {
+ oexpr = true
+ printall = YES
+ } else {
+ oexpr = false
+ printall = NO
+ }
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ nchars = getline (tp_in, Memc[line])
+ if (nchars == EOF)
+ break
+
+ # Determine the type of record.
+ if (Memc[line] == KY_CHAR_POUND) {
+
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) == 0) {
+ call pt_kyadd (key, Memc[line], nchars)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_NAME,
+ KY_LEN_STR) == 0) {
+ nunique = nunique + 1
+ call pt_kname (key, Memc[line], nchars, nunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_UNITS,
+ KY_LEN_STR) == 0) {
+ uunique = uunique + 1
+ call pt_knunits (key, Memc[line], nchars, uunique)
+ call putline (tp_out, Memc[line])
+ } else if (strncmp (Memc[line], KY_CHAR_FORMAT,
+ KY_LEN_STR) == 0) {
+ funique = funique + 1
+ call pt_knformats (key, Memc[line], nchars, funique)
+ call putline (tp_out, Memc[line])
+ } else {
+ # skip lines beginning with # sign
+ call putline (tp_out, Memc[line])
+ }
+
+ } else if (Memc[line] == KY_CHAR_NEWLINE) {
+ # skip blank lines
+ call putline (tp_out, Memc[line])
+
+ } else {
+
+ # Reset the record size.
+ if (recptr == 1)
+ lenrecord = nchars
+ else
+ lenrecord = lenrecord + nchars
+
+ # Build the record.
+ call pt_mkrec (key, Memc[line], nchars, first_rec, recptr,
+ ncontinue)
+
+ # Reallocate the temporary record space.
+ if (lenrecord > buflen) {
+ buflen = buflen + SZ_LINE
+ call realloc (lline, buflen, TY_CHAR)
+ }
+
+ # Store the record.
+ call amovc (Memc[line], Memc[lline+lenrecord-nchars], nchars)
+ Memc[lline+lenrecord] = EOS
+
+ # Do the record bookkeeping.
+ if (Memc[line+nchars-2] != KY_CHAR_CONT) {
+
+ # Evaluate the expression.
+ iferr {
+ if (printall == NO) {
+ call pt_apset (key)
+ o = evexpr (expr, locpr (pt_getop), 0)
+ if (O_TYPE(o) != TY_BOOL)
+ call error (0, "Expression must be a boolean")
+ oexpr = O_VALB(o)
+ }
+ } then {
+ call erract (EA_WARN)
+ call error (0, "Error evaluating selection expression")
+ }
+
+ # Write out the expression.
+ if (oexpr)
+ call putline (tp_out, Memc[lline])
+
+ # Increment the record counter.
+ record = record + 1
+ first_rec = NO
+
+ # Reinitialize the record read.
+ ncontinue = 0
+ recptr = 1
+ if (o != NULL) {
+ call xev_freeop (o)
+ call mfree (o, TY_STRUCT)
+ }
+ }
+ }
+
+ }
+
+ # Cleanup.
+ call mfree (line, TY_CHAR)
+ call mfree (lline, TY_CHAR)
+ call pt_kyfree (key)
+
+ return (record)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txcalc.x b/noao/digiphot/ptools/txtools/t_txcalc.x
new file mode 100644
index 00000000..2c7c39db
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txcalc.x
@@ -0,0 +1,65 @@
+include <fset.h>
+
+# T_TXCALC -- Edit a field in an APPHOT/DAOPHOT text data base using a
+# value expression.
+
+procedure t_txcalc ()
+
+pointer infile # the input file list
+pointer outfile # the output file list
+pointer field # pointer to the field to be edited
+pointer value # pointer to the value expression string
+
+int inlist, tp_in, tp_out, nrecs
+pointer sp
+int clpopnu(), access(), open(), fstati(), clgfil(), pt_xcalc()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some memory.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (outfile, SZ_FNAME, TY_CHAR)
+ call salloc (field, SZ_FNAME, TY_CHAR)
+ call salloc (value, SZ_LINE, TY_CHAR)
+
+ # Get the various task parameters.
+ inlist = clpopnu ("textfiles")
+ #outlist = clpopnu ("outfiles")
+ call clgstr ("field", Memc[field], SZ_FNAME)
+ call strupr (Memc[field])
+ call clgstr ("value", Memc[value], SZ_LINE)
+
+ while (clgfil (inlist, Memc[infile], SZ_FNAME) != EOF) {
+
+ # Open the input file.
+ if (access (Memc[infile], 0, TEXT_FILE) == YES)
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ else
+ call error (0, "The input file is a binary file.")
+
+ # Open an output text file.
+ call mktemp ("temp", Memc[outfile], SZ_FNAME)
+ tp_out = open (Memc[outfile], NEW_FILE, TEXT_FILE)
+
+ # Select the stars.
+ nrecs = pt_xcalc (tp_in, tp_out, Memc[field], Memc[value], "yes")
+
+ # Close up the input and output files.
+ call close (tp_in)
+ call close (tp_out)
+
+ if (nrecs <= 0) {
+ call delete (Memc[outfile])
+ } else {
+ call delete (Memc[infile])
+ call rename (Memc[outfile], Memc[infile])
+ }
+ }
+
+ call clpcls (inlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txconcat.x b/noao/digiphot/ptools/txtools/t_txconcat.x
new file mode 100644
index 00000000..cae8354b
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txconcat.x
@@ -0,0 +1,128 @@
+include <fset.h>
+include <error.h>
+include "../../lib/ptkeysdef.h"
+
+# T_TXCONCAT -- Procedure to concatenate standard APPHOT and DAOPHOT text
+# output files into a single file. The task checks to see that the list
+# of input files was produced by the same task.
+
+procedure t_txconcat()
+
+int list # input file list descriptor
+int tp_in # input file descriptor
+int tp_out # output file descriptor
+
+int len_list, first_file, stat
+pointer sp, infile, outfile, task, task1, task2
+int fstati(), clpopnu(), clplen(), open(), clgfil(), strncmp()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some memory.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (outfile, SZ_FNAME, TY_CHAR)
+ call salloc (task, SZ_FNAME, TY_CHAR)
+ call salloc (task1, SZ_FNAME, TY_CHAR)
+ call salloc (task2, SZ_FNAME, TY_CHAR)
+
+ # Get the task parameters.
+ list = clpopnu ("textfiles")
+ len_list = clplen (list)
+ if (len_list <= 0)
+ call error (0, "Empty input file list.\n")
+ else if (len_list == 1)
+ call error (0, "Input file list has only one file.\n")
+ call clgstr ("outfile", Memc[outfile], SZ_FNAME)
+ call clgstr ("task", Memc[task], SZ_FNAME)
+
+ # Loop over the input files to check the task keyword.
+ first_file = YES
+ stat = OK
+ while (clgfil (list, Memc[infile], SZ_FNAME) != EOF) {
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ if (first_file == YES) {
+ call pt_gtaskname (tp_in, Memc[task], Memc[task1], SZ_FNAME)
+ if (Memc[task1] == EOS) {
+ call eprintf (
+ "File: %s is not an APPHOT/DAOPHOT text database file")
+ call pargstr (Memc[infile])
+ stat = ERR
+ }
+ first_file = NO
+ } else {
+ call pt_gtaskname (tp_in, Memc[task], Memc[task2], SZ_FNAME)
+ if (Memc[task2] == EOS) {
+ call eprintf (
+ "File: %s is not an APPHOT/DAOPHOT text database file\n")
+ call pargstr (Memc[infile])
+ stat = ERR
+ }
+ if (strncmp (Memc[task1], Memc[task2], SZ_FNAME) != 0) {
+ call eprintf (
+ "TASK keyword is not the same for all input files\n")
+ stat = ERR
+ }
+ }
+ call close (tp_in)
+ if (stat == ERR)
+ break
+ }
+ call clprew (list)
+
+ # Loop over the input text files and copy each file to the output
+ # file.
+ if (stat == OK) {
+ tp_out = open (Memc[outfile], NEW_FILE, TEXT_FILE)
+ while (clgfil (list, Memc[infile], SZ_FNAME) != EOF) {
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ call fcopyo (tp_in, tp_out)
+ call close (tp_in)
+ }
+ call close (tp_out)
+ }
+
+ call clpcls (list)
+ call sfree (sp)
+end
+
+
+# PT_GTASKNAME -- Fetch a task name from an APPHOT/DAOPHOT text file.
+
+procedure pt_gtaskname (tp_in, name, outname, maxch)
+
+int tp_in # input file descriptor
+char name[ARB] # task keyword
+char outname[ARB] # output task name
+int maxch # maximum number of characters
+
+int findex, lindex
+pointer sp, line
+int getline(), strncmp(), gstrmatch(), ctowrd()
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ outname[1] = EOS
+ while (getline (tp_in, Memc[line]) != EOF) {
+ if (Memc[line] != KY_CHAR_POUND)
+ break
+ if (strncmp (Memc[line], KY_CHAR_KEYWORD, KY_LEN_STR) != 0)
+ next
+ if (gstrmatch (Memc[line], name, findex, lindex) == 0)
+ next
+ lindex = lindex + 1
+ if (ctowrd (Memc[line], lindex, outname, maxch) <= 0)
+ break
+ lindex = lindex + 1
+ if (ctowrd (Memc[line], lindex, outname, maxch) <= 0)
+ outname[1] = EOS
+ break
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txdump.x b/noao/digiphot/ptools/txtools/t_txdump.x
new file mode 100644
index 00000000..8d2b332e
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txdump.x
@@ -0,0 +1,45 @@
+# T_TXDUMP -- Procedure to perform a relational select operation upon a set of
+# records within a text file. Our function is to select all records from the
+# input file matching some criterion, printing the listed fields on the
+# standard output. Dumping the keywords and reheadersting is optional.
+
+procedure t_txdump ()
+
+pointer textfile # list of input text files
+pointer fields # list of fields to be dumped
+pointer expr # boolean expression to be evaluated
+int headers # format the output
+int parameters # print the headers
+
+int list, fd
+pointer sp
+bool clgetb()
+int clpopnu(), clgfil(), open(), btoi()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (textfile, SZ_FNAME, TY_CHAR)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (expr, SZ_LINE, TY_CHAR)
+
+ # Get the parameters.
+ list = clpopnu ("textfiles")
+ call clgstr ("fields", Memc[fields], SZ_LINE)
+ call strupr (Memc[fields])
+ call clgstr ("expr", Memc[expr], SZ_LINE)
+ headers = btoi (clgetb ("headers"))
+ parameters = btoi (clgetb ("parameters"))
+
+ # Select records.
+ while (clgfil (list, Memc[textfile], SZ_FNAME) != EOF) {
+ fd = open (Memc[textfile], READ_ONLY, TEXT_FILE)
+ if (Memc[fields] != EOS)
+ call pt_xdump (fd, Memc[fields], Memc[expr], headers,
+ parameters)
+ call close (fd)
+ }
+
+ call clpcls (list)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txrenumber.x b/noao/digiphot/ptools/txtools/t_txrenumber.x
new file mode 100644
index 00000000..2b41d541
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txrenumber.x
@@ -0,0 +1,65 @@
+include <fset.h>
+
+# T_TXRENUMBER -- Procedure to renumber standard APPHOT and DAOPHOT text
+# output files. The ST TTOOLS task can be used for binary format.
+# The program assumes that there is a column labelled ID.
+
+procedure t_txrenumber ()
+
+pointer tp_in # pointer to the input table
+pointer tp_out # pointer to the output table
+pointer id # name of the id column
+
+int inlist, nrecs, idoffset
+pointer sp, infile, outfile
+int clpopnu(), clgeti(), clgfil(), access(), open(), fstati(), pt_renumber()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some memory.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (outfile, SZ_FNAME, TY_CHAR)
+ call salloc (id, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ inlist = clpopnu ("textfiles")
+ idoffset = clgeti ("idoffset")
+ call clgstr ("id", Memc[id], SZ_FNAME)
+ call strlwr (Memc[id])
+
+ # Loop over the input files.
+ while (clgfil (inlist, Memc[infile], SZ_FNAME) != EOF) {
+
+ # Open the input file.
+ if (access (Memc[infile], 0, TEXT_FILE) == YES)
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ else
+ next
+
+ # Open an output text file.
+ call mktemp ("temp", Memc[outfile], SZ_FNAME)
+ tp_out = open (Memc[outfile], NEW_FILE, TEXT_FILE)
+
+ # Renumber the stars.
+ nrecs = pt_renumber (tp_in, tp_out, idoffset, Memc[id])
+
+ # Close up the input and output files.
+ call close (tp_in)
+ call close (tp_out)
+
+ # Rename the files.
+ if (nrecs <= 0)
+ call delete (Memc[outfile])
+ else {
+ call delete (Memc[infile])
+ call rename (Memc[outfile], Memc[infile])
+ }
+ }
+
+ call clpcls (inlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txselect.x b/noao/digiphot/ptools/txtools/t_txselect.x
new file mode 100644
index 00000000..3dee8a51
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txselect.x
@@ -0,0 +1,64 @@
+include <fset.h>
+
+# T_TXSELECT -- Select records from an APPHOT file based on the value of
+# a logical expression.
+
+procedure t_txselect ()
+
+int tp_in # input file descriptor
+int tp_out # output file descriptor
+pointer expr # pointer to the expression string
+
+int inlist, outlist
+pointer sp, infile, outfile
+int clpopnu(), clplen(), access(), open(), fstati(), clgfil(), pt_xselect()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some memory.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (outfile, SZ_FNAME, TY_CHAR)
+ call salloc (expr, SZ_LINE, TY_CHAR)
+
+ # Get the various task parameters.
+ inlist = clpopnu ("textfiles")
+ outlist = clpopnu ("outfiles")
+ call clgstr ("expr", Memc[expr], SZ_LINE)
+
+ # Check that the input and output file lists have the
+ # same length.
+ if (clplen (inlist) != clplen (outlist))
+ call error (0,
+ "Input and output file lists are not the same length")
+
+ while ((clgfil (inlist, Memc[infile], SZ_FNAME) != EOF) &&
+ (clgfil (outlist, Memc[outfile], SZ_FNAME) != EOF)) {
+
+ # Open the input file.
+ if (access (Memc[infile], 0, TEXT_FILE) == YES)
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ else
+ call error (0, "The input file is a binary file.")
+
+ # Open an output text file.
+ tp_out = open (Memc[outfile], NEW_FILE, TEXT_FILE)
+
+ # Select the stars.
+ if (pt_xselect (tp_in, tp_out, Memc[expr]) <= 0) {
+ call eprintf ("File: %s is empty\n")
+ call pargstr (Memc[infile])
+ }
+
+ # Close up the input and output files.
+ call close (tp_in)
+ call close (tp_out)
+ }
+
+ call clpcls (inlist)
+ call clpcls (outlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/txtools/t_txsort.x b/noao/digiphot/ptools/txtools/t_txsort.x
new file mode 100644
index 00000000..4635a881
--- /dev/null
+++ b/noao/digiphot/ptools/txtools/t_txsort.x
@@ -0,0 +1,65 @@
+include <fset.h>
+
+# T_TXSORT -- Procedure to sort standard APPHOT and DAOPHOT text
+# output files. The ST TTOOLS task can be used for binary format.
+
+procedure t_txsort ()
+
+int tp_in # input file descriptor
+int tp_out # input file descriptor
+
+int inlist, ascend, nrecs
+pointer sp, infile, outfile, column
+bool clgetb()
+int clpopnu(), clgfil(), access(), btoi(), open(), fstati(), pt_sortnum()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some memory.
+ call smark (sp)
+ call salloc (infile, SZ_FNAME, TY_CHAR)
+ call salloc (outfile, SZ_FNAME, TY_CHAR)
+ call salloc (column, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ inlist = clpopnu ("textfiles")
+ call clgstr ("field", Memc[column], SZ_FNAME)
+ ascend = btoi (clgetb ("ascend"))
+
+ # Check the column on which to sort.
+ call strlwr (Memc[column])
+ if (Memc[column] == EOS)
+ call error (0, "The sort column is undefined.")
+
+ while (clgfil (inlist, Memc[infile], SZ_FNAME) != EOF) {
+
+ # Open the input file.
+ if (access (Memc[infile], 0, TEXT_FILE) == YES)
+ tp_in = open (Memc[infile], READ_ONLY, TEXT_FILE)
+ else
+ call error (0, "The input file is not a text file.")
+
+ # Open an output text file.
+ call mktemp ("temp", Memc[outfile], SZ_FNAME)
+ tp_out = open (Memc[outfile], NEW_FILE, TEXT_FILE)
+
+ # Sort the stars.
+ nrecs = pt_sortnum (tp_in, tp_out, Memc[column], ascend)
+
+ # Close up the input and output files.
+ call close (tp_in)
+ call close (tp_out)
+ if (nrecs <= 0)
+ call delete (Memc[outfile])
+ else {
+ call delete (Memc[infile])
+ call rename (Memc[outfile], Memc[infile])
+ }
+ }
+
+ call clpcls (inlist)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/ptools/x_ptools.x b/noao/digiphot/ptools/x_ptools.x
new file mode 100644
index 00000000..25ecc59d
--- /dev/null
+++ b/noao/digiphot/ptools/x_ptools.x
@@ -0,0 +1,11 @@
+task pconvert = t_pconvert,
+ istable = t_istable,
+ pexamine = t_pexamine,
+ tbcrename = t_tbcrename,
+ tbkeycol = t_tbkeycol,
+ txconcat = t_txconcat,
+ txcalc = t_txcalc,
+ txdump = t_txdump,
+ txrenumber = t_txrenumber,
+ txselect = t_txselect,
+ txsort = t_txsort
diff --git a/noao/digiphot/ptools/xyplot.par b/noao/digiphot/ptools/xyplot.par
new file mode 100644
index 00000000..3ae725b0
--- /dev/null
+++ b/noao/digiphot/ptools/xyplot.par
@@ -0,0 +1,20 @@
+# The PEXAMINE task x-y plot parameters
+
+x1,r,h,INDEF,,,Left world x-coord if not autoscaling
+x2,r,h,INDEF,,,Right world x-coord if not autoscaling
+y1,r,h,INDEF,,,Lower world y-coord if not autoscaling
+y2,r,h,INDEF,,,Upper world y-coord if not autoscaling
+marker,s,h,"box","point|box|plus|cross|circle|diamond|hline|vline",,Marker type
+szmarker,r,h,1.0,0.0,,Marker size
+logx,b,h,no,,,Log scale the x axis?
+logy,b,h,no,,,Log scale the y axis?
+box,b,h,yes,,,Draw box around periphery of window?
+ticklabels,b,h,yes,,,Label tick marks?
+majrx,i,h,5,,,Number of major divisions along x axis
+minrx,i,h,5,,,Number of minor divisions along x axis
+majry,i,h,5,,,Number of major divisions along y axis
+minry,i,h,5,,,Number of minor divisions along y axis
+round,b,h,no,,,Round axes to nice values?
+fill,b,h,yes,,,Fill viewport vs enforce unity aspect ratio?
+grid,b,h,no,,,Draw grid lines at major tick marks?
+banner,b,h,yes,,,Standard banner?