aboutsummaryrefslogtreecommitdiff
path: root/noao/digiphot/daophot
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /noao/digiphot/daophot
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'noao/digiphot/daophot')
-rw-r--r--noao/digiphot/daophot/README32
-rw-r--r--noao/digiphot/daophot/Revisions918
-rw-r--r--noao/digiphot/daophot/addstar.par23
-rw-r--r--noao/digiphot/daophot/addstar/dpadconfirm.x14
-rw-r--r--noao/digiphot/daophot/addstar/dpaddrd.x89
-rw-r--r--noao/digiphot/daophot/addstar/dpartstar.x303
-rw-r--r--noao/digiphot/daophot/addstar/dpnaddstar.x265
-rw-r--r--noao/digiphot/daophot/addstar/mkpkg17
-rw-r--r--noao/digiphot/daophot/addstar/t_addstar.x331
-rw-r--r--noao/digiphot/daophot/allstar.par19
-rw-r--r--noao/digiphot/daophot/allstar/dpabuf.x495
-rw-r--r--noao/digiphot/daophot/allstar/dpaconfirm.x37
-rw-r--r--noao/digiphot/daophot/allstar/dpalinit.x665
-rw-r--r--noao/digiphot/daophot/allstar/dpalmemstar.x182
-rw-r--r--noao/digiphot/daophot/allstar/dpalphot.x1438
-rw-r--r--noao/digiphot/daophot/allstar/dpalwrite.x556
-rw-r--r--noao/digiphot/daophot/allstar/dpastar.x327
-rw-r--r--noao/digiphot/daophot/allstar/dpcache.x244
-rw-r--r--noao/digiphot/daophot/allstar/dpglim.x17
-rw-r--r--noao/digiphot/daophot/allstar/dprectify.x74
-rw-r--r--noao/digiphot/daophot/allstar/dpregroup.x219
-rw-r--r--noao/digiphot/daophot/allstar/mkpkg32
-rw-r--r--noao/digiphot/daophot/allstar/t_allstar.x355
-rw-r--r--noao/digiphot/daophot/centerpars.par12
-rw-r--r--noao/digiphot/daophot/daoedit.par9
-rw-r--r--noao/digiphot/daophot/daoedit/daoedit.h123
-rw-r--r--noao/digiphot/daophot/daoedit/daoedit.key26
-rw-r--r--noao/digiphot/daophot/daoedit/dpecolon.x441
-rw-r--r--noao/digiphot/daophot/daoedit/dpeconfirm.x433
-rw-r--r--noao/digiphot/daophot/daoedit/dpemark.x734
-rw-r--r--noao/digiphot/daophot/daoedit/dpeomark.x68
-rw-r--r--noao/digiphot/daophot/daoedit/dperplot.x172
-rw-r--r--noao/digiphot/daophot/daoedit/dperprofile.x590
-rw-r--r--noao/digiphot/daophot/daoedit/idaoedit.key22
-rw-r--r--noao/digiphot/daophot/daoedit/mkpkg16
-rw-r--r--noao/digiphot/daophot/daoedit/t_daoedit.x317
-rw-r--r--noao/digiphot/daophot/daofind.par21
-rw-r--r--noao/digiphot/daophot/daolib/bicubic.x47
-rw-r--r--noao/digiphot/daophot/daolib/daoran.x43
-rw-r--r--noao/digiphot/daophot/daolib/dpairmass.x42
-rw-r--r--noao/digiphot/daophot/daolib/dpapheader.x56
-rw-r--r--noao/digiphot/daophot/daolib/dpdate.x28
-rw-r--r--noao/digiphot/daophot/daolib/dpfilter.x41
-rw-r--r--noao/digiphot/daophot/daolib/dpfree.x71
-rw-r--r--noao/digiphot/daophot/daolib/dpgetapert.x530
-rw-r--r--noao/digiphot/daophot/daolib/dpgppars.x227
-rw-r--r--noao/digiphot/daophot/daolib/dpgsubrast.x32
-rw-r--r--noao/digiphot/daophot/daolib/dpgsvw.x162
-rw-r--r--noao/digiphot/daophot/daolib/dpimkeys.x71
-rw-r--r--noao/digiphot/daophot/daolib/dpinit.x225
-rw-r--r--noao/digiphot/daophot/daolib/dpnames.x415
-rw-r--r--noao/digiphot/daophot/daolib/dpotime.x51
-rw-r--r--noao/digiphot/daophot/daolib/dppadu.x36
-rw-r--r--noao/digiphot/daophot/daolib/dppcache.x83
-rw-r--r--noao/digiphot/daophot/daolib/dpppars.x94
-rw-r--r--noao/digiphot/daophot/daolib/dprdnoise.x36
-rw-r--r--noao/digiphot/daophot/daolib/dpreadpsf.x138
-rw-r--r--noao/digiphot/daophot/daolib/dprmwhite.x22
-rw-r--r--noao/digiphot/daophot/daolib/dpset.x181
-rw-r--r--noao/digiphot/daophot/daolib/dpstat.x180
-rw-r--r--noao/digiphot/daophot/daolib/dpverify.x563
-rw-r--r--noao/digiphot/daophot/daolib/dpwcs.x234
-rw-r--r--noao/digiphot/daophot/daolib/dpwparam.x98
-rw-r--r--noao/digiphot/daophot/daolib/erf.x81
-rw-r--r--noao/digiphot/daophot/daolib/invers.f112
-rw-r--r--noao/digiphot/daophot/daolib/invers2.x72
-rw-r--r--noao/digiphot/daophot/daolib/mkpkg48
-rw-r--r--noao/digiphot/daophot/daolib/mvmul.x48
-rw-r--r--noao/digiphot/daophot/daolib/pctile.f91
-rw-r--r--noao/digiphot/daophot/daolib/profile.x506
-rw-r--r--noao/digiphot/daophot/daolib/quick.f202
-rw-r--r--noao/digiphot/daophot/daolib/ran3.x63
-rw-r--r--noao/digiphot/daophot/daolib/usepsf.x81
-rw-r--r--noao/digiphot/daophot/daopars.par25
-rw-r--r--noao/digiphot/daophot/daophot.cl77
-rw-r--r--noao/digiphot/daophot/daophot.hd42
-rw-r--r--noao/digiphot/daophot/daophot.men31
-rw-r--r--noao/digiphot/daophot/daophot.par13
-rw-r--r--noao/digiphot/daophot/daotest.cl308
-rw-r--r--noao/digiphot/daophot/datapars.par25
-rw-r--r--noao/digiphot/daophot/doc/addstar.hlp365
-rw-r--r--noao/digiphot/daophot/doc/allstar.hlp519
-rw-r--r--noao/digiphot/daophot/doc/centerpars.hlp207
-rw-r--r--noao/digiphot/daophot/doc/daoedit.hlp164
-rw-r--r--noao/digiphot/daophot/doc/daofind.hlp601
-rw-r--r--noao/digiphot/daophot/doc/daopars.hlp331
-rw-r--r--noao/digiphot/daophot/doc/daotest.hlp89
-rw-r--r--noao/digiphot/daophot/doc/datapars.hlp289
-rw-r--r--noao/digiphot/daophot/doc/findpars.hlp135
-rw-r--r--noao/digiphot/daophot/doc/fitskypars.hlp212
-rw-r--r--noao/digiphot/daophot/doc/group.hlp304
-rw-r--r--noao/digiphot/daophot/doc/grpselect.hlp73
-rw-r--r--noao/digiphot/daophot/doc/nstar.hlp501
-rw-r--r--noao/digiphot/daophot/doc/peak.hlp439
-rw-r--r--noao/digiphot/daophot/doc/pexamine.hlp780
-rw-r--r--noao/digiphot/daophot/doc/pfmerge.hlp65
-rw-r--r--noao/digiphot/daophot/doc/phot.hlp831
-rw-r--r--noao/digiphot/daophot/doc/photpars.hlp100
-rw-r--r--noao/digiphot/daophot/doc/psf.hlp752
-rw-r--r--noao/digiphot/daophot/doc/pstselect.hlp418
-rw-r--r--noao/digiphot/daophot/doc/seepsf.hlp101
-rw-r--r--noao/digiphot/daophot/doc/setimpars.hlp165
-rw-r--r--noao/digiphot/daophot/doc/specs/daophot.spc1047
-rw-r--r--noao/digiphot/daophot/doc/specs/daoutils.spc700
-rw-r--r--noao/digiphot/daophot/doc/substar.hlp323
-rw-r--r--noao/digiphot/daophot/doc/userdocs/daophot.usr.tex2005
-rw-r--r--noao/digiphot/daophot/doc/userdocs/daoref.ms6290
-rw-r--r--noao/digiphot/daophot/findpars.par12
-rw-r--r--noao/digiphot/daophot/fitskypars.par17
-rw-r--r--noao/digiphot/daophot/group.par16
-rw-r--r--noao/digiphot/daophot/group/dpgconfirm.x24
-rw-r--r--noao/digiphot/daophot/group/dpmkgroup.x484
-rw-r--r--noao/digiphot/daophot/group/dpsmpsf.x199
-rw-r--r--noao/digiphot/daophot/group/dpwrtgroup.x448
-rw-r--r--noao/digiphot/daophot/group/mkpkg18
-rw-r--r--noao/digiphot/daophot/group/t_group.x246
-rw-r--r--noao/digiphot/daophot/grpselect.par8
-rw-r--r--noao/digiphot/daophot/lib/allstardef.h116
-rw-r--r--noao/digiphot/daophot/lib/apseldef.h57
-rw-r--r--noao/digiphot/daophot/lib/daophotdef.h257
-rw-r--r--noao/digiphot/daophot/lib/nstardef.h63
-rw-r--r--noao/digiphot/daophot/lib/peakdef.h55
-rw-r--r--noao/digiphot/daophot/lib/psfdef.h111
-rw-r--r--noao/digiphot/daophot/lib/warning.dat14
-rw-r--r--noao/digiphot/daophot/mkpkg44
-rw-r--r--noao/digiphot/daophot/nstar.par17
-rw-r--r--noao/digiphot/daophot/nstar/dpggroup.x386
-rw-r--r--noao/digiphot/daophot/nstar/dpmemnstar.x158
-rw-r--r--noao/digiphot/daophot/nstar/dpnconfirm.x34
-rw-r--r--noao/digiphot/daophot/nstar/dpnstar.x355
-rw-r--r--noao/digiphot/daophot/nstar/dpnstarfit.x1383
-rw-r--r--noao/digiphot/daophot/nstar/dpntwrite.x600
-rw-r--r--noao/digiphot/daophot/nstar/mkpkg24
-rw-r--r--noao/digiphot/daophot/nstar/t_nstar.x308
-rw-r--r--noao/digiphot/daophot/peak.par17
-rw-r--r--noao/digiphot/daophot/peak/dpmempk.x72
-rw-r--r--noao/digiphot/daophot/peak/dppeakphot.x277
-rw-r--r--noao/digiphot/daophot/peak/dppkconfirm.x25
-rw-r--r--noao/digiphot/daophot/peak/dppkfit.x411
-rw-r--r--noao/digiphot/daophot/peak/dppkwrite.x365
-rw-r--r--noao/digiphot/daophot/peak/dprrphot.x98
-rw-r--r--noao/digiphot/daophot/peak/mkpkg22
-rw-r--r--noao/digiphot/daophot/peak/t_peak.x299
-rw-r--r--noao/digiphot/daophot/pexamine.par20
-rw-r--r--noao/digiphot/daophot/pfmerge.par6
-rw-r--r--noao/digiphot/daophot/phot.par24
-rw-r--r--noao/digiphot/daophot/photpars.par7
-rw-r--r--noao/digiphot/daophot/psf.par27
-rw-r--r--noao/digiphot/daophot/psf/README2
-rw-r--r--noao/digiphot/daophot/psf/dpaddstar.x188
-rw-r--r--noao/digiphot/daophot/psf/dpcontpsf.x449
-rw-r--r--noao/digiphot/daophot/psf/dpdelstar.x112
-rw-r--r--noao/digiphot/daophot/psf/dpfitpsf.x1693
-rw-r--r--noao/digiphot/daophot/psf/dpispstars.x329
-rw-r--r--noao/digiphot/daophot/psf/dplocstar.x109
-rw-r--r--noao/digiphot/daophot/psf/dpmempsf.x217
-rw-r--r--noao/digiphot/daophot/psf/dpmkpsf.x361
-rw-r--r--noao/digiphot/daophot/psf/dppcolon.x271
-rw-r--r--noao/digiphot/daophot/psf/dppconfirm.x26
-rw-r--r--noao/digiphot/daophot/psf/dpplotpsf.x49
-rw-r--r--noao/digiphot/daophot/psf/dppset.x81
-rw-r--r--noao/digiphot/daophot/psf/dppsfutil.x381
-rw-r--r--noao/digiphot/daophot/psf/dppstat.x80
-rw-r--r--noao/digiphot/daophot/psf/dppsubrast.x172
-rw-r--r--noao/digiphot/daophot/psf/dpptconfirm.x21
-rw-r--r--noao/digiphot/daophot/psf/dppwrtgrp.x642
-rw-r--r--noao/digiphot/daophot/psf/dppwselmer.x220
-rw-r--r--noao/digiphot/daophot/psf/dpqverify.x68
-rw-r--r--noao/digiphot/daophot/psf/dpradpsf.x75
-rw-r--r--noao/digiphot/daophot/psf/dprmpsf.x156
-rw-r--r--noao/digiphot/daophot/psf/dprstars.x156
-rw-r--r--noao/digiphot/daophot/psf/dpshowpsf.x287
-rw-r--r--noao/digiphot/daophot/psf/dpspstars.x194
-rw-r--r--noao/digiphot/daophot/psf/dpsubpsf.x183
-rw-r--r--noao/digiphot/daophot/psf/dpsurfpsf.x437
-rw-r--r--noao/digiphot/daophot/psf/dpwritepsf.x270
-rw-r--r--noao/digiphot/daophot/psf/mkpkg70
-rw-r--r--noao/digiphot/daophot/psf/mkpsf.key40
-rw-r--r--noao/digiphot/daophot/psf/mkpsflist.key15
-rw-r--r--noao/digiphot/daophot/psf/showpsf.key24
-rw-r--r--noao/digiphot/daophot/psf/t_psf.x509
-rw-r--r--noao/digiphot/daophot/psf/t_pstselect.x329
-rw-r--r--noao/digiphot/daophot/pstselect.par23
-rw-r--r--noao/digiphot/daophot/seepsf.par9
-rw-r--r--noao/digiphot/daophot/seepsf/dpmkimage.x110
-rw-r--r--noao/digiphot/daophot/seepsf/mkpkg11
-rw-r--r--noao/digiphot/daophot/seepsf/t_seepsf.x91
-rw-r--r--noao/digiphot/daophot/select/dpgwselect.x141
-rw-r--r--noao/digiphot/daophot/select/dppfmerge.x81
-rw-r--r--noao/digiphot/daophot/select/dpsgroup.x95
-rw-r--r--noao/digiphot/daophot/select/mkpkg15
-rw-r--r--noao/digiphot/daophot/select/t_grpselect.x105
-rw-r--r--noao/digiphot/daophot/select/t_pfmerge.x110
-rw-r--r--noao/digiphot/daophot/setimpars.cl276
-rw-r--r--noao/digiphot/daophot/substar.par17
-rw-r--r--noao/digiphot/daophot/substar/dpgimbufr.x137
-rw-r--r--noao/digiphot/daophot/substar/dprestars.x116
-rw-r--r--noao/digiphot/daophot/substar/dpsconfirm.x18
-rw-r--r--noao/digiphot/daophot/substar/dpsubstar.x200
-rw-r--r--noao/digiphot/daophot/substar/mkpkg17
-rw-r--r--noao/digiphot/daophot/substar/t_substar.x286
-rw-r--r--noao/digiphot/daophot/test/cmds.dat4
-rw-r--r--noao/digiphot/daophot/test/fits3.fitsbin0 -> 14400 bytes
-rw-r--r--noao/digiphot/daophot/x_daophot.x14
204 files changed, 50189 insertions, 0 deletions
diff --git a/noao/digiphot/daophot/README b/noao/digiphot/daophot/README
new file mode 100644
index 00000000..1ae04629
--- /dev/null
+++ b/noao/digiphot/daophot/README
@@ -0,0 +1,32 @@
+ The Daophot Photometry Package
+ ----------------------------------
+
+The daophot package contains routines which perform crowded-filed
+photometry using point spread functions fitting techniques.
+The aperture photometry package routines are used to provide initial
+estimates for the magnitudes of these objects.
+
+The daophot directory structure is listed below. The package organization
+is by task, for example the nstar subdirectory contains routines
+specific to the nstar task or by function.
+The .h files are all in lib as many of them are shared by several tasks.
+
+ |-addstar-------routines specific to the addstar task
+ |-allstar-------routines specific to the allstar task
+ |-daoedit-------routines specific to the daoedit task
+ |-daolib--------routines common to many daophot tasks
+ |-doc-----------daophot documentation
+ |-group---------routines specific to the group task
+|-daophot----|-lib-----------daophot definitions or .h files
+ |-nstar---------routines specific to the nstar task
+ |-peak----------routines specific to the peak task
+ |-psf-----------routines specific to the psf/pstselect tasks
+ |-seepsf--------routines specific to the seepsf task
+ |-select--------routines specific to the grpselect/psfmerge tasks
+ |-substar-------routines specific to the substar task
+ |-test----------directory of test data
+
+
+Lindsey Davis
+NOAO IRAF GROUP
+May 1993
diff --git a/noao/digiphot/daophot/Revisions b/noao/digiphot/daophot/Revisions
new file mode 100644
index 00000000..7e88e82c
--- /dev/null
+++ b/noao/digiphot/daophot/Revisions
@@ -0,0 +1,918 @@
+.help revisions Jan90 noao.digiphot.daophot
+.nf
+
+daophot/psf/dpfitpsf.x
+ The ":function <func>" command was not saving the new functon when
+ refitting with the 'f' keystroke. In dp_fitpsf() the parameters are
+ reinitialized and the startup function was being reused. (4/13/10, MJF)
+
+daophot/psf/dpfitpsf.x
+ An amovi() call referenced a Memr[] array that was declared as
+ int, changed to Memi[] (8/28/09, MJF)
+
+daophot/*.par
+ Minor changes for readability suggested by Jason Quinn, i.e. made
+ consistent use of space before question marks (12/23/08, MJF)
+
+daophot/lib/warning.dat
+ Added some blank lines for readability before the package menu
+ (12/11/08, MJF)
+
+=======
+V2.14.1
+=======
+
+daophot/psf/dppwselmer.x
+ PSTSELECT was showing the IMAGE param as 'name' instead of 'imagename'
+ (7/8/08)
+
+daophot/daophot.hd
+ The source directories for pstselect and allstar were wrong.
+ (5/27/08, Valdes)
+
+=======
+V2.14
+=======
+
+daophot/allstar/dpcache.x
+ Fixed some procedure calls being closed with a ']' instead of a ')'
+ (2/17/08, MJF)
+
+daophot/psf.par
+ Fixed a type in the 'pstfile' prompt (11/24/07)
+
+========
+V2.12.3
+========
+
+daophot/allstar/dpalwrite.x
+ In dl_alxaccum there are conditions where the loop skips a star which
+ are not checked in the write routines when they compute the sharp
+ parameter. When the loop is not completed the denom value is not
+ computed and defaults to zero which caused a divide by zero error
+ in computing the sharpness. (11/18/04, Valdes)
+
+daophot/daolib/invers2.x
+daophot/daolib/mkpkg
+daophot/allstar/t_allstar.x
+daophot/allstar/dpalphot.x
+daophot/allstar/dpastar.x
+daophot/allstar.par
+ Made a small change to the matrix inversion code to avoid problems with
+ very small numbers. This was done by translating the original fortran
+ version to SPP and then replacing small numbers by zero. In order to
+ allow users to reproduces earlier results or if there is a problem
+ a version parameter was added to ALLSTAR. Setting the version to 1
+ will use the old version of the inversion routine and the default of
+ 2 will use the new version. (6/18/04, Valdes)
+
+=======
+V2.12.2
+=======
+
+daophot/daoedit/dpeconfirm.x
+daophot/daoedit/dperprofile.x
+ Added some missing sfree statements to the daophot package routines.
+
+ (19/02/02, Davis)
+
+daophot/daolib/dpppcache.x
+ Added a call setting IM_BUFFRAC to 0 to the memory caching code in the
+ daophot package tasks in order to force the imio buffer to be the size of
+ the input image.
+
+daophot/substar/dprestars.x
+ There were 3 missing arguments in the dp_tptread call which cause
+ trouble for people trying to read an input exclude file in tables
+ format.
+
+ (19/09/01, Davis)
+
+daophot/psf/dppwselmer.x
+ Changed an incorrect smark call to salloc. This bug was introduced by
+ recent output file mods. Should not have been a problem in released code.
+
+ (19/09/01, Davis)
+
+daophot/psf/t_psf.x
+ Changed the type declaration for the clgwrd function from bool to int.
+ This bug was introduced by the wcs mods. Should not have been a problem
+ in realeased code.
+
+ (19/09/01, Davis)
+
+daophot/addstar/t_addstar.x
+ Modifed the addstar task to add a ".art" suffix to the output artificial
+ star coordinate files when the user supplies the output root name. This
+ avoids file and image name conflicts when the user includes the image
+ suffix, e.g. ".imh" in the output root name.
+
+ Davis, September 17, 2001
+
+daophot/
+ Modified all the apphot tasks to accept input coordinates in logical, tv,
+ physical, or world coordinates and to write the output coordinates in
+ logical, tv, or physical coordinates. One consequence of this is that
+ the apphot tasks will now work correctly off image sections in interactive
+ mode. Another is that users can work on image sections while preserving
+ the coordinate system of the entire image.
+
+ Davis, June 8, 2000
+
+daophot/
+ Modified all the daophot tasks to strip the directory information from
+ the input image and coordinate file names written to the output files,
+ to the terminal, and to the plot headers. The colon commands will still
+ read and write full image and coordinate file path names. This change
+ improves the likelyhood that the full root image name will be written
+ to the output. This root image name is used by the photometric calibration
+ code to construct images sets.
+
+ Davis, June 8, 2000
+
+daophot/mkpkg
+ Modified the make procedure to pick up user compile and link flags.
+
+ Davis, June 17, 1999
+
+daophot/daolib/dpotime.x
+ Modified the code which reads the time of observation value from the image
+ header to extract the time field from the date-obs keyword if it is
+ present.
+
+ Davis, May 11, 1999
+
+daophot/daolib/dpdate.x
+ Modified the date and time photometry file keyword encoding tasks to
+ write the date and time in the proper fits format and in units of GMT.
+ Note that GMT is deactivated in digiphotx because the necessary routine
+ is not yet in the system.
+
+ Davis, May 11, 1999
+
+
+daophot/psf/dppwrtgrp.x
+ The row number in the psf star group file writing code was not being
+ correctly initialized results in an "invalid row number error" if
+ the psf task was run with daophot.text = no.
+
+ Davis May 10, 1999
+
+daophot/psf/dpgetapert.x
+daophot/allstar/dpalwrite.x
+daophot/group/dpwrtgroup.x
+daophot/doc/daopars.hlp
+ Removed the restriction on the number of stars imposed by the maxnstars
+ parameter and in the process fixed a segmentation violation that occurred
+ when the number for stars in the files was > maxnstars. Maxnstars is
+ now used only for setting the initial buffer size.
+
+ Removed the code which writes MAXNSTARS to the output photometry files.
+
+ Davis May 8, 1999
+
+daophot/psf/t_pstselect.x
+ Added a missing imtclose statement.
+
+ Davis, May 4, 1999
+
+daophot/psf/dpfitpsf.x
+ Changed the test for the radial weighting function from wt >= 1.0 to
+ wt >= 0.999998 to avoid floating point errors (division by a very small
+ number) under Linux and possibly other systems as well.
+
+ Davis, April 19, 1999
+
+daophot/peak/dppkfit.x
+daophot/nstar/dpnstarfit.x
+daophot/allstar/dpalphot.x
+ Added a check to make sure that the predicted error computation can
+ never be <= 0.0 This can happen in rare circumstances if the model
+ prediction is exactly 0, the rdnoise is 0.0 and flaterr and proferr are
+ 0.0.
+
+ Davis, April 12, 1999
+
+daophot/daolib/dpnames.x
+ Modified the automatic input and output image and file naming code
+ to behave more gracefully in the case where the input images have
+ kernel sections and cluster indices and sizes.
+
+ Davis, January 17, 1999
+
+daophot/daolib/dpdate.x
+daophot/addstar/dpnaddstar.x
+daophot/addstar/dpalwrite.x
+daophot/group/dpwrtgroup.x
+daophot/nstar/dpntwrite.x
+daophot/peak/dppkwrite.x
+daophot/psf/dppwrtgrp.x
+ Modified the daophot output file writing routines to write the DATE
+ header keyword in the new Y2k format even though the output files
+ are not FITS files.
+
+ Davis, Dec 29, 1998
+
+daophot/allstar/t_allstar.x
+daophot/allstar/dpcache.x
+daophot/allstar/dpalinit.x
+ Modified the allstar task to ensure that all the output and scratch
+ images and scratch space are 2D even if the input image is greater than
+ 2D to avoid a non-obvious memory error.
+
+ Davis, Aug 3, 1998
+
+
+daophot/daophot.cl
+ Modified the package cl script to check whether the tables package is
+ already loaded before checking whether it is defined and then loading it.
+
+ Davis, Aug 1, 1998
+
+daophot/psf/t_psf.x
+ The psf task psf image list reading code was using the fntgfnb routine
+ instead of the imtgetim routine to read image names from the psf image list.
+ Although the code functioned correctly, if the input psf image list was
+ an @ file, a control character (^P) was being written into the PSFIMAGE
+ keyword value in the output *.psg.* and *.pst.* files. This caused an error
+ in the nstar, allstar, etc task photometry file reading code.
+
+ Davis, Apr 1, 1998
+
+daophot/addstar/t_addstar.x
+daophot/allstar/t_allstar.x
+daophot/group/t_group.x
+daophot/nstar/t_nstar.x
+daophot/nstar/t_peak.x
+daophot/psf/t_pstselect.x
+daophot/psf/t_psf.x
+daophot/substar/t_substar.x
+ Modified the addstar, allstar, group, nstar, peak, pstselect, psf,
+ and substar tasks to be able to read and write default images and files
+ from and to directories other than the current directory just as the
+ daophot tasks daofind and phot do.
+
+ Davis, Feb 14, 1998
+
+daophot/seepsf/t_seepsf.x
+daophot/seepsf/dpmkimage.x
+ Modified the seepsf task so it explicity sets the pixel type of the
+ output psf image to real to avoid a problem with stf image kernel
+ and dataless stf images.
+
+ Davis, Jan 20, 1998
+
+daophot/allstar/dpalinit.x
+ Fixed an uninitialized memory problem that was occurring on the Dec
+ ALPHA if cache=no and readnoise=0.0. This part of memory was never
+ used by the code, but was being written to a scratch image of type real,
+ which could result in an FPE if the affected memory was not a valid
+ FP number. A similar problem was fixed for the cache=yes situtation
+ awhile back.
+
+ Davis, Nov 12, 1997
+
+
+daophot/psf/dpfitpsf.x
+ Fixed a bug in the psf task that was causing the fits image kernel to
+ crash when opening a new image, but apparently did not affect the oif
+ or stf kernels in any way.
+
+ Davis, June 23, 1997
+
+daophot/daotest.cl
+ Modified the rfits calling sequence so that the code will work
+ correctly with the new version of rfits.
+
+ Davis, May 29, 1997
+
+daophot$psf/mkpkg
+daophot$psf/dprstars.x
+daophot$psf/dpspstars.x
+daophot$psf/dpispstars.x
+ The pstselect and psf tasks were not reinitializing the psf star list
+ correctly when more than one image was being processed, resulting in
+ psf stars on successive images which have the same ids as psf stars
+ in previous images being incorrectly rejected or include in the psf star
+ list.
+
+ Davis, Feb 21, 1997
+
+daophot$psf/dpmkpsf.x
+ The id number and magnitude arguments were reversed in the 'f' keystroke
+ command call to the routine dp_addstar. This should only cause trouble
+ if the psf star list need to be reread.
+
+ Davis, July 18, 1996
+
+daophot$doc/phot.hlp
+ Fixed a type in the ERRORS section of the phot help page.
+
+ Davis, April 11, 1996
+
+daophot$daolib/dpinit.x
+daophot$psf/dpfitpsf.x
+daophot$psf/dppsfutil.x
+ The psf task was not restoring the fit for the moffat25 and moffat15
+ functions correctly, in the event that they were chosen as the best
+ fitting analytic function. This was occurring because the constant
+ beta parameter was not being copied into and out of the save array
+ resulting in a totally incorrect look-up table being computed.
+
+ Davis, March 20, 1996
+
+daophot$psf/dpfitpsf.x
+ Modified the code which computes the analytic component of the psf
+ model to start from the same initial state in auto mode as it does
+ if a single function is specified. Peviously the initial state
+ in the auto case was the state computed by the previous function.
+ Because the convergence criteria have a specified tolerance, the
+ resulting computed values of the analytic component functions and the
+ look-up table elements can be slightly different in the two cases.
+
+ Davis, March 18, 1996
+
+daophot$allstar/dpcache.x
+daophot$allstar/dpalmemstar.x
+
+ Modified the malloc calls to calloc calls in the dpcache routine to
+ avoid an unititialized memory FPE error than can occur if the readout
+ noise is exactly 0. As far as I am aware this has only caused a problem
+ on the Dec Alpha, but 0 readout noise situation does occur in the
+ daophot test script. Removed an extra fixmem call from the allstar
+ cleanup routine.
+
+ Davis, February 20, 1996
+
+daophot$daolib/dpgetapert.x
+daophot$nstar/dpggroup.x
+ Fixed a bug in the code which parses the input photometry or group files.
+ If the numerical field to be extracted is adjacent to another numerical
+ field and there is no white space between them, then the number
+ extracted may be a combination of the two fields, rather than the desired
+ individual field. This is most likely to occur when the id numbers are
+ large, e.g. 10003, and the image name is a number, e.g. 8649.imh.
+
+ Davis, February 20, 1996
+
+daophot$daopars.par
+daophot$daotest.cl
+daophot$lib/daophotdef.h
+daophot$lib/nstardef.h
+daophot$daolib/dpgppars.x
+daophot$daolib/dppppars.x
+daophot$daolib/dpset.x
+daophot$daolib/dpstat.x
+daophot$daolib/dpverify.x
+daophot$group/dpgconfirm.x
+daophot$group/dpmkgroup.x
+daophot$group/dpwrtgroup.x
+daophot$nstar/dpnstarfit.x
+daophot$nstar/dpntwrite.x
+daophot$allstar/dpastar.x
+daophot$allstar/dpalwrite.x
+daophot$doc/daopars.hlp
+daophot$doc/group.hlp
+ Added a new parameter mergerad to the daopars parameter set. Mergerad
+ permits the user to control the merging process. If mergerad is 0
+ object merging is turned off altogether. If mergerad is INDEF to default
+ mergeing radius is used. Otherwise the user can set the merging radius
+ to a specific value.
+
+ Changed the name of the critoverlap parameter to critsnratio to avoid
+ user confusion over the meaning to the parameter.
+
+ Davis, February 15, 1996
+
+daophot$nstar/dpnmemstar.x
+daophot$nstar/dpnstar.x
+daophot$allstar/dpalmemstar.x
+daophot$allstar/dpalphot.x
+ Modified the nstar and allstar tasks so that they allocate less memory for
+ the fitting matrices and vectors if object recentering is turned off. This
+ can make a big difference if the the maximum group size is large.
+
+ Davis, February 14, 1996
+
+daophot$nstar/dpnstarfit.x
+ Added a singular matrix check to avoid floating point operand errors
+ in the nstar task.
+
+ Davis, January 5, 1996
+
+daophot$nstar/dpggroup.x
+ The integer code array size was not being reallocated correctly in the
+ case that the size of a group is greater the the value of the maxgroup
+ parameter, causing nstar to die with a memory allocation parameter,
+
+ Davis, January 3, 1996
+
+daophot$doc/centerpars.hlp
+ Edited the centerpars help page to include a description of the new
+ INDEF-valued cthreshold option.
+
+ Davis, Sept 29, 1995
+
+daophot$lib/psfdef.h
+daophot$psf/dpfitpsf.x
+daophot$psf/dpmempsf.x
+daophot$psf/dppsfutil.x
+daophot$psf/dprstars.x
+daophot$psf/dpispstars.x
+daophot$psf/dpspstars.x
+daophot$psf/dpmkpsf.x
+daophot$psf/dpaddstar.x
+daophot$doc/psf.hlp
+ Modifed the way the magnitude of the psf is set. If matchbyid is
+ yes (the default) the magnitude of the first psf star in the psf
+ star list if any will be used; other wise the magnitude of the first
+ psf star in the input photometry file will be used as before. This
+ should help minimize photometric drift problems derived from repeated
+ iterations.
+
+ Davis, Sept 21, 1995
+
+daophot$psf/dpdelstar.x
+daophot$psf/dpsubpsf.x
+ Added a missing mfree to the dpsubpsf routine. This was not causing
+ a problem but might in a large script.
+
+ In dpdelstar the routine dp_psubrast was being called with an input
+ output variable that was never used being set to a constant. This was
+ causing a segvio on Solaris but not on SunOS.
+
+ Davis, Aug 25, 1995
+
+daophot$seepsf/dpmkimage.x
+ Seepsf was dying with an FPE error on the Dec Alpha. This was caused
+ by an array out-of-bounds error which was not detected on the Sun
+ machines.
+
+ Davis, July 18, 1995
+
+daophot$seepsf/t_seepsf.x
+daophot$seepsf/dpmkimage.x
+ The fix made to cure the previous seepsf problem broke the code for
+ pure analytic psf images.
+
+ Davis, July 3, 1995
+
+daophot$psf/dpfitpsf.x
+ Changed the illegal construct "} until (redo == false)" to
+ "} until (! redo)". This was causing problems on the IBM/RISC6000
+ compilers but was not caught by the Sun compilers.
+
+ Davis, November 16, 1994
+
+daophot$seepsf/t_seepsf.x
+daophot$seepsf/dpmkimage.x
+ The code that was computing the default size of the output psf image
+ was incorrectly using the size of psf requested by the user (default
+ radius = 11.0 pixesl) instead of the actual size of the input psf image.
+
+ Davis, October 3, 1994
+
+daophot$daoedit/t_daoedit.x
+daophot$daoedit/dpeconfirm.x
+ Made some minor modifications to the daoedit task which change the
+ image cursor mode and graphics cursor mode interact.
+
+ Davis, June 21, 1994
+
+daophot$addstar/dpnaddstar.x
+ Corrected an error in the format string for the output file.
+
+ Davis, June 20, 1994
+
+daophot$psf.par
+daophot$lib/psfdef.h
+daophot$psf/t_psf.x
+daophot$psf/t_dprstars.x
+daophot$doc/psf.hlp
+ Added a new parameter, matchbyid, to the psf task so that stars in the
+ psf star list can be matched to stars in the input photometry file
+ by id or by position.
+
+ Davis, June 20, 1994
+
+daophot$psf/dpspstars.
+ In non-interactive mode the pstselect task was writing a minimum
+ of two stars to the output file even if the requested number of
+ psf stars was one.
+
+ Davis, June 18, 1994
+
+daophot$addstar/dpartstar.x
+daophot$addstar/dpartstar.x
+ If the nimages parameter was greater than 1 and the addimage parameter
+ was set to other than the default value, the task would terminate
+ prematurely with a "Cannot close file error" after the first output
+ image was written. The problem was caused by addstar failing to append
+ the appropriate sequence number to the output star list.
+
+ Davis, June 13, 1994
+
+daophot$allstar/dpalwrite.x
+daophot$group/dpwrtgroup.x
+daophot$nstar/dpntwrite.x
+daophot$peak/dppkwrite.x
+daophot$psf/dppwrtgrp.x
+daophot$psf/dppwselmer.x
+daophot$select/dpgwselect.x
+ Modified all the daophot package tasks which output sky values (pstselect,
+ psf, peak, group, grpselect, nstar, allstar, pfmerge) to write the
+ values with format -%15.7g like the apphot package tasks do, instead
+ of %-12.3f/%-14.3f, to avoid precision problems with images that
+ have been "flux calibrated".
+
+ Davis, May 27, 1994
+
+daophot$nstar/dpntwrite.x
+daophot$nstar/dpalwrite.x
+ Changed the output GROUPSKY parameter name in the phot files to GRPSKY
+ to avoid a name matching conflict with the GROUP column. This was causing
+ problems in reading nstar output.
+
+ Davis, May 5, 1994
+
+daophot$daopars.par
+daophot$lib/daophotdef.h
+daophot$allstar/dpaconfirm.x
+daophot$allstar/dpalphot.x
+daophot$allstar/dpalwrite.x
+daophot$daoedit/daoedit.h
+daophot$daoedit/dpecolon.x
+daophot$daolib/dpgppars.x
+daophot$daolib/dpppars.x
+daophot$daolib/dpinit.x
+daophot$daolib/dpset.x
+daophot$daolib/dpstat.x
+daophot$daolib/dpverify.x
+daophot$nstar/dpnconfirm.x
+daophot$nstar/dpnstar.x
+daophot$nstar/dpnstarfit.x
+daophot$nstar/dpntwrite.x
+daophot$doc/allstar.hlp
+daophot$doc/daopars.hlp
+daophot$doc/nstar.hlp
+ Added a new boolean parameter, groupsky, to the daopars parameter set.
+ Groupsky determines whether the sky value for each pixel used in the fit
+ is set to, the mean of ALL the individual sky values of the stars in the
+ group (groupsky = yes), or, to the mean of the individual sky values of
+ only those stars for which the pixel in question is inside the fitting
+ radius.
+
+ Davis, Dec 20, 1993
+
+daophot II installed
+ Davis, May 31, 1993
+
+ Daophot II installed.
+
+daophot$phot.par
+ Added a leading quote to the prompt string for the daophot.phot task
+ output parameter.
+
+ Davis, Mar 24, 1993
+
+daophot$daolib/dpppars.x
+ The psfrad, fitrad, and matchrad were being written to the parameter
+ set in pixel units instead of scale units when update was set to
+ yes.
+
+ Davis, Feb 16, 1993
+
+daophot$allstar/dpalinit.x
+ In crowded regions allstar would occasionally refuse to 1) fit a group
+ of bright stars or 2) fail to converge to reasonable values for a group
+ of bright stars by the time the number of iterations equaled maxiter,
+ resulting in a group of stars with very poor subtractions.
+ The problem was caused by a bug in the code which steps through the
+ stellar groups subtracting off the current best fit to produce a residuals
+ image. Occasioanally stars which should have been subtracted from the
+ residuals image were not being subtracted. Since the residuals image is
+ used to determine the relative errors and weights,
+ which in turn control the bad data rejection algorithm, allstar sometimes
+ refused to fit stars because the residuals were too big, or was unable
+ to converge to a reasonable fit. The bug is data dependent but is
+ more likely to be a problem if 1) the stellar detection threshold is low
+ 2) the fitting radius is high producing very large groups.
+
+ Davis, Dec 23, 1992
+
+daophot$allstar/dpalphot.x
+ If 1) cache=no, or cache=yes and memory allocation failed for one of the
+ three arrays scratch, weight, or data, 2) one or more the the groups has >
+ maxgroup stars, 3) regrouping was performed and 4) the position of next
+ non-regrouped group was just right, allstar could fail with an "attempt to
+ access the scratch, weight or data pixels randomly" error. This error
+ occurrs because the regrouping process could produce groups which were out
+ of y-order with with succeeding groups which had not been regrouped,
+ forcing an illegal non-sequential image access. The solution was to buffer
+ enough data to fit original large group.
+
+ Davis, Sept 16, 1992
+
+apphot$datapars.par
+apphot$centerpars.par
+apphot$doc/datapars.hlp
+apphot$doc/centerpars.hlp
+ Changed the units of the cthreshold parameter to sigma and moved it
+ to the centerpars parameter set.
+
+ Davis, July 7, 1992
+
+daophot$daophot.par
+ The verbose, verify, update, graphics, and display parameters were
+ added to the package parameters and the corresponding individual
+ task parameters were redirected there by default.
+
+ Davis, June 20, 1992
+
+daophot$daopars.par
+daophot$lib/warning.dat
+ Fixed errors in the definition of the psfrad and fitrad parameters in
+ the daopars parameter set. These parameters are now defined in units
+ of scale not pixels as before.
+
+ Fixed some bugs in the message printed by the daophot package if the
+ tables package is not present.
+
+ Davis, May 29, 1992
+
+daophot$daophot.men
+ Changed the entries for append, convert, dump, renumber, select, and
+ sort to entries for pappend, pconvert, pdump, prenumber, pselect,
+ and psort.
+
+ Davis, Feb 28, 1992
+
+daophot$psf/dpmkpsf.x
+ Added missing fset declaration to the mkpkg line for this routine.
+
+ Davis, Nov 20, 1991
+
+daophot$
+ Renamed the append, convert, dump, renumber, select, and sort tasks to
+ pappend, pconvert, pdump, prenumber, pselect, and psort.
+
+ Davis, Nov 11, 1991
+
+ *** Ran spplint on the daophot package.
+
+daophot$allstar/dpastar.x
+ The routines dp_gst, dp_gwt, and dp_gdc were being called as subroutines
+ instead of functions inside dp_astar. This was a recent change which
+ would not affect the old testphot.
+
+daophot/psf/dpcontpsf.x
+ Changed the last argument in the call to dp_map_viewport from NO to false
+ to fix a type mismatch. This could affect the old testphot.
+
+daophot/psf/dpnewpsf.x
+ Removed extra status argument from the call to dp_gaussfit. This could
+ have caused a problem in the old daophot.
+
+daophot/peak/dppkfit.x
+ Removed an extra argument from the mfree call. This would not cause a
+ problem in the old testphot.
+
+ Davis, Oct 3, 1991
+
+daophot$daophot.cl
+daophot$daophot.men
+daophot$daophot.hd
+daophot$daotest.cl
+ At the autotmatic package test task daotest to the daophot package.
+
+ Davis, Oct 3, 1991
+
+daophot$psf/dpsurfpsf.x
+ Removed non-required variables mode, xres, yres from this routine.
+
+ Davis, Oct 1, 1991
+
+daophot$test/fits3.fits
+ Added the fits test image to the daophot test subdirectory in preparation
+ for making a test script.
+
+ Added a test cursor input file for the psf task in preparation for
+ making the test script.
+
+ Davis, Aug 13, 1991
+
+daophot$daolib/dpgetapert.x
+daophot$nstar/dpggroup.x
+ Modified the i/o routines which read aperture photometry and group
+ photometry format text files in order to take account of new additions
+ to the text database routines.
+
+ Davis, Aug 13, 1991
+
+daophot$
+ 1. All the DAOPHOT tasks except PSF have been modified to accept lists of
+ input and output files.
+
+ 2. Moved the text parameter from DAOPARS to the DAOPHOT package parameter
+ file.
+
+ 3. Modified all the DAOPHOT routines so that psfrad, fitrad and matchrad
+ are defined in terms of scale.
+
+ Davis, Aug 5, 1991
+
+daophot$
+ 1. Added support for a time of observation parameter to all the appropriate
+ daophot tasks.
+
+ 2. Changed all the daophot file header parameters to be 23 characters long
+ instead of 15 characters.
+
+ 3. Modified all the daophot tasks to strip whitespace from the filter id
+ keywords and the iraf version environment variable string.
+
+ 4. Wrote an spp version of the error function routine which was originally
+ in fortran.
+
+ Davis, Aug 2, 1991
+
+daophot$allstar/
+ 1. Redid the i/o of the ALLSTAR task to make the cache=no option run in
+ a finite period of time for large images.
+
+ Davis, Jun 24, 1991
+
+daophot$group/
+ 1. Changed GROUP so that the groups are output in y order instead of in
+ order of the size of the group. This will help make i/o more efficient
+ in NSTAR.
+
+ Davis, Jun 18, 1991
+
+daophot$allstar/
+ 1. Changed the boolean arrays inside ALLSTAR to integer arrays. These
+ use the same amount of space and are probably safer.
+
+ 2. Added protection in the code for the case that the x and y position
+ of a star is INDEF or the sky value is INDEF.
+
+ 3. Changed the format of the output of the verbose option in several places
+ in the code.
+
+ Davis, Jun 17, 1991
+
+daophot$nstar/
+ 1. Changed the boolean arrays inside NSTAR to integer arrays. Thought
+ this was probably safer.
+
+ 2. Fixed a potential problem in NSTAR wherein for groups greater than
+ the maxgroup parameter in size the old_size variable was not being
+ correctly set. This would mean that some group members could get
+ truncated from the output file.
+
+ 3. Fixed a bug in verbose mode wherein stars would not be fit, their
+ magnitude would be set to INDEF, but no error message would be generated.
+ This was occurring when the new center of a star moved too close to the
+ edge of the image.
+
+ 4. Also took the opportunity to do some code cleanup.
+
+ Davis, Jun 5, 1991
+
+daophot$psf/
+ 1. Modified the PSF task so that potential psf stars are rejected if their
+ sky or magnitude values are INDEF.
+
+ 2. Added a check so that stars with INDEF valued positions are treated as
+ stars that were not found.
+
+ 3. Added a check in the code so that the same star could not be added to
+ the psf twice.
+
+ 4. Found a code construct in the dp_friends() routine that
+ could trigger an optimizer bug and removed it.
+
+ 5. Finally changed the code which deletes an empty psf image and group
+ file so that it would handle an output ST table correctly.
+
+ 6. Did some minor code cleanup.
+
+ Davis, Jun 3, 1991
+
+daophot$peak/
+ 1. Found that the main fitting task in PEAK, dp_pkfit(), was missing an
+ sfree statement. This may account for the problems with TESTPHOT on the
+ mountain. Took the opportunity afforded by this bug to do a little
+ code cleanup in peak.
+
+ 2. Had to do a couple of modifications in PSF because of the mod to the
+ fitting code in PEAK. The two tasks share code. Found an extra sfree
+ statement in the main PSF loop and removed it.
+
+ 3. Changed the size of the extractions box in PEAK from psfrad to
+ (psfrad + fitrad + 1). This removes any problems in the unlikely
+ event that the fitting radius is bigger than the psf radius.
+
+ Davis, Jun 1, 1991
+
+daophot$group/
+ Modified GROUP so that any stars with INDEF valued centers are not
+ written to the output file. Various code modifications were made
+ to clean up the logic of the task and make it more structured.
+
+ Davis, May 31, 1991
+
+daophot$peak/
+ Modified PEAK so that stars with undefined sky values don't cause a
+ floating operand error. Also modified PEAK so that any stars with
+ INDEF centers in the input file are not written to the output file.
+
+ Davis, May 30, 1991
+
+daophot$addstar/
+ Addstar was not incrementing the row numbers correctly when writing
+ the output star list if the output file was an ST table, resulting
+ in an output file that was missing some rows. The output image was being
+ computed correctly.
+
+ Davis, May 26, 1991
+
+daophot$
+ Added the PEXAMINE task to the daophot package.
+
+ Davis, May 24, 1991
+
+daophot$allstar/
+daophot$addstar/
+ Modified the peak and allstar tasks so that they were writing the
+ keyword IMAGE instead of IMNAME in the header. IMNAME was causing
+ problems for the preprocessors.
+
+ Davis, Apr 5, 1991
+
+daophot$
+daophot$psf/
+ 1. Modified the dpppars() routine in daolib to the datamin and datamax
+ in the datapars pset are updated when the daophot fitting parameters are
+ updated.
+
+ 2. Update the psf task so that the default psf image header will hold more
+ than 22 stars. The current default will be three times that. Psf will
+ still pack up on the min_lenuserarea parameter if it is the default.
+
+ Davis, Apr 1, 1991
+
+daophot$
+ 1. The tasks allstar, group, nstar, peak, psf and substar were all modified
+ to include datamin and datamax in their verify routines.
+ As part of this a set of general utility routines were written and
+ stored in the file daolib/dpverify.x.
+
+ 2. The io routines were consolidated into a single file for output and/or
+ another for input as appropriate. This means several files in the
+ addstar, allstar, nstar, and peak routines have disappeared.
+
+ 3. The nstar text file input routine was made for efficient by changing
+ the strmatch calls to strncmp.
+
+ Davis, Mar 30, 1991
+
+daophot$psf/
+ The psf task was writing the incorrect value of xpsf and ypsf into the
+ psf image header causing the variable psf to be evaluated at the
+ wrong position. Any task which evaluated the variable psf including
+ seepsf, group, peak, nstar, and allstar would be in error. The
+ bug was located in the file dp_writepsf.x in testphot$daophot/psf/.
+
+ Davis, Feb 1, 1991
+
+daophot$psf/
+
+ The celling for surface plots was being set to 20000 in the routine
+ dp_psfsetup in file daolib/dpinit.x causing floating point divide
+ errors in images with pixels not in the usual CCD range.
+
+ Davis, Jan 21, 1991
+
+daophot$allstar/
+ A call to dp_talwrite() was missing the chigrp argument.
+
+ Davis, March 1, 1989
+
+daophot$allstar/
+ A data dependent error could occur in allstar if the user tried to
+ write to an output ST table and the computed magnitude error was
+ less than or equal to zero.
+
+ Davis, February 28, 1989
+
+daophot$
+ All task except DAOFIND and PHOT were affected by an error in the
+ ptools$pttables/pthdrs.x file. The tasks sometimes crash on input files
+ created with append task with a memory corruption error.
+ See the ptools Revisions file for a description of the error.
+
+ Davis, January 4, 1990
+
+December 21, 1989 -- Beta Daophot Release
+.endhelp
diff --git a/noao/digiphot/daophot/addstar.par b/noao/digiphot/daophot/addstar.par
new file mode 100644
index 00000000..a8b6787f
--- /dev/null
+++ b/noao/digiphot/daophot/addstar.par
@@ -0,0 +1,23 @@
+# Parameters for the ADDSTAR task
+
+image,f,a,,,,"Image to which stars are to be added"
+photfile,f,a,,,,"Input photometry file"
+psfimage,f,a,default,,,"Input PSF image (default: image.psf.?)"
+addimage,f,a,"default",,,"Output artificial image (default: image.add.?)"
+minmag,r,a,,,,Minimum magnitude of artificial stars to add
+maxmag,r,a,,,,Maximum magnitude of artificial stars to add
+nstar,i,a,100,1,,Number of artifical stars to add
+datapars,pset,h,"",,,Data dependent parameters
+daopars,pset,h,"",,,Psf fitting parameters
+simple_text,b,h,no,,,"Input is in simple text format?"
+seed,r,h,0.0,,,Seed for the random number generator
+nimage,i,h,1,1,,Number of new images per input image
+idoffset,i,h,0,,,Id numbering offset
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the output image pixels in memory?"
+verify,b,h,)_.verify,,,Verify critical addstar parameters?
+update,b,h,)_.update,,,Update critical addstar parameters?
+verbose,b,h,)_.verbose,,,Print addstar messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/addstar/dpadconfirm.x b/noao/digiphot/daophot/addstar/dpadconfirm.x
new file mode 100644
index 00000000..bff2ca93
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/dpadconfirm.x
@@ -0,0 +1,14 @@
+# DP_ADCONFIRM -- Confirm the critical ADDSTAR parameters.
+
+procedure dp_adconfirm (dao)
+
+pointer dao # pointer to the daophot structure
+
+begin
+ call printf ("\n")
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/addstar/dpaddrd.x b/noao/digiphot/daophot/addstar/dpaddrd.x
new file mode 100644
index 00000000..108448ee
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/dpaddrd.x
@@ -0,0 +1,89 @@
+include "../lib/apseldef.h"
+
+# DP_TADINIT -- Initializie the column descriptors for the input ST photometry
+# table.
+
+procedure dp_tadinit (tp, column)
+
+pointer tp # table descriptor
+int column[ARB] # column pointer array
+
+begin
+ # Find the column pointers
+ call tbcfnd (tp, ID, column[1], 1)
+ if (column[1] == NULL)
+ call tbcfnd (tp, "ID", column[1], 1)
+ if (column[1] == NULL)
+ call printf ("Error reading ID.\n")
+
+ call tbcfnd (tp, XCENTER, column[2], 1)
+ if (column[2] == NULL)
+ call tbcfnd (tp, "XCENTER", column[2], 1)
+ if (column[2] == NULL)
+ call printf ("Error reading XCENTER.\n")
+
+ call tbcfnd (tp, YCENTER, column[3], 1)
+ if (column[3] == NULL)
+ call tbcfnd (tp, "YCENTER", column[3], 1)
+ if (column[3] == NULL)
+ call printf ("Error reading YCENTER.\n")
+
+ call tbcfnd (tp, MAG, column[4], 1)
+ if (column[4] == NULL)
+ call tbcfnd (tp, APMAG, column[4], 1)
+ if (column[4] == NULL)
+ call printf ("Error reading MAG.\n")
+end
+
+
+# DP_TADREAD -- Read a record from the input ST photometry table.
+
+procedure dp_tadread (tp, column, id, x, y, mag, row)
+
+pointer tp # table descriptor
+int column[ARB] # column pointer array
+int id # output id
+real x # output x value
+real y # output y value
+real mag # output magnitude
+int row # integer row
+
+bool nullflag
+
+begin
+ call tbrgti (tp, column[1], id, nullflag, 1, row)
+ if (nullflag)
+ id = 0
+ call tbrgtr (tp, column[2], x, nullflag, 1, row)
+ call tbrgtr (tp, column[3], y, nullflag, 1, row)
+ call tbrgtr (tp, column[4], mag, nullflag, 1, row)
+end
+
+
+# DP_GCOORDS -- Read the coordinates and magnitudes from a simple text file.
+
+int procedure dp_gcoords (cl, x, y, mag, id)
+
+int cl # file descriptor
+real x # x coordinate centers
+real y # y coordinate centers
+real mag # magnitudes
+int id # id of the star
+
+int fscan(), nscan()
+
+begin
+ while (fscan (cl) != EOF) {
+ call gargr (x)
+ call gargr (y)
+ call gargr (mag)
+ if (nscan () < 3)
+ next
+ call gargi (id)
+ if (nscan() < 4)
+ id = 0
+ return (1)
+ }
+
+ return (EOF)
+end
diff --git a/noao/digiphot/daophot/addstar/dpartstar.x b/noao/digiphot/daophot/addstar/dpartstar.x
new file mode 100644
index 00000000..9f464812
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/dpartstar.x
@@ -0,0 +1,303 @@
+include <imhdr.h>
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define ADD_NINCOLUMN 4
+
+# DP_ARTSTAR -- Add artificial stars to the data frames.
+
+procedure dp_artstar (dao, iim, oim, cl, ofd, nstar, minmag, maxmag, iseed,
+ coo_text, simple, offset, cache)
+
+pointer dao # pointer to DAOPHOT structure
+pointer iim # the input image descriptor
+pointer oim # image to add stars to
+int cl # fd of input photometry file
+int ofd # fd of output photometry file
+int nstar # number of stars to be added
+real minmag, maxmag # min. and max. magnitudes to add
+int iseed[ARB] # the random number generator array
+bool coo_text # coordinate text file ?
+int simple # simple text file ?
+int offset # id offset for output photometry file
+int cache # cache the output pixels
+
+real xmin, ymin, xwide, ywide, mwide, x, y, dxfrom_psf, dyfrom_psf, mag
+real radius, psfradsq, rel_bright, sky, tx, ty
+pointer sp, colpoint, psffit, subim, subim_new, indices, fields, key
+int i, iid, id, lowx, lowy, nxpix, nypix, nrow
+
+pointer dp_gsubrast(), imps2r(), tbpsta()
+int dp_gcoords(), dp_apsel()
+
+begin
+ # Get some memory.
+ call smark (sp)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (indices, ADD_NINCOLUMN, TY_INT)
+ call salloc (colpoint, ADD_NINCOLUMN, TY_INT)
+
+ # Initialize the input photometry file.
+ key = NULL
+ if (cl != NULL) {
+ if (! coo_text) {
+ call dp_tadinit (cl, Memi[indices])
+ nrow = tbpsta (cl, TBL_NROWS)
+ #} else if (coo_text && simple == NO) {
+ } else if (simple == NO) {
+ call pt_kyinit (key)
+ Memi[indices] = DP_PAPID
+ Memi[indices+1] = DP_PAPXCEN
+ Memi[indices+2] = DP_PAPYCEN
+ Memi[indices+3] = DP_PAPMAG1
+ call dp_gappsf (Memi[indices], Memc[fields], ADD_NINCOLUMN)
+ }
+ }
+
+ # Initialize the output table.
+ if (DP_TEXT(dao) == YES)
+ call dp_xnaddstar (dao, ofd)
+ else
+ call dp_tnaddstar (dao, ofd, Memi[colpoint])
+
+ # Get some daophot pointers.
+ psffit = DP_PSFFIT (dao)
+
+ # Get the psf radius
+ if (DP_PSFSIZE(psffit) == 0)
+ radius = DP_PSFRAD(dao)
+ else
+ radius = min (DP_PSFRAD(dao), (real (DP_PSFSIZE(psffit) - 1) /
+ 2.0 - 1.0) / 2.0)
+ psfradsq = radius * radius
+
+ # Get the x and y limits for the random number generator. The
+ # magnitude limits are input by the user.
+ xmin = 1.0
+ xwide = real(IM_LEN(oim,1)) - 1.0
+ ymin = 1.0
+ ywide = real (IM_LEN(oim,2)) - 1.0
+ mwide = maxmag - minmag
+
+ if (DP_VERBOSE (dao) == YES) {
+ call printf ("OUTPUT IMAGE: %s\n")
+ call pargstr (IM_HDRFILE(oim))
+ }
+
+ # Add the stars.
+ i = 1
+ repeat {
+
+ # Get the coords and magnitudes of the star.
+ if (cl == NULL) {
+ call dp_mkcoords (x, y, mag, xmin, xwide, ymin, ywide, minmag,
+ mwide, iseed)
+ id = i + offset
+ if (i > nstar)
+ break
+ } else if (! coo_text) {
+ if (i > nrow)
+ break
+ call dp_tadread (cl, Memi[indices], iid, x, y, mag, i)
+ call dp_win (dao, iim, x, y, x, y, 1)
+ if (iid == 0)
+ iid = i + offset
+ else
+ id = iid
+ } else {
+ if (simple == YES) {
+ if (dp_gcoords (cl, x, y, mag, iid) == EOF)
+ break
+ if (iid == 0)
+ id = i + offset
+ else
+ id = iid
+ } else {
+ if (dp_apsel (key, cl, Memc[fields], Memi[indices], iid, x,
+ y, sky, mag) == EOF)
+ break
+ if (iid == 0)
+ id = i + offset
+ else
+ id = iid
+ }
+ call dp_win (dao, iim, x, y, x, y, 1)
+ }
+
+ # Increment the counter
+ i = i + 1
+
+ # Compute the psf coordinates.
+ call dp_wpsf (dao, iim, x, y, dxfrom_psf, dyfrom_psf, 1)
+ dxfrom_psf = (dxfrom_psf - 1.0) / DP_PSFX(psffit) - 1.0
+ dyfrom_psf = (dyfrom_psf - 1.0) / DP_PSFY(psffit) - 1.0
+
+ # Compute output coordinates.
+ call dp_wout (dao, iim, x, y, tx, ty, 1)
+
+ # Read in the subraster and compute the relative x-y position.
+ subim = dp_gsubrast (oim, x, y, radius, lowx, lowy, nxpix, nypix)
+ if (subim == NULL) {
+ call printf (
+ " Star: %d - X: %6.2f Y: %6.2f Mag: %7.3f off image\n")
+ call pargi (id)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (mag)
+ next
+ } else if (DP_VERBOSE (dao) == YES) {
+ call printf (
+ " Added Star: %d - X: %6.2f Y: %6.2f Mag: %7.3f\n")
+ call pargi (id)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (mag)
+ }
+
+ if (DP_TEXT(dao) == YES)
+ call dp_xwadd (ofd, id, tx, ty, mag)
+ else
+ call dp_twadd (ofd, Memi[colpoint], id, tx, ty, mag, id)
+
+ # Get the relative brightness
+ rel_bright = DAO_RELBRIGHT (psffit, mag)
+
+ # Get the output buffer.
+ subim_new = imps2r (oim, lowx, lowx + nxpix - 1, lowy,
+ lowy + nypix - 1)
+
+ # Evaluate the PSF for a single star.
+ x = x - lowx + 1.0
+ y = y - lowy + 1.0
+ call dp_artone (dao, Memr[subim], nxpix, nypix, x, y, rel_bright,
+ dxfrom_psf, dyfrom_psf, psfradsq, DP_PHOTADU(dao), iseed)
+
+ # Make sure the image buffer is flushed. Currently this is a
+ # very inefficient way to do the image i/o.
+ call amovr (Memr[subim], Memr[subim_new], nxpix * nypix)
+ if (cache == NO)
+ call imflush (oim)
+
+ }
+
+ # Release the text file structure.
+ if (key != NULL)
+ call pt_kyfree (key)
+
+ call sfree (sp)
+end
+
+
+# DP_ARTONE -- Add a single star to the image.
+
+procedure dp_artone (dao, subin, nxpix, nypix, x, y, rel_bright, xfrom_psf,
+ yfrom_psf, psfradsq, gain, iseed)
+
+pointer dao # pointer to the daophot structure
+real subin[nxpix,nypix] # input subraster
+int nxpix, nypix # dimensions of subrasters
+real x, y # input position
+real rel_bright # relative brightness
+real xfrom_psf # x distance from the psf
+real yfrom_psf # y distance from the psf
+real psfradsq # psf radius squared
+real gain # gain
+int iseed[ARB] # random number seed array
+
+int ix, iy
+pointer psffit
+real dx, dy, dxsq, dysq, radsq, dvdx, dvdy, value, err
+real dp_usepsf(), dp_nrml(), daoran()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ do iy = 1, nypix {
+ dy = real (iy) - y
+ dysq = dy * dy
+ do ix = 1, nxpix {
+ dx = real (ix) - x
+ dxsq = dx * dx
+ radsq = dxsq + dysq
+ if (radsq < psfradsq) {
+ value = rel_bright * dp_usepsf (DP_PSFUNCTION(psffit),
+ dx, dy, DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ xfrom_psf, yfrom_psf, dvdx, dvdy)
+ err = daoran (iseed[mod(ix+iy,3)+1])
+ err = sqrt (max (0.0, value / gain)) * dp_nrml (err)
+ subin[ix,iy] = subin[ix,iy] + value + err
+ }
+ }
+ }
+end
+
+
+# DP_MKCOORDS -- Construct a list of coordinates using a random number
+# generator.
+
+procedure dp_mkcoords (x, y, mag, xmin, xwide, ymin, ywide, minmag, mwide,
+ iseed)
+
+real x # x array
+real y # y array
+real mag # magnitude array
+real xmin # xmin value
+real xwide # x coordinate range
+real ymin # ymin value
+real ywide # y coordinate range
+real minmag # minimum magnitude
+real mwide # the magnitude range
+int iseed[ARB] # seed array for random number genrator
+
+real daoran()
+
+begin
+ x = xmin + daoran (iseed[1]) * xwide
+ y = ymin + daoran (iseed[2]) * ywide
+ mag = minmag + daoran (iseed[3]) * mwide
+end
+
+
+# DP_SEED3 -- Seed the random number generator.
+
+procedure dp_seed3 (seed, iseed)
+
+int seed # initial seed value
+int iseed[ARB] # the seed array
+
+int idum
+real daoran()
+
+begin
+ idum = seed
+ iseed[1] = int (524288.* daoran (idum)) + 1
+ iseed[2] = int (524288.* daoran (idum)) + 1
+ iseed[3] = int (524288.* daoran (idum)) + 1
+end
+
+
+# DP_NRML -- Convert a uniform probability distribution to a Gaussian
+# distribution with mean zero and standard deviation of unity.
+
+real procedure dp_nrml (random)
+
+real random # input random number
+
+real p, sign, t
+
+begin
+ p = random
+ sign = -1.0
+ if (p > 0.5) {
+ p = p - 0.5
+ sign = 1.0
+ } else if (p <= 0.0)
+ return (-1.0e20)
+
+ t = sqrt (log (1.0 / (p * p)))
+ return (sign * (t - (2.30753 + 0.27061 * t) /
+ (1.0 + t * (0.99229 + t * 0.04481))))
+end
diff --git a/noao/digiphot/daophot/addstar/dpnaddstar.x b/noao/digiphot/daophot/addstar/dpnaddstar.x
new file mode 100644
index 00000000..b08dd813
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/dpnaddstar.x
@@ -0,0 +1,265 @@
+include <time.h>
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define ADD_NOUTCOLUMN 4
+
+# DP_TNADDSTAR -- Create an output ADDSTAR table.
+
+procedure dp_tnaddstar (dao, tp, columns)
+
+pointer dao # pointer to daophot structure
+pointer tp # output table decscriptor
+int columns[ARB] # pointer to columns
+
+int i
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for table definition.
+ call smark (sp)
+ call salloc (colnames, ADD_NOUTCOLUMN * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, ADD_NOUTCOLUMN * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, ADD_NOUTCOLUMN * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, ADD_NOUTCOLUMN, TY_INT)
+ call salloc (col_len, ADD_NOUTCOLUMN, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+
+ # Set up the column formats.
+ call strcpy ("%5d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+
+ # Set up the units definitions.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("MAGNITIDES", Memc[colunits+3*SZ_COLUNITS+3],
+ SZ_COLUNITS)
+
+ # Set up the data types.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_REAL
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+
+ do i = 1, ADD_NOUTCOLUMN
+ Memi[col_len+i-1] = 1
+
+ call tbcdef (tp, columns, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], ADD_NOUTCOLUMN)
+ call tbtcre (tp)
+
+ # Write out the header parameters.
+ call dp_tgadppars (dao, tp)
+
+ call sfree (sp)
+
+end
+
+
+define ADD_NAMESTR "#N%4tID%10tXCENTER%20tYCENTER%30tMAG%80t\\\n"
+define ADD_UNITSTR "#U%4t##%10tpixels%20tpixels%30tmagnitudes%80t\\\n"
+define ADD_FORMATSTR "#F%4t%%-9d%10t%%-10.3f%20t%%-10.3f%30t%%-12.3f%80t \n"
+define ADD_DATASTR "%4t%-6d%10t%-10.3f%20t%-10.3f%30t%-12.3f%80t \n"
+
+
+# DP_XNADDSTAR -- Write out the ADDSTAR header parameters into a text file.
+
+procedure dp_xnaddstar (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # group output file descriptor
+
+begin
+ # Add header parameters to the table.
+ call dp_xgadppars (dao, tp)
+
+ # Write out the banner.
+ call fprintf (tp, "#\n")
+ call fprintf (tp, ADD_NAMESTR)
+ call fprintf (tp, ADD_UNITSTR)
+ call fprintf (tp, ADD_FORMATSTR)
+ call fprintf (tp, "#\n")
+end
+
+
+# DP_XWADD -- Procedure to write out the new star to the ADDSTAR output
+# text file.
+
+procedure dp_xwadd (tp, id, x, y, mag)
+
+int tp # output file descriptor
+int id # id number
+real x # x value
+real y # y value
+real mag # magnitude
+
+begin
+ call fprintf (tp, ADD_DATASTR)
+ call pargi (id)
+ call pargr (x)
+ call pargr (y)
+ call pargr (mag)
+end
+
+
+# DP_TWADD -- Procedure to write out the new star to the ADDSTAR output
+# table.
+
+procedure dp_twadd (tp, colpoint, id, x, y, mag, row)
+
+int tp # pointer to group output table
+int colpoint[ARB] # column pointers
+int id # id number
+real x # x value
+real y # y value
+real mag # magnitude
+int row # row number to be added
+
+begin
+ call tbrpti (tp, colpoint[1], id, 1, row)
+ call tbrptr (tp, colpoint[2], x, 1, row)
+ call tbrptr (tp, colpoint[3], y, 1, row)
+ call tbrptr (tp, colpoint[4], mag, 1, row)
+end
+
+
+# DP_XGADPPARS -- Add various parameters to the header of the ADDSTAR text
+# output file.
+
+procedure dp_xgadppars (dao, tp)
+
+pointer dao # pointer to the DAOPHOT structure
+int tp # output file descriptor
+
+pointer sp, outstr, date, time
+int envfind()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IRAF", Memc[outstr], "version", "")
+
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call dp_sparam (tp, "USER", Memc[outstr], "name", "")
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "HOST", Memc[outstr], "computer", "")
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (tp, "DATE", Memc[date], "yyyy-mm-dd", "")
+ call dp_sparam (tp, "TIME", Memc[time], "hh:mm:ss", "")
+ call dp_sparam (tp, "PACKAGE", "daophot", "name", "")
+ call dp_sparam (tp, "TASK", "addstar", "name", "")
+
+ # Write the file name parameters.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PHOTFILE", Memc[outstr], "filename", "")
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSFIMAGE", Memc[outstr], "imagename", "")
+ call dp_imroot (DP_OUTIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "ADDIMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "ADDFILE", Memc[outstr], "filename", "")
+
+ # Write out relevant data parameters.
+ call dp_rparam (tp, "SCALE", DP_SCALE(dao), "units/pix", "")
+ call dp_rparam (tp, "DATAMIN", DP_MINGDATA(dao), "counts", "")
+ call dp_rparam (tp, "DATAMAX", DP_MAXGDATA(dao), "counts", "")
+ call dp_rparam (tp, "GAIN", DP_PHOTADU(dao), "number", "")
+ call dp_rparam (tp, "READNOISE", DP_READNOISE(dao), "electrons", "")
+
+ # Write out the observing parameters.
+ call dp_sparam (tp, "OTIME", DP_OTIME(dao), "timeunit", "")
+ call dp_rparam (tp, "XAIRMASS", DP_XAIRMASS(dao), "number", "")
+ call dp_sparam (tp, "IFILTER", DP_IFILTER(dao), "filter", "")
+
+ # Write out the daopars parameters.
+ call dp_rparam (tp, "PSFRAD", DP_SPSFRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "FITRAD", DP_SFITRAD(dao), "scaleunit", "")
+
+ call sfree(sp)
+end
+
+
+# DP_TGADPPARS -- Add various parameters to the header of the ADDSTAR output
+# table.
+
+procedure dp_tgadppars (dao, tp)
+
+pointer dao # pointer to the DAOPHOT structure
+pointer tp # pointer to the output table
+
+pointer sp, outstr, date, time
+int envfind()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IRAF", Memc[outstr])
+
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call tbhadt (tp, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (tp, "DATE", Memc[date])
+ call tbhadt (tp, "TIME", Memc[time])
+ call tbhadt (tp, "PACKAGE", "daophot")
+ call tbhadt (tp, "TASK", "group")
+
+ # Write the file name parameters.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PHOTFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSFIMAGE", Memc[outstr])
+ call dp_imroot (DP_OUTIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "ADDIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "ADDFILE", Memc[outstr])
+
+ # Write out relevant data parameters.
+ call tbhadr (tp, "SCALE", DP_SCALE(dao))
+ call tbhadr (tp, "DATAMIN", DP_MINGDATA(dao))
+ call tbhadr (tp, "DATAMAX", DP_MAXGDATA(dao))
+ call tbhadr (tp, "GAIN", DP_PHOTADU(dao))
+ call tbhadr (tp, "READNOISE", DP_READNOISE(dao))
+
+ # Write out the observing parameters.
+ call tbhadt (tp, "OTIME", DP_OTIME(dao))
+ call tbhadr (tp, "XAIRMASS", DP_XAIRMASS(dao))
+ call tbhadt (tp, "IFILTER", DP_IFILTER(dao))
+
+ # Write out the daophot parameters.
+ call tbhadr (tp, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (tp, "FITRAD", DP_SFITRAD(dao))
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/addstar/mkpkg b/noao/digiphot/daophot/addstar/mkpkg
new file mode 100644
index 00000000..9092f186
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/mkpkg
@@ -0,0 +1,17 @@
+# ADDSTAR task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpaddrd.x ../lib/apseldef.h
+ dpadconfirm.x
+ dpartstar.x <tbset.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h
+ dpnaddstar.x <tbset.h> <time.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h
+ t_addstar.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/addstar/t_addstar.x b/noao/digiphot/daophot/addstar/t_addstar.x
new file mode 100644
index 00000000..479188c0
--- /dev/null
+++ b/noao/digiphot/daophot/addstar/t_addstar.x
@@ -0,0 +1,331 @@
+include <fset.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+define NSEED 3
+
+# T_ADDSTAR -- Add artificial stars to a list of images.
+
+procedure t_addstar ()
+
+pointer image # the input image
+pointer psfimage # the input PSF image
+pointer photfile # the input photometry file
+pointer addimage # root name for output image and file
+real minmag, maxmag # magnitude range of artificial stars
+int nstar # number of artificial stars
+int nimage # number of new images
+int cache # cache the output image pixels
+
+pointer sp, outfname, im, psffd, oim, dao, str
+int imlist, limlist, plist, lplist, pimlist, lpimlist, oimlist, loimlist
+int ifd, ofd, j, simple, idoffset, root, verbose, verify, update, wcs
+int req_size, old_size, buf_size, memstat
+int seed, iseed[NSEED]
+bool coo_text
+
+real clgetr()
+pointer immap(), tbtopn()
+int clgeti(), fstati(), btoi(), fnldir(), strlen(), strncmp()
+int access(), open(), imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb()
+int fntgfnb(), clgwrd(), sizeof(), dp_memstat()
+bool itob(), clgetb()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Allocate some memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (addimage, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the file names.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("addimage", Memc[addimage], SZ_FNAME)
+
+ # Open the file/image lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ plist = fntopnb (Memc[photfile], NO)
+ lplist = fntlenb (plist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ oimlist = imtopen (Memc[addimage])
+ loimlist = imtlen (oimlist)
+
+ # Check that the image and input photometry list lengths match.
+ if ((lplist > 1) && (lplist != limlist)) {
+ call imtclose (imlist)
+ call fntclsb (plist)
+ call imtclose (pimlist)
+ call imtclose (oimlist)
+ call sfree (sp)
+ call error (0, "Incompatible image and photometry list lengths")
+ }
+
+ # Check that the image and psf image list lengths match.
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (plist)
+ call imtclose (pimlist)
+ call imtclose (oimlist)
+ call sfree (sp)
+ call error (0, "Incompatible image and psf image list lengths")
+ }
+
+ # Check that image and output image list lengths match.
+ if ((loimlist != limlist) && (strncmp (Memc[addimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (plist)
+ call imtclose (pimlist)
+ call imtclose (oimlist)
+ call sfree (sp)
+ call error (0, "Incompatible input and output image list lengths")
+ }
+
+ # Set the type of input text file.
+ simple = btoi (clgetb ("simple_text"))
+
+ # Get the articial star parameters.
+ nimage = clgeti ("nimage")
+ if (lplist <= 0) {
+ nstar = clgeti ("nstar")
+ minmag = clgetr ("minmag")
+ maxmag = clgetr ("maxmag")
+ }
+ seed = clgeti ("seed")
+ idoffset = clgeti ("idoffset")
+
+ verbose = btoi (clgetb ("verbose"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb("cache"))
+
+ # Initialize the daophot structure.
+ call dp_gppars (dao)
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Verify, confirm, update the parameters.
+ if (verify == YES) {
+ call dp_adconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+
+ # Open the PSF structure
+ call dp_fitsetup (dao)
+
+ # Initialize the random number generator.
+ call dp_seed3 (seed, iseed)
+
+ # Now loop over the input image list
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open the input image.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Cache the output image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ #if (memstat == YES)
+ #call dp_pcache (im, INDEFI, buf_size)
+
+ # Read the PSF image.
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage]))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ psffd = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+ call dp_readpsf (dao, psffd)
+
+ # Open the input photometry file.
+ if (lplist <= 0 ) {
+ ifd = NULL
+ call strcpy ("", Memc[photfile], SZ_FNAME)
+ } else if (fntgfnb (plist, Memc[photfile], SZ_FNAME) != EOF) {
+ coo_text = itob (access (Memc[photfile], 0, TEXT_FILE))
+ if (coo_text)
+ ifd = open (Memc[photfile], READ_ONLY, TEXT_FILE)
+ else
+ ifd = tbtopn (Memc[photfile], READ_ONLY, 0)
+ } else
+ call seek (ifd, BOF)
+ call dp_sets (dao, INPHOTFILE, Memc[photfile])
+
+ # Get the output image and file root name.
+ if (imtgetim (oimlist, Memc[addimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[addimage], SZ_FNAME)
+
+ # Now loop over the number of output images per input image.
+ do j = 1, nimage {
+
+ # Open the output image.
+ root = fnldir (Memc[addimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[addimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[addimage])) {
+ call dp_oimname (Memc[image], Memc[outfname], "add",
+ Memc[outfname], SZ_FNAME)
+ oim = immap (Memc[outfname], NEW_COPY, im)
+ } else {
+ call strcpy (Memc[addimage], Memc[outfname], SZ_FNAME)
+ if (nimage > 1) {
+ call sprintf (Memc[outfname+
+ strlen(Memc[outfname])], SZ_FNAME, "%03d")
+ call pargi (j)
+ }
+ oim = immap (Memc[outfname], NEW_COPY, im)
+ }
+ call dp_sets (dao, OUTIMAGE, Memc[outfname])
+ if (memstat == YES)
+ call dp_pcache (oim, INDEFI, buf_size)
+
+ # Copy the input image to the new output image.
+ call dp_imcopy (im, oim)
+ if (memstat == NO)
+ call imflush (oim)
+
+ # Open the output photometry file.
+ root = fnldir (Memc[addimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[addimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[addimage])) {
+ call dp_outname (Memc[image], Memc[outfname], "art",
+ Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ ofd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ ofd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ } else {
+ call strcpy (Memc[addimage], Memc[outfname], SZ_FNAME)
+ if (nimage > 1) {
+ call sprintf (Memc[outfname+
+ strlen(Memc[outfname])], SZ_FNAME, "%03d")
+ call pargi (j)
+ }
+ call strcat (".art", Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ ofd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ ofd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ }
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ # Now go and actually add the stars.
+ call dp_artstar (dao, im, oim, ifd, ofd, nstar, minmag,
+ maxmag, iseed, coo_text, simple, idoffset, memstat)
+
+ # Close the output image and output table.
+ call imunmap (oim)
+ if (DP_TEXT(dao) == YES)
+ call close (ofd)
+ else
+ call tbtclo (ofd)
+ }
+
+ # Close the input image
+ call imunmap (im)
+
+ # Close the PSF image.
+ call imunmap (psffd)
+
+ # Close the input photometry file if there is more than one.
+ if ((ifd != NULL) && (lplist > 1)) {
+ if (coo_text)
+ call close (ifd)
+ else
+ call tbtclo (ifd)
+ ifd = NULL
+ }
+
+ # Uncache memory.
+ call fixmem (old_size)
+ }
+
+ # If there was only a single photometry file close it.
+ if (ifd != NULL && lplist == 1) {
+ if (coo_text)
+ call close (ifd)
+ else
+ call tbtclo (ifd)
+ }
+
+ # Close the image/file lists.
+ call imtclose (imlist)
+ call fntclsb (plist)
+ call imtclose (pimlist)
+ call imtclose (oimlist)
+
+ # Close the PSF structure.
+ call dp_fitclose (dao)
+
+ # Close the daophot structure.
+ call dp_free (dao)
+
+ call sfree (sp)
+end
+
+
+# DP_IMCOPY -- Make a copy of an image.
+
+procedure dp_imcopy (in, out)
+
+pointer in # the input image
+pointer out # input and output descriptors
+
+int npix
+long v1[IM_MAXDIM], v2[IM_MAXDIM]
+pointer l1, l2
+pointer imgnlr(), impnlr()
+
+begin
+ # Initialize position vectors.
+ call amovkl (long(1), v1, IM_MAXDIM)
+ call amovkl (long(1), v2, IM_MAXDIM)
+ npix = IM_LEN(in, 1)
+
+ # Copy the image.
+ while (imgnlr (in, l1, v1) != EOF && impnlr (out, l2, v2) != EOF)
+ call amovr (Memr[l1], Memr[l2], npix)
+end
diff --git a/noao/digiphot/daophot/allstar.par b/noao/digiphot/daophot/allstar.par
new file mode 100644
index 00000000..e8d52d28
--- /dev/null
+++ b/noao/digiphot/daophot/allstar.par
@@ -0,0 +1,19 @@
+# Parameters for the ALLSTAR task
+
+image,f,a,,,,"Image corresponding to photometry"
+photfile,f,a,default,,,"Input photometry file (default: image.mag.?)"
+psfimage,f,a,default,,,"PSF image (default: image.psf.?)"
+allstarfile,f,a,"default",,,"Output photometry file (default: image.als.?)"
+rejfile,f,a,"default",,,"Output rejections file (default: image.arj.?)"
+subimage,f,a,"default",,,"Subtracted image (default: image.sub.?)"
+datapars,pset,h,"",,, Data dependent parameters
+daopars,pset,h,"",,,Psf fitting parameters
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,yes,,,Cache the data in memory?
+verify,b,h,)_.verify,,,Verify critical allstar parameters?
+update,b,h,)_.update,,,Update critical allstar parameters?
+verbose,b,h,)_.verbose,,,Print allstar messages?
+version,i,h,2,1,2,Version
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/allstar/dpabuf.x b/noao/digiphot/daophot/allstar/dpabuf.x
new file mode 100644
index 00000000..13aac109
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpabuf.x
@@ -0,0 +1,495 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/allstardef.h"
+
+# DP_GWT -- Return a pointer to the desired weights pixels. The weights buffer
+# pointer is assumed to be NULL on the initial all. If the new line limits
+# are totally contained within the old line limits no action is taken and
+# the old line limits are returned. If the weights pixels are stored in a
+# scratch image the pixels must be accessed sequentially, otherwise an
+# error is returned.
+
+pointer procedure dp_gwt (dao, im, line1, line2, mode, flush)
+
+pointer dao # pointer to the daophot strucuture
+pointer im # pointer to the input image
+int line1 # the lower line limit
+int line2 # the upper line limit
+int mode # input / output mode
+int flush # flush the output
+
+int nx, ny, xoff, yoff, llast1, llast2
+pointer allstar
+
+begin
+ allstar = DP_ALLSTAR(dao)
+ if (DP_WBUF(allstar) == NULL) {
+ llast1 = 0
+ llast2 = 0
+ } else if (flush == YES) {
+ line1 = llast1
+ line2 = llast2
+ } else if ((line1 >= llast1) && (line2 <= llast2)) {
+ line1 = llast1
+ line2 = llast2
+ return (DP_WBUF(allstar))
+ } else if (line1 < llast1)
+ call error (0,
+ "ERROR: Attempting to access the weights pixels randomly")
+
+ # All the data is cached.
+ if (DP_CACHE (allstar, A_WEIGHT) == YES) {
+
+ nx = IM_LEN(im,1)
+ ny = IM_LEN(im,2)
+ xoff = 1
+ yoff = 1
+ DP_WBUF(allstar) = DP_WEIGHTS(allstar)
+
+ # Read in some new data.
+ } else if (mode == READ_ONLY) {
+
+ call dp_albufl2r (DP_WEIGHTS(allstar), DP_WBUF(allstar),
+ llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+
+ # Write out the old data and read in some new data.
+ } else if (mode == READ_WRITE) {
+
+ call dp_albufl2rw (DP_WEIGHTS(allstar), DP_WEIGHTS(allstar),
+ DP_WBUF(allstar), llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+ }
+
+ # Update the required buffer parameters.
+ DP_WNX(allstar) = nx
+ DP_WNY(allstar) = ny
+ DP_WXOFF(allstar) = xoff
+ DP_WYOFF(allstar) = yoff
+
+ # Update the buffer definition which is currently not used.
+ DP_WLX(allstar) = xoff
+ DP_WMX(allstar) = max (xoff + nx - 1, 0)
+ DP_WLY(allstar) = yoff
+ DP_WMY(allstar) = max (yoff + ny - 1, 0)
+
+ return (DP_WBUF(allstar))
+end
+
+
+# DP_GST -- Return a pointer to the scratch image pixels. The scratch image
+# pointer is assumed to be NULL on the initial all. If the new line limits
+# are totally contained within the old line limits no action is taken and
+# the old line limits are returned. If the scratch image pixels are stored in a
+# scratch image the pixels must be accessed sequentially, otherwise an
+# error is returned.
+
+pointer procedure dp_gst (dao, im, line1, line2, mode, flush)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int line1 # the lower line limit
+int line2 # the upper line limit
+int mode # input / output mode
+int flush # flush the buffer
+
+int nx, ny, xoff, yoff, llast1, llast2
+pointer allstar
+
+begin
+ allstar = DP_ALLSTAR(dao)
+ if (DP_SBUF(allstar) == NULL) {
+ llast1 = 0
+ llast2 = 0
+ } else if (flush == YES) {
+ line1 = llast1
+ line2 = llast2
+ } else if ((line1 >= llast1) && (line2 <= llast2)) {
+ line1 = llast1
+ line2 = llast2
+ return (DP_SBUF(allstar))
+ } else if (line1 < llast1)
+ call error (0,
+ "ERROR: Attempting to access scratch image pixels randomly")
+
+ # All the data is cached.
+ if (DP_CACHE (allstar, A_SUBT) == YES) {
+
+ nx = IM_LEN(im,1)
+ ny = IM_LEN(im,2)
+ xoff = 1
+ yoff = 1
+ DP_SBUF(allstar) = DP_SUBT(allstar)
+
+ # Read in some new data.
+ } else if (mode == READ_ONLY) {
+
+ call dp_albufl2r (DP_SUBT(allstar), DP_SBUF(allstar),
+ llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+
+ # Write out the old data and read in some new data.
+ } else if (mode == READ_WRITE) {
+
+ call dp_albufl2rw (DP_SUBT(allstar), DP_SUBT(allstar),
+ DP_SBUF(allstar), llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+ }
+
+ # Update the required buffer parameters.
+ DP_SNX(allstar) = nx
+ DP_SNY(allstar) = ny
+ DP_SXOFF(allstar) = xoff
+ DP_SYOFF(allstar) = yoff
+
+ # Update the buffer description which is not currently used.
+ DP_SLX(allstar) = xoff
+ DP_SMX(allstar) = max (xoff + nx - 1, 0)
+ DP_SLY(allstar) = yoff
+ DP_SMY(allstar) = max (yoff + ny - 1, 0)
+
+ return (DP_SBUF(allstar))
+end
+
+
+# DP_GDC -- Return a pointer to the subtracted image pixels. The subtracted
+# image pixels pointer is assumed to be NULL on the initial all. If the new
+# line limits are totally contained within the old line limits no action is
+# taken and the old line limits are returned. If the subtracted image pixels are
+# stored in a scratch image the pixels must be accessed sequentially,
+# otherwise an error is returned.
+
+pointer procedure dp_gdc (dao, im, line1, line2, mode, flush)
+
+pointer dao # pointer to the daophot strucuture
+pointer im # pointer to the input image
+int line1, line2 # the upper and lower line limits
+int mode # input / output mode
+int flush # flush the input data
+
+int nx, ny, xoff, yoff, llast1, llast2
+pointer allstar
+
+begin
+ allstar = DP_ALLSTAR(dao)
+ if (DP_DBUF(allstar) == NULL) {
+ llast1 = 0
+ llast2 = 0
+ } else if (flush == YES) {
+ line1 = llast1
+ line2 = llast2
+ } else if ((line1 >= llast1) && (line2 <= llast2)) {
+ line1 = llast1
+ line2 = llast2
+ return (DP_DBUF(allstar))
+ } else if (line1 < llast1)
+ call error (0,
+ "ERROR: Attempting to access subtracted image pixels randomly")
+
+ # All the data is cached.
+ if (DP_CACHE (allstar, A_DCOPY) == YES) {
+
+ nx = IM_LEN(im,1)
+ ny = IM_LEN(im,2)
+ xoff = 1
+ yoff = 1
+ DP_DBUF(allstar) = DP_DATA(allstar)
+
+ # Read in some new data.
+ } else if (mode == READ_ONLY) {
+
+ call dp_albufl2r (DP_DATA(allstar), DP_DBUF(allstar),
+ llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+
+ # Write out the old data and read in some new data.
+ } else if (mode == READ_WRITE) {
+
+ call dp_albufl2rw (DP_DATA(allstar), DP_DATA(allstar),
+ DP_DBUF(allstar), llast1, llast2, line1, line2, flush)
+
+ if (flush == NO) {
+ nx = IM_LEN(im,1)
+ ny = line2 - line1 + 1
+ xoff = 1
+ yoff = line1
+ } else {
+ nx = 0
+ ny = 0
+ xoff = 0
+ yoff = 0
+ }
+ }
+
+ # Update the required buffer parameters.
+ DP_DNX(allstar) = nx
+ DP_DNY(allstar) = ny
+ DP_DXOFF(allstar) = xoff
+ DP_DYOFF(allstar) = yoff
+
+ # Update the buffer definition which is currently not used.
+ DP_DLX(allstar) = xoff
+ DP_DMX(allstar) = max (xoff + nx - 1, 0)
+ DP_DLY(allstar) = yoff
+ DP_DMY(allstar) = max (yoff + ny - 1, 0)
+
+ return (DP_DBUF(allstar))
+end
+
+
+# DP_ALBUFL2RW -- Maintain a buffer of image lines and which can be read from
+# an input image and written to an output image. The input and output images
+# may be the same but must have the same dimensions. A new buffer is created
+# when the buffer pointer is null and reallocated when the buffer changes size.
+
+procedure dp_albufl2rw (inim, outim, buf, llast1, llast2, line1, line2, flush)
+
+pointer inim # the input image pointer
+pointer outim # the output image pointer
+pointer buf # pointer to the internal buffer
+int llast1, llast2 # the line limits of the previous buffer
+int line1, line2 # the line limits of the requested buffer
+int flush # flush the output buffer
+
+int i, ncols, nlines, nllast, lout, nmove
+pointer buf1, buf2
+pointer imgl2r(), impl2r()
+
+define flush_ 11
+
+begin
+ # Write the data in the buffer to the output image and free
+ # the buffer.
+
+ if (flush == YES)
+ go to flush_
+
+ # Define the size of the current buffer.
+ ncols = IM_LEN(inim,1)
+ nlines = line2 - line1 + 1
+
+ # If the buffer pointer is undefined then allocate memory for the
+ # buffer.
+
+ if (buf == NULL) {
+ call malloc (buf, ncols * nlines, TY_REAL)
+ llast1 = 0
+ llast2 = 0
+ nllast = 0
+ } else
+ nllast = llast2 - llast1 + 1
+
+ # Write out the lines that are not needed any more.
+
+ if ((line1 > llast1) && (llast1 > 0)) {
+ buf2 = buf
+ lout = min (llast2, line1 - 1)
+ do i = llast1, lout {
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ buf2 = buf2 + ncols
+ }
+ }
+
+ # Now move the remaining lines to the beginning of the buffer.
+
+ nmove = 0
+ if (llast2 >= line1) {
+ buf1 = buf
+ buf2 = buf + ncols * (line1 - llast1)
+ do i = line1, llast2 {
+ if (buf1 != buf2)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ nmove = nmove + 1
+ buf2 = buf2 + ncols
+ buf1 = buf1 + ncols
+ }
+ }
+
+ # Resize the buffer if necessary.
+
+ if (nlines > nllast)
+ call realloc (buf, ncols * nlines, TY_REAL)
+
+ # Read only the image lines with are different from the last buffer.
+
+ if (line2 > llast2) {
+ buf1 = buf + ncols * nmove
+ lout = max (line1, llast2 + 1)
+ do i = lout, line2 {
+ buf2 = imgl2r (inim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ buf1 = buf1 + ncols
+ }
+ }
+
+ # Save the buffer parameters.
+ llast1 = line1
+ llast2 = line2
+
+ if (flush == NO)
+ return
+flush_
+ # Flush the remaining portion of the buffer to the output image
+ # and free the buffer space.
+
+ if (buf != NULL) {
+
+ buf2 = buf
+ do i = llast1, llast2 {
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ buf2 = buf2 + ncols
+ }
+ call imflush (outim)
+
+ call mfree (buf, TY_REAL)
+ }
+
+ buf = NULL
+end
+
+
+# DP_ALBUFL2R -- Maintain a buffer of image lines which can be read
+# sequentially from an input image. The buffer pointer must be initialized
+# to NULL. A new buffer is created when the buffer pointer is null and
+# reallocated when the buffer increases in size.
+
+procedure dp_albufl2r (inim, buf, llast1, llast2, line1, line2, flush)
+
+pointer inim # pointer to the input image
+pointer buf # pointer to the internal buffer
+int llast1, llast2 # the line limits of the previous buffer
+int line1, line2 # the line limits of the requested buffer
+int flush # flush the output buffer
+
+int i, ncols, nlines, nllast, lout, nmove
+pointer buf1, buf2
+pointer imgl2r()
+
+define flush_ 11
+
+begin
+
+ # Write the data in the buffer to the output image and free
+ # the buffer.
+
+ if (flush == YES)
+ go to flush_
+
+ # Define the size parameters for the new buffer.
+
+ ncols = IM_LEN(inim,1)
+ nlines = line2 - line1 + 1
+
+ # If the buffer pointer is undefined then allocate memory for the
+ # buffer.
+
+ if (buf == NULL) {
+ call malloc (buf, ncols * nlines, TY_REAL)
+ llast1 = 0
+ llast2 = 0
+ nllast = 0
+ } else
+ nllast = llast2 - llast1 + 1
+
+ # Now move the remaining lines to the beginning of the buffer.
+
+ nmove = 0
+ if (llast2 >= line1) {
+ buf1 = buf
+ buf2 = buf + ncols * (line1 - llast1)
+ do i = line1, llast2 {
+ if (buf1 != buf2)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ nmove = nmove + 1
+ buf2 = buf2 + ncols
+ buf1 = buf1 + ncols
+ }
+ }
+
+ # Resize the buffer if necessary.
+
+ if (nlines > nllast)
+ call realloc (buf, ncols * nlines, TY_REAL)
+
+ # Read only the image lines with are different from the last buffer.
+
+ if (line2 > llast2) {
+ buf1 = buf + ncols * nmove
+ lout = max (line1, llast2 + 1)
+ do i = lout, line2 {
+ buf2 = imgl2r (inim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ buf1 = buf1 + ncols
+ }
+ }
+
+ # Save the buffer parameters.
+ llast1 = line1
+ llast2 = line2
+
+ if (flush == NO)
+ return
+flush_
+
+ # Free the buffer space.
+ if (buf != NULL)
+ call mfree (buf, TY_REAL)
+ buf = NULL
+end
diff --git a/noao/digiphot/daophot/allstar/dpaconfirm.x b/noao/digiphot/daophot/allstar/dpaconfirm.x
new file mode 100644
index 00000000..76e24798
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpaconfirm.x
@@ -0,0 +1,37 @@
+include "../lib/daophotdef.h"
+
+# DP_ACONFIRM -- Procedure to confirm the critical allstar parameters.
+
+procedure dp_aconfirm (dao)
+
+pointer dao # pointer to the group structure
+
+int dp_stati()
+
+begin
+ call printf ("\n")
+
+ # Confirm the recentering and sky fitting parameters.
+ call dp_vrecenter (dao)
+ call dp_vgroupsky (dao)
+ call dp_vfitsky (dao)
+ if (dp_stati (dao, FITSKY) == YES) {
+ call dp_vsannulus (dao)
+ call dp_vwsannulus (dao)
+ }
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the maximum group size.
+ call dp_vmaxgroup (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/allstar/dpalinit.x b/noao/digiphot/daophot/allstar/dpalinit.x
new file mode 100644
index 00000000..4f1afb89
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpalinit.x
@@ -0,0 +1,665 @@
+include <mach.h>
+include <imhdr.h>
+include <math.h>
+include "../lib/daophotdef.h"
+include "../lib/allstardef.h"
+
+# DP_SETWT -- Initialize the subtracted image and compute the initial weights
+# image from the input image.
+
+procedure dp_setwt (dao, im)
+
+pointer dao # pointer to daophot structure
+pointer im # input image decriptor
+
+int i, ncol, nline
+pointer sp, v1, v2, v3, v4, line1, line2, line3, line4
+pointer allstar, wtim, dataim, subtim
+real rdnoise, mingdata, maxgdata
+int imgnlr(), impnlr()
+
+begin
+ # Allocate some working space.
+ call smark (sp)
+ call salloc (v1, IM_MAXDIM, TY_LONG)
+ call salloc (v2, IM_MAXDIM, TY_LONG)
+ call salloc (v3, IM_MAXDIM, TY_LONG)
+ call salloc (v4, IM_MAXDIM, TY_LONG)
+
+ # Define the allstar pointer.
+ allstar = DP_ALLSTAR (dao)
+
+ # Define some useful constants.
+ rdnoise = (DP_READNOISE(dao) / DP_PHOTADU(dao)) ** 2
+ if (IS_INDEFR(DP_MINGDATA(dao)))
+ mingdata = -MAX_REAL
+ else
+ mingdata = DP_MINGDATA(dao)
+ if (IS_INDEFR(DP_MAXGDATA(dao)))
+ maxgdata = MAX_REAL
+ else
+ maxgdata = DP_MAXGDATA(dao)
+
+ wtim = DP_WEIGHTS (allstar)
+ dataim = DP_DATA(allstar)
+ subtim = DP_SUBT(allstar)
+ ncol = IM_LEN (im,1)
+ nline = IM_LEN(im,2)
+
+ call amovkl (long(1), Meml[v1], IM_MAXDIM)
+ call amovkl (long(1), Meml[v2], IM_MAXDIM)
+ call amovkl (long(1), Meml[v3], IM_MAXDIM)
+ call amovkl (long(1), Meml[v4], IM_MAXDIM)
+ do i = 1, nline {
+
+ # Get the next line
+ if (imgnlr (im, line1, Meml[v1]) == EOF)
+ break
+
+ # Initialize the subtracted image.
+ if (DP_CACHE(allstar, A_DCOPY) == YES) {
+ call amovr (Memr[line1], Memr[dataim], ncol)
+ dataim = dataim + ncol
+ } else if (impnlr (dataim, line2, Meml[v2]) != EOF) {
+ call amovr (Memr[line1], Memr[line2], ncol)
+ }
+
+ # Initialize the weights image.
+ if (DP_CACHE(allstar, A_WEIGHT) == YES) {
+ call dp_wtvector (Memr[line1], Memr[wtim], ncol, mingdata,
+ maxgdata, rdnoise)
+ wtim = wtim + ncol
+ } else if (impnlr (wtim, line3, Meml[v3]) != EOF) {
+ call dp_wtvector (Memr[line1], Memr[line3], ncol, mingdata,
+ maxgdata, rdnoise)
+ }
+
+ # Initilize the subtracted image.
+ if (DP_CACHE(allstar, A_WEIGHT) == YES) {
+ ;
+ } else if (impnlr (subtim, line4, Meml[v4]) != EOF) {
+ call amovkr (0.0, Memr[line4], ncol)
+ }
+
+ }
+
+ # Make sure all the changes are written to disk.
+ if (DP_CACHE(allstar, A_WEIGHT) == NO)
+ call imflush (DP_WEIGHTS(allstar))
+ if (DP_CACHE(allstar, A_DCOPY) == NO)
+ call imflush (DP_DATA(allstar))
+ if (DP_CACHE(allstar, A_SUBT) == NO)
+ call imflush (DP_SUBT(allstar))
+
+ call sfree (sp)
+end
+
+
+# DP_WTVECTOR -- Compute the initial weights for a vector of input data.
+
+procedure dp_wtvector (a, b, ncols, mingdata, maxgdata, rnoisesq)
+
+real a[ARB] # input array
+real b[ARB] # output array
+int ncols # number of points
+real mingdata # minimum good data value
+real maxgdata # maximum good data value
+real rnoisesq # read noise squared in adu
+
+int i
+
+begin
+ do i = 1, ncols {
+ if (a[i] < mingdata || a[i] > maxgdata)
+ b[i] = -MAX_REAL
+ else
+ b[i] = rnoisesq
+ }
+end
+
+
+define DELTA_MAG 12.5
+define INIT_REL_BRIGHT 0.003
+
+# DP_ALZERO -- Convert from magnitudes to relative brightnesses before
+# fitting the stars. If the star's magnitude is undefined or more than
+# 12.5 magnitudes fainter than the PSF magnitude, a default relative
+# brightness is defined.
+
+procedure dp_alzero (dao, mag, nstars)
+
+pointer dao # pointer to the daophot strucuture
+real mag[ARB] # the magnitude array
+int nstars # number of stars
+
+int i
+pointer psffit
+real faint
+
+begin
+ psffit = DP_PSFFIT (dao)
+ faint = DP_PSFMAG(psffit) + DELTA_MAG
+
+ do i = 1, nstars {
+ if (IS_INDEFR(mag[i])) {
+ mag[i] = INIT_REL_BRIGHT
+ } else if (mag[i] >= faint) {
+ mag[i] = INIT_REL_BRIGHT
+ } else {
+ mag[i] = DAO_RELBRIGHT (psffit, mag[i])
+ }
+ }
+end
+
+
+# DP_STRIP -- Remove stars with undefined centers, stars with centers that
+# are off the input image, and duplicate stars from the input photometry
+# list, where duplicate stars are defined as those within a distance of
+# radius pixels of each other. The duplicate stars are moved to the end of
+# the star list and the number of stars is recomputed.
+
+procedure dp_strip (id, x, y, mag, sky, skip, aier, nstar, sepradsq, ncol,
+ nline, fitradius, verbose)
+
+int id[ARB] # array of star ids
+real x[ARB] # array of star x values
+real y[ARB] # array of star y values
+real mag[ARB] # array of star magnitudes
+real sky[ARB] # array of star sky values
+int skip[ARB] # array of fit/nofit indicators
+int aier[ARB] # array of error codes
+int nstar # number of stars (may change)
+real sepradsq # separation radius squared
+int ncol # number of columns in the image
+int nline # number of columns in the image
+real fitradius # the fitting radius
+int verbose # print error messages ?
+
+int i, j, ier, ahold
+pointer sp, index, idhold
+real seprad, dx, dy, xhold, yhold, maghold, skyhold
+
+begin
+ # Duplicate stars are impossible.
+ if (nstar <= 1)
+ return
+
+ # Allocate some working space.
+ call smark (sp)
+ call salloc (index, nstar, TY_INT)
+
+ # Sort the data in y.
+ call quick (y, nstar, Memi[index], ier)
+
+ # Rectify the remaining arrays.
+ call dp_irectify (id, Memi[index], nstar)
+ call dp_rectify (x, Memi[index], nstar)
+ call dp_rectify (mag, Memi[index], nstar)
+ call dp_rectify (sky, Memi[index], nstar)
+
+ # Determine whether any stars are close to star i.
+ seprad = sqrt (sepradsq)
+ do i = 1, nstar - 1 {
+
+ # This star was rejected on a previous loop.
+ if (skip[i] == YES)
+ next
+
+ # Reject if star has an INDEF valued position or is off image.
+ if (IS_INDEFR(x[i]) || IS_INDEFR(y[i])) {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d has an undefined x or y value\n")
+ call pargi (id[i])
+ } else if ((int (x[i] - fitradius) + 1) > ncol) {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf ("REJECTING: Star %d is outside the image\n")
+ call pargi (id[i])
+ } else if (int (x[i] + fitradius) < 1) {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf ("REJECTING: Star %d is outside the image\n")
+ call pargi (id[i])
+ } else if ((int (y[i] - fitradius) + 1) > nline) {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf ("REJECTING: Star %d is outside the image\n")
+ call pargi (id[i])
+ } else if (int (y[i] + fitradius) < 1) {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf ("REJECTING: Star %d is outside the image\n")
+ call pargi (id[i])
+ }
+
+ # This star was rejected on this loop.
+ if (skip[i] == YES)
+ next
+
+ # Loop over the remaining stars.
+ do j = i + 1, nstar {
+
+ # Star has already been rejected on previous loop.
+ if (skip[j] == YES)
+ next
+
+ # Test for INDEF.
+ if (IS_INDEFR(x[j]) || IS_INDEFR(y[j])) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d has an undefined x or y value\n")
+ call pargi (id[j])
+ } else if ((int (x[j] - fitradius) + 1) > ncol) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d is outside the image\n")
+ call pargi (id[j])
+ } else if (int (x[j] + fitradius) < 1) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d is outside the image\n")
+ call pargi (id[j])
+ } else if ((int (y[j] - fitradius) + 1) > nline) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d is outside the image\n")
+ call pargi (id[j])
+ } else if (int (y[j] + fitradius) < 1) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_OFFIMAGE
+ if (verbose == YES)
+ call printf (
+ "REJECTING: Star %d is outside the image\n")
+ call pargi (id[j])
+ }
+
+ # Star was rejected.
+ if (skip[j] == YES)
+ next
+
+ # Test for proximity.
+ dy = y[j] - y[i]
+ if (dy > seprad)
+ break
+ dx = x[j] - x[i]
+ if (abs (dx) > seprad)
+ next
+ if ((dx * dx + dy * dy) > sepradsq)
+ next
+
+ # Set the magnitude of the star to INDEF and skip.
+ if (mag[j] <= mag[i]) {
+ mag[j] = INDEFR
+ skip[j] = YES
+ aier[j] = ALLERR_MERGE
+ if (verbose == YES) {
+ call printf (
+ "REJECTING: Star %d has merged with star %d\n")
+ call pargi (id[j])
+ call pargi (id[i])
+ }
+ } else {
+ mag[i] = INDEFR
+ skip[i] = YES
+ aier[i] = ALLERR_MERGE
+ if (verbose == YES) {
+ call printf (
+ "REJECTING: Star %d has merged with star %d\n")
+ call pargi (id[i])
+ call pargi (id[j])
+ }
+ break
+ }
+ }
+ }
+
+ # Remove the duplicate stars.
+ for (i = 1; i <= nstar; i = i + 1) {
+
+ # Redefine the number of stars by removing skipped stars from
+ # the end of the star list.
+ while (nstar >= 1) {
+ if (skip[nstar] == NO)
+ break
+ nstar = nstar - 1
+ }
+ if (i > nstar)
+ break
+ if (skip[i] == NO)
+ next
+
+ # Switch the rejected star with the one at the end of the list.
+ idhold = id[i]
+ xhold = x[i]
+ yhold = y[i]
+ maghold = mag[i]
+ skyhold = sky[i]
+ ahold = aier[i]
+
+ id[i] = id[nstar]
+ x[i] = x[nstar]
+ y[i] = y[nstar]
+ mag[i] = mag[nstar]
+ sky[i] = sky[nstar]
+ skip[i] = NO
+ aier[i] = aier[nstar]
+
+ id[nstar] = idhold
+ x[nstar] = xhold
+ y[nstar] = yhold
+ mag[nstar] = maghold
+ sky[nstar] = skyhold
+ skip[nstar] = YES
+ aier[nstar] = ahold
+
+ nstar = nstar - 1
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_WSTINIT -- Initialize the weight and scratch arrays / images.
+
+procedure dp_wstinit (dao, im, xcen, ycen, mag, nstar, radius, x1, x2, y1, y2)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real xcen[ARB] # the x centers array
+real ycen[ARB] # the y centers array
+real mag[ARB] # the magnitude array
+int nstar # the number of stars
+real radius # radius for subraction
+int x1, x2 # column limits
+int y1, y2 # line limits
+
+int j, l, ncol, npix, nl, ns, lx, mx
+pointer psffit, allstar, databuf, wtbuf, owtbuf, subtbuf
+real rsq, psfradius, psfradsq, x, y, dy, dysq, deltax, deltay
+pointer imgs2r(), imps2r()
+
+begin
+ # Set up some pointers.
+ psffit = DP_PSFFIT(dao)
+ allstar = DP_ALLSTAR(dao)
+
+ # Set up some constants.
+ ncol = IM_LEN(im,1)
+ npix = x2 - x1 + 1
+ rsq = radius ** 2
+ if (DP_PSFSIZE(psffit) == 0)
+ psfradius = DP_PSFRAD(dao)
+ else
+ psfradius = (real (DP_PSFSIZE(psffit) - 1) / 2.0 - 1.0) / 2.0
+ psfradsq = psfradius * psfradius
+
+ # Begin the search of the groups at the first group.
+ ns = 0
+ nl = 0
+
+ ns = 0
+ do j = y1, y2 {
+
+ # Get the data.
+ if (DP_CACHE(allstar,A_DCOPY) == YES)
+ databuf = DP_DATA(allstar) + (j - 1) * ncol + x1 - 1
+ else
+ databuf = imgs2r (DP_DATA(allstar), x1, x2, j, j)
+ if (DP_CACHE(allstar,A_WEIGHT) == YES) {
+ wtbuf = DP_WEIGHTS(allstar) + (j - 1) * ncol + x1 - 1
+ owtbuf = wtbuf
+ } else {
+ owtbuf = imps2r (DP_WEIGHTS(allstar), x1, x2, j, j)
+ wtbuf = imgs2r (DP_WEIGHTS(allstar), x1, x2, j, j)
+ }
+ if (DP_CACHE(allstar,A_SUBT) == YES)
+ subtbuf = DP_SUBT(allstar) + (j - 1) * ncol + x1 - 1
+ else
+ subtbuf = imps2r (DP_SUBT(allstar), x1, x2, j, j)
+
+ # Set all the weights in the working array negative.
+ call aabsr (Memr[wtbuf], Memr[owtbuf], npix)
+ call anegr (Memr[owtbuf], Memr[owtbuf], npix)
+ call amovkr (0.0, Memr[subtbuf], npix)
+
+ # Set the y coordinate.
+ y = real (j)
+
+ # Initialize the weight and scratch arrays.
+
+ # Find all the points within one working radius of each star.
+ # Set all the sigmas positive again and copy them from DATA
+ # to SUBT.
+ do l = ns + 1, nstar {
+ dy = y - ycen[l]
+ if (dy > radius) {
+ ns = l
+ next
+ } else if (dy < -radius)
+ break
+ dysq = dy ** 2
+ lx = max (x1, min (x2, int (xcen[l] - radius) + 1))
+ mx = max (x1, min (x2, int (xcen[l] + radius)))
+ x = xcen[l] - lx + 1.0
+ lx = lx - x1 + 1
+ mx = mx - x1 + 1
+ call dp_wstvector (x, Memr[databuf+lx-1], Memr[owtbuf+lx-1],
+ Memr[subtbuf+lx-1], mx - lx + 1, dysq, rsq, -MAX_REAL)
+ }
+
+ do l = nl + 1, nstar {
+ dy = y - ycen[l]
+ if (dy > psfradius) {
+ nl = l
+ next
+ } else if (dy < -psfradius)
+ break
+ dysq = dy ** 2
+ lx = max (x1, min (x2, int (xcen[l] - psfradius) + 1))
+ mx = max (x1, min (x2, int (xcen[l] + psfradius)))
+ x = xcen[l] - lx + 1.0
+ lx = lx - x1 + 1
+ mx = mx - x1 + 1
+ call dp_wpsf (dao, im, xcen[l], ycen[l], deltax, deltay, 1)
+ deltax = (deltax - 1.0) / DP_PSFX(psffit) - 1.0
+ deltay = (deltay - 1.0) / DP_PSFY(psffit) - 1.0
+ call dp_alsubstar (psffit, x, dy, deltax, deltay, mag[l],
+ Memr[subtbuf+lx-1], Memr[owtbuf+lx-1], mx - lx + 1, dysq,
+ psfradsq)
+ }
+ }
+
+ if (DP_CACHE(allstar,A_WEIGHT) == NO)
+ call imflush (DP_WEIGHTS(allstar))
+ if (DP_CACHE(allstar,A_SUBT) == NO)
+ call imflush (DP_SUBT(allstar))
+end
+
+
+# DP_WSTVECTOR -- Set the weight and scratch vector
+
+procedure dp_wstvector (xcen, data, weight, subt, npix, dysq, rsq, badwt)
+
+real xcen # x coordinate of center
+real data[ARB] # the data array
+real weight[ARB] # the weight array
+real subt[ARB] # the subtracted array array
+int npix # the number of pixels
+real dysq # the y distance squared
+real rsq # the inclusion radius squared
+real badwt # badwt value
+
+int i
+real dx
+
+begin
+ do i = 1, npix {
+ dx = (real (i) - xcen)
+ if ((dx ** 2 + dysq) <= rsq) {
+ if (weight[i] <= badwt)
+ next
+ weight[i] = abs (weight[i])
+ subt[i] = data[i]
+ } else if (dx >= 0.0)
+ break
+ }
+end
+
+
+# DP_ALSUBSTAR -- The subtraction vector.
+
+procedure dp_alsubstar (psffit, xcen, dy, deltax, deltay, mag, subt, weight,
+ npix, dysq, psfradsq)
+
+pointer psffit # pointer to the psf fitting structure
+real xcen # x coordinate of center
+real dy # y offset from psf center
+real deltax # x distance from psf position
+real deltay # y distance from psf position
+real mag # the magnitude of the star
+real subt[ARB] # the subtracted array array
+real weight[ARB] # the weight array
+int npix # the number of pixels
+real dysq # the y distance squared
+real psfradsq # the inclusion radius squared
+
+int i
+real dx, dvdxc, dvdyc
+real dp_usepsf()
+
+begin
+ do i = 1, npix {
+ if (weight[i] < 0.0)
+ next
+ dx = real (i) - xcen
+ if ((dx ** 2 + dysq) < psfradsq) {
+ subt[i] = subt[i] - mag * dp_usepsf (DP_PSFUNCTION(psffit),
+ dx, dy, DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), deltax, deltay,
+ dvdxc, dvdyc)
+ } else if (dx > 0.0)
+ break
+ }
+end
+
+
+# DP_ALSKY -- Recompute the sky values.
+
+procedure dp_alsky (dao, im, xcen, ycen, sky, nstar, x1, x2, y1, y2, rinsky,
+ routsky, minnsky, badwt)
+
+pointer dao # pointer to the daophot structure
+int im # the input image pointer
+real xcen[ARB] # x coordinates
+real ycen[ARB] # y coordinates
+real sky[ARB] # sky values
+int nstar # number of stars
+int x1, x2 # coordinate limits
+int y1, y2 # coordinate limits
+real rinsky # inner radius of the sky annulus
+real routsky # outer radius of the sky annulus
+int minnsky # minimum number of sky pixels
+real badwt # the bad weight value
+
+int istar, i, j, ncols, lenskybuf, lx, mx, ly, my, line1, line2, nsky, ier
+pointer allstar, sub, psub, wgt, pwgt, skyvals, index
+real risq, rosq, dannulus, dysq, dx, rsq
+pointer dp_gst(), dp_gwt()
+
+begin
+ # Get the allstar pointer.
+ allstar = DP_ALLSTAR(dao)
+
+ # Define some constants
+ ncols = IM_LEN(im,1)
+ risq = rinsky ** 2
+ rosq = routsky ** 2
+ dannulus = routsky - rinsky
+
+ # Allcoate some working memory.
+ lenskybuf = PI * (2.0 * rinsky + dannulus + 1.0) * (dannulus + 0.5)
+ call malloc (skyvals, lenskybuf, TY_REAL)
+ call malloc (index, lenskybuf, TY_INT)
+
+ # Accumulate the sky buffer.
+ do istar = 1, nstar {
+
+ # Get the data.
+ lx = max (x1, min (x2, int (xcen[istar] - routsky) + 1))
+ mx = max (x1, min (x2, int (xcen[istar] + routsky)))
+ ly = max (y1, min (y2, int (ycen[istar] - routsky) + 1))
+ my = max (y1, min (y2, int (ycen[istar] + routsky)))
+ line1 = ly
+ line2 = my
+ sub = dp_gst (dao, im, line1, line2, READ_ONLY, NO)
+ wgt = dp_gwt (dao, im, line1, line2, READ_ONLY, NO)
+
+ nsky = 0
+ psub = sub + (ly - DP_SYOFF(allstar)) * ncols
+ pwgt = wgt + (ly - DP_WYOFF(allstar)) * ncols
+ do j = ly, my {
+ dysq = (real (j) - ycen[istar]) ** 2
+ do i = lx, mx {
+ dx = (real (i) - xcen[istar])
+ rsq = dx ** 2 + dysq
+ if (rsq > rosq) {
+ if (dx > 0.0)
+ break
+ else
+ next
+ }
+ if (rsq < risq)
+ next
+ if (Memr[pwgt+i-1] <= badwt)
+ next
+ Memr[skyvals+nsky] = Memr[psub+i-1]
+ nsky = nsky + 1
+ }
+ psub = psub + ncols
+ pwgt = pwgt + ncols
+ }
+
+ # Compute the new sky value.
+ if (nsky > minnsky) {
+ call quick (Memr[skyvals], nsky, Memi[index], ier)
+ j = nint (0.2 * nsky)
+ dx = 0.0
+ do i = (nsky + 1) / 2 - j, (nsky / 2) + j + 1
+ dx = dx + Memr[skyvals+i-1]
+ sky[istar] = dx / real ((nsky / 2) + 2 * j + 2 -
+ (nsky + 1) / 2)
+ }
+ }
+
+
+ call mfree (skyvals, TY_REAL)
+ call mfree (index, TY_INT)
+ sub = dp_gst (dao, im, line1, line2, READ_ONLY, YES)
+ wgt = dp_gwt (dao, im, line1, line2, READ_ONLY, YES)
+end
diff --git a/noao/digiphot/daophot/allstar/dpalmemstar.x b/noao/digiphot/daophot/allstar/dpalmemstar.x
new file mode 100644
index 00000000..fd9ee80e
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpalmemstar.x
@@ -0,0 +1,182 @@
+include "../lib/daophotdef.h"
+include "../lib/allstardef.h"
+
+# DP_ALLSTARSETUP -- Procedure to set up the ALLSTAR parameters.
+
+procedure dp_allstarsetup (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer allstar
+
+begin
+ # Allocate memory.
+ call malloc (DP_ALLSTAR(dp), LEN_ALLSTARSTRUCT, TY_STRUCT)
+ allstar = DP_ALLSTAR(dp)
+
+ DP_DATA(allstar) = NULL
+ DP_SUBT(allstar) = NULL
+ DP_WEIGHTS(allstar) = NULL
+ DP_DBUF(allstar) = NULL
+ DP_SBUF(allstar) = NULL
+ DP_WBUF(allstar) = NULL
+
+ DP_ANUMER(allstar) = NULL
+ DP_ADENOM(allstar) = NULL
+ DP_ASUMWT(allstar) = NULL
+ DP_ARPIXSQ(allstar) = NULL
+ DP_ASKIP(allstar) = NULL
+ DP_AXCLAMP(allstar) = NULL
+ DP_AYCLAMP(allstar) = NULL
+ DP_AXOLD(allstar) = NULL
+ DP_AYOLD(allstar) = NULL
+ DP_AX(allstar) = NULL
+ DP_AV(allstar) = NULL
+ DP_AC(allstar) = NULL
+ DP_ALAST(allstar) = NULL
+ DP_ANPIX(allstar) = NULL
+ DP_AIER(allstar) = NULL
+end
+
+
+# DP_ALMEMSTAR -- Procedure to allocate sufficient memory for ALLSTAR.
+
+procedure dp_almemstar (dao, max_star, max_group)
+
+pointer dao # pointer to daophot structure
+int max_star # maximum number of stars
+int max_group # maximum group size
+
+pointer allstar
+
+begin
+ allstar = DP_ALLSTAR(dao)
+
+ if (DP_ANUMER (allstar) != NULL)
+ call mfree (DP_ANUMER (allstar), TY_REAL)
+ call malloc (DP_ANUMER (allstar), max_star, TY_REAL)
+
+ if (DP_ADENOM (allstar) != NULL)
+ call mfree (DP_ADENOM (allstar), TY_REAL)
+ call malloc (DP_ADENOM (allstar), max_star, TY_REAL)
+
+ if (DP_ARPIXSQ (allstar) != NULL)
+ call mfree (DP_ARPIXSQ (allstar), TY_REAL)
+ call malloc (DP_ARPIXSQ (allstar), max_star, TY_REAL)
+
+ if (DP_ASUMWT (allstar) != NULL)
+ call mfree (DP_ASUMWT (allstar), TY_REAL)
+ call malloc (DP_ASUMWT (allstar), max_star, TY_REAL)
+
+ if (DP_ANPIX (allstar) != NULL)
+ call mfree (DP_ANPIX (allstar), TY_INT)
+ call malloc (DP_ANPIX (allstar), max_star, TY_INT)
+
+ if (DP_AIER (allstar) != NULL)
+ call mfree (DP_AIER (allstar), TY_INT)
+ call malloc (DP_AIER (allstar), max_star, TY_INT)
+
+ if (DP_ASKIP (allstar) != NULL)
+ call mfree (DP_ASKIP (allstar), TY_INT)
+ call malloc (DP_ASKIP (allstar), max_star, TY_INT)
+
+ if (DP_ALAST (allstar) != NULL)
+ call mfree (DP_ALAST (allstar), TY_INT)
+ call malloc (DP_ALAST (allstar), max_star, TY_INT)
+
+ if (DP_AXCLAMP (allstar) != NULL)
+ call mfree (DP_AXCLAMP (allstar), TY_REAL)
+ call malloc (DP_AXCLAMP (allstar), max_star, TY_REAL)
+
+ if (DP_AYCLAMP (allstar) != NULL)
+ call mfree (DP_AYCLAMP (allstar), TY_REAL)
+ call malloc (DP_AYCLAMP (allstar), max_star, TY_REAL)
+
+ if (DP_AXOLD (allstar) != NULL)
+ call mfree (DP_AXOLD (allstar), TY_REAL)
+ call malloc (DP_AXOLD (allstar), max_star, TY_REAL)
+
+ if (DP_AYOLD (allstar) != NULL)
+ call mfree (DP_AYOLD (allstar), TY_REAL)
+ call malloc (DP_AYOLD (allstar), max_star, TY_REAL)
+
+ # Allocate space for the fitting matrices. Note that nine
+ # times less space is required if recentering is turned
+ # off.
+ if (DP_RECENTER(dao) == YES) {
+
+ if (DP_AX (allstar) != NULL)
+ call mfree (DP_AX (allstar), TY_REAL)
+ call malloc (DP_AX (allstar), 3 * max_group + 1, TY_REAL)
+
+ if (DP_AV (allstar) != NULL)
+ call mfree (DP_AV (allstar), TY_REAL)
+ call malloc (DP_AV (allstar), 3 * max_group + 1, TY_REAL)
+
+ if (DP_AC (allstar) != NULL)
+ call mfree (DP_AC (allstar), TY_REAL)
+ call malloc (DP_AC (allstar), (3 * max_group + 1) *
+ (3 * max_group + 1), TY_REAL)
+
+ } else {
+
+ if (DP_AX (allstar) != NULL)
+ call mfree (DP_AX (allstar), TY_REAL)
+ call malloc (DP_AX (allstar), max_group + 1, TY_REAL)
+
+ if (DP_AV (allstar) != NULL)
+ call mfree (DP_AV (allstar), TY_REAL)
+ call malloc (DP_AV (allstar), max_group + 1, TY_REAL)
+
+ if (DP_AC (allstar) != NULL)
+ call mfree (DP_AC (allstar), TY_REAL)
+ call malloc (DP_AC (allstar), (max_group + 1) * (max_group + 1),
+ TY_REAL)
+ }
+end
+
+
+# DP_ALCLOSE -- Procedure to close up the ALLSTAR parameters.
+
+procedure dp_alclose (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer allstar
+
+begin
+ allstar = DP_ALLSTAR(dp)
+
+ if (DP_ANUMER (allstar) != NULL)
+ call mfree (DP_ANUMER (allstar), TY_REAL)
+ if (DP_ADENOM (allstar) != NULL)
+ call mfree (DP_ADENOM (allstar), TY_REAL)
+ if (DP_ARPIXSQ (allstar) != NULL)
+ call mfree (DP_ARPIXSQ (allstar), TY_REAL)
+ if (DP_ASUMWT (allstar) != NULL)
+ call mfree (DP_ASUMWT (allstar), TY_REAL)
+ if (DP_ASKIP (allstar) != NULL)
+ call mfree (DP_ASKIP (allstar), TY_INT)
+ if (DP_ALAST (allstar) != NULL)
+ call mfree (DP_ALAST (allstar), TY_INT)
+ if (DP_AXCLAMP (allstar) != NULL)
+ call mfree (DP_AXCLAMP (allstar), TY_REAL)
+ if (DP_AYCLAMP (allstar) != NULL)
+ call mfree (DP_AYCLAMP (allstar), TY_REAL)
+ if (DP_AXOLD (allstar) != NULL)
+ call mfree (DP_AXOLD (allstar), TY_REAL)
+ if (DP_AYOLD (allstar) != NULL)
+ call mfree (DP_AYOLD (allstar), TY_REAL)
+ if (DP_AX (allstar) != NULL)
+ call mfree (DP_AX (allstar), TY_REAL)
+ if (DP_AV (allstar) != NULL)
+ call mfree (DP_AV (allstar), TY_REAL)
+ if (DP_AC (allstar) != NULL)
+ call mfree (DP_AC (allstar), TY_REAL)
+ if (DP_ANPIX (allstar) != NULL)
+ call mfree (DP_ANPIX (allstar), TY_INT)
+ if (DP_AIER (allstar) != NULL)
+ call mfree (DP_AIER (allstar), TY_INT)
+
+ call mfree (allstar, TY_STRUCT)
+end
diff --git a/noao/digiphot/daophot/allstar/dpalphot.x b/noao/digiphot/daophot/allstar/dpalphot.x
new file mode 100644
index 00000000..74741958
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpalphot.x
@@ -0,0 +1,1438 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/allstardef.h"
+
+# DP_ALPHOT -- Perform one iteration on each group of stars.
+
+int procedure dp_alphot (dao, im, ntot, istar, niter, sepcrit, sepmin, wcrit,
+ clip, clampmax, version)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int ntot # the total number of stars left unfit
+int istar # first star in the current group
+int niter # the current iteration
+real sepcrit # critical separation for merging
+real sepmin # minimum separation for merging
+real wcrit # the critical error for merging
+bool clip # clip the data
+real clampmax # maximum clamping factor
+int version # version number
+
+bool regroup
+int cdimen, lstar, nstar, fstar, nterm, ixmin, ixmax, iymin, iymax
+int fixmin, fixmax, fiymin, fiymax, nxpix, nypix, flag, i, j, k, ifaint
+pointer apsel, psffit, allstar, data, subt, weights
+real radius, totradius, mean_sky, pererr, peakerr, faint
+real xmin, xmax, ymin, ymax, sumres, grpwt, chigrp
+
+bool dp_alredo(), dp_checkc(), dp_almerge(), dp_alclamp(), dp_alfaint()
+int dp_laststar(), dp_delfaintest()
+pointer dp_gwt(), dp_gst(), dp_gdc()
+real dp_almsky(), asumr()
+
+begin
+ # Get some daophot pointers.
+ psffit = DP_PSFFIT (dao)
+ apsel = DP_APSEL(dao)
+ allstar = DP_ALLSTAR (dao)
+
+ # Define some constants. At some point these should be stored
+ # in the allstar structure at task initialization. When the final
+ # rewrite gets done this will occur.
+
+ radius = DP_FITRAD(dao)
+ totradius = DP_FITRAD(dao) + DP_PSFRAD(dao) + 1
+ if (DP_RECENTER(dao) == YES)
+ cdimen = 3 * DP_MAXGROUP(dao) + 1
+ else
+ cdimen = DP_MAXGROUP(dao) + 1
+ pererr = 0.01 * DP_FLATERR(dao)
+ peakerr = 0.01 * DP_PROFERR(dao) / (Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1])
+ regroup = false
+
+ repeat {
+
+ # Given the last star arrary as computed by dp_regroup, the first
+ # star in the current group, and the total number of stars,
+ # find the last star in the current group and compute the
+ # total number of stars in the group.
+
+ lstar = dp_laststar (Memi[DP_ALAST(allstar)], istar, ntot)
+ nstar = lstar - istar + 1
+
+ # Don't compute the subraster limits if no regroup has been
+ # performed.
+ if (! regroup) {
+ call alimr (Memr[DP_APXCEN(apsel)+istar-1], nstar, xmin, xmax)
+ call alimr (Memr[DP_APYCEN(apsel)+istar-1], nstar, ymin, ymax)
+ }
+
+ # Determine whether the group is too large to be fit.
+
+ if (nstar > DP_MAXGROUP (dao)) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Group too large: %5d Fitting Radius: %5.2f Regrouping\n")
+ call pargi (nstar)
+ call pargr (radius)
+ }
+
+ # If size of group too small go to next group.
+ radius = RADIUS_FRACTION * radius
+ if ((DP_RECENTER(dao) == YES) && (niter >= 2)) {
+ if (radius < DENSE_RADIUS1) {
+ fstar = dp_delfaintest (Memr[DP_APMAG(apsel)], istar,
+ lstar)
+ Memr[DP_APMAG(apsel)+fstar-1] = INDEFR
+ Memi[DP_ASKIP(allstar)+fstar-1] = YES
+ Memi[DP_AIER(allstar)+fstar-1] = ALLERR_BIGGROUP
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "REJECTING: Star ID: %d Group too dense to reduce\n")
+ call pargi (Memi[DP_APID(apsel)+fstar-1])
+ }
+ return (lstar)
+ }
+ } else {
+ if (radius < DENSE_RADIUS2) {
+ fstar = dp_delfaintest (Memr[DP_APMAG(apsel)], istar,
+ lstar)
+ Memr[DP_APMAG(apsel)+fstar-1] = INDEFR
+ Memi[DP_ASKIP(allstar)+fstar-1] = YES
+ Memi[DP_AIER(allstar)+fstar-1] = ALLERR_BIGGROUP
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "REJECTING: Star ID: %d Group too dense to reduce\n")
+ call pargi (Memi[DP_APID(apsel)+fstar-1])
+ }
+ return (lstar)
+ }
+ }
+
+ # Regroup the stars.
+ call dp_regroup (Memi[DP_APID(apsel)+istar-1],
+ Memr[DP_APXCEN(apsel)+istar-1], Memr[DP_APYCEN(apsel)+
+ istar-1], Memr[DP_APMAG(apsel)+istar-1],
+ Memr[DP_APMSKY(apsel)+istar-1],
+ Memr[DP_ASUMWT(allstar)+istar-1],
+ Memr[DP_AXOLD(allstar)+ istar-1],
+ Memr[DP_AYOLD(allstar)+istar-1],
+ Memr[DP_AXCLAMP(allstar)+istar-1],
+ Memr[DP_AYCLAMP(allstar)+istar-1], nstar, radius,
+ Memi[DP_ALAST(allstar)+istar-1])
+ regroup = true
+ next
+ }
+
+ # Compute the mean sky for the group. If the sky is undefined
+ # reject the group.
+ mean_sky = dp_almsky (Memr[DP_APMSKY(apsel)+istar-1], nstar)
+ if (IS_INDEFR(mean_sky)) {
+ call amovkr (INDEFR, Memr[DP_APMAG(apsel)+istar-1], nstar)
+ call amovki (YES, Memi[DP_ASKIP(allstar)+istar-1], nstar)
+ call amovki (ALLERR_INDEFSKY, Memi[DP_AIER(allstar)+istar-1],
+ nstar)
+ if (DP_VERBOSE(dao) == YES) {
+ do i = istar, lstar {
+ call printf (
+ "REJECTING: Star ID: %d Group sky value is undefined\n")
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ }
+ }
+ return (lstar)
+ }
+
+ # Re-compute the number of terms in the fitting equation.
+ if ((DP_RECENTER(dao) == YES) && (niter >= 2))
+ nterm = 3 * nstar
+ else
+ nterm = nstar
+
+ # Zero the fitting arrays.
+ chigrp = asumr (Memr[DP_ASUMWT(allstar)+istar-1], nstar) / nstar
+ call aclrr (Memr[DP_APCHI(apsel)+istar-1], nstar)
+ call aclrr (Memr[DP_ASUMWT(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_ANUMER(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_ADENOM(allstar)+istar-1], nstar)
+ call aclri (Memi[DP_ANPIX(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_AV(allstar)], nterm)
+ call aclrr (Memr[DP_AC(allstar)], cdimen * cdimen)
+
+ # Compute the subraster limits.
+
+ ixmin = min (IM_LEN (im,1), max (1, int (xmin - totradius) + 1))
+ ixmax = min (IM_LEN (im,1), max (1,int (xmax + totradius)))
+ iymin = min (IM_LEN (im,2), max (1, int (ymin - totradius) + 1))
+ iymax = min (IM_LEN (im,2), max (1, int (ymax + totradius)))
+
+ # Get pointer to the required weight, scratch image and
+ # subtracted image pixels. Need to modify this so writing
+ # is only enabled if iter >= MIN_ITER.
+
+ subt = dp_gst (dao, im, iymin, iymax, READ_ONLY, NO)
+ weights = dp_gwt (dao, im, iymin, iymax, READ_WRITE, NO)
+ data = dp_gdc (dao, im, iymin, iymax, READ_WRITE, NO)
+
+ # Compute the fitting limits in the subraster.
+
+ fixmin = min (ixmax, max (ixmin, int (xmin - DP_FITRAD(dao)) + 1))
+ fixmax = min (ixmax, max (ixmin, int (xmax + DP_FITRAD(dao))))
+ fiymin = min (iymax, max (iymin, int (ymin - DP_FITRAD(dao)) + 1))
+ fiymax = min (iymax, max (iymin, int (ymax + DP_FITRAD(dao))))
+ nypix = fiymax - fiymin + 1
+ nxpix = fixmax - fixmin + 1
+
+ # Now we deal with the pixels one by one.
+ sumres = 0.0
+ grpwt = 0.0
+
+ # Accumulate the data into the matrix.
+ call dp_alaccum (dao, im, Memr[data], DP_DNX(allstar),
+ DP_DNY(allstar), DP_DXOFF(allstar), DP_DYOFF(allstar),
+ Memr[subt], DP_SNX(allstar), DP_SNY(allstar), DP_SXOFF(allstar),
+ DP_SYOFF(allstar), Memr[weights], DP_WNX(allstar),
+ DP_WNY(allstar), DP_WXOFF(allstar), DP_WYOFF(allstar), nxpix,
+ nypix, fixmin, fiymin, mean_sky, istar, lstar, niter, clip,
+ pererr, peakerr, sumres, grpwt, chigrp, cdimen, nterm)
+
+ # Reflect the normal matrix across the diagonal.
+
+ call dp_mreflect (Memr[DP_AC(allstar)], cdimen, nterm)
+
+ # Compute the estimate of the standard deviation of the residuals
+ # for the group as a whole, and for each star. This estimate starts
+ # out as SQRT (PI / 2) * [sum [weight * ABS (residual / sigma)] /
+ # sum [weight] # and then gets corrected for bias by SQRT (# of
+ # pixels / [# of pixel - # degrees of freedom]).
+ #
+ # But now we drive the value toward unity, depending upon exactly
+ # how many pixels were involved. If CHI is based on exactly a total
+ # weight of 3, then it is extremely poorly determined, and we just
+ # want to keep CHI = 1. The larger the GRPWT is, the better
+ # determined CHI is, and the less we want to force it toward unity.
+ # So, just take the weighted average of CHI and unity, with weights
+ # GRPWT = 3, and 1, respectively.
+
+ if (grpwt > nterm) {
+ chigrp = CHI_NORM * sumres / sqrt (grpwt * (grpwt - nterm))
+ chigrp = ((grpwt - 3.0) * chigrp + 3.0) / grpwt
+ } else {
+ chigrp = 1.0
+ }
+
+ # CHIGRP has been pulled towards its expected value of unity to
+ # keep the statistics of a small number of pixels from completely
+ # dominating the error analysis. Similarly, the photometric errors
+ # for the individual stars will be pulled toward unity now. Later
+ # on, if the number of stars in the group is greater than one,
+ # CHI(I) will nudged toward the group average. In order to work
+ # optimally this requires that the gain and read noise and any
+ # other parameters which represent the noise sources have been
+ # properly specified.
+ #
+ # At the same time, make sure that every star in the group contains
+ # at least MIN_FIT_PIXEL valid pixels if re-centroiding is being
+ # performed, 1 valid pixel if not. If any star in the group fails
+ # to meet this criterion, mark that star for deletion and skip
+ # ahead to the next group.
+
+ if (dp_alredo (Memi[DP_APID(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APCHI(apsel)], Memr[DP_ASUMWT(allstar)],
+ Memi[DP_ANPIX(allstar)], Memi[DP_ASKIP(allstar)],
+ Memi[DP_AIER(allstar)], istar, lstar, niter, chigrp,
+ DP_RECENTER(dao), DP_VERBOSE(dao)))
+ return (lstar)
+
+ # Invert the matrix.
+ if (version == 1)
+ call invers (Memr[DP_AC(allstar)], cdimen, nterm, flag)
+ else
+ call invers2 (Memr[DP_AC(allstar)], cdimen, nterm, flag)
+
+ if (dp_checkc (Memr[DP_AC(allstar)], cdimen, nterm,
+ Memi[DP_APID(apsel)], Memr[DP_APMAG(apsel)],
+ Memi[DP_ASKIP(allstar)], Memi[DP_AIER(allstar)], istar, niter,
+ DP_RECENTER(dao), DP_VERBOSE(dao)))
+ return (lstar)
+
+ # Compute the coefficients.
+ call mvmul (Memr[DP_AC(allstar)], cdimen, nterm,
+ Memr[DP_AV(allstar)], Memr[DP_AX(allstar)])
+
+ # In the beginning, the brightness of each star will be permitted
+ # to change by no more than 2 magnitudes per iteration, and the
+ # x,y coordinates of each centroid will be permitted to change by
+ # no more than 0.4 pixel per iteration. Any time that the
+ # parameter correction changes sign from one iteration to the next
+ # the maximum permissable change will be reduced by a factor of
+ # two. These clamps are released any time a star in the group
+ # disappears.
+
+ if (dp_alclamp (dao, im, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memr[DP_ASUMWT(allstar)], Memi[DP_ASKIP(allstar)],
+ Memr[DP_AXOLD(allstar)], Memr[DP_AXCLAMP(allstar)],
+ Memr[DP_AYOLD(allstar)], Memr[DP_AYCLAMP(allstar)], istar,
+ lstar, Memr[DP_AC(allstar)], Memr[DP_AX(allstar)], cdimen,
+ niter, clampmax, pererr, peakerr)) {
+
+ # Flush the new data to the output buffers. Actually
+ # only data which fits this criterion need be written.
+ # However this makes sequential i/o management tricky.
+ # Leave this alone for the moment. Note only the cache-
+ # state is affected.
+ }
+
+ # If there is more than one star, check to see whether any two
+ # stars have merged.
+
+ if (nstar > 1) {
+
+ if (dp_almerge (Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memi[DP_ASKIP(allstar)], istar, lstar, sepcrit, sepmin,
+ wcrit, j, k)) {
+
+ call dp_alcentroid (Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)], j, k)
+
+ # Remove the k-th star from this group.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "REJECTING: Star ID: %d has merged with star ID: %d\n")
+ call pargi (Memi[DP_APID(apsel)+j-1])
+ call pargi (Memi[DP_APID(apsel)+k-1])
+ }
+ Memr[DP_APMAG(apsel)+j-1] = INDEFR
+ Memi[DP_ASKIP(allstar)+j-1] = YES
+ Memi[DP_AIER(allstar)+j-1] = ALLERR_MERGE
+
+ # Loosen the clamps of every star in the group
+ call aclrr (Memr[DP_AXOLD(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_AYOLD(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AXCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AXCLAMP(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AYCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AYCLAMP(allstar)+istar-1], nstar)
+
+ }
+ }
+
+ # If the number of iterations completed is less than or equal
+ # to 3, perform another iteration no questions asked.
+
+ if (niter <= (MIN_ITER - 1))
+ return (lstar)
+
+ # If not star has been removed from the group in the previous
+ # iteration, check to see if any of the stars is too faint (more
+ # than 12.5 magnitudes fainter thanthe PSF star). If several stars
+ # are too faint, delete the faintest one, and set the
+ # brightnesses of the other faint ones exactly to 12.5
+ # magnitudes below the PSF star. That way on the next iteration
+ # we will see whether these stars want to grow or disappear.
+
+ if (dp_alfaint (Memr[DP_APMAG(apsel)], Memi[DP_ASKIP(allstar)],
+ istar, lstar, faint, ifaint))
+ return (lstar)
+
+ # If at least one star is more than 12.5 magnitudes fainter
+ # than the PSF, then IFAINT is the index of the faintest of them
+ # and faint is the relative brightness of the faintest of them.
+
+ if (ifaint > 0) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("REJECTING: Star ID: %d is too faint\n")
+ call pargi (Memi[DP_APID(apsel)+ifaint-1])
+ }
+ Memr[DP_APMAG(apsel)+ifaint-1] = INDEFR
+ Memi[DP_ASKIP(allstar)+ifaint-1] = YES
+ Memi[DP_AIER(allstar)+ifaint-1] = ALLERR_FAINT
+
+ call aclrr (Memr[DP_AXOLD(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_AYOLD(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AXCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AXCLAMP(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AYCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AYCLAMP(allstar)+istar-1], nstar)
+
+ # If no star is more than 12.5 magnitudes fainter than the PSF
+ # then after the 50th iteration delete the least certain star i
+ # if it is less than a one sigma detection; after the 100th
+ # iteration delete the least certain star if it is less than a
+ # two sigma detection; after the 150th delete the least certain
+ # star if it is less than a 3 sigma detection.
+
+ } else if (niter >= 5) {
+
+ call dp_almfaint (Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ istar, lstar, faint, ifaint)
+
+ if (faint < wcrit) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("REJECTING: Star ID: %d is too faint\n")
+ call pargi (Memi[DP_APID(apsel)+ifaint-1])
+ }
+ Memr[DP_APMAG(apsel)+ifaint-1] = INDEFR
+ Memi[DP_ASKIP(allstar)+ifaint-1] = YES
+ Memi[DP_AIER(allstar)+ifaint-1] = ALLERR_FAINT
+
+ # Loosen the clamps of every star in the group.
+ call aclrr (Memr[DP_AXOLD(allstar)+istar-1], nstar)
+ call aclrr (Memr[DP_AYOLD(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AXCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AXCLAMP(allstar)+istar-1], nstar)
+ call amaxkr (Memr[DP_AYCLAMP(allstar)+istar-1], 0.5 *
+ clampmax, Memr[DP_AYCLAMP(allstar)+istar-1], nstar)
+ }
+ }
+
+ break
+ }
+
+ return (lstar)
+end
+
+
+# DP_LASTSTAR -- Find the last star in the current group.
+
+int procedure dp_laststar (last, istar, ntot)
+
+int last[ARB] # the grouping information array
+int istar # index of the first star in the group
+int ntot # total number of stars
+
+int lstar
+
+begin
+ do lstar = istar, ntot, 1 {
+ if (last[lstar] == YES)
+ break
+ }
+
+ return (lstar)
+end
+
+
+# DP_DELFAINTEST -- Delete the faintest star in the group.
+
+int procedure dp_delfaintest (mag, istar, lstar)
+
+real mag[ARB] # the array of magnitudes
+int istar # the first star in the group
+int lstar # the last star in the group
+
+int i, starno
+real faint
+
+begin
+ starno = 0
+ faint = MAX_REAL
+ do i = istar, lstar {
+ if (mag[i] >= faint)
+ next
+ faint = mag[i]
+ starno = i
+ }
+
+ return (starno)
+end
+
+
+# DP_ALMSKY -- Determine the mean sky value for the current group of stars.
+
+real procedure dp_almsky (sky, nstar)
+
+real sky[ARB] # array of sky values
+int nstar # number of stars in the group
+
+int i, nsky
+real sky_sum
+
+begin
+ sky_sum = 0.0
+ nsky = 0
+
+ do i = 1, nstar {
+ if (IS_INDEFR(sky[i]))
+ next
+ sky_sum = sky_sum + sky[i]
+ nsky = nsky + 1
+ }
+
+ if (nsky <= 0)
+ return (INDEFR)
+ else
+ return (sky_sum / nsky)
+end
+
+
+# DP_ALACCUM -- Accumulate the data into the matrix.
+
+procedure dp_alaccum (dao, im, data, dnx, dny, dxoff, dyoff, subt, snx, sny,
+ sxoff, syoff, weights, wnx, wny, wxoff, wyoff, nxpix, nypix, ixmin,
+ iymin, mean_sky, istar, lstar, niter, clip, pererr, peakerr, sumres,
+ grpwt, chigrp, cdimen, nterm)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+real data[dnx,dny] # the subtracted data array
+int dnx, dny # dimenions of the data array
+int dxoff, dyoff # lower left corner of the data array
+real subt[snx,sny] # the scratch array
+int snx, sny # dimensions of the scratch array
+int sxoff, syoff # lower left corner of the scratch array
+real weights[wnx,wny] # the weight array
+int wnx, wny # dimensions of the weight array
+int wxoff, wyoff # lower left corner of the weight array
+int nxpix, nypix # the dimensions of the area of interest
+int ixmin,iymin # lower left corner of area of interest
+real mean_sky # the group sky value
+int istar # the index of the first star in current group
+int lstar # the index of the last star in current group
+int niter # the current interation
+bool clip # clip the errors ?
+real pererr # flat fielding error factor
+real peakerr # profile error factor
+real sumres # sum of the residuals
+real grpwt # the group weight
+real chigrp # the group chi value
+int cdimen # maximum number of maxtrix dimensions
+int nterm # number of terms in the matrix to fit
+
+real fitradsq, maxgdata, fix, fiy, d, delta, sigmasq, relerr, wt, dwt
+pointer psffit, apsel, allstar
+int dix, diy, sxdiff, sydiff, wxdiff, wydiff
+real sky_value, dp_alskyval()
+bool dp_alomit()
+
+begin
+ # Set up some pointers.
+ apsel = DP_APSEL(dao)
+ psffit = DP_PSFFIT(dao)
+ allstar = DP_ALLSTAR(dao)
+
+ # These constants need to be stored more permanently in the
+ # allstar structure at some point. They should all be defined
+ # once and for all at task startup. Leave for next phase
+ # of code cleanup.
+
+ fitradsq = DP_FITRAD(dao) ** 2
+ if (IS_INDEFR(DP_MAXGDATA(dao)))
+ maxgdata = MAX_REAL
+ else
+ maxgdata = DP_MAXGDATA(dao)
+
+ # Compute the array offsets.
+ sxdiff = dxoff - sxoff
+ sydiff = dyoff - syoff
+ wxdiff = dxoff - wxoff
+ wydiff = dyoff - wyoff
+
+ do diy = iymin - dyoff + 1, iymin - dyoff + nypix, 1 {
+ fiy = real (diy + dyoff - 1)
+ do dix = ixmin - dxoff + 1, ixmin - dxoff + nxpix, 1 {
+
+ # Skip data with negative weights.
+ if (weights[dix+wxdiff,diy+wydiff] < 0.0)
+ next
+ fix = real (dix + dxoff - 1)
+
+ # If this current pixel is within one fitting radius of
+ # at least one star in the current group, include it in the
+ # calculation. Otherwise skip it. While figuring this out,
+ # compute the squared distance of this pixel from the
+ # centroid of each star in the group.
+
+ if (dp_alomit (Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_ARPIXSQ(allstar)], istar, lstar, fix, fiy,
+ fitradsq))
+ next
+
+ call dp_alsetskip (Memr[DP_ARPIXSQ(allstar)],
+ Memi[DP_ASKIP(allstar)], istar, lstar, fitradsq)
+
+ if (DP_GROUPSKY(dao) == NO) {
+ sky_value = dp_alskyval (Memr[DP_APMSKY(apsel)],
+ Memi[DP_ASKIP(allstar)], istar, lstar)
+ if (IS_INDEFR(sky_value))
+ sky_value = mean_sky
+ } else
+ sky_value = mean_sky
+
+ # The expected random error in the pixel is the quadratic
+ # sum of the Poisson statistics, plus the readout noise,
+ # plus an estimated error of 0.75% of the total brightness
+ # for the difficulty of flat-fielding and bias-correcting
+ # the chip, plus an estimated error of some fraction of the
+ # of the fourth derivative at the peak of the profile, to
+ # account for the difficulty of accurately interpolating
+ # within the PSF. The fourth derivative of the PSF is
+ # proportional to H/hwhm ** 4 (hwhm is the width of the
+ # stellar core); using the geometric mean of hwhmx and
+ # hwhmy, this becomes H/(hwhmx * hwhmy) ** 2. The ratio of
+ # the fitting error to this quantity is estimated from a
+ # good-seeing CTIO frame to be approimxately 0.027.
+
+ #d = subt[dix+sxdiff,diy+sydiff] - mean_sky
+ d = subt[dix+sxdiff,diy+sydiff] - sky_value
+ delta = max (0.0, data[dix,diy] - d)
+ if ((delta > maxgdata) && (niter >= MIN_ITER))
+ next
+
+ # Dpos = raw data - residual
+ # = model-predicted brightness in this pixel consisting
+ # of sky plus all stellar profiles, which is
+ # presumably non-negative
+ #
+ # The four noise sources in the model are
+ # readout noise
+ # poisson noise
+ # flat-field errors
+ # profile errors
+ #
+ # Numerically the squares of these quantities are
+ # ronoise = sigma[i,j]
+ # poisson noise = delta / gain
+ # flat-field error = constant * delta ** 2
+ # profile error = constant * sum of profile ** 2
+
+ #sigmasq = weights[dix+wxdiff,diy+wydiff] + delta /
+ #DP_PHOTADU(dao) + (pererr * delta) ** 2 +
+ #(peakerr * (delta - mean_sky)) ** 2
+ sigmasq = weights[dix+wxdiff,diy+wydiff] + delta /
+ DP_PHOTADU(dao) + (pererr * delta) ** 2 +
+ (peakerr * (delta - sky_value)) ** 2
+ if (sigmasq <= 0.0)
+ next
+ relerr = abs (d) / sqrt (sigmasq)
+
+ if (clip && (relerr > MAX_RELERR))
+ next
+
+ # Now include this pixel in the fitting equation for the
+ # group.
+
+ wt = 0.0
+ call dp_alxaccum (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_ARPIXSQ(allstar)], Memi[DP_ASKIP(allstar)],
+ Memr[DP_AX(allstar)], Memr[DP_ANUMER(allstar)],
+ Memr[DP_ADENOM(allstar)], istar, lstar, fix, fiy, d,
+ wt, sigmasq, nterm, fitradsq)
+
+ # At this point the vector X contains the first
+ # derivative of the condition equation for pixel (I,J)
+ # with respect to each of the fitting parameters for
+ # all of the stars. Now these derivatives will be added
+ # into the normal matrix and the vector of residuals.
+ # Add this residual into the weighted sum of the absolute
+ # relative residuals
+
+ dwt = wt * relerr
+ sumres = sumres + dwt
+ grpwt = grpwt + wt
+
+ # SUMRES is the weighted sum for all the pixels in the group.
+ # Now also add the weigghted value of the residuals into the
+ # accumulating sum for each of the stars.
+
+ call dp_alchi (Memi[DP_ASKIP(allstar)], Memr[DP_APCHI(apsel)],
+ Memr[DP_ASUMWT(allstar)], Memi[DP_ANPIX(allstar)], istar,
+ lstar, wt, dwt)
+
+ # Up until now, WT represents only the radial weighting
+ # profile. Now figure in the anticipated standard error
+ # of the pixel.
+
+ wt = wt / sigmasq
+
+ # After the third iteration, reduce the weight of a bad pixel
+ # Note that for the first iteration, only the stellar magnitude
+ # is being solved for, which is a problem in LINEAR least
+ # squares, and so should be solved exactly the first time.
+ # After that, the star is given two iterations to adjust it's
+ # centroid before the clipping is turned on. After that a
+ # pixel having a residual of DP_CLIPRANGE times sigma gets
+ # reduced to half weight; a pixel having a residual of n
+ # sigma gets a weight of 1 / [1 + (n/DP_CLIPRANGE) **
+ # DP_CLIPEXP].
+
+ if (clip)
+ wt = wt / (1.0 + (relerr / (chigrp * DP_CLIPRANGE (dao))) **
+ DP_CLIPEXP (dao))
+
+ # Now work this pixel into the normal matrix
+ dwt = d * wt
+ call dp_alcaccum (Memr[DP_AX(allstar)], Memr[DP_AC(allstar)],
+ Memr[DP_AV(allstar)], Memi[DP_ASKIP(allstar)], cdimen,
+ nterm, istar, lstar, wt, dwt)
+ }
+ }
+end
+
+
+# DP_ALOMIT - Omit pixels which are too far from the center of any star
+# in the group.
+
+bool procedure dp_alomit (xcen, ycen, rpixsq, istar, lstar, fix, fiy,
+ fitradsq)
+
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real rpixsq[ARB] # array of pixel differences
+int istar, lstar # first and last star
+real fix, fiy # current star position
+real fitradsq # fit radius squared
+
+bool omit
+int i
+
+begin
+ omit = true
+ do i = istar, lstar {
+ rpixsq[i] = (fix - xcen[i]) ** 2 + (fiy - ycen[i]) ** 2
+ if (rpixsq[i] < fitradsq)
+ omit = false
+ }
+
+ return (omit)
+end
+
+
+# DP_ALSETSKIP -- Initialize the skip array.
+
+procedure dp_alsetskip (rpixsq, skip, istar, lstar, fitradsq)
+
+real rpixsq[ARB] # pixel distance squared
+int skip[ARB] # skip array
+int istar # the index of the first star
+int lstar # the index of the last star
+real fitradsq # the fitting radius squared
+
+int i
+
+begin
+ do i = istar, lstar {
+ if (rpixsq[i] < fitradsq)
+ skip[i] = NO
+ else
+ skip[i] = YES
+ }
+end
+
+
+# DP_ALSKYVAL -- Compute the sky value to be subtracted from a given pixel
+# by averaging the sky values of all the the stars for which the pixel in
+# question is within one fitting radius.
+
+real procedure dp_alskyval (sky, skip, istar, lstar)
+
+real sky[ARB] # the array of sky values
+int skip[ARB] # the array of skip values
+int istar # the index of the first star
+int lstar # the index of the last star
+
+int i, npts
+real sum
+
+begin
+ sum = 0.0
+ npts = 0
+ do i = istar, lstar {
+ if (skip[i] == YES)
+ next
+ sum = sum + sky[i]
+ npts = npts + 1
+ }
+
+ if (npts <= 0)
+ return (INDEFR)
+ else
+ return (sum / npts)
+end
+
+
+# DP_ALXACCUM - Accumulate the x vector.
+
+procedure dp_alxaccum (dao, im, xcen, ycen, mag, rpixsq, skip, x, numer1,
+ denom1, istar, lstar, fix, fiy, resid, wt, sigmasq, nterm, fitradsq)
+
+pointer dao # pointer to the daopot structure
+pointer im # pointer to the input image
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of relative brightnesses
+real rpixsq[ARB] # array of pixel distances squared
+int skip[ARB] # the include / exclude array
+real x[ARB] # the x vector to be accumulated
+real numer1[ARB] # first numerator array
+real denom1[ARB] # first denominator array
+int istar # index of the first star in group
+int lstar # index of the last star in group
+real fix # the x position of the current pixel
+real fiy # the y position of the current pixel
+real resid # the input data residual
+real wt # the output weight value
+real sigmasq # the sigma squared value
+int nterm # number of terms in the matrix
+real fitradsq # fitting radius squared
+
+real psfsigsqx, psfsigsqy, dx, dy, deltax, deltay, value, radsq, rhosq
+real dvdx, dvdy, dfdsig
+pointer psffit
+int nstar, i, i3, k
+real dp_usepsf()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ nstar = lstar - istar + 1
+ psfsigsqx = Memr[DP_PSFPARS(psffit)]
+ psfsigsqy = Memr[DP_PSFPARS(psffit)+1]
+
+ do i = istar, lstar {
+
+ if (skip[i] == YES)
+ next
+ radsq = rpixsq[i] / fitradsq
+ if (radsq >= MAX_RSQ)
+ next
+ wt = max (wt, 5.0 / (5.0 + radsq / (1.0 - radsq)))
+
+ # The condition equation for pixel[I,J] is the following.
+ #
+ # data[I,J] - sum [scale * psf[I,J]] - mean_sky = residual
+ #
+ # Then we will adjust the scale factors, x centers and ycenters
+ # such that sum [weight * residual ** 2] is minimized.
+ # WT will be a function (1) of the distance of this pixel from
+ # the center of the nearest star, (2) of the model predicted
+ # brightness of the pixel (taking into consideration the
+ # readout noise, the photons/ADU, and the interpolation error
+ # of the PSF), and (3) of the size of the residual itself. (1) is
+ # necessary to prevent the non-linear least-squares from
+ # fit from oscillating. (2) is simply sensible weighting and (3)
+ # is a crude attempt at making the solution more robust
+ # against bad pixels.
+
+ dx = fix - xcen[i]
+ dy = fiy - ycen[i]
+ call dp_wpsf (dao, im, xcen[i], ycen[i], deltax, deltay, 1)
+ deltax = (deltax - 1.0) / DP_PSFX(psffit) - 1.0
+ deltay = (deltay - 1.0) / DP_PSFY(psffit) - 1.0
+ value = dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), deltax, deltay,
+ dvdx, dvdy)
+
+ if (nterm > nstar) {
+ i3 = (i - istar + 1) * 3
+ k = i3 - 2
+ x[k] = -value
+ k = i3 - 1
+ x[k] = -mag[i] * dvdx
+ x[i3] = -mag[i] * dvdy
+ } else {
+ k = i - istar + 1
+ x[k] = -value
+ }
+
+ rhosq = (dx / psfsigsqx) ** 2 + (dy / psfsigsqy) ** 2
+ if (rhosq > MAX_RHOSQ)
+ next
+ rhosq = 0.6931472 * rhosq
+ dfdsig = exp (-rhosq) * (rhosq - 1.)
+ numer1[i] = numer1[i] + dfdsig * resid / sigmasq
+ denom1[i] = denom1[i] + dfdsig ** 2 / sigmasq
+ }
+end
+
+
+# DP_ALCHI -- Compute the weights and chis.
+
+procedure dp_alchi (skip, chi, sumwt, npix, istar, lstar, wt, dwt)
+
+int skip[ARB] # include / exclude array for the stars
+real chi[ARB] # array of chi values
+real sumwt[ARB] # array of weight sums
+int npix[ARB] # array of pixel counts
+int istar # index of first star
+int lstar # index of last star
+real wt # input weight
+real dwt # weighted residual
+
+int i
+
+begin
+ do i = istar, lstar {
+ if (skip[i] == YES)
+ next
+ chi[i] = chi[i] + dwt
+ sumwt[i] = sumwt[i] + wt
+ npix[i] = npix[i] + 1
+ }
+end
+
+
+# DP_ALCACCUM -- Accumulate the main matrix.
+
+procedure dp_alcaccum (x, c, v, skip, cdimen, nterm, istar, lstar, wt, dwt)
+
+
+real x[ARB] # x array
+real c[cdimen,ARB] # maxtrix array
+real v[ARB] # v vector
+int skip[ARB] # include / exclude array
+int cdimen # maximum size of c matrix
+int nterm # number of terms to be fit
+int istar # index of the first star
+int lstar # index of the last star
+real wt # input weight
+real dwt # input residual weight
+
+int nstar, i, j, k, l, i3, i3m2, j3
+real xkwt
+
+begin
+ nstar = lstar - istar + 1
+ do i = istar, lstar {
+ if (skip[i] == YES)
+ next
+ if (nterm > nstar) {
+ i3 = (i - istar + 1) * 3
+ i3m2 = i3 - 2
+ do k = i3m2, i3
+ v[k] = v[k] + x[k] * dwt
+ do j = istar, i {
+ if (skip[j] == YES)
+ next
+ j3 = (j - istar + 1) * 3
+ do k = i3m2, i3 {
+ xkwt = x[k] * wt
+ do l = j3 - 2, min (k, j3)
+ c[k,l] = c[k,l] + x[l] * xkwt
+ }
+ }
+ } else {
+ k = i - istar + 1
+ v[k] = v[k] + x[k] * dwt
+ xkwt = x[k] * wt
+ do j = istar, i {
+ if (skip[j] == YES)
+ next
+ l = j - istar + 1
+ c[k,l] = c[k,l] + x[l] * xkwt
+ }
+ }
+ }
+end
+
+
+# DP_ALREDO -- Check to see that there are enough good pixels to fit the
+# star and compute the individual chi values.
+
+bool procedure dp_alredo (id, mag, chi, sumwt, npix, skip, aier, istar, lstar,
+ niter, chigrp, center, verbose)
+
+int id[ARB] # the array of star ids
+real mag[ARB] # the array of relative brightnesses
+real chi[ARB] # the array of chi values
+real sumwt[ARB] # the array of weight values
+int npix[ARB] # the array of pixel counts
+int skip[ARB] # the include / exclude array
+int aier[ARB] # the array of error codes
+int istar # index of the first star
+int lstar # index of the last star
+int niter # the current iteration
+real chigrp # chi value of the group
+int center # recenter the values ?
+int verbose # verbose mode ?
+
+bool redo
+int i
+
+begin
+ redo = false
+ do i = istar, lstar {
+ if (center == YES && (niter >= 2)) {
+ if (npix[i] < MIN_NPIX) {
+ redo = true
+ skip[i] = YES
+ if (verbose == YES) {
+ call printf (
+ "REJECTING: Star ID: %d has too few good pixels\n")
+ call pargi (id[i])
+ }
+ aier[i] = ALLERR_NOPIX
+ mag[i] = INDEFR
+ } else {
+ skip[i] = NO
+ if (sumwt[i] > MIN_SUMWT) {
+ chi[i] = CHI_NORM * chi[i] / sqrt (sumwt[i] *
+ (sumwt[i] - MIN_SUMWT))
+ sumwt[i] = ((sumwt[i] - MIN_SUMWT) * chi[i] +
+ MIN_SUMWT) / sumwt[i]
+ } else
+ chi[i] = chigrp
+ }
+ } else {
+ if (npix[i] < MIN_NPIX) {
+ redo = true
+ skip[i] = YES
+ if (verbose == YES) {
+ call printf (
+ "REJECTING: Star ID: %d has too few good pixels\n")
+ call pargi (id[i])
+ }
+ aier[i] = ALLERR_NOPIX
+ mag[i] = INDEFR
+ } else {
+ skip[i] = NO
+ if (sumwt[i] > 1.0) {
+ chi[i] = CHI_NORM * chi[i] / sqrt (sumwt[i] *
+ (sumwt[i] - 1.0))
+ sumwt[i] = ((sumwt[i] - MIN_SUMWT) * chi[i] +
+ MIN_SUMWT) / sumwt[i]
+ } else
+ chi[i] = chigrp
+ }
+ }
+ }
+
+ return (redo)
+end
+
+
+# DP_CHECKC - Check the c matrix for valid diagonal elements.
+
+bool procedure dp_checkc (c, cdimen, nterm, id, mag, skip, aier, istar, niter,
+ recenter, verbose)
+
+real c[cdimen,ARB] # the c matrix
+int cdimen # maximum size of the c matrix
+int nterm # number of terms to be fit
+int id[ARB] # the array of ids
+real mag[ARB] # the array of relative brightnesses
+int skip[ARB] # the include / exclude array
+int aier[ARB] # the array of error codes
+int istar # index of the first star
+int niter # the iteration number
+int recenter # recenter ?
+int verbose # verbose mode ?
+
+bool redo
+int j, starno
+
+begin
+ redo = false
+ do j = 1, nterm {
+ if (c[j,j] > 0.0)
+ next
+ if ((recenter == YES) && (niter >= 2))
+ starno = (j + 2) / 3
+ else
+ starno = j
+ starno = starno + istar - 1
+ skip[starno] = YES
+ if (verbose == YES) {
+ call printf (
+ "REJECTING: Star ID: %d generated a fitting error\n")
+ call pargi (id[starno])
+ }
+ aier[starno] = ALLERR_SINGULAR
+ mag[starno] = INDEFR
+ redo = true
+ break
+ }
+
+ return (redo)
+end
+
+
+# DP_ALCLAMP -- Get the answers.
+
+bool procedure dp_alclamp (dao, im, id, xcen, ycen, mag, magerr, sumwt,
+ skip, xold, xclamp, yold, yclamp, istar, lstar, c, x,
+ cdimen, niter, clampmax, pererr, peakerr)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int id[ARB] # array of star ids
+real xcen[ARB] # array of star x centers
+real ycen[ARB] # array of star y centers
+real mag[ARB] # array of relative brightnesses
+real magerr[ARB] # array of relative brightness errors
+real sumwt[ARB] # array of pixel distance squared values
+int skip[ARB] # include / exclude array
+real xold[ARB] # xold array
+real xclamp[ARB] # xclamp array
+real yold[ARB] # yold array
+real yclamp[ARB] # yclamp array
+int istar # the index of the first star
+int lstar # the index of the last star
+real c[cdimen,ARB] # c matrix
+real x[ARB] # x vector
+int cdimen # the maximum size of c matrix
+int niter # the current iteration
+real clampmax # the maximum clamp value
+real pererr # flat field error
+real peakerr # the profile error
+
+bool redo, bufwrite
+int i, l, k, j, lx, mx, ly, my, nx, ny
+pointer psffit, allstar
+real dwt, psfrad, psfradsq, df
+
+begin
+ # Get some daophot pointers.
+ allstar = DP_ALLSTAR(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Get some constants.
+ if (DP_PSFSIZE(psffit) == 0)
+ psfrad = DP_PSFRAD(dao)
+ else
+ psfrad = (real (DP_PSFSIZE(psffit) - 1) / 2.0 - 1.0) / 2.0
+ psfradsq = psfrad * psfrad
+
+ # Initialize.
+ bufwrite = false
+
+ do i = istar, lstar {
+
+ if ((DP_RECENTER(dao) == YES) && (niter >= 2)) {
+
+ l = 3 * (i - istar + 1)
+ k = l - 1
+ j = l - 2
+
+ # Note that the sign of the correction is such that it must be
+ # SUBTRACTED from the current value of the parameter to get the
+ # improved parameter value. This being the case, if the
+ # correction to the brightness is negative a change of one
+ # magnitude is a change of factor of 2.5; if the brightness
+ # correction is positive a change of one magnitude is a change
+ # of 60%.
+
+ dwt = xold[i] * x[k]
+ if (dwt < 0.0)
+ xclamp[i] = max (MIN_XYCLAMP, MIN_XYCLAMP_FRACTION *
+ xclamp[i])
+ else
+ xclamp[i] = min (clampmax, MAX_XYCLAMP_FRACTION * xclamp[i])
+ xcen[i] = xcen[i] - x[k] / (1.0 + abs (x[k] / xclamp[i]))
+ xold[i] = x[k]
+
+ dwt = yold[i] * x[l]
+ if (dwt < 0.0)
+ yclamp[i] = max (MIN_XYCLAMP, MIN_XYCLAMP_FRACTION *
+ yclamp[i])
+ else
+ yclamp[i] = min (clampmax, MAX_XYCLAMP_FRACTION * yclamp[i])
+ ycen[i] = ycen[i] - x[l] / (1.0 + abs (x[l] / yclamp[i]))
+ yold[i] = x[l]
+
+ mag[i] = mag[i] - x[j] / (1.0 + max (x[j] / (MAX_DELTA_FAINTER *
+ mag[i]), -x[j] / (MAX_DELTA_BRIGHTER * mag[i])))
+ magerr[i] = sumwt[i] * sqrt (c[j,j])
+
+ if (niter >= MIN_ITER) {
+ redo = false
+ if (abs(x[j]) > max (MAX_NEW_ERRMAG * magerr[i],
+ MAX_NEW_RELBRIGHT2 * mag[i]))
+ redo = true
+ else {
+ df = (MAX_NEW_ERRMAG * sumwt[i]) ** 2
+ if ((x[k] ** 2) > max (df * c[k,k], MAX_PIXERR2))
+ redo = true
+ else if ((x[l] ** 2) > max (df * c[l,l], MAX_PIXERR2))
+ redo = true
+ }
+ } else
+ redo = true
+
+ } else {
+ j = i - istar + 1
+ mag[i] = mag[i] - x[j] / (1.0 + 1.2 * abs (x[j] / mag[i]))
+ magerr[i] = sumwt[i] * sqrt (c[j,j])
+ if (niter >= 2) {
+ redo = false
+ if (abs(x[j]) > max (MAX_NEW_ERRMAG * magerr[i],
+ MAX_NEW_RELBRIGHT2 * mag[i]))
+ redo = true
+ } else
+ redo = true
+ }
+
+ if (mag[i] < 2.0 * magerr[i])
+ redo = true
+ if (niter >= DP_MAXITER(dao))
+ redo = false
+ if (redo && (niter < DP_MAXITER(dao)))
+ next
+
+ # If this star converged, write out the results for it,
+ # flag it for deletion from the star list and subtract it
+ # from the reference copy of the image.
+
+ call dp_glim (xcen[i], ycen[i], psfrad, DP_DLX(allstar),
+ DP_DMX(allstar), DP_DLY(allstar), DP_DMY(allstar),
+ lx, mx, ly, my)
+ nx = mx - lx + 1
+ ny = my - ly + 1
+
+ call dp_swstar (dao, im, Memr[DP_DBUF(allstar)], DP_DNX(allstar),
+ DP_DNY(allstar), DP_DXOFF(allstar), DP_DYOFF(allstar),
+ Memr[DP_WBUF(allstar)], DP_WNX(allstar), DP_WNY(allstar),
+ DP_WXOFF(allstar), DP_WYOFF(allstar), xcen[i], ycen[i],
+ mag[i], lx, ly, nx, ny, psfradsq, DP_PHOTADU(dao), pererr,
+ peakerr)
+
+ skip[i] = YES
+
+ if (DP_VERBOSE(dao) == YES) {
+ call dp_wout (dao, im, xcen[i], ycen[i], xcen[i], ycen[i], 1)
+ call printf (
+ "FITTING: ID: %5d XCEN: %8.2f YCEN: %8.2f MAG: %8.2f\n")
+ call pargi (id[i])
+ call pargr (xcen[i])
+ call pargr (ycen[i])
+ if (mag[i] <= 0.0)
+ call pargr (INDEFR)
+ else
+ call pargr (DP_PSFMAG(psffit) - 2.5 * log10 (mag[i]))
+
+ }
+ bufwrite = true
+ }
+
+ return (bufwrite)
+end
+
+
+# DP_SWSTAR -- Subtract the fitted star for the data and adjust the
+# weights.
+
+procedure dp_swstar (dao, im, data, dnx, dny, dxoff, dyoff, weights, wnx, wny,
+ wxoff, wyoff, xcen, ycen, mag, lx, ly, nx, ny, psfradsq, gain,
+ pererr, peakerr)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real data[dnx,dny] # the data array
+int dnx, dny # dimensions of the data array
+int dxoff, dyoff # lower left corner of data array
+real weights[wnx,wny] # the weights array
+int wnx, wny # dimensions of the weights array
+int wxoff, wyoff # lower left corner of weights array
+real xcen, ycen # the position of the star
+real mag # relative brightness of the star
+int lx, ly # lower left corner region of interest
+int nx, ny # size of region of interest
+real psfradsq # the psf radius squared
+real gain # the gain in photons per adu
+real pererr # the flat field error factor
+real peakerr # the peak error factor
+
+real deltax, deltay, dx, dy, dysq, diff, dvdx, dvdy
+pointer psffit
+int di, dj, wxdiff, wydiff
+real dp_usepsf()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ wxdiff = dxoff - wxoff
+ wydiff = dyoff - wyoff
+ call dp_wpsf (dao, im, xcen, ycen, deltax, deltay, 1)
+ deltax = (deltax - 1.0) / DP_PSFX(psffit) - 1.0
+ deltay = (deltay - 1.0) / DP_PSFY(psffit) - 1.0
+
+ do dj = ly - dyoff + 1, ly - dyoff + ny {
+ dy = (dj + dyoff - 1) - ycen
+ dysq = dy * dy
+ do di = lx - dxoff + 1, lx - dxoff + nx {
+ if (weights[di+wxdiff,dj+wydiff] <= -MAX_REAL)
+ next
+ dx = (di + dxoff - 1) - xcen
+ if ((dx * dx + dysq) >= psfradsq)
+ next
+ diff = mag * dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), deltax, deltay,
+ dvdx, dvdy)
+ data[di,dj] = data[di,dj] - diff
+ if (diff > 0.0) {
+ diff = diff / gain + pererr *
+ 2.0 * max (0.0, data[di,dj]) * diff +
+ (peakerr * diff) ** 2
+ if (weights[di+wxdiff,dj+wydiff] >= 0.0)
+ weights[di+wxdiff,dj+wydiff] = weights[di+wxdiff,
+ dj+wydiff] + diff
+ else
+ weights[di+wxdiff,dj+wydiff] = - (abs (weights[di+
+ wxdiff,dj+wydiff]) + diff)
+ }
+ }
+ }
+end
+
+
+# DP_ALMERGE -- Determine whether or not two stars should merge.
+
+bool procedure dp_almerge (xcen, ycen, mag, magerr, skip, istar, lstar,
+ sepcrit, sepmin, wcrit, k, l)
+
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of relative brightnesses
+real magerr[ARB] # array of relative brightness errors
+int skip[ARB] # the include / exclude array
+int istar # index to the first star
+int lstar # index to the last star
+real sepcrit # the critical separation
+real sepmin # the minimum separation
+real wcrit # the critical error
+int k, l # indices of stars to be merged
+
+bool merge
+int i, j
+real rsq, sep
+
+begin
+ # Initialize.
+ rsq = sepcrit
+ merge = false
+ k = 0
+ l = 0
+
+ # Find the closest two stars within the critical separation.
+ do i = istar + 1, lstar {
+
+ if (skip[i] == YES)
+ next
+
+ do j = istar, i - 1 {
+ if (skip[j] == YES)
+ next
+ sep = (xcen[i] - xcen[j]) ** 2 + (ycen[i] - ycen[j]) ** 2
+ if (sep >= rsq)
+ next
+
+ # Two stars are overlapping. Identify the fainter of the two.
+ rsq = sep
+ if (mag[i] < mag[j]) {
+ k = i
+ l = j
+ } else {
+ k = j
+ l = i
+ }
+
+ merge = true
+ }
+ }
+
+ # No stars overlap.
+ if (! merge)
+ return (merge)
+
+ # The stars are not close enough.
+ if ((rsq > sepmin) && (mag[k] > wcrit * magerr[k]))
+ merge = false
+
+ return (merge)
+end
+
+
+# DP_ALCENTROID -- Merge two stars by adding their relative brightnesses
+# and replacing their individual positions with the relative brightness
+# weighted mean position.
+
+procedure dp_alcentroid (xcen, ycen, mag, k, l)
+
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+int k, l # input indices, k is fainter
+
+begin
+ xcen[l] = xcen[l] * mag[l] + xcen[k] * mag[k]
+ ycen[l] = ycen[l] * mag[l] + ycen[k] * mag[k]
+ mag[l] = mag[l] + mag[k]
+ xcen[l] = xcen[l] / mag[l]
+ ycen[l] = ycen[l] / mag[l]
+end
+
+
+# DP_ALFAINT -- Find all the stars with realtive brightnesss less than
+# a given number and set their magnitudes to a given minimum relative
+# brightness.
+
+bool procedure dp_alfaint (mag, skip, istar, lstar, faint, ifaint)
+
+real mag[ARB] # array of magnitudes
+int skip[ARB] # skip array
+int istar, lstar # first and last stars
+real faint # faintest star
+int ifaint # index of faintest star
+
+int i
+
+begin
+ # Initialize
+ faint = MIN_REL_BRIGHT
+ ifaint = 0
+
+ do i = istar, lstar {
+ if (skip[i] == YES)
+ return (true)
+ if (mag[i] < faint) {
+ faint = mag[i]
+ ifaint = i
+ }
+ if (mag[i] < MIN_REL_BRIGHT)
+ mag[i] = MIN_REL_BRIGHT
+ }
+
+ return (false)
+end
+
+
+# DP_ALMFAINT -- Find the star with the greatest error in its relative
+# brightness.
+
+procedure dp_almfaint (mag, magerr, istar, lstar, faint, ifaint)
+
+real mag[ARB] # array of relative brightnesses
+real magerr[ARB] # array of relative brightness errors
+int istar # index of first star
+int lstar # index of last star
+real faint # computed faintness limit
+int ifaint # index of faintest star
+
+int i
+real wt
+
+begin
+ faint = MAX_REAL
+ ifaint = 0
+ do i = istar, lstar {
+ wt = mag[i] / magerr[i]
+ if (wt < faint) {
+ faint = wt
+ ifaint = i
+ }
+ }
+end
diff --git a/noao/digiphot/daophot/allstar/dpalwrite.x b/noao/digiphot/daophot/allstar/dpalwrite.x
new file mode 100644
index 00000000..c4688924
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpalwrite.x
@@ -0,0 +1,556 @@
+include <tbset.h>
+include <time.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/allstardef.h"
+
+# DP_TNEWAL -- Create an new ALLSTAR output ST table.
+
+procedure dp_tnewal (dao, tp, colpoint)
+
+pointer dao # pointer to the daophot strucuture
+pointer tp # pointer to the output table
+int colpoint[ARB] # array of column pointers
+
+int i
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for table definition.
+ call smark (sp)
+ call salloc (colnames, ALL_NOUTCOLUMN * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, ALL_NOUTCOLUMN * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, ALL_NOUTCOLUMN * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, ALL_NOUTCOLUMN, TY_INT)
+ call salloc (col_len, ALL_NOUTCOLUMN, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (MAGERR, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+5*SZ_COLNAME+5], SZ_COLNAME)
+ call strcpy (NITER, Memc[colnames+6*SZ_COLNAME+6], SZ_COLNAME)
+ call strcpy (SHARP, Memc[colnames+7*SZ_COLNAME+7], SZ_COLNAME)
+ call strcpy (CHI, Memc[colnames+8*SZ_COLNAME+8], SZ_COLNAME)
+ call strcpy (PIER, Memc[colnames+9*SZ_COLNAME+9], SZ_COLNAME)
+ call strcpy (PERROR, Memc[colnames+10*SZ_COLNAME+10], SZ_COLNAME)
+
+ # Define the column formats.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("%14.3f", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+ call strcpy ("%15.7g", Memc[colformat+5*SZ_COLFMT+5], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+6*SZ_COLFMT+6], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+7*SZ_COLFMT+7], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+8*SZ_COLFMT+8], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+9*SZ_COLFMT+9], SZ_COLFMT)
+ call strcpy ("%13s", Memc[colformat+10*SZ_COLFMT+10], SZ_COLFMT)
+
+ # Define the column units.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+ call strcpy ("ADC", Memc[colunits+5*SZ_COLUNITS+5], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+6*SZ_COLUNITS+6], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+7*SZ_COLUNITS+7], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+8*SZ_COLUNITS+8], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+9*SZ_COLUNITS+9], SZ_COLUNITS)
+ call strcpy ("PERRORS", Memc[colunits+10*SZ_COLUNITS+10], SZ_COLUNITS)
+
+ # Define the column types.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_REAL
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+ Memi[col_dtype+4] = TY_REAL
+ Memi[col_dtype+5] = TY_REAL
+ Memi[col_dtype+6] = TY_INT
+ Memi[col_dtype+7] = TY_REAL
+ Memi[col_dtype+8] = TY_REAL
+ Memi[col_dtype+9] = TY_INT
+ Memi[col_dtype+10] = -13
+
+ # Define the column lengths.
+ do i = 1, ALL_NOUTCOLUMN
+ Memi[col_len+i-1] = 1
+
+ # Define and create the table.
+ call tbcdef (tp, colpoint, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], ALL_NOUTCOLUMN)
+ call tbtcre (tp)
+
+ # Write out the header parameters.
+ call dp_talpars (dao, tp)
+
+ call sfree (sp)
+
+end
+
+
+define AL_NAME1STR "#N%4tID%10tXCENTER%20tYCENTER%30tMAG%42tMERR%56tMSKY%71t\
+NITER%80t\\\n"
+define AL_UNIT1STR "#U%4t##%10tpixels%20tpixels%30tmagnitudes%42tmagnitudes%56t\
+counts%71t##%80t\\\n"
+define AL_FORMAT1STR "#F%4t%%-9d%10t%%-10.3f%20t%%-10.3f%30t%%-12.3f%42t\
+%%-14.3f%56t%%-15.7g%71t%%-6d%80t \n"
+
+define AL_NAME2STR "#N%12tSHARPNESS%24tCHI%36tPIER%42tPERROR%80t\\\n"
+define AL_UNIT2STR "#U%12t##%24t##%36t##%42tperrors%80t\\\n"
+define AL_FORMAT2STR "#F%12t%%-23.3f%24t%%-12.3f%36t%%-6d%42t%%-13s%80t \n"
+
+
+# DP_XNEWAL -- Initialize a new output ALLSTAR text file.
+
+procedure dp_xnewal (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # the output file descriptor
+
+begin
+ # Write out the header parameters.
+ call dp_xalpars (dao, tp)
+
+ # Write out the banner.
+ call fprintf (tp, "#\n")
+ call fprintf (tp, AL_NAME1STR)
+ call fprintf (tp, AL_UNIT1STR)
+ call fprintf (tp, AL_FORMAT1STR)
+ call fprintf (tp, "#\n")
+ call fprintf (tp, AL_NAME2STR)
+ call fprintf (tp, AL_UNIT2STR)
+ call fprintf (tp, AL_FORMAT2STR)
+ call fprintf (tp, "#\n")
+end
+
+
+# DP_TALPARS -- Add various parameters to the header of the ALLSTAR table.
+
+procedure dp_talpars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+pointer tp # pointer to the output table
+
+pointer sp, psffit, outstr, date, time
+bool itob()
+int envfind()
+
+begin
+ # Define some daophot pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate workin space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IRAF", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) <= 0)
+ call tbhadt (tp, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (tp, "DATE", Memc[date])
+ call tbhadt (tp, "TIME", Memc[time])
+ call tbhadt (tp, "PACKAGE", "daophot")
+ call tbhadt (tp, "TASK", "allstar")
+
+ # Write out the files names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PHOTFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSFIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "ALLSTARFILE", Memc[outstr])
+ if (DP_OUTREJFILE(dao) == EOS) {
+ call tbhadt (tp, "REJFILE", "\"\"")
+ } else {
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "REJFILE", Memc[outstr])
+ }
+ call dp_imroot (DP_OUTIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "SUBIMAGE", Memc[outstr])
+
+ # Define the data characteristics.
+ call tbhadr (tp, "SCALE", DP_SCALE(dao))
+ call tbhadr (tp, "DATAMIN", DP_MINGDATA(dao))
+ call tbhadr (tp, "DATAMAX", DP_MAXGDATA(dao))
+ call tbhadr (tp, "GAIN", DP_PHOTADU(dao))
+ call tbhadr (tp, "READNOISE", DP_READNOISE(dao))
+
+ # Define the observing parameters.
+ call tbhadt (tp, "OTIME", DP_OTIME(dao))
+ call tbhadr (tp, "XAIRMASS", DP_XAIRMASS(dao))
+ call tbhadt (tp, "IFILTER", DP_IFILTER(dao))
+
+ # Define the fitting parameters.
+ call tbhadb (tp, "RECENTER", itob (DP_RECENTER(dao)))
+ call tbhadb (tp, "GRPSKY", itob (DP_GROUPSKY(dao)))
+ call tbhadb (tp, "FITSKY", itob (DP_FITSKY(dao)))
+ call tbhadr (tp, "PSFMAG", DP_PSFMAG(psffit))
+ call tbhadr (tp, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (tp, "FITRAD", DP_SFITRAD(dao))
+ call tbhadr (tp, "ANNULUS", DP_SANNULUS(dao))
+ call tbhadr (tp, "DANNULUS", DP_SDANNULUS(dao))
+ call tbhadi (tp, "MAXITER", DP_MAXITER(dao))
+ call tbhadi (tp, "MAXGROUP", DP_MAXGROUP(dao))
+ #call tbhadi (tp, "MAXNSTAR", DP_MAXNSTAR(dao))
+ call tbhadr (tp, "FLATERROR", DP_FLATERR(dao))
+ call tbhadr (tp, "PROFERROR", DP_PROFERR(dao))
+ call tbhadi (tp, "CLIPEXP", DP_CLIPEXP(dao))
+ call tbhadr (tp, "CLIPRANGE", DP_CLIPRANGE(dao))
+ call tbhadr (tp, "MERGERAD", DP_SMERGERAD(dao))
+
+ call sfree(sp)
+end
+
+
+# DP_XALPARS -- Add various parameters to the header of the PEAK table
+
+procedure dp_xalpars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # the output file descriptor
+
+pointer sp, psffit, outstr, date, time, dummy
+bool itob()
+int envfind()
+
+begin
+ # Define some daophot pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate workin space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+ call salloc (dummy, 2, TY_CHAR)
+ Memc[dummy] = EOS
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IRAF", Memc[outstr], "version", Memc[dummy])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) <= 0)
+ call dp_sparam (tp, "USER", Memc[outstr], "name", Memc[dummy])
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "HOST", Memc[outstr], "computer", Memc[dummy])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (tp, "DATE", Memc[date], "yyyy-mm-dd", Memc[dummy])
+ call dp_sparam (tp, "TIME", Memc[time], "hh:mm:ss", Memc[dummy])
+ call dp_sparam (tp, "PACKAGE", "daophot", "name", Memc[dummy])
+ call dp_sparam (tp, "TASK", "allstar", "name", Memc[dummy])
+
+ # Write out the files names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IMAGE", Memc[outstr], "imagename", Memc[dummy])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PHOTFILE", Memc[outstr], "filename", Memc[dummy])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSFIMAGE", Memc[outstr], "imagename", Memc[dummy])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "ALLSTARFILE", Memc[outstr], "filename",
+ Memc[dummy])
+ if (DP_OUTREJFILE(dao) == EOS)
+ call dp_sparam (tp, "REJFILE", "\"\"", "filename", Memc[dummy])
+ else {
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "REJFILE", Memc[outstr], "filename",
+ Memc[dummy])
+ }
+ call dp_imroot (DP_OUTIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "SUBIMAGE", Memc[outstr], "imagename",
+ Memc[dummy])
+
+ # Define the data characteristics.
+ call dp_rparam (tp, "SCALE", DP_SCALE(dao), "units/pix", Memc[dummy])
+ call dp_rparam (tp, "DATAMIN", DP_MINGDATA(dao), "counts", Memc[dummy])
+ call dp_rparam (tp, "DATAMAX", DP_MAXGDATA(dao), "counts", Memc[dummy])
+ call dp_rparam (tp, "GAIN", DP_PHOTADU(dao), "e-/adu", Memc[dummy])
+ call dp_rparam (tp, "READNOISE", DP_READNOISE(dao), "electrons",
+ Memc[dummy])
+
+ # Define the observing parameters.
+ call dp_sparam (tp, "OTIME", DP_OTIME(dao), "timeunit", Memc[dummy])
+ call dp_rparam (tp, "XAIRMASS", DP_XAIRMASS(dao), "number", Memc[dummy])
+ call dp_sparam (tp, "IFILTER", DP_IFILTER(dao), "filter", Memc[dummy])
+
+ # Define the fitting parameters.
+ call dp_bparam (tp, "RECENTER", itob (DP_RECENTER(dao)), "switch",
+ Memc[dummy])
+ call dp_bparam (tp, "GRPSKY", itob (DP_GROUPSKY(dao)), "switch",
+ Memc[dummy])
+ call dp_bparam (tp, "FITSKY", itob (DP_FITSKY(dao)), "switch",
+ Memc[dummy])
+ call dp_rparam (tp, "PSFMAG", DP_PSFMAG(psffit), "magnitude",
+ Memc[dummy])
+ call dp_rparam (tp, "PSFRAD", DP_SPSFRAD(dao), "scaleunit", Memc[dummy])
+ call dp_rparam (tp, "FITRAD", DP_SFITRAD(dao), "scaleunit", Memc[dummy])
+ call dp_rparam (tp, "ANNULUS", DP_SANNULUS(dao), "scaleunit",
+ Memc[dummy])
+ call dp_rparam (tp, "DANNULUS", DP_SDANNULUS(dao), "scaleunit",
+ Memc[dummy])
+ call dp_iparam (tp, "MAXITER", DP_MAXITER(dao), "number", Memc[dummy])
+ call dp_iparam (tp, "MAXGROUP", DP_MAXGROUP(dao), "number", Memc[dummy])
+ #call dp_iparam (tp, "MAXNSTAR", DP_MAXNSTAR(dao), "number",
+ #Memc[dummy])
+ call dp_rparam (tp, "FLATERROR", DP_FLATERR(dao), "percentage",
+ Memc[dummy])
+ call dp_rparam (tp, "PROFERROR", DP_PROFERR(dao), "percentage",
+ Memc[dummy])
+ call dp_iparam (tp, "CLIPEXP", DP_CLIPEXP(dao), "number", Memc[dummy])
+ call dp_rparam (tp, "CLIPRANGE", DP_CLIPRANGE(dao), "sigma",
+ Memc[dummy])
+ call dp_rparam (tp, "MERGERAD", DP_SMERGERAD(dao), "scaleunit",
+ Memc[dummy])
+
+ call sfree (sp)
+end
+
+
+# DP_TALWRITE -- Write out a photometry record to an ALLSTAR ST table.
+
+procedure dp_talwrite (tpout, tprout, colpoint, id, x, y, mag, magerr, sky,
+ chi, numer, denom, skip, aier, niter, istar, lstar, star, rstar,
+ psfmag, csharp)
+
+pointer tpout # the output photometry file descriptor
+pointer tprout # the output rejections file descriptor
+int colpoint[ARB] # array of column pointers
+int id[ARB] # array of ids
+real x[ARB] # array of xpositions
+real y[ARB] # array of y positions
+real mag[ARB] # array of magnitude values
+real magerr[ARB] # array of mangitudes
+real sky[ARB] # array of sky values
+real chi[ARB] # array of chi values
+real numer[ARB] # array of first numerator values
+real denom[ARB] # array of first denominator values
+int skip[ARB] # array of skipped stars
+int aier[ARB] # array of error codes
+int niter # number of iterations
+int istar, lstar # first and last stars
+int star # photometry file row number
+int rstar # rejections file row number
+real psfmag # magnitude of the psf
+real csharp # the sharpness constant
+
+int i, iter, pier, plen
+pointer sp, perror
+real err, sharp
+int dp_gallerr()
+
+begin
+ call smark (sp)
+ call salloc (perror, SZ_FNAME, TY_CHAR)
+
+ do i = istar, lstar {
+
+ # Skip the star ?
+ if (skip[i] == NO)
+ next
+ if (IS_INDEFR(x[i]) || IS_INDEFR(y[i]))
+ next
+
+ # Get the results.
+ if (IS_INDEFR(mag[i]) || mag[i] <= 0.0 || denom[i] == 0.) {
+ mag[i] = INDEFR
+ iter = 0
+ err = INDEFR
+ sharp = INDEFR
+ chi[i] = INDEFR
+ } else {
+ if (magerr[i] <= 0.0)
+ err = 0.0
+ else
+ err = 1.085736 * magerr[i] / mag[i]
+ sharp = csharp * numer[i] / (mag[i] * denom[i])
+ sharp = max (MIN_SHARP, min (sharp, MAX_SHARP))
+ mag[i] = psfmag - 2.5 * log10 (mag[i])
+ iter = niter
+ }
+ pier = aier[i]
+ plen = dp_gallerr (pier, Memc[perror], SZ_FNAME)
+
+ # Write the output row.
+ if ((tprout != NULL) && (pier != ALLERR_OK)) {
+ rstar = rstar + 1
+ call tbrpti (tprout, colpoint[1], id[i], 1, rstar)
+ call tbrptr (tprout, colpoint[2], x[i], 1, rstar)
+ call tbrptr (tprout, colpoint[3], y[i], 1, rstar)
+ call tbrptr (tprout, colpoint[4], mag[i], 1, rstar)
+ call tbrptr (tprout, colpoint[5], err, 1, rstar)
+ call tbrptr (tprout, colpoint[6], sky[i], 1, rstar)
+ call tbrpti (tprout, colpoint[7], iter, 1, rstar)
+ call tbrptr (tprout, colpoint[8], sharp, 1, rstar)
+ call tbrptr (tprout, colpoint[9], chi[i], 1, rstar)
+ call tbrpti (tprout, colpoint[10], pier, 1, rstar)
+ call tbrptt (tprout, colpoint[11], Memc[perror], plen,
+ 1, rstar)
+ } else {
+ star = star + 1
+ call tbrpti (tpout, colpoint[1], id[i], 1, star)
+ call tbrptr (tpout, colpoint[2], x[i], 1, star)
+ call tbrptr (tpout, colpoint[3], y[i], 1, star)
+ call tbrptr (tpout, colpoint[4], mag[i], 1, star)
+ call tbrptr (tpout, colpoint[5], err, 1, star)
+ call tbrptr (tpout, colpoint[6], sky[i], 1, star)
+ call tbrpti (tpout, colpoint[7], iter, 1, star)
+ call tbrptr (tpout, colpoint[8], sharp, 1, star)
+ call tbrptr (tpout, colpoint[9], chi[i], 1, star)
+ call tbrpti (tpout, colpoint[10], pier, 1, star)
+ call tbrptt (tpout, colpoint[11], Memc[perror], plen,
+ 1, star)
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+define AL_DATA1STR "%-9d%10t%-10.3f%20t%-10.3f%30t%-12.3f%42t%-14.3f%56t%-15.7g%71t%-6d%80t\\\n"
+define AL_DATA2STR "%12t%-12.3f%24t%-12.3f%36t%-6d%42t%-13.13s%80t \n"
+
+# DP_XALWRITE -- Write out photometry record to an ALLSTAR text file.
+
+procedure dp_xalwrite (tpout, tprout, id, x, y, mag, magerr, sky, chi, numer,
+ denom, skip, aier, niter, istar, lstar, psfmag, csharp)
+
+int tpout # the output photometry file descriptor
+int tprout # the output rejections file descriptor
+int id[ARB] # array of ids
+real x[ARB] # array of xpositions
+real y[ARB] # array of y positions
+real mag[ARB] # array of magnitude values
+real magerr[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+real chi[ARB] # array of chi values
+real numer[ARB] # array of first numerator values
+real denom[ARB] # array of first denominator values
+int skip[ARB] # array of skipped stars
+int aier[ARB] # array of error codes
+int niter # number of iterations
+int istar, lstar # first and last stars
+real psfmag # magnitude of the psf
+real csharp # sharpness constant
+
+int i, iter, pier, plen
+pointer sp, perror
+real err, sharp
+int dp_gallerr()
+
+begin
+ call smark (sp)
+ call salloc (perror, SZ_FNAME, TY_CHAR)
+
+ do i = istar, lstar {
+
+ # Skip the star ?
+ if (skip[i] == NO)
+ next
+ if (IS_INDEFR(x[i]) || IS_INDEFR(y[i]))
+ next
+
+ if (IS_INDEFR(mag[i]) || mag[i] <= 0.0 || denom[i] == 0.) {
+ mag[i] = INDEFR
+ iter = 0
+ err = INDEFR
+ sharp = INDEFR
+ chi[i] = INDEFR
+ } else {
+ if (magerr[i] <= 0.0)
+ err = 0.0
+ else
+ err = 1.085736 * magerr[i] / mag[i]
+ sharp = csharp * numer[i] / (mag[i] * denom[i])
+ sharp = max (MIN_SHARP, min (sharp, MAX_SHARP))
+ mag[i] = psfmag - 2.5 * log10 (mag[i])
+ iter = niter
+ }
+ pier = aier[i]
+ plen = dp_gallerr (pier, Memc[perror], SZ_FNAME)
+
+ if ((tprout != NULL) && (pier != ALLERR_OK)) {
+ call fprintf (tprout, AL_DATA1STR)
+ call pargi (id[i])
+ call pargr (x[i])
+ call pargr (y[i])
+ call pargr (mag[i])
+ call pargr (err)
+ call pargr (sky[i])
+ call pargi (iter)
+ call fprintf (tprout, AL_DATA2STR)
+ call pargr (sharp)
+ call pargr (chi[i])
+ call pargi (pier)
+ call pargstr (Memc[perror])
+ } else {
+ call fprintf (tpout, AL_DATA1STR)
+ call pargi (id[i])
+ call pargr (x[i])
+ call pargr (y[i])
+ call pargr (mag[i])
+ call pargr (err)
+ call pargr (sky[i])
+ call pargi (iter)
+ call fprintf (tpout, AL_DATA2STR)
+ call pargr (sharp)
+ call pargr (chi[i])
+ call pargi (pier)
+ call pargstr (Memc[perror])
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_GALLERR -- Set the ALLSTAR task error code string.
+
+int procedure dp_gallerr (ier, perror, maxch)
+
+int ier # the integer error code
+char perror # the output error code string
+int maxch # the maximum size of the error code string
+
+int plen
+int gstrcpy()
+
+begin
+ switch (ier) {
+ case ALLERR_OK:
+ plen = gstrcpy ("No_error", perror, maxch)
+ case ALLERR_BIGGROUP:
+ plen = gstrcpy ("Big_group", perror, maxch)
+ case ALLERR_INDEFSKY:
+ plen = gstrcpy ("Bad_sky", perror, maxch)
+ case ALLERR_NOPIX:
+ plen = gstrcpy ("Npix_too_few", perror, maxch)
+ case ALLERR_SINGULAR:
+ plen = gstrcpy ("Singular", perror, maxch)
+ case ALLERR_FAINT:
+ plen = gstrcpy ("Too_faint", perror, maxch)
+ case ALLERR_MERGE:
+ plen = gstrcpy ("Merged", perror, maxch)
+ case ALLERR_OFFIMAGE:
+ plen = gstrcpy ("Off_image", perror, maxch)
+ default:
+ plen = gstrcpy ("No_error", perror, maxch)
+ }
+
+ return (plen)
+end
diff --git a/noao/digiphot/daophot/allstar/dpastar.x b/noao/digiphot/daophot/allstar/dpastar.x
new file mode 100644
index 00000000..c8004f6d
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpastar.x
@@ -0,0 +1,327 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/allstardef.h"
+
+
+# DP_ASTAR -- Begin doing the photometry.
+
+procedure dp_astar (dao, im, subim, allfd, rejfd, cache, savesub, version)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+pointer subim # pointer to the subtracted image
+int allfd # file descriptor for the output photometry file
+int rejfd # file descriptor for rejections files
+int cache # cache the data ?
+int savesub # save the subtracted image ?
+int version # version number
+
+bool clip
+int nstar, row1_number, row2_number, niter, itsky, x1, x2, y1, y2, istar
+int lstar, ldummy, newsky
+pointer apsel, psffit, allstar, sp, indices, colpoints
+real fradius, sepcrt, sepmin, clmpmx, wcrit, radius, xmin, xmax, ymin, ymax
+real csharp, rdummy
+
+int dp_alphot(), dp_alnstar()
+pointer dp_gst(), dp_gwt(), dp_gdc()
+real dp_usepsf()
+
+begin
+ # Define some daophot structure pointers.
+ apsel = DP_APSEL(dao)
+ psffit = DP_PSFFIT (dao)
+ allstar = DP_ALLSTAR (dao)
+
+ # Store the original fitting radius
+ fradius = DP_FITRAD(dao)
+ DP_FITRAD(dao) = min (DP_FITRAD(dao), DP_PSFRAD(dao))
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (indices, NAPPAR, TY_INT)
+ call salloc (colpoints, ALL_NOUTCOLUMN, TY_INT)
+
+ # Define some daophot constants.
+ nstar = DP_APNUM(apsel)
+ csharp = 1.4427 * Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1] / dp_usepsf (DP_PSFUNCTION(psffit), 0.0,
+ 0.0, DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit), DP_NVLTABLE(psffit),
+ DP_NFEXTABLE(psffit), 0.0, 0.0, rdummy, rdummy)
+ if (IS_INDEFR(DP_MERGERAD(dao)))
+ sepcrt = 2.0 * (Memr[DP_PSFPARS(psffit)] ** 2 +
+ Memr[DP_PSFPARS(psffit)+1] ** 2)
+ else
+ sepcrt = DP_MERGERAD(dao) ** 2
+ sepmin = min (1.0, FRACTION_MINSEP * sepcrt)
+ itsky = 3
+
+ # Initialize the output photometry file for writing.
+ row1_number = 0
+ row2_number = 0
+ if (DP_TEXT(dao) == YES) {
+ call dp_xnewal (dao, allfd)
+ if (rejfd != NULL)
+ call dp_xnewal (dao, rejfd)
+ } else {
+ call dp_tnewal (dao, allfd, Memi[colpoints])
+ if (rejfd != NULL)
+ call dp_tnewal (dao, rejfd, Memi[colpoints])
+ }
+
+ # Allocate memory for the input, output and fitting arrays.
+ call dp_gnindices (Memi[indices])
+ call dp_rmemapsel (dao, Memi[indices], NAPPAR, nstar)
+ call dp_almemstar (dao, nstar, DP_MAXGROUP(dao))
+ call dp_cache (dao, im, subim, cache)
+
+ # Read in the input data and assign the initial weights.
+ call dp_setwt (dao, im)
+
+ # Convert the magnitudes to relative brightnesses.
+ call dp_alzero (dao, Memr[DP_APMAG(apsel)], nstar)
+
+ # Initialize all the fit/nofit indices and the error codes.
+ call amovki (NO, Memi[DP_ASKIP(allstar)], nstar)
+ call amovki (ALLERR_OK, Memi[DP_AIER(allstar)], nstar)
+
+ # Remove stars that have INDEF centers, are off the image altogether,
+ # or are too close to another star before beginning to fit.
+ call dp_strip (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_ASKIP(allstar)],
+ Memi[DP_AIER(allstar)], nstar, sepmin, int(IM_LEN(im,1)),
+ int(IM_LEN(im,2)), DP_FITRAD(dao), DP_VERBOSE(dao))
+
+ # Write out results for the rejected stars.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+nstar],
+ Memr[DP_APYCEN(apsel)+nstar], Memr[DP_APXCEN(apsel)+nstar],
+ Memr[DP_APYCEN(apsel)+nstar], DP_APNUM(apsel) - nstar)
+ if (DP_TEXT(dao) == YES) {
+ call dp_xalwrite (allfd, rejfd, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_APCHI(apsel)],
+ Memr[DP_ANUMER(allstar)], Memr[DP_ADENOM(allstar)],
+ Memi[DP_ASKIP(allstar)], Memi[DP_AIER(allstar)], niter,
+ nstar + 1, DP_APNUM(apsel), DP_PSFMAG(psffit), csharp)
+ } else {
+ call dp_talwrite (allfd, rejfd, Memi[colpoints],
+ Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APERR(apsel)], Memr[DP_APMSKY(apsel)],
+ Memr[DP_APCHI(apsel)], Memr[DP_ANUMER(allstar)],
+ Memr[DP_ADENOM(allstar)], Memi[DP_ASKIP(allstar)],
+ Memi[DP_AIER(allstar)], niter, nstar + 1, DP_APNUM(apsel),
+ row1_number, row2_number, DP_PSFMAG(psffit), csharp)
+ }
+
+ # Do some initialization for the fit.
+ clmpmx = CLAMP_FRACTION * DP_FITRAD(dao)
+ call aclrr (Memr[DP_AXOLD(allstar)], nstar)
+ call aclrr (Memr[DP_AYOLD(allstar)], nstar)
+ call amovkr (clmpmx, Memr[DP_AXCLAMP(allstar)], nstar)
+ call amovkr (clmpmx, Memr[DP_AYCLAMP(allstar)], nstar)
+ call amovkr (1.0, Memr[DP_ASUMWT(allstar)], nstar)
+
+ # Begin iterating.
+ for (niter = 1; (nstar > 0) && (niter <= DP_MAXITER (dao));
+ niter = niter + 1) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("NITER = %d\n")
+ call pargi (niter)
+ }
+
+ if ((DP_CLIPEXP(dao) != 0) && (niter >= 4))
+ clip = true
+ else
+ clip = false
+
+ # Define the critical errors.
+ if (niter >= 15)
+ wcrit = WCRIT15
+ else if (niter >= 10)
+ wcrit = WCRIT10
+ else if (niter >= 5)
+ wcrit = WCRIT5
+ else
+ wcrit = WCRIT0
+
+ # Sort the data on y.
+ call dp_alsort (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_ASUMWT(allstar)],
+ Memr[DP_AXOLD(allstar)], Memr[DP_AYOLD(allstar)],
+ Memr[DP_AXCLAMP(allstar)], Memr[DP_AYCLAMP(allstar)], nstar)
+
+ # Compute the working radius. This is either the fitting radius
+ # or the outer sky radius if this is an iteration during which
+ # sky is to be determined whichever is larger.
+ if ((DP_FITSKY(dao) == YES) && (mod (niter, itsky) == 0)) {
+ newsky = YES
+ if ((DP_ANNULUS(dao) + DP_DANNULUS(dao)) > DP_FITRAD(dao))
+ radius = DP_ANNULUS(dao) + DP_DANNULUS(dao)
+ else
+ radius = DP_FITRAD(dao)
+ } else {
+ newsky = NO
+ radius = DP_FITRAD(dao)
+ }
+
+ # Define region of the image used to fit the remaining stars.
+ call alimr (Memr[DP_APXCEN(apsel)], nstar, xmin, xmax)
+ call alimr (Memr[DP_APYCEN(apsel)], nstar, ymin, ymax)
+ x1 = max (1, min (IM_LEN(im,1), int (xmin-radius)+1))
+ x2 = max (1, min (IM_LEN(im,1), int (xmax+radius)))
+ y1 = max (1, min (IM_LEN(im,2), int (ymin-radius)+1))
+ y2 = max (1, min (IM_LEN (im,2), int (ymax+radius)))
+
+ # Reinitialize the weight and scratch arrays / images .
+ call dp_wstinit (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ nstar, radius, x1, x2, y1, y2)
+
+ # Recompute the initial sky estimates if that switch is enabled.
+ if (newsky == YES)
+ call dp_alsky (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMSKY(apsel)], nstar,
+ x1, x2, y1, y2, DP_ANNULUS(dao), DP_ANNULUS(dao) +
+ DP_DANNULUS(dao), 100, -MAX_REAL)
+
+ # Group the remaining stars.
+ call dp_regroup (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_ASUMWT(allstar)],
+ Memr[DP_AXOLD(allstar)], Memr[DP_AYOLD(allstar)],
+ Memr[DP_AXCLAMP(allstar)], Memr[DP_AYCLAMP(allstar)], nstar,
+ DP_FITRAD(dao), Memi[DP_ALAST(allstar)])
+
+ # Reset the error codes.
+ call amovki (ALLERR_OK, Memi[DP_AIER(allstar)], nstar)
+
+ # Do the serious fitting one group at a time.
+ for (istar = 1; istar <= nstar; istar = lstar + 1) {
+
+ # Do the fitting a group at a time.
+ lstar = dp_alphot (dao, im, nstar, istar, niter, sepcrt,
+ sepmin, wcrit, clip, clmpmx, version)
+
+ # Write the results.
+ if (DP_TEXT(dao) == YES) {
+ call dp_xalwrite (allfd, rejfd, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_APCHI(apsel)],
+ Memr[DP_ANUMER(allstar)], Memr[DP_ADENOM(allstar)],
+ Memi[DP_ASKIP(allstar)], Memi[DP_AIER(allstar)],
+ niter, istar, lstar, DP_PSFMAG(psffit), csharp)
+ } else {
+ call dp_talwrite (allfd, rejfd, Memi[colpoints],
+ Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APERR(apsel)], Memr[DP_APMSKY(apsel)],
+ Memr[DP_APCHI(apsel)], Memr[DP_ANUMER(allstar)],
+ Memr[DP_ADENOM(allstar)], Memi[DP_ASKIP(allstar)],
+ Memi[DP_AIER(allstar)], niter, istar, lstar, row1_number,
+ row2_number, DP_PSFMAG(psffit), csharp)
+ }
+
+ }
+
+ # Find the last star in the list that still needs more work.
+ nstar = dp_alnstar (Memi[DP_ASKIP(allstar)], nstar)
+
+ # Remove the fitted stars from the list.
+ for (istar = 1; (istar < nstar) && nstar > 0; istar = istar + 1) {
+ call dp_alswitch (Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_ASUMWT(allstar)],
+ Memr[DP_AXOLD(allstar)], Memr[DP_AYOLD(allstar)],
+ Memr[DP_AXCLAMP(allstar)], Memr[DP_AYCLAMP(allstar)],
+ Memi[DP_ASKIP(allstar)], istar, nstar)
+ }
+
+ # Flush the output buffers.
+ if (dp_gwt (dao, im, ldummy, ldummy, READ_WRITE, YES) == NULL)
+ ;
+ if (dp_gst (dao, im, ldummy, ldummy, READ_ONLY, YES) == NULL)
+ ;
+ if (dp_gdc (dao, im, ldummy, ldummy, READ_WRITE, YES) == NULL)
+ ;
+ }
+
+ # Release cached memory.
+ call dp_uncache (dao, subim, savesub)
+
+ call sfree (sp)
+
+ # Restore the original fitting radius
+ DP_FITRAD(dao) = fradius
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+end
+
+
+# DP_ALNSTAR -- Compute the number of stars left
+
+int procedure dp_alnstar (skip, nstar)
+
+int skip[ARB] # skip array
+int nstar # number of stars
+
+begin
+ while (nstar > 0) {
+ if (skip[nstar] == NO)
+ break
+ nstar = nstar - 1
+ }
+
+ return (nstar)
+end
+
+
+# DP_ALSWITCH -- Switch array elements.
+
+procedure dp_alswitch (id, xcen, ycen, mag, magerr, sky, chi, xold, yold,
+ xclamp, yclamp, skip, istar, nstar)
+
+int id[ARB] # array of ids
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+real magerr[ARB] # array of magnitude errors
+real sky[ARB] # array of sky values
+real chi[ARB] # array of chi values
+real xold[ARB] # old x array
+real yold[ARB] # old y array
+real xclamp[ARB] # array of x clamps
+real yclamp[ARB] # array of y clamps
+int skip[ARB] # skip array
+int istar # next star
+int nstar # total number of stars
+
+int dp_alnstar()
+
+begin
+ if (skip[istar] == YES) {
+ id[istar] = id[nstar]
+ xcen[istar] = xcen[nstar]
+ ycen[istar] = ycen[nstar]
+ mag[istar] = mag[nstar]
+ magerr[istar] = magerr[nstar]
+ sky[istar] = sky[nstar]
+ chi[istar] = chi[nstar]
+ xold[istar] = xold[nstar]
+ yold[istar] = yold[nstar]
+ xclamp[istar] = xclamp[nstar]
+ yclamp[istar] = yclamp[nstar]
+ skip[istar] = NO
+ nstar = nstar - 1
+ nstar = dp_alnstar (skip, nstar)
+ }
+end
diff --git a/noao/digiphot/daophot/allstar/dpcache.x b/noao/digiphot/daophot/allstar/dpcache.x
new file mode 100644
index 00000000..0782b98f
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpcache.x
@@ -0,0 +1,244 @@
+include <imhdr.h>
+include <mach.h>
+include "../lib/allstardef.h"
+include "../lib/daophotdef.h"
+
+define FUDGE 1.2 # fudge factor for memory allocation
+
+# DP_CACHE -- Determine whether it is possible to store all the data
+# in memory or not.
+
+procedure dp_cache (dao, im, subim, cache)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+pointer subim # pointer to the output subtracted image
+int cache # cache the data ?
+
+int npix, req_mem1, req_mem2, req_mem3, old_mem, max_mem
+pointer sp, temp, allstar, data, weights, subt
+int sizeof(), begmem()
+pointer immap()
+errchk begmem(), calloc()
+
+begin
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (temp, SZ_FNAME, TY_CHAR)
+
+ # Define the allstar pointer.
+ allstar = DP_ALLSTAR(dao)
+
+ # Store the old working set size.
+ DP_SZOLDCACHE(allstar) = begmem (0, old_mem, max_mem)
+
+ # Figure out the memory requirements.
+ npix = IM_LEN(im,1) * IM_LEN(im,2)
+ req_mem1 = FUDGE * npix * sizeof (TY_REAL)
+ req_mem2 = req_mem1 + req_mem1
+ req_mem3 = req_mem2 + req_mem1
+
+ # Initialize.
+ DP_CACHE (allstar,A_DCOPY) = NO
+ DP_CACHE (allstar,A_SUBT) = NO
+ DP_CACHE (allstar,A_WEIGHT) = NO
+
+ DP_DBUF(allstar) = NULL
+ DP_SBUF(allstar) = NULL
+ DP_WBUF(allstar) = NULL
+
+ # Use IRAF images as temporary storage space.
+ if (cache == NO) {
+
+ # The output subtracted image.
+ DP_DATA (allstar) = subim
+
+ # The scratch image.
+ call mktemp ("subt", Memc[temp], SZ_FNAME)
+ DP_SUBT (allstar) = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(DP_SUBT(allstar)) = 2
+ IM_PIXTYPE(DP_SUBT(allstar)) = TY_REAL
+
+ # The weights image.
+ call mktemp ("wt", Memc[temp], SZ_FNAME)
+ DP_WEIGHTS (allstar) = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(DP_WEIGHTS(allstar)) = 2
+ IM_PIXTYPE(DP_WEIGHTS(allstar)) = TY_REAL
+
+ # Set the type of caching to be used.
+ DP_ISCACHE(allstar) = NO
+ DP_ALLCACHE(allstar) = NO
+
+ } else {
+
+ # Is the memory available.
+ if (old_mem >= req_mem3) {
+ DP_CACHE(allstar,A_DCOPY) = YES
+ DP_CACHE(allstar,A_WEIGHT) = YES
+ DP_CACHE (allstar,A_SUBT) = YES
+ } else {
+ if (begmem (req_mem1, old_mem, max_mem) >= req_mem1)
+ DP_CACHE(allstar,A_SUBT) = YES
+ if (begmem (req_mem2, old_mem, max_mem) >= req_mem2)
+ DP_CACHE(allstar,A_WEIGHT) = YES
+ if (begmem (req_mem3, old_mem, max_mem) >= req_mem3)
+ DP_CACHE(allstar,A_DCOPY) = YES
+ }
+
+ # Allocate space for the scratch image.
+ subt = NULL
+ if (DP_CACHE(allstar, A_SUBT) == YES) {
+ iferr {
+ call calloc (subt, npix, TY_REAL)
+ } then {
+ if (subt != NULL)
+ call mfree (subt, TY_REAL)
+ call mktemp ("subt", Memc[temp], SZ_FNAME)
+ subt = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(subt) = 2
+ IM_PIXTYPE(subt) = TY_REAL
+ DP_SUBT(allstar) = subt
+ DP_CACHE(allstar,A_SUBT) = NO
+ } else
+ DP_SUBT(allstar) = subt
+ } else {
+ call mktemp ("subt", Memc[temp], SZ_FNAME)
+ subt = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(subt) = 2
+ IM_PIXTYPE(subt) = TY_REAL
+ DP_SUBT(allstar) = subt
+ }
+
+ # Allocate space for the weights image.
+ weights = NULL
+ if (DP_CACHE(allstar, A_WEIGHT) == YES) {
+ iferr {
+ call calloc (weights, npix, TY_REAL)
+ } then {
+ if (weights != NULL)
+ call mfree (weights, TY_REAL)
+ call mktemp ("wt", Memc[temp], SZ_FNAME)
+ weights = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(weights) = 2
+ IM_PIXTYPE(weights) = TY_REAL
+ DP_WEIGHTS(allstar) = weights
+ DP_CACHE(allstar,A_WEIGHT) = NO
+ } else
+ DP_WEIGHTS(allstar) = weights
+ } else {
+ call mktemp ("wt", Memc[temp], SZ_FNAME)
+ weights = immap (Memc[temp], NEW_COPY, im)
+ IM_NDIM(weights) = 2
+ IM_PIXTYPE(weights) = TY_REAL
+ DP_WEIGHTS(allstar) = weights
+ }
+
+ # Allocate space for the output subtracted image.
+ data = NULL
+ if (DP_CACHE(allstar, A_DCOPY) == YES) {
+ iferr {
+ call calloc (data, npix, TY_REAL)
+ } then {
+ if (data != NULL)
+ call mfree (data, TY_REAL)
+ DP_DATA(allstar) = subim
+ DP_CACHE(allstar,A_DCOPY) = NO
+ } else {
+ DP_DATA(allstar) = data
+ }
+ } else
+ DP_DATA(allstar) = subim
+
+ # Set the type of caching to be used.
+ if (DP_CACHE(allstar,A_DCOPY) == NO && DP_CACHE(allstar,A_SUBT) ==
+ NO && DP_CACHE(allstar,A_WEIGHT) == NO) {
+ DP_ISCACHE(allstar) = NO
+ DP_ALLCACHE(allstar) = NO
+ } else if (DP_CACHE(allstar,A_DCOPY) == YES && DP_CACHE(allstar,
+ A_SUBT) == YES && DP_CACHE(allstar,A_WEIGHT) == YES) {
+ DP_ISCACHE(allstar) = YES
+ DP_ALLCACHE(allstar) = YES
+ } else {
+ DP_ISCACHE(allstar) = YES
+ DP_ALLCACHE(allstar) = NO
+ }
+
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_UNCACHE -- Release all the stored memory.
+
+procedure dp_uncache (dao, subim, savesub)
+
+pointer dao # pointer to the daophot strucuture
+pointer subim # pointer to the output subtracted image
+int savesub # save the subtracted image ?
+
+int j, ncol, nline
+pointer sp, imname, v, data, buf, allstar
+pointer impnlr()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (imname, SZ_FNAME, TY_CHAR)
+ call salloc (v, IM_MAXDIM, TY_LONG)
+
+ # Define the allstar pointer.
+ allstar = DP_ALLSTAR(dao)
+
+ ncol = IM_LEN(subim,1)
+ nline = IM_LEN(subim,2)
+
+ # Write out the subtracted image.
+ if (DP_CACHE(allstar,A_DCOPY) == YES && savesub == YES) {
+ data = DP_DBUF(allstar)
+ call amovkl (long(1), Meml[v], IM_MAXDIM)
+ do j = 1, nline {
+ if (impnlr (subim, buf, Meml[v]) != EOF)
+ call amovr (Memr[data], Memr[buf], ncol)
+ data = data + ncol
+ }
+ }
+ DP_DATA(allstar) = NULL
+
+ # Release any memory used by the subtracted image.
+ if (DP_DBUF(allstar) != NULL)
+ call mfree (DP_DBUF(allstar), TY_REAL)
+ DP_DBUF(allstar) = NULL
+
+ # Delete the scratch image if any.
+ if (DP_CACHE(allstar,A_SUBT) == NO) {
+ call strcpy (IM_HDRFILE(DP_SUBT(allstar)), Memc[imname], SZ_FNAME)
+ call imunmap (DP_SUBT(allstar))
+ call imdelete (Memc[imname])
+ }
+ DP_SUBT(allstar) = NULL
+
+ # Release any memory used by the scratch image.
+ if (DP_SBUF(allstar) != NULL)
+ call mfree (DP_SBUF(allstar), TY_REAL)
+ DP_SBUF(allstar) = NULL
+
+ # Delete the weights image if any.
+ if (DP_CACHE(allstar,A_WEIGHT) == NO) {
+ call strcpy (IM_HDRFILE(DP_WEIGHTS(allstar)), Memc[imname],
+ SZ_FNAME)
+ call imunmap (DP_WEIGHTS(allstar))
+ call imdelete (Memc[imname])
+ }
+ DP_WEIGHTS(allstar) = NULL
+
+ # Release any memory used by the weights buffer.
+ if (DP_WBUF(allstar) != NULL)
+ call mfree (DP_WBUF(allstar), TY_REAL)
+ DP_WBUF(allstar) = NULL
+
+ # Reset the working set size to the previous value.
+ call fixmem (DP_SZOLDCACHE(allstar))
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/allstar/dpglim.x b/noao/digiphot/daophot/allstar/dpglim.x
new file mode 100644
index 00000000..d5f1fedb
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpglim.x
@@ -0,0 +1,17 @@
+# DP_GLIM -- Get the lower and upper limits of a section around a specified
+# center.
+
+procedure dp_glim (xc, yc, radius, ixmin, ixmax, iymin, iymax, lx, mx, ly, my)
+
+real xc, yc # the x and y center points
+real radius # the radial distance
+int ixmin, ixmax # absolute x boundaries
+int iymin, iymax # absolute y boundaries
+int lx, mx, ly, my # the returned limits
+
+begin
+ lx = max (ixmin - 1, min (ixmax, int (xc - radius))) + 1
+ mx = max (ixmin, min (ixmax, int (xc + radius)))
+ ly = max (iymin - 1, min (iymax, int (yc - radius))) + 1
+ my = max (iymin, min (iymax, int (yc + radius)))
+end
diff --git a/noao/digiphot/daophot/allstar/dprectify.x b/noao/digiphot/daophot/allstar/dprectify.x
new file mode 100644
index 00000000..5fd7c0db
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dprectify.x
@@ -0,0 +1,74 @@
+# DP_RECTIFY -- Shuffle a real vector based upon an input index vector using
+# dynamic memory.
+
+procedure dp_rectify (x, index, nitem)
+
+real x[ARB]
+int index[ARB]
+int nitem
+
+pointer sp, hold
+
+begin
+ call smark (sp)
+ call salloc (hold, nitem, TY_REAL)
+ call dp_dorect (x, Memr[hold], index, nitem)
+ call sfree (sp)
+end
+
+
+# DP_IRECTIFY -- Shuffle an integer vector based upon an input index vector
+# using dynamic memory.
+
+procedure dp_irectify (x, index, nitem)
+
+int x[ARB]
+int index[ARB]
+int nitem
+
+pointer sp, hold
+
+begin
+ call smark (sp)
+ call salloc (hold, nitem, TY_INT)
+ call dp_idorect (x, Memi[hold], index, nitem)
+ call sfree (sp)
+end
+
+
+# DP_DORECT -- Shuffle a vector based upon an input index vector using
+# a preallocated dummy array.
+
+procedure dp_dorect (x, hold, index, nitem)
+
+real x[ARB]
+real hold[ARB]
+int index[ARB]
+int nitem
+
+int i
+
+begin
+ call amovr (x, hold, nitem)
+ do i = 1, nitem
+ x[i] = hold[index[i]]
+end
+
+
+# DP_IDORECT -- Shuffle an integer vector based upon an input index vector
+# using a preallocated dummy array.
+
+procedure dp_idorect (x, hold, index, nitem)
+
+int x[ARB]
+int hold[ARB]
+int index[ARB]
+int nitem
+
+int i
+
+begin
+ call amovi (x, hold, nitem)
+ do i = 1, nitem
+ x[i] = hold[index[i]]
+end
diff --git a/noao/digiphot/daophot/allstar/dpregroup.x b/noao/digiphot/daophot/allstar/dpregroup.x
new file mode 100644
index 00000000..a7561fb8
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/dpregroup.x
@@ -0,0 +1,219 @@
+# DP_ALSORT -- Sort the stars on the y coordinate.
+
+procedure dp_alsort (id, x, y, mag, sky, sumwt, dxold, dyold, xclamp, yclamp,
+ nstar)
+
+int id[ARB] # array if star ids
+real x[ARB] # array of star x values
+real y[ARB] # array of y values
+real mag[ARB] # array of star magnitudes
+real sky[ARB] # array of star sky values
+real sumwt[ARB] # array of weighted sums
+real dxold[ARB] # the previous star x array
+real dyold[ARB] # the previous star y array
+real xclamp[ARB] # the x array clamps
+real yclamp[ARB] # the y array clamps
+int nstar # the number of stars
+
+int ier
+pointer sp, index
+
+begin
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (index, nstar, TY_INT)
+
+ # Sort the star list on y.
+ call quick (y, nstar, Memi[index], ier)
+
+ # Recitfy the remaining arrays.
+ call dp_irectify (id, Memi[index], nstar)
+ call dp_rectify (x, Memi[index], nstar)
+ call dp_rectify (mag, Memi[index], nstar)
+ call dp_rectify (sky, Memi[index], nstar)
+ call dp_rectify (sumwt, Memi[index], nstar)
+ call dp_rectify (dxold, Memi[index], nstar)
+ call dp_rectify (dyold, Memi[index], nstar)
+ call dp_rectify (xclamp, Memi[index], nstar)
+ call dp_rectify (yclamp, Memi[index], nstar)
+
+ # Release memory.
+ call sfree (sp)
+end
+
+
+# DP_REGROUP -- Group stars into physical associations based on proximity.
+
+procedure dp_regroup (id, x, y, mag, sky, chi, dxold, dyold, xclamp, yclamp,
+ nstar, radius, last)
+
+int id[ARB] # array if star ids
+real x[ARB] # array of star x values
+real y[ARB] # array of y values
+real mag[ARB] # array of star magnitudes
+real sky[ARB] # array of star sky values
+real chi[ARB] # array of chis
+real dxold[ARB] # the previous star x array
+real dyold[ARB] # the previous star y array
+real xclamp[ARB] # the x array clamps
+real yclamp[ARB] # the y array clamps
+int nstar # the number of stars
+real radius # the fitting radius
+int last[ARB] # the last array (NO or YES for last star)
+
+int itop, itest, j, k, i, ier
+pointer sp, index
+real critrad, critradsq, xtest, ytest, dx, dy
+
+begin
+ # If there is only one stars its value of last is YES.
+ if (nstar <= 1) {
+ last[1] = YES
+ return
+ }
+
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (index, nstar, TY_INT)
+
+ # Compute the critical radius.
+ critrad = 2.0 * radius
+ critradsq = critrad * critrad
+
+ # Sort the star list on y and rectify the accompanying x array.
+ call quick (y, nstar, Memi[index], ier)
+ call dp_rectify (x, Memi[index], nstar)
+
+ # At this point the stars are in a stack NSTAR stars long. The
+ # variable ITEST will point to the position in the stack
+ # occupied by the star which is currently the center of a
+ # circle of the CRITRAD pixels, within which we are
+ # looking for other stars. ITEST starts out with a value of one.
+ # ITOP points to the top position in the stack of the
+ # stars which have not yet been assigned to groups. ITOP starts
+ # out with the value of 2. Each time through, the program goes
+ # down through the stack from ITOP and looks for stars within
+ # the critrad pixels from the star at stack position ITEST.
+ # When such a star is found, it changes places in the
+ # stack with the star at ITOP and ITOP is incremented by one.
+ # When the search reaches a star J such that Y(J) - Y(ITEST)
+ # > CRITRAD we know that no further stars will be found
+ # within the CRITRAD pixels, the pointer ITEST is incremented
+ # by one, and the search proceeds again from the new
+ # value of ITOP. If the pointer ITEST catches up with the
+ # pointer ITOP, then the current group is complete
+ # with the star at the position ITEST-1, and
+ # ITOP is incremented by one. If ITOP catches up with NSTAR
+ # the grouping process is complete.
+
+ itop = 2
+ do itest = 1, nstar {
+
+ # Initialize the last array.
+ last[itest] = NO
+
+ # ITEST has reached ITOP; so no other unassigned stars are
+ # within CRITRADIUS pixels of any member of the current
+ # group. The group is therefore complete. Signify this by
+ # setting LAST[ITEST-1] = YES, and incrementing the value of
+ # ITOP by one. If ITOP is greater than NSTAR at this point
+ # list is finished.
+
+ if (itest == itop) {
+ j = itest - 1
+ if (j > 0)
+ last[j] = YES
+ itop = itop + 1
+ if (itop > nstar) {
+ last[itest] = YES
+ break
+ }
+ }
+
+ # Now go through the list of unassigned stars, occupying
+ # positions ITOP through NSTAR in the stack, to look for
+ # stars within CRITRADIUS pixels of the star at
+ # position ITEST inthe stack. If one is found, move it
+ # up to stack position ITOP and increment ITOP by one.
+
+ xtest = x[itest]
+ ytest = y[itest]
+ j = itop
+
+ do i = j, nstar {
+
+ # Check the distance between the stars.
+ dy = y[i] - ytest
+ if (dy > critrad)
+ break
+ dx = x[i] - xtest
+ if (abs (dx) > critrad)
+ next
+ if ((dx * dx + dy * dy) > critradsq)
+ next
+
+ # This star is within CRITRAD pixels of the
+ # star at stack position ITEST. Therefore it is
+ # added to the current group by moving it up to position
+ # ITOP in the stack, where the pointer ITEST may reach it.
+
+ call dp_rgswap (itop, i, x, y, Memi[index])
+
+ # Now increment ITOP by 1 to point at the top most
+ # unassigned star in the stack.
+ itop = itop + 1
+ if (itop > nstar) {
+ do k = itest, nstar - 1
+ last[k] = NO
+ last[nstar] = YES
+ break
+ }
+ }
+
+ if (itop > nstar)
+ break
+ }
+
+ # Reorder the remaining arrays to match the x and y arrays.
+ call dp_irectify (id, Memi[index], nstar)
+ call dp_rectify (mag, Memi[index], nstar)
+ call dp_rectify (sky, Memi[index], nstar)
+ call dp_rectify (chi, Memi[index], nstar)
+ call dp_rectify (dxold, Memi[index], nstar)
+ call dp_rectify (dyold, Memi[index], nstar)
+ call dp_rectify (xclamp, Memi[index], nstar)
+ call dp_rectify (yclamp, Memi[index], nstar)
+
+ call sfree (sp)
+end
+
+
+# DP_RGSWAP -- Swap the i-th and j-th stars in the stack without otherwise
+# altering the order of the stars..
+
+procedure dp_rgswap (i, j, x, y, index)
+
+int i, j # indices of the two stars to be swapped
+real x[ARB] # the array of x values
+real y[ARB] # the array of y values
+int index[ARB] # the index array
+
+int ihold, k,l
+real xhold, yhold
+
+begin
+ xhold = x[j]
+ yhold = y[j]
+ ihold = index[j]
+
+ do k = j, i + 1, -1 {
+ l = k - 1
+ x[k] = x[l]
+ y[k] = y[l]
+ index[k] = index[l]
+ }
+
+ x[i] = xhold
+ y[i] = yhold
+ index[i] = ihold
+end
diff --git a/noao/digiphot/daophot/allstar/mkpkg b/noao/digiphot/daophot/allstar/mkpkg
new file mode 100644
index 00000000..d607592b
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/mkpkg
@@ -0,0 +1,32 @@
+# ALLSTAR task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpabuf.x <imhdr.h> ../lib/daophotdef.h \
+ ../lib/allstardef.h
+ dpaconfirm.x ../lib/daophotdef.h
+ dpcache.x <imhdr.h> <mach.h> \
+ ../lib/daophotdef.h ../lib/allstardef.h
+ dpregroup.x
+ dprectify.x
+ dpalwrite.x <tbset.h> <time.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/allstardef.h
+ dpastar.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/allstardef.h \
+ ../lib/apseldef.h
+ dpalphot.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/allstardef.h
+ dpalinit.x <imhdr.h> <mach.h> \
+ <math.h> ../lib/daophotdef.h \
+ ../lib/allstardef.h
+ dpglim.x
+ dpalmemstar.x ../lib/daophotdef.h ../lib/allstardef.h
+ t_allstar.x <fset.h> ../lib/daophotdef.h \
+ <imhdr.h>
+ ;
diff --git a/noao/digiphot/daophot/allstar/t_allstar.x b/noao/digiphot/daophot/allstar/t_allstar.x
new file mode 100644
index 00000000..b3991179
--- /dev/null
+++ b/noao/digiphot/daophot/allstar/t_allstar.x
@@ -0,0 +1,355 @@
+include <imhdr.h>
+include <fset.h>
+include "../lib/daophotdef.h"
+
+# T_ALLSTAR -- Group a list of stars into physical associations, fit the PSF
+# to the stars in each group simultaneously, and produce an output subtracted
+# image.
+
+procedure t_allstar ()
+
+pointer image # the input image
+pointer psfimage # the input psf image
+pointer photfile # the input photometry file
+pointer allstarfile # the output photometry file
+pointer subimage # the output subtracted image
+pointer rejfile # the output rejections file
+int cache # cache the data in memory
+int verbose # verbose mode ?
+int verify # verify critical task parameters ?
+int update # update the task parameters ?
+int version # version number
+
+pointer sp, outfname, im, subim, dao, str
+int imlist, limlist, alist, lalist, pimlist, lpimlist, olist, lolist
+int simlist, lsimlist, rlist, lrlist, photfd, psffd, allfd, root, savesub
+int rejfd, wcs
+bool ap_text
+
+pointer immap(), tbtopn()
+int clgwrd(), clgeti()
+int open(), fnldir(), strncmp(), strlen(), btoi(), access()
+int fstati(), imtopen, imtlen(), imtgetim(), fntopnb(), fntlenb()
+int fntgfnb()
+bool itob(), clgetb()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (allstarfile, SZ_FNAME, TY_CHAR)
+ call salloc (rejfile, SZ_FNAME, TY_CHAR)
+ call salloc (subimage, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the task input and output file names.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("allstarfile", Memc[allstarfile], SZ_FNAME)
+ call clgstr ("subimage", Memc[subimage], SZ_FNAME)
+ call clgstr ("rejfile", Memc[rejfile], SZ_FNAME)
+
+ # Get the task mode parameters.
+ verbose = btoi (clgetb ("verbose"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb ("cache"))
+ version = clgeti ("version")
+ version = 2
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[photfile], NO)
+ lalist = fntlenb (alist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ olist = fntopnb (Memc[allstarfile], NO)
+ lolist = fntlenb (olist)
+ simlist = imtopen (Memc[subimage])
+ lsimlist = imtlen (simlist)
+ rlist = fntopnb (Memc[rejfile], NO)
+ lrlist = fntlenb (rlist)
+
+ # Test the lengths of the photometry file, psf image and subtracted
+ # image lists are the same as the length of the input image.
+
+ if ((limlist != lalist) && (strncmp (Memc[photfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and photometry file list lengths")
+ }
+
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and psf file list lengths")
+ }
+
+ if ((limlist != lsimlist) && (strncmp (Memc[subimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and subtracted image list lengths")
+ }
+
+ if ((limlist != lolist) && (strncmp (Memc[allstarfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and subtracted image list lengths")
+ }
+
+ if ((lrlist > 0) && (limlist != lrlist) && (strncmp (Memc[rejfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and subtracted image list lengths")
+ }
+
+ # Open the input image, initialize the daophot structure, get the
+ # pset parameters
+
+ call dp_gppars (dao)
+
+ # Set some parameters.
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Verify and update the parameters as appropriate.
+ if (verify == YES) {
+ call dp_aconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Initialize the daophot fitting structure.
+ call dp_apsetup (dao)
+
+ # Initialize the allstar structure.
+ call dp_allstarsetup (dao)
+
+ # Loop over the images.
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open the image and store some header parameters.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Open the input photometry file.
+ if (fntgfnb (alist, Memc[photfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[photfile], SZ_FNAME)
+ root = fnldir (Memc[photfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[photfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[photfile]))
+ call dp_inname (Memc[image], Memc[outfname], "mag",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[photfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ photfd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ photfd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+ call dp_wgetapert (dao, im, photfd, DP_MAXNSTAR(dao), ap_text)
+
+ # Open the PSF image and read in the PSF.
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage]))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ psffd = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+ call dp_readpsf (dao, psffd)
+
+ # Open the output ALLSTAR file. If the output is DEF_DEFNAME,
+ # dir$default or a directory specification then the extension
+ # "als" is added to the image name and a suitable version
+ # number if appended to the output name.
+
+ if (fntgfnb (olist, Memc[allstarfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[allstarfile], SZ_FNAME)
+ root = fnldir (Memc[allstarfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[allstarfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[allstarfile]))
+ call dp_outname (Memc[image], Memc[outfname], "als",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[allstarfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ allfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ allfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ if (lrlist <= 0) {
+ rejfd = NULL
+ Memc[outfname] = EOS
+ } else {
+ if (fntgfnb (rlist, Memc[rejfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[rejfile], SZ_FNAME)
+ root = fnldir (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[rejfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[rejfile]))
+ call dp_outname (Memc[image], Memc[outfname], "arj",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ rejfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ rejfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ }
+ call dp_sets (dao, OUTREJFILE, Memc[outfname])
+
+ # Open the subtracted image.
+ savesub = YES
+ if (imtgetim (simlist, Memc[subimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[subimage], SZ_FNAME)
+ root = fnldir (Memc[subimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[subimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[subimage])) {
+ call dp_oimname (Memc[image], Memc[outfname], "sub",
+ Memc[outfname], SZ_FNAME)
+ subim = immap (Memc[outfname], NEW_COPY, im)
+ IM_NDIM(subim) = 2
+ IM_PIXTYPE(subim) = TY_REAL
+ } else {
+ call strcpy (Memc[subimage], Memc[outfname], SZ_FNAME)
+ subim = immap (Memc[outfname], NEW_COPY, im)
+ IM_NDIM(subim) = 2
+ IM_PIXTYPE(subim) = TY_REAL
+ }
+ call dp_sets (dao, OUTIMAGE, Memc[outfname])
+
+ # Fit the stars.
+ call dp_astar (dao, im, subim, allfd, rejfd, cache, savesub,
+ version)
+
+ # Close the input image.
+ call imunmap (im)
+
+ # Close the input photometry file.
+ if (ap_text)
+ call close (photfd)
+ else
+ call tbtclo (photfd)
+
+ # Close PSF image.
+ call imunmap (psffd)
+
+ # Close the output photometry file.
+ if (DP_TEXT(dao) == YES)
+ call close (allfd)
+ else
+ call tbtclo (allfd)
+
+ # Close the output rejections files.
+ if (rejfd != NULL) {
+ if (DP_TEXT(dao) == YES)
+ call close (rejfd)
+ else
+ call tbtclo (rejfd)
+ }
+
+ # Close the output subtracted image.
+ call strcpy (IM_HDRFILE(subim), Memc[subimage], SZ_FNAME)
+ call imunmap (subim)
+ if (savesub == NO)
+ call imdelete (Memc[subimage])
+ }
+
+ # Close the file/image lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call imtclose (simlist)
+
+ # Close the allstar structure.
+ call dp_alclose (dao)
+
+ # Close the photometry structure.
+ call dp_apclose (dao)
+
+ # Close the PSF structure.
+ call dp_fitclose (dao)
+
+ # Close up the daophot structure.
+ call dp_free (dao)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/centerpars.par b/noao/digiphot/daophot/centerpars.par
new file mode 100644
index 00000000..b7ff737a
--- /dev/null
+++ b/noao/digiphot/daophot/centerpars.par
@@ -0,0 +1,12 @@
+calgorithm,s,h,"none","|centroid|gauss|none|ofilter|",,Centering algorithm
+cbox,r,h,5.0,,,Centering box width in scale units
+cthreshold,r,h,0.0,,,Centering threshold in sigma above background
+minsnratio,r,h,1.0,0.0,,Minimum signal-to-noise ratio for centering algorithim
+cmaxiter,i,h,10,,,Maximum iterations for centering algorithm
+maxshift,r,h,1.0,,,Maximum center shift in scale units
+clean,b,h,no,,,Symmetry clean before centering
+rclean,r,h,1.0,,,Cleaning radius in scale units
+rclip,r,h,2.0,,,Clipping radius in scale units
+kclean,r,h,3.0,,,K-sigma rejection criterion in skysigma
+mkcenter,b,h,no,,,Mark the computed center
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/daoedit.par b/noao/digiphot/daophot/daoedit.par
new file mode 100644
index 00000000..52723991
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit.par
@@ -0,0 +1,9 @@
+# DAOEDIT parameters
+
+image,f,a,,,,Input image
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor: [x y wcs] key [cmd]"
+cache,b,h,)_.cache,,,"Cache the image pixels?"
+graphics,s,h,)_.graphics,,,Graphics device
+display,s,h,)_.display,,,Display device
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/daoedit/daoedit.h b/noao/digiphot/daophot/daoedit/daoedit.h
new file mode 100644
index 00000000..c373f7c8
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/daoedit.h
@@ -0,0 +1,123 @@
+# The definitions file for the DAOEDIT task
+# At some point this should become paert of daophotdef.h
+
+define PSET_LIST "|datapars|centerpars|fitskypars|photpars|daopars|\
+findpars|"
+
+define PSET_DATAPARS 1
+define PSET_CENTERPARS 2
+define PSET_FITSKYPARS 3
+define PSET_PHOTPARS 4
+define PSET_DAOPARS 5
+define PSET_FINDPARS 6
+
+define CMD_LIST "|lpar|epar|unlearn|scale|fwhmpsf|emission|sigma|datamin|\
+datamax|noise|ccdread|gain|readnoise|epadu|exposure|airmass|filter|obstime|\
+itime|xairmass|ifilter|otime|calgorithm|cbox|cthreshold|maxshift|minsnratio|\
+cmaxiter|clean|rclean|rclip|kclean|mkcenter|salgorithm|annulus|\
+dannulus|skyvalue|smaxiter|sloclip|shiclip|snreject|sloreject|shireject|\
+khist|binsize|smooth|rgrow|mksky|weighting|apertures|zmag|mkapert|\
+function|varorder|nclean|saturated|matchrad|psfrad|fitrad|recenter|fitsky|\
+groupsky|sannulus|wsannulus|flaterr|proferr|maxiter|clipexp|cliprange|\
+critoverlap|maxnstar|maxgroup|threshold|nsigma|ratio|theta|sharplo|sharphi|\
+roundlo|roundhi|mkdetections|"
+
+define CMD_LPAR 1
+define CMD_EPAR 2
+define CMD_UNLEARN 3
+
+define CMD_SCALE 4
+define CMD_FWHMPSF 5
+define CMD_EMISSION 6
+define CMD_SIGMA 7
+define CMD_DATAMIN 8
+define CMD_DATAMAX 9
+define CMD_NOISE 10
+define CMD_CCDREAD 11
+define CMD_GAIN 12
+define CMD_READNOISE 13
+define CMD_EPADU 14
+define CMD_EXPOSURE 15
+define CMD_AIRMASS 16
+define CMD_FILTER 17
+define CMD_OBSTIME 18
+define CMD_ITIME 19
+define CMD_XAIRMASS 20
+define CMD_IFILTER 21
+define CMD_OTIME 22
+
+define CMD_CALGORITHM 23
+define CMD_CBOX 24
+define CMD_CTHRESHOLD 25
+define CMD_MAXSHIFT 26
+define CMD_MINSNRATIO 27
+define CMD_CMAXITER 28
+define CMD_CLEAN 29
+define CMD_RCLEAN 30
+define CMD_RCLIP 31
+define CMD_KCLEAN 32
+define CMD_MKCENTER 33
+
+define CMD_SALGORITHM 34
+define CMD_ANNULUS 35
+define CMD_DANNULUS 36
+define CMD_SKYVALUE 37
+define CMD_SMAXITER 38
+define CMD_SLOCLIP 39
+define CMD_SHICLIP 40
+define CMD_SNREJECT 41
+define CMD_SLOREJECT 42
+define CMD_SHIREJECT 43
+define CMD_KHIST 44
+define CMD_BINSIZE 45
+define CMD_SMOOTH 46
+define CMD_RGROW 47
+define CMD_MKSKY 48
+
+define CMD_WEIGHTING 49
+define CMD_APERTURES 50
+define CMD_ZMAG 51
+define CMD_MKAPERT 52
+
+define CMD_FUNCTION 53
+define CMD_VARORDER 54
+define CMD_NCLEAN 55
+define CMD_SATURATED 56
+define CMD_MATCHRAD 57
+define CMD_PSFRAD 58
+define CMD_FITRAD 59
+define CMD_RECENTER 60
+define CMD_FITSKY 61
+define CMD_GROUPSKY 62
+define CMD_SANNULUS 63
+define CMD_WSANNULUS 64
+define CMD_FLATERR 65
+define CMD_PROFERR 66
+define CMD_MAXITER 67
+define CMD_CLIPEXP 68
+define CMD_CLIPRANGE 69
+define CMD_CRITOVERLAP 70
+define CMD_MAXNSTAR 71
+define CMD_MAXGROUP 72
+
+define CMD_THRESHOLD 73
+define CMD_NSIGMA 74
+define CMD_RATIO 75
+define CMD_THETA 76
+define CMD_SHARPLO 77
+define CMD_SHARPHI 78
+define CMD_ROUNDLO 79
+define CMD_ROUNDHI 80
+define CMD_MKDETECTIONS 81
+
+# define the different WCSS for the radial profile plots
+
+define WCS_XPIX 1
+define WCS_XSCALE 2
+
+define WCS_YCOUNT 1
+define WCS_YNORM 2
+
+# miscellaneous definitions
+
+define MAX_NAPERTS 100
diff --git a/noao/digiphot/daophot/daoedit/daoedit.key b/noao/digiphot/daophot/daoedit/daoedit.key
new file mode 100644
index 00000000..bd2f6b95
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/daoedit.key
@@ -0,0 +1,26 @@
+ Daoedit Commands
+
+? Print help
+: Colon commands
+i Interactive parameter setup menu
+a Estimate center, sky, skysigma, fwhmpsf and magnitude of a star
+r Plot the radial profile of an object and its integral
+g Toggle between image and graphics cursor
+x Toggle radial profile plot between pixel and scale units
+y Toggle radial profile plot between counts and normal units
+q Quit task
+
+ Colon Commands
+
+:lparam/eparam/unlearn pset List/edit/unlearn the named pset
+:parameter [value] List or set an individual pset parameter
+
+
+ Named Parameter Sets
+
+datapars The data dependent parameters
+findpars The daofind task object detection parameters
+centerpars The phot task centering algorithm parameters
+fitskypars The phot task sky fitting algorithm parameters
+photpars The phot task photometry algroithm parameters
+daopars The psf fitting algorithm parameters
diff --git a/noao/digiphot/daophot/daoedit/dpecolon.x b/noao/digiphot/daophot/daoedit/dpecolon.x
new file mode 100644
index 00000000..36bccdf9
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dpecolon.x
@@ -0,0 +1,441 @@
+include <error.h>
+include "daoedit.h"
+
+# DP_ECOLON -- Show/set the DAOPHOT algorithm parameters.
+
+procedure dp_ecolon (cmdstr, gd, redraw)
+
+char cmdstr[ARB] # input colon command
+int gd # pointer to the graphics stream
+int redraw # redraw the radial profile plot
+
+bool bval
+int cmd, pset, ival
+pointer sp, incmd, param, value
+real rval
+bool clgetb()
+int strdic(), nscan(), clgeti()
+real clgetr()
+string datapars "datapars"
+string centerpars "centerpars"
+string fitskypars "fitskypars"
+string photpars "photpars"
+string daopars "daopars"
+string findpars "findpars"
+
+begin
+ call smark (sp)
+ call salloc (incmd, SZ_LINE, TY_CHAR)
+ call salloc (param, SZ_LINE, TY_CHAR)
+ call salloc (value, SZ_LINE, TY_CHAR)
+
+ # Get the command.
+ call sscan (cmdstr)
+ call gargwrd (Memc[incmd], SZ_LINE)
+ if (Memc[incmd] == EOS) {
+ call sfree (sp)
+ return
+ }
+
+ cmd = strdic (Memc[incmd], Memc[incmd], SZ_LINE, CMD_LIST)
+ switch (cmd) {
+ case CMD_LPAR:
+ call gargwrd (Memc[incmd], SZ_LINE)
+ pset = strdic (Memc[incmd], Memc[incmd], SZ_LINE, PSET_LIST)
+ if (pset != 0)
+ call gdeactivate (gd, 0)
+ switch (pset) {
+ case PSET_DATAPARS:
+ call clcmdw ("lparam datapars")
+ case PSET_CENTERPARS:
+ call clcmdw ("lparam centerpars")
+ case PSET_FITSKYPARS:
+ call clcmdw ("lparam fitskypars")
+ case PSET_PHOTPARS:
+ call clcmdw ("lparam photpars")
+ case PSET_DAOPARS:
+ call clcmdw ("lparam daopars")
+ case PSET_FINDPARS:
+ call clcmdw ("lparam findpars")
+ default:
+ call printf ("Unknown parameter set\7\n")
+ }
+
+ case CMD_EPAR:
+ call gargwrd (Memc[incmd], SZ_LINE)
+ pset = strdic (Memc[incmd], Memc[incmd], SZ_LINE, PSET_LIST)
+ if (pset != 0)
+ call gdeactivate (gd, 0)
+ switch (pset) {
+ case PSET_DATAPARS:
+ call clcmdw ("eparam datapars")
+ case PSET_CENTERPARS:
+ call clcmdw ("eparam centerpars")
+ case PSET_FITSKYPARS:
+ call clcmdw ("eparam fitskypars")
+ case PSET_PHOTPARS:
+ call clcmdw ("eparam photpars")
+ case PSET_DAOPARS:
+ call clcmdw ("eparam daopars")
+ case PSET_FINDPARS:
+ call clcmdw ("eparam findpars")
+ default:
+ call printf ("Unknown parameter set\7\n")
+ }
+ if (pset != 0)
+ redraw = YES
+
+ case CMD_UNLEARN:
+ call gargwrd (Memc[incmd], SZ_LINE)
+ pset = strdic (Memc[incmd], Memc[incmd], SZ_LINE, PSET_LIST)
+ switch (pset) {
+ case PSET_DATAPARS:
+ call clcmdw ("unlearn datapars")
+ case PSET_CENTERPARS:
+ call clcmdw ("unlearn centerpars")
+ case PSET_FITSKYPARS:
+ call clcmdw ("unlearn fitskypars")
+ case PSET_PHOTPARS:
+ call clcmdw ("unlearn photpars")
+ case PSET_DAOPARS:
+ call clcmdw ("unlearn daopars")
+ case PSET_FINDPARS:
+ call clcmdw ("unlearn findpars")
+ default:
+ call printf ("Unknown parameter set\7\n")
+ }
+ if (pset != 0)
+ redraw = YES
+
+ case CMD_SCALE:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (datapars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else {
+ call clputr (Memc[param], rval)
+ redraw = YES
+ }
+
+ case CMD_FWHMPSF, CMD_SIGMA, CMD_DATAMIN, CMD_DATAMAX,
+ CMD_READNOISE, CMD_EPADU, CMD_ITIME, CMD_XAIRMASS:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (datapars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_EMISSION:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (datapars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ case CMD_NOISE:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (datapars)
+ call pargstr (Memc[incmd])
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = %s\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+
+ case CMD_CCDREAD, CMD_GAIN, CMD_EXPOSURE, CMD_AIRMASS, CMD_FILTER,
+ CMD_OBSTIME, CMD_IFILTER, CMD_OTIME:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (datapars)
+ call pargstr (Memc[incmd])
+ call gargwrd (Memc[value], SZ_LINE)
+ if (nscan() == 1) {
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = \"%s\"\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+ } else
+ call clpstr (Memc[param], Memc[value])
+
+ case CMD_CALGORITHM:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (centerpars)
+ call pargstr (Memc[incmd])
+ call gargwrd (Memc[value], SZ_LINE)
+ if (nscan() == 1) {
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = \"%s\"\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+ } else {
+ call clpstr (Memc[param], Memc[value])
+ }
+
+ case CMD_CBOX:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (centerpars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else {
+ call clputr (Memc[param], rval)
+ redraw = YES
+ }
+
+ case CMD_CTHRESHOLD, CMD_MAXSHIFT, CMD_MINSNRATIO, CMD_RCLEAN,
+ CMD_RCLIP, CMD_KCLEAN:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (centerpars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_CMAXITER:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (centerpars)
+ call pargstr (Memc[incmd])
+ call gargi (ival)
+ if (nscan() == 1) {
+ call printf ("%s = %d\n")
+ call pargstr (Memc[incmd])
+ call pargi (clgeti (Memc[param]))
+ } else
+ call clputi (Memc[param], ival)
+
+ case CMD_CLEAN, CMD_MKCENTER:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (centerpars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ case CMD_SALGORITHM:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (fitskypars)
+ call pargstr (Memc[incmd])
+ call gargwrd (Memc[value], SZ_LINE)
+ if (nscan() == 1) {
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = \"%s\"\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+ } else {
+ call clpstr (Memc[param], Memc[value])
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ }
+
+ case CMD_ANNULUS, CMD_DANNULUS:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (fitskypars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else {
+ call clputr (Memc[param], rval)
+ redraw = YES
+ }
+
+ case CMD_SLOCLIP, CMD_SHICLIP, CMD_SLOREJECT, CMD_SHIREJECT,
+ CMD_KHIST, CMD_BINSIZE, CMD_SKYVALUE, CMD_RGROW:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (fitskypars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_SMAXITER, CMD_SNREJECT:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (fitskypars)
+ call pargstr (Memc[incmd])
+ call gargi (ival)
+ if (nscan() == 1) {
+ call printf ("%s = %d\n")
+ call pargstr (Memc[incmd])
+ call pargi (clgeti (Memc[param]))
+ } else
+ call clputi (Memc[param], ival)
+
+ case CMD_SMOOTH, CMD_MKSKY:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (fitskypars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ case CMD_WEIGHTING:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (photpars)
+ call pargstr (Memc[incmd])
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = %s\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+
+ case CMD_APERTURES:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (photpars)
+ call pargstr (Memc[incmd])
+ call gargwrd (Memc[value], SZ_LINE)
+ if (nscan() == 1) {
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = \"%s\"\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+ } else {
+ call clpstr (Memc[param], Memc[value])
+ redraw = YES
+ }
+
+ case CMD_ZMAG:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (photpars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else {
+ call clputr (Memc[param], rval)
+ }
+
+ case CMD_MKAPERT:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (photpars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ case CMD_FUNCTION:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (daopars)
+ call pargstr (Memc[incmd])
+ call clgstr (Memc[param], Memc[value], SZ_LINE)
+ call printf ("%s = %s\n")
+ call pargstr (Memc[incmd])
+ call pargstr (Memc[value])
+
+ case CMD_RECENTER, CMD_FITSKY, CMD_GROUPSKY, CMD_SATURATED:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (daopars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ case CMD_PSFRAD, CMD_FITRAD:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (daopars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_MATCHRAD, CMD_SANNULUS, CMD_WSANNULUS, CMD_FLATERR,
+ CMD_PROFERR, CMD_CRITOVERLAP, CMD_CLIPRANGE:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (daopars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_VARORDER, CMD_NCLEAN, CMD_MAXITER, CMD_MAXGROUP,
+ CMD_MAXNSTAR, CMD_CLIPEXP:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (daopars)
+ call pargstr (Memc[incmd])
+ call gargi (ival)
+ if (nscan() == 1) {
+ call printf ("%s = %d\n")
+ call pargstr (Memc[incmd])
+ call pargi (clgeti (Memc[param]))
+ } else
+ call clputi (Memc[param], ival)
+
+ case CMD_THRESHOLD, CMD_NSIGMA, CMD_RATIO, CMD_THETA, CMD_SHARPLO,
+ CMD_SHARPHI, CMD_ROUNDLO, CMD_ROUNDHI:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (findpars)
+ call pargstr (Memc[incmd])
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("%s = %g\n")
+ call pargstr (Memc[incmd])
+ call pargr (clgetr (Memc[param]))
+ } else
+ call clputr (Memc[param], rval)
+
+ case CMD_MKDETECTIONS:
+ call sprintf (Memc[param], SZ_LINE, "%s.%s")
+ call pargstr (findpars)
+ call pargstr (Memc[incmd])
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("%s = %b\n")
+ call pargstr (Memc[incmd])
+ call pargb (clgetb (Memc[param]))
+ } else
+ call clputb (Memc[param], bval)
+
+ default:
+ call printf ("Unknown or ambiguous colon command\7\n")
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daoedit/dpeconfirm.x b/noao/digiphot/daophot/daoedit/dpeconfirm.x
new file mode 100644
index 00000000..31aa359f
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dpeconfirm.x
@@ -0,0 +1,433 @@
+include "daoedit.h"
+
+# DP_CBANNER -- Pritnt the confirm banner.
+
+procedure dp_cbanner ()
+
+begin
+ call printf ("\nVERIFY THE NEW VALUES\n")
+end
+
+
+# DP_CFWHMPSF -- Confirm the new value of fwhmpsf.
+
+procedure dp_cfwhmpsf()
+
+real fwhmpsf, scale, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ fwhmpsf = clgetr ("datapars.fwhmpsf")
+
+ # Confirm the fwhmpsf.
+ call printf ("FWHM of features (%g scale units) (CR or value): ")
+ call pargr (fwhmpsf)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan() == 1)
+ fwhmpsf = rval
+ }
+ call printf ("\tNew FWHM of features: %g scale units %g pixels\n")
+ call pargr (fwhmpsf)
+ call pargr (scale * fwhmpsf)
+
+ # Store the new fwhmpsf.
+ call clputr ("datapars.fwhmpsf", fwhmpsf)
+end
+
+
+# DP_CSIGMA -- Confirm the sigma parameters.
+
+procedure dp_csigma()
+
+real sigma, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current value.
+ sigma = clgetr ("datapars.sigma")
+
+ # Confirm the sky sigma.
+ call printf (
+ "Standard deviation of background (%g counts) (CR or value): ")
+ call pargr (sigma)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ sigma = rval
+ }
+ call printf ("\tNew standard deviation of background: %g counts\n")
+ call pargr (sigma)
+
+ # Store the new sky sigma.
+ call clputr ("datapars.sigma", sigma)
+end
+
+
+# DP_CDMIN -- Confirm the good data minimum value.
+
+procedure dp_cdmin ()
+
+real datamin, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current value.
+ datamin = clgetr ("datapars.datamin")
+
+ # Confirm the new minimum good data value.
+ call printf (
+ "Minimum good data value (%g counts) (CR or value): ")
+ call pargr (datamin)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ datamin = rval
+ }
+ call printf ("\tNew good data minimum: %g counts\n")
+ call pargr (datamin)
+
+ # Store the new good data minimum.
+ call clputr ("datapars.datamin", datamin)
+end
+
+
+# DP_CDMAX -- Confirm the good data maximum value.
+
+procedure dp_cdmax ()
+
+real datamax, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current value.
+ datamax = clgetr ("datapars.datamax")
+
+ # Confirm the new maximum good data value.
+ call printf (
+ "Maximum good data value (%g counts) (CR or value): ")
+ call pargr (datamax)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ datamax = rval
+ }
+ call printf ("\tNew good data maximum: %g counts\n")
+ call pargr (datamax)
+
+ # Store the new maximum good data value.
+ call clputr ("datapars.datamax", datamax)
+end
+
+
+# DP_CCBOX -- Confirm the cbox parameter.
+
+procedure dp_ccbox()
+
+real scale, cbox, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ cbox = clgetr ("centerpars.cbox")
+
+ # Confirm the centering box value.
+ call printf ("Centering box width (%g scale units) (CR or value): ")
+ call pargr (cbox)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ cbox = rval
+ }
+ call printf ("\tNew centering box width: %g scale units %g pixels\n")
+ call pargr (cbox)
+ call pargr (scale * cbox)
+
+ # Store the new centering box.
+ call clputr ("centerpars.cbox", cbox)
+end
+
+
+# DP_CRCLEAN -- Confirm the cleaning radius.
+
+procedure dp_crclean()
+
+real scale, rclean, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rclean = clgetr ("centerpars.rclean")
+
+ # Confirm the cleaning radius..
+ call printf ("Cleaning radius (%g scale units) (CR or value): ")
+ call pargr (rclean)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ rclean = rval
+ }
+ call printf ("\tNew cleaning radius: %g scale units %g pixels\n")
+ call pargr (rclean)
+ call pargr (scale * rclean)
+
+ # Store the new cleaning radius.
+ call clputr ("centerpars.rclean", rclean)
+end
+
+
+# DP_CRCLIP -- Confirm the clipping radius.
+
+procedure dp_crclip()
+
+real scale, rclip, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rclip = clgetr ("centerpars.rclip")
+
+ # Confirm the cleaning radius..
+ call printf ("Clipping radius (%g scale units) (CR or value): ")
+ call pargr (rclip)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ rclip = rval
+ }
+ call printf ("\tNew clipping radius: %g scale units %g pixels\n")
+ call pargr (rclip)
+ call pargr (scale * rclip)
+
+ # Store the new clipping radius.
+ call clputr ("centerpars.rclip", rclip)
+end
+
+
+# DP_CANNULUS -- Confirm the inner radius of the sky annulus.
+
+procedure dp_cannulus()
+
+real scale, annulus, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ annulus = clgetr ("fitskypars.annulus")
+
+ # Confirm the sky annulus.
+ call printf (
+ "Inner radius of sky annulus (%g scale units) (CR or value): ")
+ call pargr (annulus)
+ call flush (STDOUT)
+ if (scan () != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ annulus = rval
+ }
+ call printf (
+ "\tNew inner radius of sky annulus: %g scale units %g pixels\n")
+ call pargr (annulus)
+ call pargr (scale * annulus)
+
+ # Store the new sky annulus.
+ call clputr ("fitskypars.annulus", annulus)
+end
+
+
+# DP_CDANNULUS -- Confirm the annulus width parameter.
+
+procedure dp_cdannulus()
+
+real scale, dannulus, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ dannulus = clgetr ("fitskypars.dannulus")
+
+ # Confirm the sky annulus width.
+ call printf (
+ "Width of the sky annulus (%g scale units) (CR or value): ")
+ call pargr (dannulus)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ dannulus = rval
+ }
+ call printf (
+ "\tNew width of the sky annulus: %g scale units %g pixels\n")
+ call pargr (dannulus)
+ call pargr (scale * dannulus)
+
+ # Save the new sky annulus width.
+ call clputr ("fitskypars.dannulus", dannulus)
+end
+
+
+# DP_CRGROW -- Confirm the region growing radius.
+
+procedure dp_crgrow()
+
+real scale, rgrow, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Mark the region growing radius.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rgrow = clgetr ("fitskypars.rgrow")
+
+ # Confirm the new region growing radius.
+ call printf (
+ "Region growing radius (%g scale units) (CR or value): ")
+ call pargr (rgrow)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ rgrow = rval
+ }
+ call printf (
+ "\tNew region growing radius: %g scale units %g pixels\n")
+ call pargr (rgrow)
+ call pargr (scale * rgrow)
+
+ # Save the new region growing radius.
+ call clputr ("fitskypars.rgrow", rgrow)
+end
+
+
+# DP_CAPER -- Confirm the aperture string.
+
+procedure dp_caper()
+
+int i, naperts
+pointer sp, apstr, newapstr, aperts
+real scale
+int scan(), nscan(), dp_gaperts()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (apstr, SZ_LINE, TY_CHAR)
+ call salloc (newapstr, SZ_LINE, TY_CHAR)
+ call salloc (aperts, MAX_NAPERTS, TY_REAL)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ call clgstr ("photpars.apertures", Memc[apstr], SZ_LINE)
+
+ # Confirm the aperture string.
+ call printf (
+ "File/list of aperture radii (%s scale units) (CR or value): ")
+ call pargstr (Memc[apstr])
+ call flush (STDOUT)
+
+ # Get the new apertures.
+ if (scan() != EOF) {
+ call gargwrd (Memc[newapstr], SZ_LINE)
+ if (nscan () == 1)
+ call strcpy (Memc[newapstr], Memc[apstr], SZ_LINE)
+ }
+
+ # Print the new apertures.
+ naperts = dp_gaperts (Memc[apstr], Memr[aperts], MAX_NAPERTS)
+ do i = 1, naperts {
+ call printf ("\tAperture radius %d: %g scale units %g pixels\n")
+ call pargi (i)
+ call pargr (Memr[aperts+i-1])
+ call pargr (scale * Memr[aperts+i-1])
+ }
+
+ # Save the new aperture string.
+ call clpstr ("photpars.apertures", Memc[apstr])
+
+ call sfree (sp)
+end
+
+
+# DP_CPSFRAD -- Confirm the psf radius.
+
+procedure dp_cpsfrad()
+
+real scale, psfrad, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ psfrad = clgetr ("daopars.psfrad")
+
+ # Confirm the new PSF radius.
+ call printf ("PSF radius (%g scale units) (CR or value): ")
+ call pargr (psfrad)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ psfrad = rval
+ }
+ call printf ("\tNew PSF radius: %g scale units %g pixels\n")
+ call pargr (psfrad)
+ call pargr (scale * psfrad)
+
+ # Store the new PSF radius.
+ call clputr ("daopars.psfrad", psfrad)
+end
+
+
+# DP_CFITRAD -- Confirm the fitting radius.
+
+procedure dp_cfitrad ()
+
+real scale, fitrad, rval
+int scan(), nscan()
+real clgetr()
+
+begin
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ fitrad = clgetr ("daopars.fitrad")
+
+ # Confirm the new fitting radius.
+ call printf ("Fitting radius (%g scale units) (CR or value): ")
+ call pargr (fitrad)
+ call flush (STDOUT)
+ if (scan() != EOF) {
+ call gargr (rval)
+ if (nscan () == 1)
+ fitrad = rval
+ }
+ call printf ("\tNew fitting radius: %g scale units %g pixels\n")
+ call pargr (fitrad)
+ call pargr (scale * fitrad)
+
+ # Store the new fitting radius.
+ call clputr ("daopars.fitrad", fitrad)
+end
diff --git a/noao/digiphot/daophot/daoedit/dpemark.x b/noao/digiphot/daophot/daoedit/dpemark.x
new file mode 100644
index 00000000..de72fc2c
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dpemark.x
@@ -0,0 +1,734 @@
+include <ctype.h>
+include "daoedit.h"
+
+# DP_MFWHMPSF -- Mark the fwhmpsf on the radial profile plot and confirm.
+
+procedure dp_mfwhmpsf (gd)
+
+pointer gd # pointer to the graphics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, fwhmpsf, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the x and y limits of the current plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current parameters.
+ scale = 1.0 / clgetr ("datapars.scale")
+ fwhmpsf = clgetr ("datapars.fwhmpsf") / 2.0
+
+ # Mark the FWHM of the PSF on the radial profile plot.
+ call printf ("Mark HWHM of the psf (%g pixels):")
+ call pargr (fwhmpsf * scale)
+ call gscur (gd, fwhmpsf * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ fwhmpsf = wx / scale
+
+ # Store the new fwhmpsf.
+ call clputr ("datapars.fwhmpsf", 2.0 * fwhmpsf)
+
+ call sfree (sp)
+end
+
+
+# DP_MSIGMA -- Mark the sky sigma on the radial profile plot and confirm.
+
+procedure dp_msigma (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, mean, sigma, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the range of the plot
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Mark the mean sky on the radial profile plot.
+ call printf ("Mark mean sky background level:")
+ call gscur (gd, (rmin + rmax) / 2.0, imin)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wy < imin || wy > imax)
+ mean = imin
+ else
+ mean = wy
+
+ # Get the current value.
+ sigma = clgetr ("datapars.sigma")
+ if (! IS_INDEFR (sigma))
+ sigma = 3.0 * sigma
+
+ # Mark the sky sigma on the radial profile plot.
+ call printf ("Mark 3 sigma sky level (%g counts):")
+ call pargr (sigma)
+ if (IS_INDEFR(sigma))
+ call gscur (gd, (rmin + rmax) / 2.0, imax)
+ else
+ call gscur (gd, (rmin + rmax) / 2.0, mean + sigma)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wy < imin || wy > imax)
+ ;
+ else
+ sigma = abs (wy - mean) / 3.0
+
+ # Store the new sky sigma.
+ call clputr ("datapars.sigma", sigma)
+
+ call sfree (sp)
+end
+
+
+# DP_MDMIN -- Mark the minimum good data value on the radial profile plot
+# and confirm.
+
+procedure dp_mdmin (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, datamin, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the limits of the plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current value.
+ datamin = clgetr ("datapars.datamin")
+
+ # Mark the threshold on the radial profile plot.
+ call printf ("Mark the minimum good data level (%g counts):")
+ call pargr (datamin)
+
+ if (IS_INDEFR(datamin) || datamin < imin)
+ call gscur (gd, (rmin + rmax) / 2.0, imin)
+ else
+ call gscur (gd, (rmin + rmax) / 2.0, datamin)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wy < imin || wy > imax)
+ ;
+ else
+ datamin = wy
+
+ # Store the new good data minimum.
+ call clputr ("datapars.datamin", datamin)
+
+ call sfree (sp)
+end
+
+
+# DP_MDMAX -- Mark the maximum good data value on the radial profile plot
+# and confirm.
+
+procedure dp_mdmax (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, datamax, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the limits of the plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current value.
+ datamax = clgetr ("datapars.datamax")
+
+ # Mark the threshold on the radial profile plot.
+ call printf ("Mark the maximum good data level (%g counts):")
+ call pargr (datamax)
+
+ if (IS_INDEFR(datamax) || datamax > imax)
+ call gscur (gd, (rmin + rmax) / 2.0, imax)
+ else
+ call gscur (gd, (rmin + rmax) / 2.0, datamax)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wy < imin || wy > imax)
+ ;
+ else
+ datamax = wy
+
+ # Store the new maximum good data value.
+ call clputr ("datapars.datamax", datamax)
+
+ call sfree (sp)
+end
+
+
+# DP_MCBOX -- Mark the centering aperture on the radial profile plot and
+# confirm.
+
+procedure dp_mcbox (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, capert, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the x and y limits of the current plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ capert = clgetr ("centerpars.cbox") / 2.0
+
+ # Mark the centering aperture on the radial profile plot.
+ call printf ("Mark centering box half width (%g pixels):")
+ call pargr (capert * scale)
+ call gscur (gd, capert * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ capert = wx / scale
+
+ # Store the new centering box.
+ call clputr ("centerpars.cbox", 2.0 * capert)
+
+ call sfree (sp)
+end
+
+
+# DP_MRCLEAN -- Mark the cleaning radius on the radial profile plot and
+# confirm.
+
+procedure dp_mrclean (gd)
+
+pointer gd # pointer to the graphics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, rclean, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Get the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rclean = clgetr ("centerpars.rclean")
+
+ # Mark the cleaning radius on the plot.
+ call printf (
+ "Mark the centering algorithm cleaning radius (%g pixels):")
+ call pargr (scale * rclean)
+ call gscur (gd, scale * rclean, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ rclean = wx / scale
+
+ # Store the new cleaning radius.
+ call clputr ("centerpars.rclean", rclean)
+
+ call sfree (sp)
+end
+
+
+# DP_MRCLIP -- Mark the clipping radius on the radial profile plot and.
+# confirm.
+
+procedure dp_mrclip (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, rclip, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Get the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the clipping radius values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rclip = clgetr ("centerpars.rclip")
+
+ # Mark clipping radius on the plot.
+ call printf (
+ "Mark the centering algorithm clipping radius (%g pixels):")
+ call pargr (scale * rclip)
+ call gscur (gd, scale * rclip, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ rclip = wx / scale
+
+ # Store the new clipping radius.
+ call clputr ("centerpars.rclip", rclip)
+
+ call sfree (sp)
+end
+
+
+# DP_MANNULUS -- Mark the sky annulus on the radial profile plot and confirm.
+
+procedure dp_mannulus (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, annulus, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Get the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ annulus = clgetr ("fitskypars.annulus")
+
+ # Mark the inner sky radius.
+ call printf ("Mark inner sky radius (%g pixels):")
+ call pargr (annulus * scale)
+ call gscur (gd, annulus * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx < 0.0 || wx > rmax)
+ ;
+ else
+ annulus = wx / scale
+
+ # Store the new sky annulus.
+ call clputr ("fitskypars.annulus", annulus)
+
+ call sfree (sp)
+
+end
+
+
+# DP_MDANNULUS -- Mark the sky annulus width on the radial profile plot and
+# confirm.
+
+procedure dp_mdannulus (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, annulus, dannulus, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Get the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ annulus = clgetr ("fitskypars.annulus")
+ dannulus = clgetr ("fitskypars.dannulus")
+
+ # Mark the outer sky radius.
+ call printf ("Mark outer sky radius (%g pixels):")
+ call pargr (scale * (annulus + dannulus))
+ call gscur (gd, scale * (annulus + dannulus), (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || (wx / scale < annulus) || wx > rmax)
+ ;
+ else
+ dannulus = (wx / scale - annulus)
+
+ # Save the new sky annulus width.
+ call clputr ("fitskypars.dannulus", dannulus)
+
+ call sfree (sp)
+end
+
+
+# DP_MRGROW -- Mark the regions growing radius the radial profile plot.
+
+procedure dp_mrgrow (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, rgrow, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Get the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ rgrow = clgetr ("fitskypars.rgrow")
+
+ # Mark the inner sky radius.
+ call printf ("Mark region growing radius (%g pixels):")
+ call pargr (rgrow * scale)
+ call gscur (gd, rgrow * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx < 0.0 || wx > rmax)
+ ;
+ else
+ rgrow = wx / scale
+
+ # Store the new sky annulus.
+ call clputr ("fitskypars.rgrow", rgrow)
+
+ call sfree (sp)
+
+end
+
+
+# DP_MAPER -- Mark the photometry apertures on the radial profile plot and
+# confirm.
+
+procedure dp_maper (gd)
+
+pointer gd # pointer to the grapics stream
+
+int wcs, key, naperts
+pointer sp, oapstr, aperts, tapstr, apstr, cmd
+real rmin, rmax, imin, imax, scale, wx, wy
+int dp_gaperts(), clgcur(), strlen()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (oapstr, SZ_LINE, TY_CHAR)
+ call salloc (aperts, MAX_NAPERTS, TY_REAL)
+ call salloc (apstr, SZ_LINE, TY_CHAR)
+ call salloc (tapstr, SZ_LINE, TY_CHAR)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the current plot window.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Decode the apertures.
+ scale = 1.0 / clgetr ("datapars.scale")
+ call clgstr ("photpars.apertures", Memc[oapstr], SZ_LINE)
+ naperts = dp_gaperts (Memc[oapstr], Memr[aperts], MAX_NAPERTS)
+
+ # Type prompt string.
+ call printf ("Mark apertures (%s pixels) [q=quit]:")
+ call pargstr (Memc[oapstr])
+ call gscur (gd, Memr[aperts] * scale, (imin + imax) / 2.0)
+
+ # Mark the apertures.
+ Memc[apstr] = EOS
+ Memc[tapstr] = EOS
+ while (clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd],
+ SZ_LINE) != EOF) {
+ if (key == 'q')
+ break
+ if (wx <= 0.0 || wx > rmax)
+ next
+ call sprintf (Memc[apstr+strlen(Memc[apstr])], SZ_FNAME,"%.2f,")
+ call pargr (wx / scale)
+ call sprintf (Memc[tapstr+strlen(Memc[tapstr])], SZ_FNAME,"%.2f,")
+ call pargr (wx)
+ call printf ("Mark apertures (%s pixels) [q=quit]:")
+ call pargstr (Memc[tapstr])
+ }
+ Memc[apstr+strlen(Memc[apstr])-1] = EOS
+
+ # Save the new aperture string.
+ call clpstr ("photpars.apertures", Memc[apstr])
+
+ call sfree (sp)
+end
+
+
+# DP_MPSFRAD -- Mark the psf radius on the radial profile plot and confirm.
+
+procedure dp_mpsfrad (gd)
+
+pointer gd # pointer to the graphics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, psfrad, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the x and y limits of the current plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ psfrad = clgetr ("daopars.psfrad")
+
+ # Mark the FWHM of the PSF on the radial profile plot.
+ call printf ("Mark the PSF radius (%g pixels):")
+ call pargr (psfrad * scale)
+ call gscur (gd, psfrad * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ psfrad = wx / scale
+
+ # Store the new PSF radius.
+ call clputr ("daopars.psfrad", psfrad)
+
+ call sfree (sp)
+end
+
+
+# DP_MFITRAD -- Mark the fitting radius on the radial profile plot and confirm.
+
+procedure dp_mfitrad (gd)
+
+pointer gd # pointer to the graphics stream
+
+int wcs, key, stat
+pointer sp, cmd
+real rmin, rmax, imin, imax, scale, fitrad, wx, wy
+int clgcur()
+real clgetr()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Determine the x and y limits of the current plot.
+ call ggwind (gd, rmin, rmax, imin, imax)
+
+ # Get the current values.
+ scale = 1.0 / clgetr ("datapars.scale")
+ fitrad = clgetr ("daopars.fitrad")
+
+ # Mark the FWHM of the PSF on the radial profile plot.
+ call printf ("Mark the fitting radius (%g pixels):")
+ call pargr (fitrad * scale)
+ call gscur (gd, fitrad * scale, (imin + imax) / 2.0)
+ stat = clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE)
+ if (stat == EOF || wx <= 0.0 || wx > rmax)
+ ;
+ else
+ fitrad = wx / scale
+
+ # Store the new fitting radius.
+ call clputr ("daopars.fitrad", fitrad)
+
+ call sfree (sp)
+end
+
+
+# DP_GAPERTS -- Decode the aperture string.
+
+int procedure dp_gaperts (str, aperts, max_naperts)
+
+char str[ARB] # aperture string
+real aperts[ARB] # aperture array
+int max_naperts # maximum number of apertures
+
+int naperts, ip, op, ndecode, nap
+pointer sp, outstr
+real apstart, apend, apstep
+bool fp_equalr()
+int dp_gctor()
+
+begin
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+
+ naperts = 0
+ for (ip = 1; str[ip] != EOS && naperts < max_naperts;) {
+
+ # Initialize.
+ apstart = 0.0
+ apend = 0.0
+ apstep = 0.0
+ ndecode = 0
+
+ # Skip past white space and commas.
+ while (IS_WHITE(str[ip]))
+ ip = ip + 1
+ if (str[ip] == ',')
+ ip = ip + 1
+
+ # Get the starting aperture number.
+ op = 1
+ while (IS_DIGIT(str[ip]) || str[ip] == '.') {
+ Memc[outstr+op-1] = str[ip]
+ ip = ip + 1
+ op = op + 1
+ }
+ Memc[outstr+op-1] = EOS
+
+ # Decode the starting aperture.
+ op = 1
+ if (dp_gctor (Memc[outstr], op, apstart) > 0) {
+ apend = apstart
+ ndecode = 1
+ } else
+ apstart = 0.0
+
+ # Skip past white space and commas.
+ while (IS_WHITE(str[ip]))
+ ip = ip + 1
+ if (str[ip] == ',')
+ ip = ip + 1
+
+ # Search for the ending aperture.
+ if (str[ip] == ':') {
+ ip = ip + 1
+
+ # Get the ending aperture.
+ op = 1
+ while (IS_DIGIT(str[ip]) || str[ip] == '.') {
+ Memc[outstr+op-1] = str[ip]
+ ip = ip + 1
+ op = op + 1
+ }
+ Memc[outstr+op-1] = EOS
+
+ # Decode the ending aperture.
+ op = 1
+ if (dp_gctor (Memc[outstr], op, apend) > 0) {
+ ndecode = 2
+ apstep = apend - apstart
+ }
+ }
+
+ # Skip past the white space.
+ while (IS_WHITE(str[ip]))
+ ip = ip + 1
+
+ # Skip past the commas.
+ if (str[ip] == ',')
+ ip = ip + 1
+
+ # Get the step size.
+ if (str[ip] == ':') {
+ ip = ip + 1
+
+ # Get the step size.
+ op = 1
+ while (IS_DIGIT(str[ip]) || str[ip] == '.') {
+ Memc[outstr+op-1] = str[ip]
+ ip = ip + 1
+ op = op + 1
+ }
+ Memc[outstr+op-1] = EOS
+
+ # Decode the step size.
+ op = 1
+ if (dp_gctor (Memc[outstr], op, apstep) > 0) {
+ if (fp_equalr (apstep, 0.0))
+ apstep = apend - apstart
+ else
+ ndecode = (apend - apstart) / apstep + 1
+ if (ndecode < 0) {
+ ndecode = -ndecode
+ apstep = - apstep
+ }
+ }
+ }
+
+ # Negative apertures are not permitted.
+ if (apstart <= 0.0 || apend <= 0.0)
+ break
+
+ # Fill in the apertures.
+ if (ndecode == 0) {
+ ;
+ } else if (ndecode == 1) {
+ naperts = naperts + 1
+ aperts[naperts] = apstart
+ } else if (ndecode == 2) {
+ naperts = naperts + 1
+ aperts[naperts] = apstart
+ if (naperts >= max_naperts)
+ break
+ naperts = naperts + 1
+ aperts[naperts] = apend
+ } else {
+ for (nap = 1; nap <= ndecode && naperts < max_naperts;
+ nap = nap + 1) {
+ naperts = naperts + 1
+ aperts[naperts] = apstart + (nap - 1) * apstep
+ }
+ }
+ }
+
+ call sfree (sp)
+
+ return (naperts)
+end
+
+
+# DP_GCTOR -- Procedure to convert a character variable to a real number.
+# This routine is just an interface routine to the IRAF procedure gctod.
+
+int procedure dp_gctor (str, ip, rval)
+
+char str[ARB] # string to be converted
+int ip # pointer to the string
+real rval # real value
+
+double dval
+int nchars
+int gctod()
+
+begin
+ nchars = gctod (str, ip, dval)
+ rval = dval
+ return (nchars)
+end
diff --git a/noao/digiphot/daophot/daoedit/dpeomark.x b/noao/digiphot/daophot/daoedit/dpeomark.x
new file mode 100644
index 00000000..d635c31a
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dpeomark.x
@@ -0,0 +1,68 @@
+include <gset.h>
+
+# DP_EOMARK -- Procedure to mark center, fitsky and phot parameters on the
+# display.
+
+procedure dp_eomark (id, xcenter, ycenter, srin, srout, apr, mkcenter, mksky,
+ mkapert)
+
+pointer id # pointer to image display stream
+real xcenter # the center x coordinate
+real ycenter # the center y coordinate
+real srin # the inner radius of the sky annulus
+real srout # the outer radius of the sky annulus
+real apr # the maximum photometry aperture radius
+int mkcenter # mark the computed center
+int mksky # mark the sky annulus
+int mkapert # mark the aperture(s)
+
+real rad
+int marktype
+int gstati()
+
+errchk greactivate, gdeactivate
+
+begin
+ if (id == NULL)
+ return
+ if (mkcenter == NO && mksky == NO && mkapert == NO)
+ return
+ iferr {
+ call greactivate (id, 0)
+ } then {
+ return
+ }
+
+ # Save old mark type.
+ marktype = gstati (id, G_PMLTYPE)
+
+ # Mark the center and shift on the display.
+ if (mkcenter == YES) {
+ call gseti (id, G_PMLTYPE, GL_SOLID)
+ call gmark (id, xcenter, xcenter, GM_PLUS, -2.0, -2.0)
+ }
+
+ # Draw the sky annuli on the display.
+ if (mksky == YES) {
+ call gseti (id, G_PMLTYPE, GL_DASHED)
+ rad = 2.0 * srin
+ call gmark (id, xcenter, ycenter, GM_CIRCLE, -rad, -rad)
+ rad = 2.0 * srout
+ call gmark (id, xcenter, ycenter, GM_CIRCLE, -rad, -rad)
+ }
+
+ # Draw the apertures on the display.
+ if (mkapert == YES) {
+ call gseti (id, G_PMLTYPE, GL_DASHED)
+ rad = 2.0 * apr
+ call gmark (id, xcenter, ycenter, GM_CIRCLE, -rad, -rad)
+ }
+
+ # Restore the mark type.
+ call gseti (id, G_PMLTYPE, marktype)
+
+ iferr {
+ call gdeactivate (id, 0)
+ } then
+ return
+end
diff --git a/noao/digiphot/daophot/daoedit/dperplot.x b/noao/digiphot/daophot/daoedit/dperplot.x
new file mode 100644
index 00000000..95a78848
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dperplot.x
@@ -0,0 +1,172 @@
+include <gset.h>
+include "daoedit.h"
+
+define FRACTION 0.10
+
+# DP_ERPLOT -- Plot the radial profile.
+
+procedure dp_erplot (gd, title, xwcs, ywcs, radius, intensity, npts,
+ rcentroid, pmean, integral, nbins, rmin, rmax, iannulus, oannulus,
+ apradius, skyval, skysigma, rscale, pnorm)
+
+pointer gd # pointer to the graphics stream
+char title[ARB] # the plot title
+int xwcs # the x wcs type of the final plot
+int ywcs # the y wcs type of the final plot
+real radius[ARB] # the radius vector
+real intensity[ARB] # the intensity vector
+int npts # number of points in the profile
+real rcentroid[ARB] # the radius centroid vector
+real pmean[ARB] # the mean intensity vector
+real integral[ARB] # the integral of the profile
+int nbins # the number of bins
+real rmin, rmax # min and max radius
+real iannulus # the inner radius of the sky annulus
+real oannulus # the outer radius of the sky annulus
+real apradius # the aperture radius
+real skyval # the sky value
+real skysigma # the sigma of the sky value
+real rscale # the image scale
+real pnorm # the profile normalization factor
+
+int i, j
+pointer sp, pxlabel, pylabel, sxlabel, sylabel
+real r1, r2, rp1, rp2, rs1, rs2, i1, i2, ip1, ip2, is1, is2, dr, fraction
+
+begin
+ # Get space for the x and y labels.
+ call smark (sp)
+ call salloc (pxlabel, SZ_FNAME, TY_CHAR)
+ call salloc (pylabel, SZ_FNAME, TY_CHAR)
+ call salloc (sxlabel, SZ_FNAME, TY_CHAR)
+ call salloc (sylabel, SZ_FNAME, TY_CHAR)
+
+ # Clear the plot.
+ call gclear (gd)
+
+ # Determine the data range of the x and y axes.
+
+ r1 = rmin - FRACTION * (rmax - rmin)
+ r2 = rmax + FRACTION * (rmax - rmin)
+ switch (xwcs) {
+ case WCS_XPIX:
+ rp1 = r1
+ rp2 = r2
+ rs1 = r1 / rscale
+ rs2 = r2 / rscale
+ case WCS_XSCALE:
+ rp1 = r1 / rscale
+ rp2 = r2 / rscale
+ rs1 = r1
+ rs2 = r2
+ default:
+ rp1 = r1
+ rp2 = r2
+ rs1 = r1 / rscale
+ rs2 = r2 / rscale
+ }
+ fraction = max (FRACTION, 5.0 * skysigma / pnorm)
+ i1 = -pnorm * fraction
+ i2 = pnorm * (1.0 + fraction)
+ switch (ywcs) {
+ case WCS_YNORM:
+ ip1 = i1 / pnorm
+ ip2 = i2 / pnorm
+ is1 = i1 + skyval
+ is2 = i2 + skyval
+ case WCS_YCOUNT:
+ ip1 = i1 + skyval
+ ip2 = i2 + skyval
+ is1 = i1 / pnorm
+ is2 = i2 / pnorm
+ default:
+ ip1 = i1 / pnorm
+ ip2 = i2 / pnorm
+ is1 = i1 + skyval
+ is2 = i2 + skyval
+ }
+
+ # Draw the axes and axis labels.
+ call gsetr (gd, G_ASPECT, 0.0)
+ switch (xwcs) {
+ case WCS_XPIX:
+ call strcpy ("Radius (b=pixels, t=scale units)", Memc[pxlabel],
+ SZ_FNAME)
+ call strcpy ("", Memc[sxlabel], SZ_FNAME)
+ case WCS_XSCALE:
+ call strcpy ("Radius (b=scale units, t=pixels)", Memc[pxlabel],
+ SZ_FNAME)
+ call strcpy ("", Memc[sxlabel], SZ_FNAME)
+ default:
+ call strcpy ("Radius (b=pixels, t=scale units)", Memc[pxlabel],
+ SZ_FNAME)
+ call strcpy ("", Memc[sxlabel], SZ_FNAME)
+ }
+ switch (ywcs) {
+ case WCS_YCOUNT:
+ call strcpy ("Counts", Memc[pylabel], SZ_FNAME)
+ call strcpy ("Norm Counts", Memc[sylabel], SZ_FNAME)
+ case WCS_YNORM:
+ call strcpy ("Norm Counts", Memc[pylabel], SZ_FNAME)
+ call strcpy ("Counts", Memc[sylabel], SZ_FNAME)
+ default:
+ call strcpy ("Counts", Memc[pylabel], SZ_FNAME)
+ call strcpy ("Norm Counts", Memc[sylabel], SZ_FNAME)
+ }
+
+ call gseti (gd, G_XDRAWAXES, 1)
+ call gseti (gd, G_YDRAWAXES, 1)
+ call gswind (gd, rp1, rp2, ip1, ip2)
+ call glabax (gd, title, Memc[pxlabel], Memc[pylabel])
+ call gseti (gd, G_XDRAWAXES, 2)
+ call gseti (gd, G_YDRAWAXES, 2)
+ call gswind (gd, rs1, rs2, is1, is2)
+ call glabax (gd, title, Memc[sxlabel], Memc[sylabel])
+
+ # Plot the data points.
+ call gswind (gd, r1, r2, i1, i2)
+ call gpmark (gd, radius, intensity, npts, GM_PLUS, 1.0, 1.0)
+
+ # Plot the smoothed radial profile skipping any points with no data.
+ call gswind (gd, r1, r2, -fraction, 1.0 + fraction)
+ for (i = 1; i <= nbins && rcentroid[i] <= 0.0; i = i + 1)
+ ;
+ call gamove (gd, rcentroid[i], pmean[i])
+ do j = i, nbins {
+ if (pmean[j] == 0.0)
+ next
+ call gadraw (gd, rcentroid[j], pmean[j])
+ }
+
+ # Plot the integral.
+ call gswind (gd, r1, r2, -fraction, 1.0 + fraction)
+ call gamove (gd, 0.0, 0.0)
+ dr = (rmax - rmin) / real (nbins - 1)
+ do j = 2, nbins {
+ call gadraw (gd, real (j - 1) * dr, integral[j])
+ }
+
+ # Plot the sky annuli and the aperture radius.
+ call gamove (gd, iannulus, -fraction)
+ call gadraw (gd, iannulus, 1.0 + fraction)
+ call gamove (gd, oannulus, -fraction)
+ call gadraw (gd, oannulus, 1.0 + fraction)
+ call gamove (gd, apradius, -fraction)
+ call gadraw (gd, apradius, 1.0 + fraction)
+
+ # Plot the zero level.
+ call gswind (gd, rp1, rp2, ip1, ip2)
+ switch (ywcs) {
+ case WCS_YCOUNT:
+ call gamove (gd, rp1, skyval)
+ call gadraw (gd, rp2, skyval)
+ case WCS_YNORM:
+ call gamove (gd, rp1, 0.0)
+ call gadraw (gd, rp2, 0.0)
+ default:
+ call gamove (gd, rp1, 0.0)
+ call gadraw (gd, rp2, 0.0)
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daoedit/dperprofile.x b/noao/digiphot/daophot/daoedit/dperprofile.x
new file mode 100644
index 00000000..37cccf97
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/dperprofile.x
@@ -0,0 +1,590 @@
+include <mach.h>
+include <imhdr.h>
+include "daoedit.h"
+
+
+# DP_ERPROFILE -- Compute and optionally plot the radial profile of the
+# selected star.
+
+procedure dp_erprofile (gd, id, banner, xwcs, ywcs, im, xinit, yinit)
+
+pointer gd # pointer to the graphics descriptor
+pointer id # pointer to the display descriptor
+int banner # print banner for photometry results
+int xwcs # the x wcs type
+int ywcs # the y wcs type
+pointer im # pointer to the input image
+real xinit # initial x position
+real yinit # initial y position
+
+int cboxsize, rboxsize, npts, naperts, nbins, nr
+pointer sp, radius, intensity, apstr, aperts, rcentroid, pmean, integral, title
+real scale, pradius, iannulus, oannulus, mean, median, sigma, pnorm, inorm
+real fwhmpsf, xcenter, ycenter, apradius, counts
+real clgetr(), dp_aprcounts()
+int dp_rprofile(), strlen(), dp_gaperts(), btoi()
+bool clgetb()
+
+begin
+ # Return if the initial x and y centers are undefined.
+ if (IS_INDEFR(xinit) || IS_INDEFR(yinit))
+ return
+
+ # Get the scale of the image from the datapars pset.
+ scale = clgetr ("datapars.scale")
+ if (scale <= 0.0)
+ scale = 1.0
+ else
+ scale = 1.0 / scale
+
+ # Estimate the center of the star using the datapars parameter
+ # scale and the centerpars parameter cbox and an initial center.
+ # Force the centering box to be an odd number of pixels.
+ cboxsize = scale * clgetr ("centerpars.cbox") + 1.0
+ if (mod (cboxsize, 2) == 0)
+ cboxsize = cboxsize + 1
+ call dp_rcenter (im, xinit, yinit, cboxsize, xcenter, ycenter)
+
+ # Allocate working memory for the radial profile data.
+ pradius = scale * (clgetr ("fitskypars.annulus") +
+ clgetr ("fitskypars.dannulus") + 1.0)
+ rboxsize = 2 * nint (pradius + 1.0) + 1
+ call smark (sp)
+ call salloc (radius, rboxsize * rboxsize, TY_REAL)
+ call salloc (intensity, rboxsize * rboxsize, TY_REAL)
+
+ # Compute the radial profile.
+ npts = dp_rprofile (im, xcenter, ycenter, rboxsize, pradius,
+ Memr[radius], Memr[intensity])
+ if (npts <= 0) {
+ call printf ("No data for computing radial profile\n")
+ call sfree (sp)
+ return
+ }
+
+ # Estimate the sky level and subtract it from the profile.
+ iannulus = scale * clgetr ("fitskypars.annulus")
+ oannulus = iannulus + scale * clgetr ("fitskypars.dannulus")
+ call dp_rskyval (Memr[radius], Memr[intensity], npts,
+ iannulus, oannulus, mean, median, sigma)
+ call asubkr (Memr[intensity], median, Memr[intensity], npts)
+
+ # Get the last photometry aperture and sum up the pixels inside it.
+ call salloc (apstr, SZ_LINE, TY_CHAR)
+ call salloc (aperts, MAX_NAPERTS, TY_REAL)
+ call clgstr ("photpars.apertures", Memc[apstr], SZ_LINE)
+ naperts = dp_gaperts (Memc[apstr], Memr[aperts], MAX_NAPERTS)
+ apradius = scale * Memr[aperts+naperts-1]
+ counts = dp_aprcounts (Memr[radius], Memr[intensity], npts, apradius)
+
+ # Compute the normalized mean intensity as a function of radius
+ # and the normalized integral of the intensity as a function of
+ # radius.
+ nbins = int (pradius / 0.5 + 0.5)
+ call salloc (nr, nbins, TY_INT)
+ call salloc (rcentroid, nbins, TY_REAL)
+ call salloc (pmean, nbins, TY_REAL)
+ call salloc (integral, nbins, TY_REAL)
+ call dp_crprofile (Memr[radius], Memr[intensity], npts, Memi[nr],
+ Memr[rcentroid], Memr[pmean], Memr[integral], nbins, 0.0,
+ pradius, real ((cboxsize-1)/ 2), iannulus, fwhmpsf, pnorm, inorm)
+
+ # Mark the objects on the display.
+ if (id != NULL) {
+ call dp_eomark (id, xcenter, ycenter, iannulus, oannulus,
+ apradius, btoi (clgetb ("centerpars.mkcenter")),
+ btoi (clgetb ("fitskypars.mksky")),
+ btoi (clgetb ("photpars.mkapert")))
+ if (gd == id)
+ call gflush (gd)
+ else
+ call gframe (id)
+ }
+ # Convert the center coordinates if appropriate.
+ call dp_ltov (im, xcenter, ycenter, xcenter, ycenter, 1)
+
+ # Draw the plot.
+ if (gd != NULL) {
+ call salloc (title, 3 * SZ_LINE, TY_CHAR)
+ call sprintf (Memc[title], 3 * SZ_LINE,
+ "%s: Radial profile at %0.2f %0.2f\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargr (xcenter)
+ call pargr (ycenter)
+ call sprintf (Memc[title+strlen(Memc[title])], 3 * SZ_LINE,
+ "Sky: mean %g median %g sigma %g\n")
+ call pargr (mean)
+ call pargr (median)
+ call pargr (sigma)
+ call sprintf (Memc[title+strlen(Memc[title])], 3 * SZ_LINE,
+ "Fwhmpsf: %0.2f Counts: %g Mag: %0.3f\n\n")
+ call pargr (fwhmpsf)
+ call pargr (counts)
+ if (counts <= 0.0)
+ call pargr (INDEFR)
+ else
+ call pargr (-2.5 * log10 (counts))
+ call dp_erplot (gd, Memc[title], xwcs, ywcs, Memr[radius],
+ Memr[intensity], npts, Memr[rcentroid], Memr[pmean],
+ Memr[integral], nbins, 0.0, pradius, iannulus, oannulus,
+ apradius, median, sigma, scale, pnorm)
+ }
+
+ # Print the results.
+ if (gd == NULL) {
+ if (banner == YES)
+ call dp_bprint (STDOUT)
+ call dp_aprint (STDOUT, xcenter, ycenter, median, sigma, fwhmpsf,
+ counts)
+ }
+
+ # Free memory.
+ call sfree (sp)
+end
+
+
+# DP_RCENTER -- Compute the star center using a simple 1D centroiding
+# algorithm on the x and y marginals, after thresholding at the mean.
+
+procedure dp_rcenter (im, xstart, ystart, boxsize, xcntr, ycntr)
+
+pointer im # pointer to the input image
+real xstart, ystart # starting coordinates
+int boxsize # width of the centering box
+real xcntr, ycntr # centered coordinates
+
+int half_box, x1, x2, y1, y2, ncols, nrows, nx, ny, try
+pointer bufptr, sp, x_vect, y_vect
+real xinit, yinit
+pointer imgs2r()
+
+begin
+ # Initialize.
+ half_box = (boxsize - 1) / 2
+ xinit = xstart
+ yinit = ystart
+ ncols = IM_LEN (im,1)
+ nrows = IM_LEN (im,2)
+
+ try = 0
+ repeat {
+
+ # Compute the parameters of the extraction region.
+ x1 = max (xinit - half_box, 1.0) + 0.5
+ x2 = min (xinit + half_box, real (ncols)) + 0.5
+ y1 = max (yinit - half_box, 1.0) + 0.5
+ y2 = min (yinit + half_box, real (nrows)) + 0.5
+ nx = x2 - x1 + 1
+ ny = y2 - y1 + 1
+
+ # Get the data.
+ bufptr = imgs2r (im, x1, x2, y1, y2)
+
+ # Allocate space for the marginals.
+ call smark (sp)
+ call salloc (x_vect, nx, TY_REAL)
+ call salloc (y_vect, ny, TY_REAL)
+
+ # Compute the marginals.
+ call aclrr (Memr[x_vect], nx)
+ call aclrr (Memr[y_vect], ny)
+ call dp_rowsum (Memr[bufptr], Memr[x_vect], nx, ny)
+ call dp_colsum (Memr[bufptr], Memr[y_vect], nx, ny)
+
+ # Compute the centers.
+ call dp_vcentroid (Memr[x_vect], nx, xcntr)
+ call dp_vcentroid (Memr[y_vect], ny, ycntr)
+
+ # Add in offsets to image coordinate system.
+ xcntr = xcntr + x1
+ ycntr = ycntr + y1
+
+ call sfree (sp)
+
+ # If the shifts are greater than 1 pixel in either direction
+ # do 1 more iteration.
+ try = try + 1
+ if (try == 1) {
+ if ((abs (xcntr - xinit) > 1.0) || (abs (ycntr - yinit) >
+ 1.0)) {
+ xinit = xcntr
+ yinit = ycntr
+ }
+ } else
+ break
+ }
+end
+
+
+# DP_RPROFILE -- Get the data and compute the radius and intensity vectors.
+
+int procedure dp_rprofile (im, xcntr, ycntr, rboxsize, pradius, radius,
+ intensity)
+
+pointer im # pointer to the input image
+real xcntr, ycntr # the center of the extraction box
+int rboxsize # the width of the extraction box
+real pradius # the plotting radius
+real radius[ARB] # the output radius vector
+real intensity[ARB] # the output intensity vector
+
+int half_box, ncols, nrows, x1, x2, y1, y2, nx, ny, npts
+pointer bufptr
+real xinit, yinit
+int dp_rivectors()
+pointer imgs2r()
+
+begin
+ # Initialize.
+ half_box = (rboxsize - 1) / 2
+ xinit = xcntr
+ yinit = ycntr
+ ncols = IM_LEN(im,1)
+ nrows = IM_LEN(im,2)
+
+ # Get the data.
+ x1 = max (xinit - half_box, 1.0) + 0.5
+ x2 = min (xinit + half_box, real (ncols)) + 0.5
+ y1 = max (yinit - half_box, 1.0) + 0.5
+ y2 = min (yinit + half_box, real (nrows)) + 0.5
+ nx = x2 - x1 + 1
+ ny = y2 - y1 + 1
+ bufptr = imgs2r (im, x1, x2, y1, y2)
+
+ # Compute the radius and intensity vectors.
+ npts = dp_rivectors (Memr[bufptr], nx, ny, x1, y1, xcntr, ycntr,
+ pradius, radius, intensity)
+
+ return (npts)
+end
+
+
+# DP_RSKYVAL -- Compute the mean, median and sigma of the pixels in the
+# sky annulus.
+
+procedure dp_rskyval (radius, intensity, npts, iannulus, oannulus, mean,
+ median, sigma)
+
+real radius[ARB] # the output radius vector
+real intensity[ARB] # the output intensity vector
+int npts # number of points in the profile
+real iannulus # inner radius of sky annulus
+real oannulus # outer radius of sky annulus
+real mean # mean sky value
+real median # median sky value
+real sigma # standard deviation of sky values
+
+int i, nsky, il, ih, ngood
+pointer skypix
+real slocut, shicut
+
+begin
+ call malloc (skypix, npts, TY_REAL)
+
+ nsky = 0
+ do i = 1, npts {
+ if (radius[i] < iannulus || radius[i] > oannulus)
+ next
+ nsky = nsky + 1
+ Memr[skypix+nsky-1] = intensity[i]
+ }
+ call asrtr (Memr[skypix], Memr[skypix], nsky)
+
+ if (nsky == 0) {
+ mean = 0.0
+ median = 0.0
+ sigma = 0.0
+ } else {
+ call aavgr (Memr[skypix], nsky, mean, sigma)
+ if (mod (nsky, 2) == 0)
+ median = 0.5 * (Memr[skypix+(nsky+1)/2-1] +
+ Memr[skypix+(nsky+1)/2])
+ else
+ median = Memr[skypix+(nsky+1)/2-1]
+ }
+
+ # Detect pixels to be rejected.
+ slocut = median - min (median - Memr[skypix], Memr[skypix+nsky-1] -
+ median, 3.0 * sigma)
+ shicut = median + min (median - Memr[skypix], Memr[skypix+nsky-1] -
+ median, 3.0 * sigma)
+ for (il = 1; il <= nsky; il = il + 1) {
+ if (Memr[skypix+il-1] >= slocut)
+ break
+ }
+ for (ih = nsky; ih >= 1; ih = ih - 1) {
+ if (Memr[skypix+ih-1] <= shicut)
+ break
+ }
+ ngood = ih - il + 1
+ if (ngood < nsky) {
+ if (ngood == 0) {
+ mean = 0.0
+ median = 0.0
+ sigma = 0.0
+ } else {
+ call aavgr (Memr[skypix+il-1], ngood, mean, sigma)
+ if (mod (ngood, 2) == 0)
+ median = 0.5 * (Memr[skypix+il-1+(ngood+1)/2-1] +
+ Memr[skypix+il-1+(ngood+1)/2])
+ else
+ median = Memr[skypix+il-1+(ngood+1)/2-1]
+ }
+ }
+
+
+ call mfree (skypix, TY_REAL)
+end
+
+
+# DP_APRCOUNTS -- Sumup the counts inside the aperture.
+
+real procedure dp_aprcounts (radius, intensity, npts, apradius)
+
+real radius[ARB] # the output radius vector
+real intensity[ARB] # the output intensity vector
+int npts # number of points in the profile
+real apradius # the aperture radius
+
+int i
+real counts
+
+begin
+ counts = 0.0
+ do i = 1, npts {
+ if (radius[i] > apradius)
+ next
+ counts = counts + intensity[i]
+ }
+ return (counts)
+end
+
+
+# DP_CRPROFILE -- Compute the smoothed radial profile and its integral at half
+# pixel intervals.
+
+procedure dp_crprofile (radius, intensity, npts, nr, rcentroid, pmean,
+ integral, nbins, rmin, rmax, prad, irad, fwhmpsf, pnorm, inorm)
+
+real radius[ARB] # the output radius vector
+real intensity[ARB] # the output intensity vector
+int npts # number of points in the profile
+int nr[ARB] # the number of points in each interval
+real rcentroid[ARB] # the centroid of the radius values
+real pmean[ARB] # the mean of the intensity values
+real integral[ARB] # the integral of the curve
+int nbins # the number of radius bins
+real rmin, rmax # the radius min and max values
+real prad # the normalization radius for the profile
+real irad # the normalization radius for the integral
+real fwhmpsf # computed full width halfmax psf
+real pnorm # the maximum profile value
+real inorm # the maximum count value
+
+int i, bin
+real dr, r
+
+begin
+ # Initialize the arrays.
+ call aclri (nr, nbins)
+ call aclrr (rcentroid, nbins)
+ call aclrr (pmean, nbins)
+ call aclrr (integral, nbins)
+
+ # Accumulate the data.
+ dr = real (nbins - 1) / real (rmax - rmin)
+ do i = 1, npts {
+ r = radius[i]
+ if (r < rmin || r > rmax)
+ next
+ bin = int ((r - rmin) * dr) + 1
+ nr[bin] = nr[bin] + 1
+ pmean[bin] = pmean[bin] + intensity[i]
+ rcentroid[bin] = rcentroid[bin] + r
+ }
+
+ # Compute the integral of the radial profile and normalize it
+ # to 1.0 at the radius irad.
+ do i = 2, nbins
+ integral[i] = integral[i-1] + pmean[i-1]
+ bin = int ((irad - rmin) * dr) + 1
+ inorm = integral[min (bin, nbins)]
+ call adivkr (integral, inorm, integral, nbins)
+
+ # Compute the smoothed radial profile and normalize to the
+ # maximum data point inside the radius prad.
+ pnorm = -MAX_REAL
+ do i = 1, npts {
+ if (radius[i] > prad)
+ next
+ if (intensity[i] > pnorm)
+ pnorm = intensity[i]
+ }
+ do i = 1, nbins {
+ if (nr[i] <= 0) {
+ rcentroid[i] = (i - 1.0 + 0.5) / dr
+ if (rcentroid[i] < rmin || rcentroid[i] > rmax)
+ pmean[i] = 0.0
+ else
+ pmean[i] = pnorm
+ } else {
+ rcentroid[i] = rcentroid[i] / nr[i]
+ pmean[i] = pmean[i] / nr[i]
+ }
+ }
+ call adivkr (pmean, pnorm, pmean, nbins)
+
+ # Estimate the full width half max of the psf in pixels.
+ do i = 1, nbins {
+ if (pmean[i] == 0.0)
+ next
+ if (pmean[i] < 0.5)
+ break
+ }
+ if (i == 1)
+ fwhmpsf = 2.0 * rcentroid[1]
+ else if (i == nbins && pmean[nbins] >= 0.5)
+ fwhmpsf = 2.0 * rcentroid[nbins]
+ else if (pmean[i-1] == pmean[i])
+ fwhmpsf = rcentroid[i-1] + rcentroid[i]
+ else
+ fwhmpsf = 2.0 * ((rcentroid[i] * (0.5 - pmean[i-1]) +
+ rcentroid[i-1] * (pmean[i] - 0.5)) / (pmean[i] - pmean[i-1]))
+end
+
+
+# DP_ROWSUM -- Sum all the rows in a raster.
+
+procedure dp_rowsum (raster, row, nx, ny)
+
+real raster[nx,ny] # the input subraster
+real row[ARB] # the output summed row
+int nx, ny # the dimensions of the input subraster
+
+int i, j
+
+begin
+ do i = 1, ny
+ do j = 1, nx
+ row[j] = row[j] + raster[j,i]
+end
+
+
+# DP_COLSUM -- Sum all the columns in a raster.
+
+procedure dp_colsum (raster, col, nx, ny)
+
+real raster[nx,ny] # the input subraster
+real col[ARB] # the output summed column
+int nx, ny # the dimensions of the input subraster
+
+int i, j
+
+begin
+ do i = 1, ny
+ do j = 1, nx
+ col[j] = col[j] + raster[i,j]
+end
+
+
+# DP_VCENTROID -- Compute the centroid of a vector.
+
+procedure dp_vcentroid (vector, nv, vc)
+
+real vector[ARB] # the input vector
+int nv # length of the input array
+real vc # the output centroid
+
+int i
+real sum1, sum2, sigma, cont
+
+begin
+ sum1 = 0.0
+ sum2 = 0.0
+
+ call aavgr (vector, nv, cont, sigma)
+ do i = 1, nv
+ if (vector[i] > cont) {
+ sum1 = sum1 + (i - 1) * (vector[i] - cont)
+ sum2 = sum2 + (vector[i] - cont)
+ }
+
+ vc = sum1 / sum2
+end
+
+
+# DP_RIVECTORS -- Compute the radius and intensity vectors.
+
+int procedure dp_rivectors (a, nx, ny, x1, y1, xcntr, ycntr, pradius,
+ radius, intensity)
+
+real a[nx,ny] # the input data array
+int nx, ny # dimensions of the input array
+int x1, y1 # lower left corner of input array
+real xcntr, ycntr # coordinates of center pixel
+real pradius # the plotting radius
+real radius[ARB] # the output radius vector
+real intensity[ARB] # the output intensity vector
+
+int i, j, npts
+real pr2, r2, dy2
+
+begin
+ pr2 = pradius * pradius
+
+ npts = 0
+ do i = 1, ny {
+ dy2 = (ycntr - y1 + 1 - i) ** 2
+ do j = 1, nx {
+ r2 = (xcntr - x1 + 1 - j) ** 2 + dy2
+ if (r2 > pr2)
+ next
+ npts = npts + 1
+ radius[npts] = sqrt (r2)
+ intensity[npts] = a[j,i]
+ }
+ }
+
+ return (npts)
+end
+
+
+# DP_BPRINT -- Print the photometry banner.
+
+procedure dp_bprint (fd)
+
+int fd # output file descriptor
+
+string banner "# XCENTER YCENTER SKY SKYSIGMA FWHM COUNTS MAG"
+
+begin
+ call fprintf (fd, "\n%s\n")
+ call pargstr (banner)
+end
+
+
+# DP_APRINT -- Print the photometry results.
+
+procedure dp_aprint (fd, xcenter, ycenter, skyval, sigma, fwhmpsf, inorm)
+
+int fd # output file descriptor
+real xcenter # x coordinate of profile
+real ycenter # y coordinate of profile
+real skyval # the sky value
+real sigma # the standard deviation of the sky pixels
+real fwhmpsf # the estimated fwhmpsf
+real inorm # the total counts
+
+begin
+ call fprintf (fd, " %7.2f %7.2f %8.1f %8.2f %6.2f %8.1f %7.3f\n")
+ call pargr (xcenter)
+ call pargr (ycenter)
+ call pargr (skyval)
+ call pargr (sigma)
+ call pargr (fwhmpsf)
+ call pargr (inorm)
+ if (inorm <= 0.0)
+ call pargr (INDEFR)
+ else
+ call pargr (-2.5 * log10 (inorm))
+end
diff --git a/noao/digiphot/daophot/daoedit/idaoedit.key b/noao/digiphot/daophot/daoedit/idaoedit.key
new file mode 100644
index 00000000..5967d1e8
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/idaoedit.key
@@ -0,0 +1,22 @@
+ Interactive Daoedit Parameter Setup Menu
+
+? Print help
+spbar Mark/verify critical parameters (f, t, a, d, r, w, b)
+q Quit
+
+f Mark/verify the fwhm of the psf on the radial profile plot
+s Mark/verify the sky sigma on the radial profile plot
+l Mark/verify the minimum good data value on the radial profile plot
+u Mark/verify the maximum good data value on the radial profile plot
+
+c Mark/verify the centering box on the radial profile plot
+n Mark/verify the cleaning radius on the radial profile plot
+p Mark/verify the clipping radius on the radial profile plot
+
+a Mark/verify the inner sky annulus radius on the radial profile plot
+d Mark/verify the width of the sky annulus on the radial profile plot
+g Mark/verify the sky region growing radius on the radial profile plot
+
+r Mark/verify the photometry aperture(s) on the radial profile plot
+w Mark/verify the psf function radius on the radial profile plot
+b Mark/verify the psf fitting radius on the radial profile plot
diff --git a/noao/digiphot/daophot/daoedit/mkpkg b/noao/digiphot/daophot/daoedit/mkpkg
new file mode 100644
index 00000000..0fc962d1
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/mkpkg
@@ -0,0 +1,16 @@
+# DAOEDIT task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ t_daoedit.x <imhdr.h> <gset.h> ../lib/daophotdef.h daoedit.h
+ dpecolon.x <error.h> daoedit.h
+ dpemark.x <ctype.h> daoedit.h
+ dpeomark.x <gset.h>
+ dpeconfirm.x daoedit.h
+ dperprofile.x <mach.h> <imhdr.h> daoedit.h
+ dperplot.x <gset.h> daoedit.h
+ ;
diff --git a/noao/digiphot/daophot/daoedit/t_daoedit.x b/noao/digiphot/daophot/daoedit/t_daoedit.x
new file mode 100644
index 00000000..8c92e969
--- /dev/null
+++ b/noao/digiphot/daophot/daoedit/t_daoedit.x
@@ -0,0 +1,317 @@
+include <imhdr.h>
+include <gset.h>
+include "../lib/daophotdef.h"
+include "daoedit.h"
+
+define HELPFILE "daophot$daoedit/daoedit.key"
+define IHELPFILE "daophot$daoedit/daoedit.key"
+
+# T_DAOEDIT -- Edit the DAOPHOT parameters interactively using the image
+# display and a radial profile plot.
+
+procedure t_daoedit ()
+
+pointer image # the name of the input image
+int cache # cache the image pixels
+pointer graphics # the graphics device
+pointer display # the image display
+
+real wx, wy, xlast, ylast
+pointer sp, cmd, im, gd, id
+int wcs, key, redraw, gcurtype, curtype, xwcs, ywcs, lastkey
+int req_size, memstat, old_size, buf_size
+
+pointer immap(), gopen()
+int dp_gcur(), btoi(), sizeof(), dp_memstat()
+bool clgetb(), streq()
+errchk gopen()
+
+data gcurtype /'g'/
+
+begin
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (graphics, SZ_FNAME, TY_CHAR)
+ call salloc (display, SZ_FNAME, TY_CHAR)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ im = immap (Memc[image], READ_ONLY, 0)
+
+ call clgstr ("graphics", Memc[graphics], SZ_FNAME)
+ iferr (gd = gopen (Memc[graphics], AW_DEFER+NEW_FILE, STDGRAPH))
+ gd = NULL
+ call clgstr ("display", Memc[display], SZ_FNAME)
+ if (Memc[display] == EOS)
+ id = NULL
+ else if (streq (Memc[graphics], Memc[display]))
+ id = gd
+ else {
+ iferr {
+ id = gopen (Memc[display], APPEND, STDIMAGE)
+ } then {
+ call eprintf (
+ "Warning: Graphics overlay not available for display device.\n")
+ id = NULL
+ }
+ }
+ cache = btoi (clgetb ("cache"))
+
+ # Set up the display coordinate system.
+ if ((id != NULL) && (id != gd))
+ call dp_gswv (id, Memc[image], im, 4)
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ xlast = INDEFR
+ ylast = INDEFR
+ lastkey = INDEFI
+ xwcs = WCS_XPIX
+ ywcs = WCS_YCOUNT
+ curtype = 'i'
+ redraw = NO
+
+ while (dp_gcur (curtype, wx, wy, wcs, key, Memc[cmd], SZ_LINE) != EOF) {
+
+ # Convert the cursor coordinates if necessary.
+ if (curtype == 'i')
+ call dp_vtol (im, wx, wy, wx, wy, 1)
+
+ switch (key) {
+
+ # Print help page.
+ case '?':
+ if (curtype == 'i') {
+ call pagefile (HELPFILE, "[space=cmhelp,q=quit,?=help]")
+ } else if (curtype == 'g') {
+ #call greactivate (gd, 0)
+ call gpagefile (gd, HELPFILE, "")
+ }
+
+
+ # Quit the program.
+ case 'q':
+ break
+
+ # Toggle between the image display and graphics cursor.
+ case 'g':
+ if (curtype == 'i') {
+ call greactivate (gd, 0)
+ curtype = 'g'
+ } else {
+ call gdeactivate (gd, 0)
+ curtype = 'i'
+ }
+
+ # Toggle between the pixel and scale units plot scale in x.
+ case 'x':
+ if (xwcs == WCS_XPIX)
+ xwcs = WCS_XSCALE
+ else if (xwcs == WCS_XSCALE)
+ xwcs = WCS_XPIX
+ redraw = YES
+
+ # Toggle between the counts and norm plot scale in y.
+ case 'y':
+ if (ywcs == WCS_YCOUNT)
+ ywcs = WCS_YNORM
+ else if (ywcs == WCS_YNORM)
+ ywcs = WCS_YCOUNT
+ redraw = YES
+
+ case 'a':
+ if (curtype == 'i') {
+ if (lastkey == 'a')
+ call dp_erprofile (NULL, id, NO, xwcs, ywcs, im, wx, wy)
+ else
+ call dp_erprofile (NULL, id, YES, xwcs, ywcs, im,
+ wx, wy)
+ } else {
+ call dp_erprofile (NULL, id, NO, xwcs, ywcs, im,
+ xlast, ylast)
+ }
+
+ case 'r':
+ if (curtype == 'i') {
+ xlast = wx
+ ylast = wy
+ }
+ redraw = YES
+
+ case 'i':
+ if (curtype == 'i') {
+ xlast = wx
+ ylast = wy
+ }
+ xwcs = WCS_XPIX
+ ywcs = WCS_YCOUNT
+ redraw = YES
+
+ case ':':
+ call dp_ecolon (Memc[cmd], gd, redraw)
+
+ default:
+ call printf ("Unknown or ambiguous keystroke command\7\n")
+ }
+
+ # Draw the plot.
+ if (redraw == YES) {
+ call dp_erprofile (gd, id, NO, xwcs, ywcs, im, xlast, ylast)
+ if (key == 'i')
+ call dp_isetup (gcurtype, gd)
+ redraw = NO
+ if (curtype == 'i')
+ call gdeactivate (gd, 0)
+ }
+
+ lastkey = key
+ }
+
+ if (id == gd && gd != NULL) {
+ call gclose (gd)
+ } else {
+ if (gd != NULL)
+ call gclose (gd)
+ if (id != NULL)
+ call gclose (id)
+ }
+
+ call imunmap (im)
+
+ # Uncache memory.
+ call fixmem (old_size)
+
+ call sfree (sp)
+end
+
+
+# DP_GCUR --Get a SETPARS cursor value.
+
+int procedure dp_gcur (curtype, x, y, wcs, key, strval, maxch)
+
+int curtype # cursor type
+real x, y # cursor position
+int wcs # cursor wcs
+int key # keystroke value of cursor event
+char strval[ARB] # string value, if any
+int maxch # max chars out
+
+int nitems
+int 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)
+ }
+
+ return (nitems)
+end
+
+
+# DP_ISETUP -- Setup the daophot parameters interactively using a
+# radial profile plot.
+
+procedure dp_isetup (curtype, gd)
+
+int curtype # the cursor type graphics or display
+pointer gd # pointer to the graphics stream
+
+int wcs, key
+pointer sp, cmd
+real wx, wy
+int dp_gcur()
+
+begin
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ call printf (
+ "Interactive setup menu (?=help, spbar=default, q=quit):\n")
+ while (dp_gcur (curtype, wx, wy, wcs, key, Memc[cmd],
+ SZ_LINE) != EOF) {
+ switch (key) {
+ case '?':
+ call gpagefile (gd, IHELPFILE, "")
+ case 'q':
+ break
+ case 'f':
+ call dp_mfwhmpsf(gd)
+ call dp_cfwhmpsf()
+ case 's':
+ call dp_msigma(gd)
+ call dp_csigma()
+ case 'u':
+ call dp_mdmax(gd)
+ call dp_cdmax()
+ case 'l':
+ call dp_mdmin(gd)
+ call dp_cdmin()
+ case 'c':
+ call dp_mcbox(gd)
+ call dp_ccbox()
+ case 'n':
+ call dp_mrclean(gd)
+ call dp_crclean()
+ case 'p':
+ call dp_mrclip(gd)
+ call dp_crclip()
+ case 'a':
+ call dp_mannulus(gd)
+ call dp_cannulus()
+ case 'd':
+ call dp_mdannulus(gd)
+ call dp_cdannulus()
+ case 'g':
+ call dp_mrgrow(gd)
+ call dp_crgrow()
+ case 'r':
+ call dp_maper(gd)
+ call dp_caper()
+ case 'w':
+ call dp_mpsfrad(gd)
+ call dp_cpsfrad()
+ case 'b':
+ call dp_mfitrad(gd)
+ call dp_cfitrad()
+ case ' ':
+ call dp_mfwhmpsf(gd)
+ call dp_mcbox(gd)
+ call dp_mannulus(gd)
+ call dp_mdannulus(gd)
+ call dp_maper(gd)
+ call dp_mpsfrad(gd)
+ call dp_mfitrad(gd)
+ call gdeactivate(gd, 0)
+ call dp_cbanner()
+ call dp_cfwhmpsf()
+ call dp_ccbox()
+ call dp_cannulus()
+ call dp_cdannulus()
+ call dp_caper()
+ call dp_cpsfrad()
+ call dp_cfitrad()
+ call greactivate(gd, 0)
+ default:
+ call printf (
+ "Interactive setup menu (?=help, spbar=default, q=quit):\n")
+ }
+ call printf (
+ "Interactive setup menu (?=help, spbar=default, q=quit):\n")
+ }
+
+ if (curtype == 'i')
+ call gdeactivate (gd, 0)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daofind.par b/noao/digiphot/daophot/daofind.par
new file mode 100644
index 00000000..3dbe1b34
--- /dev/null
+++ b/noao/digiphot/daophot/daofind.par
@@ -0,0 +1,21 @@
+# DAOFIND
+
+image,s,a,,,,"Input image(s)"
+output,f,a,"default",,,"Output coordinate file(s) (default: image.coo.?)"
+starmap,s,h,"",,,"Output density enhancement image(s)"
+skymap,s,h,"",,,"Output sky image(s)"
+datapars,pset,h,"",,,"Data dependent parameters"
+findpars,pset,h,"",,,"Object detection parameters"
+boundary,s,h,nearest,,,"Boundary extension (constant|nearest|reflect|wrap)"
+constant,r,h,0.0,,,"Constant for boundary extension"
+interactive,b,h,no,,,"Interactive mode?"
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor: [x y wcs] key [cmd]"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the image pixels?"
+verify,b,h,)_.verify,,,"Verify critical daofind parameters?"
+update,b,h,)_.update,,,"Update critical daofind parameters?"
+verbose,b,h,)_.verbose,,,"Print daofind messages?"
+graphics,s,h,)_.graphics,,,"Graphics device"
+display,s,h,)_.display,,,"Display device"
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/daolib/bicubic.x b/noao/digiphot/daophot/daolib/bicubic.x
new file mode 100644
index 00000000..50bec983
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/bicubic.x
@@ -0,0 +1,47 @@
+# BICUBIC -- Perform bicubic interpolation on an array. The point at which
+# the function is to be estimated lies between the second and third columns
+# and second and third rows of f, at a distance of (dx, dy), from the (2,2)
+# element of f.
+
+real procedure bicubic (f, nbox, dx, dy, dfdx, dfdy)
+
+real f[nbox,nbox] # input real array to be interpolated
+int nbox # size of the input array
+real dx, dy # point at which array is to be interpolated
+real dfdx, dfdy # output derivative of the interpolant
+
+int jy
+real c1, c2, c3, c4, temp[4], dfdxt[4], interp
+
+begin
+ # Interpolate first in x.
+ do jy = 1, 4 {
+ c1 = 0.5 * (f[3,jy] - f[1,jy])
+ c4 = f[3,jy] - f[2,jy] - c1
+ c2 = 3.0 * c4 - 0.5 * (f[4,jy] - f[2,jy]) + c1
+ c3 = c4 - c2
+ c4 = dx * c3
+ temp[jy] = dx * (dx * (c4 + c2) + c1) + f[2,jy]
+ dfdxt[jy] = dx * (c4 * 3.0 + 2.0 * c2) + c1
+ }
+
+ # Interpolate next in y.
+ c1 = 0.5 * (temp[3] - temp[1])
+ c4 = temp[3] - temp[2] - c1
+ c2 = 3.0 * c4 - 0.5 * (temp[4] - temp[2]) + c1
+ c3 = c4 - c2
+ c4 = dy * c3
+
+ # Get the result.
+ interp = dy * (dy * (c4 + c2) + c1) + temp[2]
+
+ # Compute the derivatives.
+ dfdy = dy * (c4 * 3.0 + 2.0 * c2) + c1
+ c1 = 0.5 * (dfdxt[3] - dfdxt[1])
+ c4 = dfdxt[3] - dfdxt[2] - c1
+ c2 = 3.0 * c4 - 0.5 * (dfdxt[4] - dfdxt[2]) + c1
+ c3 = c4 - c2
+ dfdx = dy * (dy * (dy * c3 + c2) + c1) + dfdxt[2]
+
+ return (interp)
+end
diff --git a/noao/digiphot/daophot/daolib/daoran.x b/noao/digiphot/daophot/daolib/daoran.x
new file mode 100644
index 00000000..a63b8b39
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/daoran.x
@@ -0,0 +1,43 @@
+define LEN_IR 97
+define IC 150889
+define M 714025
+define IA 1366
+define RM 1.400511e-6
+
+# DAORAN -- The random number generator RAN2 from Numerical Recipes.
+
+real procedure daoran (idum)
+
+int idum # seed for the random number generator
+
+int j, iff, iy, ir[LEN_IR]
+real rnum2
+data iff /0/
+
+begin
+ repeat {
+
+ # Initialize the random number generator.
+ if ((idum < 0) || (iff == 0)) {
+ iff = 1
+ idum = mod (abs (IC - idum), M)
+ do j = 1, LEN_IR {
+ idum = mod (IA * idum + IC, M)
+ ir[j] = idum
+ }
+ idum = mod (IA * idum + IC, M)
+ iy = idum
+ }
+
+ # Get the random number
+ j = 1 + (LEN_IR * iy) / M
+ j = max (1, min (LEN_IR, j))
+ iy = ir[j]
+ rnum2 = iy * RM
+ idum = mod (IA * idum + IC, M)
+ ir[j] = idum
+
+ } until (rnum2 > 0.0)
+
+ return (rnum2)
+end
diff --git a/noao/digiphot/daophot/daolib/dpairmass.x b/noao/digiphot/daophot/daolib/dpairmass.x
new file mode 100644
index 00000000..bad13607
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpairmass.x
@@ -0,0 +1,42 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_AIRMASS -- Set the image airmass.
+
+procedure dp_airmass (im, dao)
+
+pointer im # pointer to IRAF image
+pointer dao # pointer to the daophot structure
+
+pointer sp, key
+real xair
+real imgetr(), dp_statr()
+
+begin
+ # Get the airmass keyword.
+ call smark (sp)
+ call salloc (key, SZ_FNAME, TY_CHAR)
+ call dp_stats (dao, AIRMASS, Memc[key], SZ_FNAME)
+
+ # Get the value.
+ if (Memc[key] == EOS)
+ xair = dp_statr (dao, XAIRMASS)
+ else {
+ iferr {
+ xair = imgetr (im, Memc[key])
+ } then {
+ xair = dp_statr (dao, XAIRMASS)
+ call eprintf ("Warning: Image %s Keyword: %s not found\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargstr (Memc[key])
+ }
+ }
+
+ # Store the value.
+ if (IS_INDEFR(xair) || xair <= 0.0)
+ call dp_setr (dao, XAIRMASS, INDEFR)
+ else
+ call dp_setr (dao, XAIRMASS, xair)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpapheader.x b/noao/digiphot/daophot/daolib/dpapheader.x
new file mode 100644
index 00000000..898f9dab
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpapheader.x
@@ -0,0 +1,56 @@
+# DP_APHEADER -- Copy the text database column headers to another file.
+# Consider placing this simple routine in the pttables library at some point.
+
+procedure dp_apheader (in, out)
+
+int in # input file descriptor
+int out # output file descriptor
+
+pointer sp, line
+int getline()
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ while (getline (in, Memc[line]) != EOF) {
+ if (Memc[line] != '#')
+ break
+ if (Memc[line+1] == 'N')
+ break
+ call putline (out, Memc[line])
+ }
+
+ call seek (in, BOF)
+
+ call sfree (sp)
+end
+
+
+# DP_APBANNER -- Copy the text database keyword definitions to another file.
+# Consider placing this simple routine in the pttables library at some point.
+
+
+procedure dp_apbanner (in, out)
+
+int in # input file descriptor
+int out # output file descriptor
+
+pointer sp, line
+int getline()
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ while (getline (in, Memc[line]) != EOF) {
+ if (Memc[line] != '#')
+ break
+ if (Memc[line+1] == 'K')
+ next
+ call putline (out, Memc[line])
+ }
+ call seek (in, BOF)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpdate.x b/noao/digiphot/daophot/daolib/dpdate.x
new file mode 100644
index 00000000..70bf8f41
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpdate.x
@@ -0,0 +1,28 @@
+include <time.h>
+
+# DP_DATE -- Create the date and time strings for the daophot output files.
+
+procedure dp_date (date, time, maxch)
+
+char date[ARB] # the date string
+char time[ARB] # the time string
+int maxch # the maximum number of character in the string
+
+int tm[LEN_TMSTRUCT]
+long ctime
+long clktime()
+#long lsttogmt()
+
+begin
+ ctime = clktime (long(0))
+ #ctime = lsttogmt (ctime)
+ call brktime (ctime, tm)
+ call sprintf (date, maxch, "%04d-%02d-%02d")
+ call pargi (TM_YEAR(tm))
+ call pargi (TM_MONTH(tm))
+ call pargi (TM_MDAY(tm))
+ call sprintf (time, maxch, "%02d:%02d:%02d")
+ call pargi (TM_HOUR(tm))
+ call pargi (TM_MIN(tm))
+ call pargi (TM_SEC(tm))
+end
diff --git a/noao/digiphot/daophot/daolib/dpfilter.x b/noao/digiphot/daophot/daolib/dpfilter.x
new file mode 100644
index 00000000..b6932aa1
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpfilter.x
@@ -0,0 +1,41 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_FILTER -- Procedure to set the image airmass.
+
+procedure dp_filter (im, dao)
+
+pointer im # pointer to IRAF image
+pointer dao # pointer to the daophot structure
+
+pointer sp, key, filt
+
+begin
+ call smark (sp)
+ call salloc (key, SZ_FNAME, TY_CHAR)
+ call salloc (filt, SZ_FNAME, TY_CHAR)
+
+ call dp_stats (dao, FILTER, Memc[key], SZ_FNAME)
+ Memc[filt] = EOS
+ if (Memc[key] == EOS)
+ call dp_stats (dao, IFILTER, Memc[filt], SZ_FNAME)
+ else {
+ iferr {
+ call imgstr (im, Memc[key], Memc[filt], SZ_FNAME)
+ } then {
+ call dp_stats (dao, IFILTER, Memc[filt], SZ_FNAME)
+ call eprintf ("Warning: Image %s Keyword: %s not found\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargstr (Memc[key])
+ }
+ }
+
+ if (Memc[filt] == EOS) {
+ call dp_sets (dao, IFILTER, "INDEF")
+ } else {
+ call dp_rmwhite (Memc[filt], Memc[filt], SZ_FNAME)
+ call dp_sets (dao, IFILTER, Memc[filt])
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpfree.x b/noao/digiphot/daophot/daolib/dpfree.x
new file mode 100644
index 00000000..fa7c954d
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpfree.x
@@ -0,0 +1,71 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/allstardef.h"
+
+# DP_FREE - Procedure to free the the daophot structure.
+
+procedure dp_free (dp)
+
+pointer dp # pointer to the daophot structure
+
+begin
+ if (DP_MW(dp) != NULL)
+ call mw_close (DP_MW(dp))
+ call mfree (dp, TY_STRUCT)
+end
+
+
+# DP_FITCLOSE -- Procedure to close up the psf fitting structure.
+
+procedure dp_fitclose (dp)
+
+pointer dp # pointer to the daophot structure
+
+pointer psffit
+
+begin
+ psffit = DP_PSFFIT(dp)
+ if (DP_PSFLUT(psffit) != NULL)
+ call mfree (DP_PSFLUT(psffit), TY_REAL)
+ if (DP_PSFPARS(psffit) != NULL)
+ call mfree (DP_PSFPARS(psffit), TY_REAL)
+ call mfree (psffit, TY_STRUCT)
+end
+
+
+# DP_APCLOSE -- Procedure to close up the APSEL parameters.
+
+procedure dp_apclose (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dp)
+
+ if (DP_APRESULT(apsel) != NULL)
+ call mfree (DP_APRESULT(apsel), TY_INT)
+ if (DP_APID(apsel) != NULL)
+ call mfree (DP_APID(apsel), TY_INT)
+ if (DP_APXCEN(apsel) != NULL)
+ call mfree (DP_APXCEN(apsel), TY_REAL)
+ if (DP_APYCEN(apsel) != NULL)
+ call mfree (DP_APYCEN(apsel), TY_REAL)
+ if (DP_APMAG(apsel) != NULL)
+ call mfree (DP_APMAG(apsel), TY_REAL)
+ if (DP_APERR(apsel) != NULL)
+ call mfree (DP_APERR(apsel), TY_REAL)
+ if (DP_APMSKY(apsel) != NULL)
+ call mfree (DP_APMSKY(apsel), TY_REAL)
+ if (DP_APGROUP(apsel) != NULL)
+ call mfree (DP_APGROUP(apsel), TY_INT)
+ if (DP_APNITER(apsel) != NULL)
+ call mfree (DP_APNITER(apsel), TY_INT)
+ if (DP_APSHARP(apsel) != NULL)
+ call mfree (DP_APSHARP(apsel), TY_REAL)
+ if (DP_APCHI(apsel) != NULL)
+ call mfree (DP_APCHI(apsel), TY_REAL)
+
+ call mfree (apsel, TY_STRUCT)
+end
diff --git a/noao/digiphot/daophot/daolib/dpgetapert.x b/noao/digiphot/daophot/daolib/dpgetapert.x
new file mode 100644
index 00000000..8268373f
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpgetapert.x
@@ -0,0 +1,530 @@
+include <tbset.h>
+include "../../lib/ptkeysdef.h"
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+# DP_WGETAPERT -- Read the aperture photometry results and transform the
+# input coordinates to the appropriate coordinate system. Works with
+# either the "old" APPHOT files or the new ST Tables.
+
+procedure dp_wgetapert (dao, im, apd, max_nstars, old_ap)
+
+pointer dao # pointer to the DAOPHOT structure
+pointer im # the input image descriptor
+int apd # input photometry file descriptor
+int max_nstars # maximum number of stars
+bool old_ap # YES indicates old APPHOT file
+
+pointer apsel
+int dp_stati()
+
+begin
+ # Get the stars.
+ call dp_getapert (dao, apd, max_nstars, old_ap)
+
+ # Transform the coordinates if necessary.
+ apsel = DP_APSEL (dao)
+ if (dp_stati (dao, WCSIN) != WCS_LOGICAL)
+ call dp_win (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], DP_APNUM(apsel))
+end
+
+
+# DP_GETAPERT -- Read the aperture photometry results. Works with
+# either the "old" APPHOT files or the new ST Tables.
+
+procedure dp_getapert (dao, apd, max_nstars, old_ap)
+
+pointer dao # pointer to the DAOPHOT structure
+int apd # input Photometry file descriptor
+int max_nstars # maximum number of stars
+bool old_ap # YES indicates old APPHOT file
+
+int nstars
+pointer apsel
+int tbpsta(), dp_goldap(), dp_gtabphot()
+
+begin
+ # Get APSEL pointer.
+ apsel = DP_APSEL (dao)
+
+ # Get the required memory.
+ Memi[DP_APRESULT(apsel)] = DP_PAPID
+ Memi[DP_APRESULT(apsel)+1] = DP_PAPXCEN
+ Memi[DP_APRESULT(apsel)+2] = DP_PAPYCEN
+ Memi[DP_APRESULT(apsel)+3] = DP_PAPMAG1
+ Memi[DP_APRESULT(apsel)+4] = DP_PAPSKY
+
+ # Get the results.
+ if (old_ap) {
+ call dp_memapsel (dao, Memi[DP_APRESULT(apsel)], NAPRESULT,
+ max_nstars)
+ nstars = dp_goldap (apd, dao, max_nstars)
+ } else {
+ call dp_memapsel (dao, Memi[DP_APRESULT(apsel)], NAPRESULT,
+ tbpsta (apd, TBL_NROWS))
+ nstars = dp_gtabphot (apd, dao, tbpsta (apd, TBL_NROWS))
+ }
+
+ # Reallocate to save space if appropopriate.
+ if (nstars < max_nstars)
+ call dp_rmemapsel (dao, Memi[DP_APRESULT(apsel)], NAPRESULT,
+ nstars)
+end
+
+
+# DP_MEMAPSEL -- Procedure to allocate memory for the apselect strucuture.
+
+procedure dp_memapsel (dao, fields, nfields, max_nstars)
+
+pointer dao # pointer to the daophot strucuture
+int fields[ARB] # array of fields
+int nfields # number of fields to allocate space for
+int max_nstars # maximum number of stars
+
+int i
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dao)
+
+ # Allocate space for results.
+ do i = 1, nfields {
+ switch (fields[i]) {
+ case DP_PAPID:
+ if (DP_APID(apsel) != NULL)
+ call mfree (DP_APID(apsel), TY_INT)
+ call malloc (DP_APID(apsel), max_nstars, TY_INT)
+
+ case DP_PAPXCEN:
+ if (DP_APXCEN(apsel) != NULL)
+ call mfree (DP_APXCEN(apsel), TY_REAL)
+ call malloc (DP_APXCEN(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPYCEN:
+ if (DP_APYCEN(apsel) != NULL)
+ call mfree (DP_APYCEN(apsel), TY_REAL)
+ call malloc (DP_APYCEN(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPSKY:
+ if (DP_APMSKY(apsel) != NULL)
+ call mfree (DP_APMSKY(apsel), TY_REAL)
+ call malloc (DP_APMSKY(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPMAG1:
+ if (DP_APMAG(apsel) != NULL)
+ call mfree (DP_APMAG(apsel), TY_REAL)
+ call malloc (DP_APMAG(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPGROUP:
+ if (DP_APGROUP(apsel) != NULL)
+ call mfree (DP_APGROUP(apsel), TY_INT)
+ #call malloc (DP_APGROUP(apsel), max_nstars, TY_INT)
+
+ case DP_PAPMERR1:
+ if (DP_APERR(apsel) != NULL)
+ call mfree (DP_APERR(apsel), TY_REAL)
+ call malloc (DP_APERR(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPNITER:
+ if (DP_APNITER(apsel) != NULL)
+ call mfree (DP_APNITER(apsel), TY_INT)
+ #call malloc (DP_APNITER(apsel), max_nstars, TY_INT)
+
+ case DP_PAPCHI:
+ if (DP_APCHI(apsel) != NULL)
+ call mfree (DP_APCHI(apsel), TY_REAL)
+ call malloc (DP_APCHI(apsel), max_nstars, TY_REAL)
+
+ case DP_PAPSHARP:
+ if (DP_APSHARP(apsel) != NULL)
+ call mfree (DP_APSHARP(apsel), TY_REAL)
+ call malloc (DP_APSHARP(apsel), max_nstars, TY_REAL)
+ }
+ }
+end
+
+
+# DP_GOLDAP -- Read in the photometry from an old style APPHOT file
+
+int procedure dp_goldap (apd, dao, max_nstars)
+
+int apd # the input file descriptor
+pointer dao # pointer to the daophot structure
+int max_nstars # maximum number of stars
+
+int nstars, bufsize, stat
+pointer apsel, apkey, sp, fields
+int dp_apsel()
+
+begin
+ # Define the point to the apselect structure.
+ apsel = DP_APSEL (dao)
+
+ # Allocate some temporary space.
+ call smark (sp)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+
+ # Initialize the keyword structure.
+ call pt_kyinit (apkey)
+
+ # Set up the fields to be retrieved.
+ call dp_gappsf (Memi[DP_APRESULT(apsel)], Memc[fields], NAPRESULT)
+
+ # Now read in the results.
+ nstars = 0
+ bufsize = max_nstars
+ repeat {
+
+ # Read in a group of stars.
+ while (nstars < bufsize) {
+ stat = dp_apsel (apkey, apd, Memc[fields],
+ Memi[DP_APRESULT(apsel)], Memi[DP_APID(apsel)+nstars],
+ Memr[DP_APXCEN(apsel)+nstars],
+ Memr[DP_APYCEN(apsel)+nstars],
+ Memr[DP_APMSKY(apsel)+nstars],
+ Memr[DP_APMAG(apsel)+nstars])
+ if (stat == EOF)
+ break
+ nstars = nstars + 1
+ }
+
+ # Check the buffer size.
+ if (stat == EOF)
+ break
+ bufsize = bufsize + max_nstars
+ call dp_rmemapsel (dao, Memi[DP_APRESULT(apsel)], NAPRESULT,
+ bufsize)
+
+ }
+ DP_APNUM(apsel) = nstars
+
+ # Free the keyword structure.
+ call pt_kyfree (apkey)
+ call sfree (sp)
+
+ return (nstars)
+end
+
+
+# DP_GTABPHOT -- Read in the complete photometry from an ST table.
+
+int procedure dp_gtabphot (tp, dao, max_nstars)
+
+pointer tp # table descriptor
+pointer dao # pointer to daophot structure
+int max_nstars # maximum number of stars
+
+bool nullflag
+int record, index, nrow
+pointer apsel, idpt, xcenpt, ycenpt, magpt, skypt
+int tbpsta()
+
+begin
+ # Define the point to the apselect structure.
+ apsel = DP_APSEL (dao)
+
+ # Find the column pointers
+ call tbcfnd (tp, ID, idpt, 1)
+ if (idpt == NULL)
+ call tbcfnd (tp, "ID", idpt, 1)
+ if (idpt == NULL)
+ call printf ("Error reading ID.\n")
+
+ call tbcfnd (tp, XCENTER, xcenpt, 1)
+ if (xcenpt == NULL)
+ call tbcfnd (tp, "XCENTER", xcenpt, 1)
+ if (xcenpt == NULL)
+ call printf ("Error reading XCENTER.\n")
+
+ call tbcfnd (tp, YCENTER, ycenpt, 1)
+ if (ycenpt == NULL)
+ call tbcfnd (tp, "YCENTER", ycenpt, 1)
+ if (ycenpt == NULL)
+ call printf ("Error reading YCENTER.\n")
+
+ call tbcfnd (tp, MAG, magpt, 1)
+ if (magpt == NULL)
+ call tbcfnd (tp, APMAG, magpt, 1)
+ if (magpt == NULL)
+ call printf ("Error reading MAG.\n")
+
+ call tbcfnd (tp, SKY, skypt, 1)
+ if (skypt == NULL)
+ call tbcfnd (tp, SKY, skypt, 1)
+ if (skypt == NULL)
+ call printf ("Error reading SKY.\n")
+
+
+ # Get the results ignoring any record with ID = NULL.
+ nrow = min (tbpsta (tp, TBL_NROWS), max_nstars)
+ index = 0
+ do record = 1, nrow {
+
+ # Check the ID record.
+ call tbrgti (tp, idpt, Memi[DP_APID(apsel)+index], nullflag, 1,
+ record)
+ if (nullflag)
+ next
+
+ # Read the remaining records.
+ call tbrgtr (tp, xcenpt, Memr[DP_APXCEN(apsel)+index], nullflag, 1,
+ record)
+ call tbrgtr (tp, ycenpt, Memr[DP_APYCEN(apsel)+index], nullflag, 1,
+ record)
+ call tbrgtr (tp, magpt, Memr[DP_APMAG(apsel)+index], nullflag, 1,
+ record)
+ call tbrgtr (tp, skypt, Memr[DP_APMSKY(apsel)+index], nullflag, 1,
+ record)
+ index = index + 1
+ }
+
+ DP_APNUM(apsel) = index
+
+ return (index)
+end
+
+
+# DP_RMEMAPSEL -- Procedure to reallocate memory for the apselect strucuture.
+
+procedure dp_rmemapsel (dao, fields, nfields, max_nstars)
+
+pointer dao # pointer to the daophot strucuture
+int fields[ARB] # integer fields
+int nfields # number of fields
+int max_nstars # maximum number of stars
+
+int i
+pointer apsel
+
+begin
+ # Reallocate space for results.
+ apsel = DP_APSEL(dao)
+
+ do i = 1, nfields {
+ switch (fields[i]) {
+ case DP_PAPID:
+ call realloc (DP_APID(apsel), max_nstars, TY_INT)
+ case DP_PAPXCEN:
+ call realloc (DP_APXCEN(apsel), max_nstars, TY_REAL)
+ case DP_PAPYCEN:
+ call realloc (DP_APYCEN(apsel), max_nstars, TY_REAL)
+ case DP_PAPSKY:
+ call realloc (DP_APMSKY(apsel), max_nstars, TY_REAL)
+ case DP_PAPGROUP:
+ #call realloc (DP_APGROUP(apsel), max_nstars, TY_INT)
+ case DP_PAPMAG1:
+ call realloc (DP_APMAG(apsel), max_nstars, TY_REAL)
+ case DP_PAPMERR1:
+ call realloc (DP_APERR(apsel), max_nstars, TY_REAL)
+ case DP_PAPNITER:
+ #call realloc (DP_APNITER(apsel), max_nstars, TY_INT)
+ case DP_PAPSHARP:
+ call realloc (DP_APSHARP(apsel), max_nstars, TY_REAL)
+ case DP_PAPCHI:
+ call realloc (DP_APCHI(apsel), max_nstars, TY_REAL)
+ }
+ }
+end
+
+
+# DP_GAPPSF -- Set up the structures necessary for retrieving the
+# aperture phtometery results needed for the PSF task.
+
+procedure dp_gappsf (fields, sel_fields, max_nfields)
+
+int fields[ARB] # array of selected fields
+char sel_fields[ARB] # names of selected containing fields
+int max_nfields # maximum number of fields selected
+
+int i
+int strlen()
+
+begin
+ sel_fields[1] = EOS
+
+ do i = 1, max_nfields {
+ switch (fields[i]) {
+ case DP_PAPID:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (ID)
+ case DP_PAPXCEN:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (XCENTER)
+ case DP_PAPYCEN:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (YCENTER)
+ case DP_PAPSKY:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (SKY)
+ case DP_PAPMAG1:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (APMAG)
+ }
+ }
+
+ if (sel_fields[1] != EOS)
+ sel_fields[strlen(sel_fields)] = EOS
+end
+
+
+# DP_APSEL -- Select records from an apphot/daophot text file.
+
+int procedure dp_apsel (key, fd, fields, indices, id, x, y, sky, mag)
+
+pointer key # pointer to key structure
+int fd # text file descriptor
+char fields[ARB] # fields to be output
+int indices[ARB] # indices of fields
+int id # star id number
+real x # x center
+real y # y center
+real sky # sky value
+real mag # magnitude
+
+int nchars, nunique, uunique, funique, ncontinue, recptr
+int first_rec, nselect, record
+pointer line
+int getline(), strncmp(), pt_choose()
+
+data first_rec /YES/
+
+begin
+ # Initialize the file read.
+ if (first_rec == YES) {
+ nunique = 0
+ uunique = 0
+ funique = 0
+ nselect = 0
+ record = 0
+ call malloc (line, SZ_LINE, TY_CHAR)
+ }
+
+ ncontinue = 0
+ recptr = 1
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ 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 (nselect <= 0) {
+ nselect = pt_choose (key, fields)
+ if (nselect <= 0)
+ break
+ }
+
+ # Construct the output record by moving selected fields
+ # into data structures.
+ call dp_getap (key, indices, id, x, y, sky, mag)
+ record = record + 1
+ first_rec = NO
+
+ # Record is complete so exist the loop.
+ break
+ }
+ }
+
+ }
+
+ if (nchars == EOF || nselect <= 0) {
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ nselect = 0
+ call mfree (line, TY_CHAR)
+ return (EOF)
+ } else
+ return (record)
+end
+
+
+# DP_GETAP -- Decode the selected daophot/apphot values.
+
+procedure dp_getap (key, indices, id, x, y, sky, mag)
+
+pointer key # pointer to keys strucuture
+int indices[ARB] # index array
+int id # star id
+real x # x position
+real y # y position
+real sky # sky value
+real mag # magnitude
+
+int i, index, elem, maxch, kip, ip
+int ctoi(), ctor()
+char buffer[SZ_LINE]
+
+begin
+ 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
+
+ # Extract the appropriate field.
+ call amovc (Memc[kip], buffer, maxch)
+ buffer[maxch+1] = EOS
+
+ # Decode the output value.
+ ip = 1
+ switch (indices[i]) {
+ case DP_PAPID:
+ if (ctoi (buffer, ip, id) <= 0)
+ id = 0
+ case DP_PAPXCEN:
+ if (ctor (buffer, ip, x) <= 0)
+ x = INDEFR
+ case DP_PAPYCEN:
+ if (ctor (buffer, ip, y) <= 0)
+ y = INDEFR
+ case DP_PAPSKY:
+ if (ctor (buffer, ip, sky) <= 0)
+ sky = INDEFR
+ case DP_PAPMAG1:
+ if (ctor (buffer, ip, mag) <= 0)
+ mag = INDEFR
+ default:
+ call printf ("Error reading the APPHOT results.\n")
+ }
+
+ }
+end
diff --git a/noao/digiphot/daophot/daolib/dpgppars.x b/noao/digiphot/daophot/daolib/dpgppars.x
new file mode 100644
index 00000000..f16fc59e
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpgppars.x
@@ -0,0 +1,227 @@
+include <ctotok.h>
+include "../lib/daophotdef.h"
+
+# DP_GPPARS -- Procedure to fetch the daophot task parameters.
+
+procedure dp_gppars (dao)
+
+pointer dao # pointer to daophot structure
+
+int dp, dap
+pointer mp, str, tstr
+real scale, fwhmpsf, psfrad, matchrad, fitrad, annulus, dannulus, mergerad
+
+bool clgetb(), clgpsetb()
+int clgpseti(), btoi(), dp_fctdecode(), dp_strwrd()
+pointer clopset()
+real clgpsetr()
+
+begin
+ # Allocate working space.
+ call smark (mp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+ call salloc (tstr, SZ_FNAME, TY_CHAR)
+
+ # Open the daophot structure.
+ call dp_init (dao)
+
+ # Set the package parameter text and initialize the verbose switch.
+ call dp_seti (dao, TEXT, btoi (clgetb ("text")))
+ call dp_seti (dao, VERBOSE, btoi (false))
+
+ # Open the datapars parameter set.
+ dp = clopset ("datapars")
+
+ # Set the datapars parameters.
+ scale = clgpsetr (dp, "scale")
+ call dp_setr (dao, SCALE, scale)
+ fwhmpsf = clgpsetr (dp, "fwhmpsf")
+ call dp_setr (dao, SFWHMPSF, fwhmpsf)
+ call dp_setr (dao, MAXGDATA, clgpsetr (dp, "datamax"))
+ call dp_setr (dao, MINGDATA, clgpsetr (dp, "datamin"))
+
+ # Initialize the noise parameters.
+ call clgpset (dp, "ccdread", Memc[str], SZ_FNAME)
+ call dp_sets (dao, CCDREAD, Memc[str])
+ call dp_setr (dao, READNOISE, clgpsetr (dp, "readnoise"))
+ call clgpset (dp, "gain", Memc[str], SZ_FNAME)
+ call dp_sets (dao, CCDGAIN, Memc[str])
+ call dp_setr (dao, PHOTADU, clgpsetr (dp, "epadu"))
+
+ # Initialize the observing parameters. Note that whitespace
+ # is removed from the filter id.
+ call clgpset (dp, "exposure", Memc[str], SZ_FNAME)
+ call dp_sets (dao, EXPTIME, Memc[str])
+ call dp_setr (dao, ITIME, 1.0)
+ call clgpset (dp, "airmass", Memc[str], SZ_FNAME)
+ call dp_sets (dao, AIRMASS, Memc[str])
+ call dp_setr (dao, XAIRMASS, clgpsetr (dp, "xairmass"))
+ call clgpset (dp, "filter", Memc[str], SZ_FNAME)
+ call dp_sets (dao, FILTER, Memc[str])
+ call clgpset (dp, "ifilter", Memc[str], SZ_FNAME)
+ call dp_rmwhite (Memc[str], Memc[str], SZ_FNAME)
+ call dp_sets (dao, IFILTER, Memc[str])
+ call clgpset (dp, "obstime", Memc[str], SZ_FNAME)
+ call dp_sets (dao, OBSTIME, Memc[str])
+ call clgpset (dp, "otime", Memc[str], SZ_FNAME)
+ call dp_sets (dao, OTIME, Memc[str])
+
+ # Close the datapars parameter set.
+ call clcpset (dp)
+
+ # Open the daopars parameter set.
+ dap = clopset ("daopars")
+
+ # Set the psf fitting parameters.
+ call clgpset (dap, "function", Memc[tstr], SZ_FNAME)
+ if (dp_fctdecode (Memc[tstr], Memc[str], SZ_FNAME) <= 0)
+ call strcpy (",gauss,", Memc[str], SZ_FNAME)
+ call dp_sets (dao, FUNCLIST, Memc[str])
+ if (dp_strwrd (1, Memc[tstr], SZ_FNAME, Memc[str]) <= 0)
+ call strcpy ("gauss", Memc[tstr], SZ_FNAME)
+ call dp_sets (dao, FUNCTION, Memc[tstr])
+ call dp_seti (dao, VARORDER, clgpseti (dap, "varorder"))
+ #call dp_seti (dao, FEXPAND, btoi (clgpsetb (dap, "fexpand")))
+ call dp_seti (dao, FEXPAND, NO)
+ call dp_seti (dao, NCLEAN, clgpseti (dap, "nclean"))
+ call dp_seti (dao, SATURATED, btoi (clgpsetb (dap, "saturated")))
+ psfrad = clgpsetr (dap, "psfrad")
+ call dp_setr (dao, RPSFRAD, psfrad)
+ call dp_setr (dao, SPSFRAD, psfrad)
+ matchrad = clgpsetr (dap, "matchrad")
+ call dp_setr (dao, SMATCHRAD, matchrad)
+
+ # Set the fitting parameters.
+ fitrad = clgpsetr (dap, "fitrad")
+ call dp_setr (dao, SFITRAD, fitrad)
+ annulus = clgpsetr (dap, "sannulus")
+ call dp_setr (dao, SANNULUS, annulus)
+ dannulus = clgpsetr (dap, "wsannulus")
+ call dp_setr (dao, SDANNULUS, dannulus)
+ call dp_setr (dao, CRITSNRATIO, clgpsetr (dap, "critsnratio"))
+ call dp_seti (dao, MAXITER, clgpseti (dap, "maxiter"))
+ call dp_seti (dao, MAXGROUP, clgpseti (dap, "maxgroup"))
+ call dp_seti (dao, MAXNSTAR, clgpseti (dap, "maxnstar"))
+ call dp_seti (dao, RECENTER, btoi (clgpsetb (dap, "recenter")))
+ call dp_seti (dao, FITSKY, btoi (clgpsetb (dap, "fitsky")))
+ call dp_seti (dao, GROUPSKY, btoi (clgpsetb (dap, "groupsky")))
+ call dp_setr (dao, FLATERR, clgpsetr (dap, "flaterr"))
+ call dp_setr (dao, PROFERR, clgpsetr (dap, "proferr"))
+ call dp_setr (dao, CLIPRANGE, clgpsetr (dap, "cliprange"))
+ call dp_seti (dao, CLIPEXP, clgpseti (dap, "clipexp"))
+ mergerad = clgpsetr (dap, "mergerad")
+ call dp_setr (dao, SMERGERAD, mergerad)
+
+ # Close the daopars pset file.
+ call clcpset (dap)
+
+ # Compute the fwhmpsf, psf radius, fitting radius and matching radius
+ # in pixels and store.
+
+ call dp_setr (dao, FWHMPSF, fwhmpsf / scale)
+ call dp_setr (dao, PSFRAD, psfrad / scale)
+ call dp_setr (dao, MATCHRAD, matchrad / scale)
+ call dp_setr (dao, FITRAD, fitrad / scale)
+ call dp_setr (dao, ANNULUS, annulus / scale)
+ call dp_setr (dao, DANNULUS, dannulus / scale)
+ if (IS_INDEFR(mergerad))
+ call dp_setr (dao, MERGERAD, INDEFR)
+ else
+ call dp_setr (dao, MERGERAD, mergerad / scale)
+
+ call sfree (mp)
+end
+
+
+# DP_FCTDECODE -- Decode and re-encode the list of analytic functions to be
+# fit in a from suitable for use by strdic. If no valid psf types are included
+# in the list set the dictionary to the gaussian function.
+
+int procedure dp_fctdecode (instr, outstr, maxch)
+
+char instr[ARB] # the input list of functions
+char outstr[ARB] # the output list of functions
+int maxch # maximum size of the output string
+
+int ip, op, ntok, tok
+pointer sp, token
+int ctotok(), strdic(), gstrcpy, gstrcat()
+
+begin
+ call smark (sp)
+ call salloc (token, maxch, TY_CHAR)
+
+ outstr[1] = ','
+ outstr[2] = EOS
+ op = 2
+
+ ntok = 0
+ ip = 1
+ while (instr[ip] != EOS) {
+ tok = ctotok (instr, ip, Memc[token], maxch)
+ if (tok != TOK_IDENTIFIER)
+ next
+ if (strdic (Memc[token], Memc[token], maxch, FCTN_FTYPES) <= 0)
+ next
+ ntok = ntok + 1
+ op = op + gstrcpy (Memc[token], outstr[op], maxch - op + 1)
+ op = op + gstrcat (",", outstr[op], maxch - op + 1)
+ }
+
+ call sfree (sp)
+
+ return (ntok)
+end
+
+
+# DP_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 dp_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/daophot/daolib/dpgsubrast.x b/noao/digiphot/daophot/daolib/dpgsubrast.x
new file mode 100644
index 00000000..6794824b
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpgsubrast.x
@@ -0,0 +1,32 @@
+include <imhdr.h>
+
+# DP_GSUBRAST -- Extract a sub-raster around a specified position such that
+# all pixels within the specified radius are included.
+
+pointer procedure dp_gsubrast (im, x, y, radius, lowx, lowy, nxpix, nypix)
+
+pointer im # image descriptor
+real x,y # position
+real radius # radius
+int lowx, lowy # lower boundaries of subraster
+int nxpix, nypix # number of pixels in subraster
+
+pointer imgs2r()
+
+begin
+ # Determine the boundaries of the area.
+ lowx = int (x - radius) + 1
+ lowy = int (y - radius) + 1
+ lowx = max (1, lowx)
+ lowy = max (1, lowy)
+
+ # Compute the size of the area.
+ nxpix = min (int (x + radius), IM_LEN(im, 1)) - lowx + 1
+ nypix = min (int (y + radius), IM_LEN(im, 2)) - lowy + 1
+
+ # Return a pointer to the pixel buffer.
+ if ((nxpix < 1) || (nypix < 1))
+ return (NULL)
+ else
+ return (imgs2r (im, lowx, lowx + nxpix - 1, lowy, lowy + nypix - 1))
+end
diff --git a/noao/digiphot/daophot/daolib/dpgsvw.x b/noao/digiphot/daophot/daolib/dpgsvw.x
new file mode 100644
index 00000000..289b7d15
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpgsvw.x
@@ -0,0 +1,162 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imio.h>
+include <imhdr.h>
+include <math.h>
+
+# DP_GSWV -- Set the data window and viewport for the image display.
+
+procedure dp_gswv (id, image, im, max_nframes)
+
+pointer id # pointer to the image display graphics stream
+char image # the input image name
+pointer im # pointer to the input image
+int max_nframes # the maximum number of display frames
+
+real vx1, vx2, vy1, vy2
+
+begin
+ if (id == NULL)
+ return
+ call dp_gsview (image, im, max_nframes, vx1, vx2, vy1, vy2)
+ call gsview (id, vx1, vx2, vy1, vy2)
+ call gswind (id, 1.0, real (IM_LEN(im,1)), 1.0, real (IM_LEN(im,2)))
+end
+
+
+# DP_GSVIEW -- Map the viewport and window of the image display.
+
+procedure dp_gsview (image, im, max_nframes, vx1, vx2, vy1, vy2)
+
+char image # the input image name
+pointer im # pointer to the input image
+int max_nframes # the maximum number of display frames
+real vx1, vx2, vy1, vy2 # the output viewport
+
+int i, frame, wcs_status, dim1, dim2, step1, step2
+pointer sp, rimname, frimage, frimname, frim, iw
+real x1, x2, y1, y2, fx1, fx2, fy1, fy2, junkx, junky
+bool streq()
+pointer imd_mapframe(), iw_open()
+
+begin
+ # Allocate some memory.
+ call smark (sp)
+ call salloc (rimname, SZ_FNAME, TY_CHAR)
+ call salloc (frimage, SZ_FNAME, TY_CHAR)
+ call salloc (frimname, SZ_FNAME, TY_CHAR)
+
+ # Get the root image name.
+ call imgimage (image, Memc[rimname], SZ_FNAME)
+
+ # Loop through the defined image frames searching for the one
+ # which has the image loaded.
+
+ frame = 0
+ do i = 1, max_nframes {
+ frim = imd_mapframe (i, READ_ONLY, NO)
+ iw = iw_open (frim, i, Memc[frimage], SZ_FNAME, wcs_status)
+ call imgimage (Memc[frimage], Memc[frimname], SZ_FNAME)
+ if (streq (Memc[rimname], Memc[frimname])) {
+ frame = i
+ break
+ } else {
+ call iw_close (iw)
+ call imunmap (frim)
+ }
+ }
+
+ # Default to current frame if the image has not been displayes?
+ if (frame == 0) {
+ call eprintf ("Warning: image %s is not loaded in the display\n")
+ call pargstr (Memc[rimname])
+ vx1 = 0.0
+ vx2 = 1.0
+ vy1 = 0.0
+ vy2 = 1.0
+ call sfree (sp)
+ return
+ }
+
+ # Find the beginning and end points of the requested image section.
+ # We already know at this point that the input logical image is
+ # 2-dimensional. However this 2-dimensional section may be part of
+ # n-dimensional image.
+
+ # X dimension.
+ dim1 = IM_VMAP(im,1)
+ step1 = IM_VSTEP(im,dim1)
+ if (step1 >= 0) {
+ x1 = IM_VOFF(im,dim1) + 1
+ x2 = x1 + IM_LEN(im,1) - 1
+ } else {
+ x1 = IM_VOFF(im,dim1) - 1
+ x2 = x1 - IM_LEN(im,1) + 1
+ }
+
+ # Y dimension.
+ dim2 = IM_VMAP(im,2)
+ step2 = IM_VSTEP(im,dim2)
+ if (step2 >= 0) {
+ y1 = IM_VOFF(im,dim2) + 1
+ y2 = y1 + IM_LEN(im,2) - 1
+ } else {
+ y1 = IM_VOFF(im,dim2) - 1
+ y2 = y1 - IM_LEN(im,2) + 1
+ }
+
+ # Get the frame buffer coordinates corresponding to the lower left
+ # and upper right corners of the image section.
+
+ call iw_im2fb (iw, x1, y1, fx1, fy1)
+ call iw_im2fb (iw, x2, y2, fx2, fy2)
+ if (fx1 > fx2) {
+ junkx = fx1
+ fx1 = fx2
+ fx2 = junkx
+ }
+ if (fy1 > fy2) {
+ junky = fy1
+ fy1 = fy2
+ fy2 = junky
+ }
+
+ # Check that some portion of the input image is in the display.
+ # If not select the default viewport and window coordinates.
+ if (fx1 > IM_LEN(frim,1) || fx2 < 1.0 || fy1 > IM_LEN(frim,2) ||
+ fy2 < 1.0) {
+ vx1 = 0.0
+ vx2 = 1.0
+ vy1 = 0.0
+ vy2 = 1.0
+ call iw_close (iw)
+ call imunmap (frim)
+ call sfree (sp)
+ return
+ }
+
+ # Compute a new viewport and window for X.
+ if (fx1 >= 1.0)
+ vx1 = max (0.0, min (1.0, (fx1 - 0.5) / IM_LEN(frim,1)))
+ else
+ vx1 = 0.0
+ if (fx2 <= IM_LEN(frim,1))
+ vx2 = max (0.0, min (1.0, (fx2 + 0.5) / IM_LEN(frim,1)))
+ else
+ vx2 = 1.0
+
+ # Compute a new viewport and window for Y.
+ if (fy1 >= 1.0)
+ vy1 = max (0.0, min (1.0, (fy1 - 0.5) / IM_LEN(frim,2)))
+ else
+ vy1 = 0.0
+ if (fy2 <= IM_LEN(frim,2))
+ vy2 = max (0.0, min (1.0, (fy2 + 0.5) / IM_LEN(frim,2)))
+ else
+ vy2 = 1.0
+
+ # Clean up.
+ call iw_close (iw)
+ call imunmap (frim)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpimkeys.x b/noao/digiphot/daophot/daolib/dpimkeys.x
new file mode 100644
index 00000000..9cfd1943
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpimkeys.x
@@ -0,0 +1,71 @@
+include "../lib/daophotdef.h"
+
+# DP_IMKEYS - Set the image name and keyword parameters after an image
+# is mapped.
+
+procedure dp_imkeys (dp, im)
+
+pointer dp # pointer to the daophot structure
+pointer im # the image descriptor
+
+pointer mw, ct
+int dp_stati()
+pointer mw_openim(), mw_sctran()
+errchk mw_openim(), mw_sctran()
+
+begin
+ # Set the wcs descriptors.
+ mw = dp_stati (dp, MW)
+ if (mw != NULL)
+ call mw_close (mw)
+ iferr {
+ mw = mw_openim (im)
+ } then {
+ call dp_seti (dp, MW, NULL)
+ call dp_seti (dp, CTIN, NULL)
+ call dp_seti (dp, CTOUT, NULL)
+ call dp_seti (dp, CTPSF, NULL)
+ } else {
+ call dp_seti (dp, MW, mw)
+ switch (dp_stati (dp, WCSIN)) {
+ case WCS_WORLD:
+ iferr (ct = mw_sctran (mw, "world", "logical", 03B))
+ ct = NULL
+ case WCS_PHYSICAL:
+ iferr (ct = mw_sctran (mw, "physical", "logical", 03B))
+ ct = NULL
+ case WCS_TV, WCS_LOGICAL:
+ ct = NULL
+ default:
+ ct = NULL
+ }
+ call dp_seti (dp, CTIN, ct)
+ switch (dp_stati (dp, WCSOUT)) {
+ case WCS_PHYSICAL:
+ iferr (ct = mw_sctran (mw, "logical", "physical", 03B))
+ ct = NULL
+ case WCS_TV, WCS_LOGICAL:
+ ct = NULL
+ default:
+ ct = NULL
+ }
+ call dp_seti (dp, CTOUT, ct)
+ switch (dp_stati (dp, WCSPSF)) {
+ case WCS_PHYSICAL:
+ iferr (ct = mw_sctran (mw, "logical", "physical", 03B))
+ ct = NULL
+ case WCS_TV, WCS_LOGICAL:
+ ct = NULL
+ default:
+ ct = NULL
+ }
+ call dp_seti (dp, CTPSF, ct)
+ }
+
+ # Get the proper values from the image header if an image is defined.
+ call dp_padu (im, dp)
+ call dp_rdnoise (im, dp)
+ call dp_filter (im, dp)
+ call dp_airmass (im, dp)
+ call dp_otime (im, dp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpinit.x b/noao/digiphot/daophot/daolib/dpinit.x
new file mode 100644
index 00000000..ceac884b
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpinit.x
@@ -0,0 +1,225 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/allstardef.h"
+
+# DP_INIT - Procedure to initialize the daophot structure.
+
+procedure dp_init (dp)
+
+pointer dp # pointer to the daophot structure
+
+begin
+ # Set the daophot structure.
+ call calloc (dp, LEN_DPSTRUCT, TY_STRUCT)
+
+ # Initalize the output type parameters.
+ DP_TEXT(dp) = YES
+ DP_VERBOSE(dp) = YES
+
+ # Initialize the wcs parameters.
+ DP_MW(dp) = NULL
+ DP_WCSIN(dp) = WCS_LOGICAL
+ DP_WCSOUT(dp) = WCS_LOGICAL
+ DP_WCSPSF(dp) = WCS_LOGICAL
+ DP_CTIN(dp) = NULL
+ DP_CTOUT(dp) = NULL
+ DP_CTPSF(dp) = NULL
+
+ # Initialize the data depedent parameters.
+ DP_SCALE(dp) = DEF_SCALE
+ DP_SFWHMPSF(dp) = DEF_FWHMPSF
+ DP_FWHMPSF(dp) = DEF_FWHMPSF / DEF_SCALE
+ DP_MINGDATA(dp) = INDEFR
+ DP_MAXGDATA(dp) = INDEFR
+
+ # Initialize the noise parameters
+ DP_CCDGAIN(dp) = EOS
+ DP_PHOTADU(dp) = INDEFR
+ DP_CCDREAD(dp) = EOS
+ DP_READNOISE(dp) = INDEFR
+
+ # Initialize the observing parameters.
+ DP_EXPTIME(dp) = EOS
+ DP_ITIME(dp) = INDEFR
+ DP_AIRMASS(dp) = EOS
+ DP_XAIRMASS(dp) = INDEFR
+ DP_FILTER(dp) = EOS
+ DP_IFILTER(dp) = EOS
+ DP_OBSTIME(dp) = EOS
+ DP_OTIME(dp) = EOS
+
+ # Initialize the psf fitting parameters.
+ call strcpy (",gauss,", DP_FUNCLIST(dp), SZ_FNAME)
+ call strcpy ("gauss", DP_FUNCTION(dp), SZ_FNAME)
+ DP_VARORDER(dp) = -1
+ DP_FEXPAND(dp) = NO
+ DP_SATURATED(dp) = NO
+ DP_RPSFRAD(dp) = DEF_PSFRAD / DEF_SCALE
+ DP_SPSFRAD (dp) = DEF_PSFRAD / DEF_SCALE
+ DP_PSFRAD (dp) = DEF_PSFRAD
+
+ # Initialize the fitting parameters.
+ DP_SFITRAD(dp) = DEF_FITRAD / DEF_SCALE
+ DP_FITRAD(dp) = DEF_FITRAD
+ DP_SANNULUS(dp) = DEF_ANNULUS / DEF_SCALE
+ DP_ANNULUS(dp) = DEF_ANNULUS
+ DP_SDANNULUS(dp) = DEF_DANNULUS / DEF_SCALE
+ DP_DANNULUS(dp) = DEF_DANNULUS
+ DP_MAXITER(dp) = DEF_MAXITER
+ DP_MAXGROUP(dp) = DEF_MAXGROUP
+ DP_MAXNSTAR(dp) = DEF_MAXNSTAR
+ DP_RECENTER(dp) = YES
+ DP_FITSKY(dp) = NO
+ DP_GROUPSKY(dp) = YES
+
+ # Initialize the file names.
+ DP_INIMAGE(dp) = EOS
+ DP_COORDS(dp) = EOS
+ DP_INPHOTFILE(dp) = EOS
+ DP_PSFIMAGE(dp) = EOS
+ DP_OUTPHOTFILE(dp) = EOS
+ DP_OUTIMAGE(dp) = EOS
+ DP_OUTREJFILE(dp) = EOS
+
+ # Initialize the substructure pointers.
+ DP_PSF(dp) = NULL
+ DP_PSFFIT(dp) = NULL
+ DP_GROUP(dp) = NULL
+ DP_PEAK(dp) = NULL
+ DP_NSTAR(dp) = NULL
+ DP_SUBSTAR(dp) = NULL
+ DP_ADDSTAR(dp) = NULL
+ DP_ALLSTAR(dp) = NULL
+ DP_APSEL(dp) = NULL
+end
+
+
+# DP_FITSETUP -- Setup the current PSF parameters given that the fitting
+# parameters have been correctly read in.
+
+procedure dp_fitsetup (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer psffit
+bool streq()
+
+begin
+ # Set up the psf fit structure.
+ call malloc (DP_PSFFIT(dp), LEN_PSFFIT, TY_STRUCT)
+ psffit = DP_PSFFIT(dp)
+ call calloc (DP_PSFPARS(psffit), MAX_NFCTNPARS, TY_REAL)
+
+ # Define the psf function. The if user entered string is "auto"
+ # or a list then intialize the psf function to "gauss" or the
+ # first function in the list respectively.
+
+ if (streq (DP_FUNCTION(dp), "gauss")) {
+ DP_PSFUNCTION(psffit) = FCTN_GAUSS
+ } else if (streq (DP_FUNCTION(dp), "moffat25")) {
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT25
+ } else if (streq (DP_FUNCTION(dp), "penny1")) {
+ DP_PSFUNCTION(psffit) = FCTN_PENNY1
+ } else if (streq (DP_FUNCTION(dp), "moffat15")) {
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT15
+ } else if (streq (DP_FUNCTION(dp), "penny2")) {
+ DP_PSFUNCTION(psffit) = FCTN_PENNY2
+ } else if (streq (DP_FUNCTION(dp), "lorentz")) {
+ DP_PSFUNCTION(psffit) = FCTN_LORENTZ
+ } else if (streq (DP_FUNCTION(dp), "auto")) {
+ DP_PSFUNCTION(psffit) = FCTN_GAUSS
+ } else {
+ call error (0, "Unknown analytic PSF function")
+ }
+
+ switch (DP_VARORDER(dp)) {
+ case -1:
+ DP_NVLTABLE(psffit) = 0
+ case 0:
+ DP_NVLTABLE(psffit) = 1
+ case 1:
+ DP_NVLTABLE(psffit) = 3
+ case 2:
+ DP_NVLTABLE(psffit) = 6
+ }
+ if (DP_FEXPAND(dp) == NO)
+ DP_NFEXTABLE(psffit) = 0
+ else
+ DP_NFEXTABLE(psffit) = 5
+
+ # Set the initial values of the function parameters.
+ switch (DP_PSFUNCTION(psffit)) {
+ case FCTN_GAUSS:
+ DP_PSFNPARS(psffit) = 2
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ case FCTN_MOFFAT25:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ Memr[DP_PSFPARS(psffit)+3] = 2.5
+ case FCTN_PENNY1:
+ DP_PSFNPARS(psffit) = 4
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.75
+ Memr[DP_PSFPARS(psffit)+3] = 0.0
+ case FCTN_MOFFAT15:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ Memr[DP_PSFPARS(psffit)+3] = 1.5
+ case FCTN_PENNY2:
+ DP_PSFNPARS(psffit) = 5
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.75
+ Memr[DP_PSFPARS(psffit)+3] = 0.0
+ Memr[DP_PSFPARS(psffit)+4] = 0.0
+ case FCTN_LORENTZ:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dp) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ default:
+ call error (0, "Unknown analytic PSF function")
+ }
+
+ DP_PSFHEIGHT(psffit) = INDEFR
+ DP_PSFMAG(psffit) = INDEFR
+ DP_PSFX(psffit) = INDEFR
+ DP_PSFY(psffit) = INDEFR
+
+ DP_PSFSIZE(psffit) = 0
+ DP_PSFLUT(psffit) = NULL
+end
+
+
+# DP_APSELSETUP -- Procedure to set up the APSEL parameters.
+
+procedure dp_apselsetup (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer apsel
+
+begin
+ # APSEL structure
+ call malloc (DP_APSEL(dp), LEN_DPAPSTRUCT, TY_STRUCT)
+ apsel = DP_APSEL(dp)
+ call malloc (DP_APRESULT(apsel), NAPPAR, TY_INT)
+
+ # Set the default values for the apsel parameters.
+ DP_APID(apsel) = NULL
+ DP_APXCEN(apsel)= NULL
+ DP_APYCEN(apsel)= NULL
+ DP_APMAG(apsel) = NULL
+ DP_APERR(apsel) = NULL
+ DP_APMSKY(apsel)= NULL
+ DP_APGROUP(apsel) = NULL
+ DP_APNITER(apsel) = NULL
+ DP_APCHI(apsel) = NULL
+ DP_APSHARP(apsel) = NULL
+end
diff --git a/noao/digiphot/daophot/daolib/dpnames.x b/noao/digiphot/daophot/daolib/dpnames.x
new file mode 100644
index 00000000..ca1fa858
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpnames.x
@@ -0,0 +1,415 @@
+
+# DP_IIMNAME -- Procedure to construct an daophot input image name.
+# If input is null or a directory a name is constructed from the root
+# of the image name and the extension. The disk is searched to avoid
+# name collisions.
+
+procedure dp_iimname (image, input, ext, name, maxch)
+
+char image[ARB] # image name
+char input[ARB] # input directory or name
+char ext[ARB] # extension
+char name[ARB] # input name
+int maxch # maximum size of name
+
+int ndir, nimdir, clindex, clsize
+pointer sp, root, str
+int fnldir(), strlen()
+
+begin
+ call smark (sp)
+ call salloc (root, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ ndir = fnldir (input, name, maxch)
+ if (strlen (input) == ndir) {
+ call imparse (image, Memc[root], SZ_FNAME, Memc[str], SZ_FNAME,
+ Memc[str], SZ_FNAME, clindex, clsize)
+ nimdir = fnldir (Memc[root], Memc[str], SZ_FNAME)
+ if (clindex >= 0) {
+ call sprintf (name[ndir+1], maxch, "%s%d.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargi (clindex)
+ call pargstr (ext)
+ } else {
+ call sprintf (name[ndir+1], maxch, "%s.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargstr (ext)
+ }
+
+ call dp_iimversion (name, name, maxch)
+ } else
+ call strcpy (input, name, maxch)
+
+ call sfree (sp)
+end
+
+
+# DP_IMROOT -- Fetch the root image name minus the directory specification
+# and the section notation.
+
+procedure dp_imroot (image, root, maxch)
+
+char image[ARB] # image specification
+char root[ARB] # output root name
+int maxch # maximum number of characters
+
+pointer sp, imroot, kernel, section, str
+int clindex, clsize, nchars
+int fnldir()
+
+begin
+ call smark (sp)
+ call salloc (imroot, SZ_PATHNAME, TY_CHAR)
+ call salloc (kernel, SZ_FNAME, TY_CHAR)
+ call salloc (section, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_PATHNAME, TY_CHAR)
+
+ call imparse (image, Memc[imroot], SZ_PATHNAME, Memc[kernel], SZ_FNAME,
+ Memc[section], SZ_FNAME, clindex, clsize)
+ nchars = fnldir (Memc[imroot], Memc[str], SZ_PATHNAME)
+ if (clindex >= 0) {
+ call sprintf (root, maxch, "%s[%d]%s%s")
+ call pargstr (Memc[imroot+nchars])
+ call pargi (clindex)
+ call pargstr (Memc[kernel])
+ call pargstr (Memc[section])
+ } else {
+ call sprintf (root, maxch, "%s%s%s")
+ call pargstr (Memc[imroot+nchars])
+ call pargstr (Memc[kernel])
+ call pargstr (Memc[section])
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_OIMVERSION -- Routine to compute the next available version number of
+# a given file name template and output the new files name.
+
+procedure dp_oimversion (template, filename, maxch)
+
+char template[ARB] # name template
+char filename[ARB] # output name
+int maxch # maximum number of characters
+
+char period
+int newversion, version, len
+pointer sp, list, name
+int imtopen(), imtgetim(), strldx(), ctoi()
+
+begin
+ # Allocate temporary space
+ call smark (sp)
+ call salloc (name, maxch, TY_CHAR)
+ period = '.'
+ list = imtopen (template)
+
+ # Loop over the names in the list searchng for the highest version.
+ newversion = 0
+ while (imtgetim (list, Memc[name], maxch) != EOF) {
+ len = strldx (period, Memc[name])
+ Memc[name+len-1] = EOS
+ len = strldx (period, Memc[name])
+ len = len + 1
+ if (ctoi (Memc[name], len, version) <= 0)
+ next
+ newversion = max (newversion, version)
+ }
+
+ # Make new output file name.
+ len = strldx (period, template)
+ call strcpy (template, filename, len)
+ call sprintf (filename[len+1], maxch, "%d")
+ call pargi (newversion + 1)
+
+ call imtclose (list)
+ call sfree (sp)
+end
+
+
+# DP_IIMVERSION -- Routine to compute the next available version number of
+# a given file name template and output the new files name.
+
+procedure dp_iimversion (template, filename, maxch)
+
+char template[ARB] # name template
+char filename[ARB] # output name
+int maxch # maximum number of characters
+
+char period
+int newversion, version, len
+pointer sp, list, name
+int imtopen(), imtgetim() strldx(), ctoi()
+
+begin
+ # Allocate temporary space
+ call smark (sp)
+ call salloc (name, maxch, TY_CHAR)
+ period = '.'
+ list = imtopen (template)
+
+ # Loop over the names in the list searchng for the highest version.
+ newversion = 0
+ while (imtgetim (list, Memc[name], maxch) != EOF) {
+ len = strldx (period, Memc[name])
+ Memc[name+len-1] = EOS
+ len = strldx (period, Memc[name])
+ len = len + 1
+ if (ctoi (Memc[name], len, version) <= 0)
+ next
+ newversion = max (newversion, version)
+ }
+
+ # Make new output file name.
+ len = strldx (period, template)
+ call strcpy (template, filename, len)
+ call sprintf (filename[len+1], maxch, "%d")
+ call pargi (newversion)
+
+ call imtclose (list)
+ call sfree (sp)
+end
+
+
+# DP_OIMNAME -- Procedure to construct an daophot output image name.
+# If output is null or a directory a name is constructed from the root
+# of the image name and the extension. The disk is searched to avoid
+# name collisions.
+
+procedure dp_oimname (image, output, ext, name, maxch)
+
+char image[ARB] # image name
+char output[ARB] # output directory or name
+char ext[ARB] # extension
+char name[ARB] # output name
+int maxch # maximum size of name
+
+int ndir, nimdir, clindex, clsize
+pointer sp, root, str
+int fnldir(), strlen()
+
+begin
+ call smark (sp)
+ call salloc (root, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ ndir = fnldir (output, name, maxch)
+ if (strlen (output) == ndir) {
+ call imparse (image, Memc[root], SZ_FNAME, Memc[str], SZ_FNAME,
+ Memc[str], SZ_FNAME, clindex, clsize)
+ nimdir = fnldir (Memc[root], Memc[str], SZ_FNAME)
+ if (clindex >= 0) {
+ call sprintf (name[ndir+1], maxch, "%s%d.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargi (clindex)
+ call pargstr (ext)
+ } else {
+ call sprintf (name[ndir+1], maxch, "%s.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargstr (ext)
+ }
+ call dp_oimversion (name, name, maxch)
+ } else
+ call strcpy (output, name, maxch)
+
+ call sfree (sp)
+end
+
+
+# DP_INNAME -- Procedure to construct an daophot input file name.
+# If input is null or a directory a name is constructed from the root
+# of the image name and the extension. The disk is searched to avoid
+# name collisions.
+
+procedure dp_inname (image, input, ext, name, maxch)
+
+char image[ARB] # image name
+char input[ARB] # input directory or name
+char ext[ARB] # extension
+char name[ARB] # input name
+int maxch # maximum size of name
+
+int ndir, nimdir, clindex, clsize
+pointer sp, root, str
+int fnldir(), strlen()
+
+begin
+ call smark (sp)
+ call salloc (root, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ ndir = fnldir (input, name, maxch)
+ if (strlen (input) == ndir) {
+ call imparse (image, Memc[root], SZ_FNAME, Memc[str], SZ_FNAME,
+ Memc[str], SZ_FNAME, clindex, clsize)
+ nimdir = fnldir (Memc[root], Memc[str], SZ_FNAME)
+ if (clindex >= 0) {
+ call sprintf (name[ndir+1], maxch, "%s%d.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargi (clindex)
+ call pargstr (ext)
+ } else {
+ call sprintf (name[ndir+1], maxch, "%s.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargstr (ext)
+ }
+ call dp_iversion (name, name, maxch)
+ } else
+ call strcpy (input, name, maxch)
+
+ call sfree (sp)
+end
+
+
+# DP_OUTNAME -- Procedure to construct an daophot output file name.
+# If output is null or a directory a name is constructed from the root
+# of the image name and the extension. The disk is searched to avoid
+# name collisions.
+
+procedure dp_outname (image, output, ext, name, maxch)
+
+char image[ARB] # image name
+char output[ARB] # output directory or name
+char ext[ARB] # extension
+char name[ARB] # output name
+int maxch # maximum size of name
+
+int ndir, nimdir, clindex, clsize
+pointer sp, root, str
+int fnldir(), strlen()
+
+begin
+ call smark (sp)
+ call salloc (root, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ ndir = fnldir (output, name, maxch)
+ if (strlen (output) == ndir) {
+ call imparse (image, Memc[root], SZ_FNAME, Memc[str], SZ_FNAME,
+ Memc[str], SZ_FNAME, clindex, clsize)
+ nimdir = fnldir (Memc[root], Memc[str], SZ_FNAME)
+ if (clindex >= 0) {
+ call sprintf (name[ndir+1], maxch, "%s%d.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargi (clindex)
+ call pargstr (ext)
+ } else {
+ call sprintf (name[ndir+1], maxch, "%s.%s.*")
+ call pargstr (Memc[root+nimdir])
+ call pargstr (ext)
+ }
+ call dp_oversion (name, name, maxch)
+ } else
+ call strcpy (output, name, maxch)
+
+ call sfree (sp)
+end
+
+
+# DP_OVERSION -- Routine to compute the next available version number of a given
+# file name template and output the new files name.
+
+procedure dp_oversion (template, filename, maxch)
+
+char template[ARB] # name template
+char filename[ARB] # output name
+int maxch # maximum number of characters
+
+char period
+int newversion, version, len
+pointer sp, list, name
+int fntgfnb() strldx(), ctoi(), fntopnb()
+
+begin
+ # Allocate temporary space
+ call smark (sp)
+ call salloc (name, maxch, TY_CHAR)
+ period = '.'
+ list = fntopnb (template, NO)
+
+ # Loop over the names in the list searchng for the highest version.
+ newversion = 0
+ while (fntgfnb (list, Memc[name], maxch) != EOF) {
+ len = strldx (period, Memc[name])
+ len = len + 1
+ if (ctoi (Memc[name], len, version) <= 0)
+ next
+ newversion = max (newversion, version)
+ }
+
+ # Make new output file name.
+ len = strldx (period, template)
+ call strcpy (template, filename, len)
+ call sprintf (filename[len+1], maxch, "%d")
+ call pargi (newversion + 1)
+
+ call fntclsb (list)
+ call sfree (sp)
+end
+
+
+# DP_IVERSION -- Routine to compute the last version number of a given
+# file name template and output the new files name.
+
+procedure dp_iversion (template, filename, maxch)
+
+char template[ARB] # name template
+char filename[ARB] # output name
+int maxch # maximum number of characters
+
+char period
+int newversion, version, len
+pointer sp, list, name
+int fntgfnb() strldx(), ctoi(), fntopnb()
+
+begin
+ # Allocate temporary space
+ call smark (sp)
+ call salloc (name, maxch, TY_CHAR)
+ period = '.'
+ list = fntopnb (template, NO)
+
+ # Loop over the names in the list searchng for the highest version.
+ newversion = 0
+ while (fntgfnb (list, Memc[name], maxch) != EOF) {
+ len = strldx (period, Memc[name])
+ len = len + 1
+ if (ctoi (Memc[name], len, version) <= 0)
+ next
+ newversion = max (newversion, version)
+ }
+
+ # Make new output file name.
+ len = strldx (period, template)
+ call strcpy (template, filename, len)
+ call sprintf (filename[len+1], maxch, "%d")
+ call pargi (newversion)
+
+ call fntclsb (list)
+ call sfree (sp)
+end
+
+
+# DP_FROOT -- Fetch the file name minus the directory specification,
+
+procedure dp_froot (filename, root, maxch)
+
+char filename[ARB] # input file name
+char root[ARB] # output root file name
+int maxch # maximum number of characters
+
+pointer sp, str
+int nchars
+int fnldir()
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_PATHNAME, TY_CHAR)
+
+ nchars = fnldir (filename, Memc[str], SZ_PATHNAME)
+ call strcpy (filename[nchars+1], root, maxch)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpotime.x b/noao/digiphot/daophot/daolib/dpotime.x
new file mode 100644
index 00000000..0c8a7925
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpotime.x
@@ -0,0 +1,51 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_OTIME -- Read the epoch of the observation from the image header.
+
+procedure dp_otime (im, dao)
+
+pointer im # pointer to IRAF image
+pointer dao # pointer to the daophot structure
+
+char timechar
+int index
+pointer sp, key, otime
+bool streq()
+int strldx()
+
+begin
+ call smark (sp)
+ call salloc (key, SZ_FNAME, TY_CHAR)
+ call salloc (otime, SZ_FNAME, TY_CHAR)
+
+ call dp_stats (dao, OBSTIME, Memc[key], SZ_FNAME)
+ Memc[otime] = EOS
+ if (Memc[key] == EOS)
+ call dp_stats (dao, OTIME, Memc[otime], SZ_FNAME)
+ else {
+ iferr {
+ call imgstr (im, Memc[key], Memc[otime], SZ_FNAME)
+ } then {
+ call dp_stats (dao, OTIME, Memc[otime], SZ_FNAME)
+ call eprintf ("Warning: Image %s Keyword: %s not found\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargstr (Memc[key])
+ }
+ }
+ if (Memc[otime] == EOS) {
+ call dp_sets (dao, OTIME, "INDEF")
+ } else if (streq ("DATE-OBS", Memc[key]) || streq ("date-obs",
+ Memc[key])) {
+ timechar = 'T'
+ index = strldx (timechar, Memc[otime])
+ if (index > 0)
+ call dp_sets (dao, OTIME, Memc[otime+index])
+ else
+ call dp_sets (dao, OTIME, "INDEF")
+ } else {
+ call dp_sets (dao, OTIME, Memc[otime])
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dppadu.x b/noao/digiphot/daophot/daolib/dppadu.x
new file mode 100644
index 00000000..b1ca7c25
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dppadu.x
@@ -0,0 +1,36 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_PADU -- Read the gain value from the image header.
+
+procedure dp_padu (im, dao)
+
+pointer im # pointer to IRAF image
+pointer dao # pointer to the daophot structure
+
+pointer sp, key
+real padu
+real imgetr(), dp_statr()
+
+begin
+ call smark (sp)
+ call salloc (key, SZ_FNAME, TY_CHAR)
+ call dp_stats (dao, CCDGAIN, Memc[key], SZ_FNAME)
+ if (Memc[key] == EOS)
+ padu = dp_statr (dao, PHOTADU)
+ else {
+ iferr {
+ padu = imgetr (im, Memc[key])
+ } then {
+ padu = dp_statr (dao, PHOTADU)
+ call eprintf ("Warning: Image %s Keyword %s not found.\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargstr (Memc[key])
+ }
+ }
+ if (IS_INDEFR(padu) || padu <= 0.0)
+ call dp_setr (dao, PHOTADU, 1.0)
+ else
+ call dp_setr (dao, PHOTADU, padu)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dppcache.x b/noao/digiphot/daophot/daolib/dppcache.x
new file mode 100644
index 00000000..81ca7a3d
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dppcache.x
@@ -0,0 +1,83 @@
+include <imhdr.h>
+include <imset.h>
+
+# DP_MEMSTAT -- Figure out if there is enough memory to cache the image
+# pixels. If it is necessary to request more memory and the memory is
+# avalilable return YES otherwise return NO.
+
+int procedure dp_memstat (cache, req_size, old_size)
+
+int cache #I cache memory ?
+int req_size #I the requested working set size in chars
+int old_size #O the original working set size in chars
+
+int cur_size, max_size
+int begmem()
+
+begin
+ # Find the default working set size.
+ cur_size = begmem (0, old_size, max_size)
+
+ # If cacheing is disabled return NO regardless of the working set size.
+ if (cache == NO)
+ return (NO)
+
+ # If the requested working set size is less than the current working
+ # set size return YES.
+ if (req_size <= cur_size)
+ return (YES)
+
+ # Reset the current working set size.
+ cur_size = begmem (req_size, old_size, max_size)
+ if (req_size <= cur_size) {
+ return (YES)
+ } else {
+ return (NO)
+ }
+end
+
+
+# DP_PCACHE -- Cache the image pixels im memory by resetting the default image
+# buffer size. If req_size is INDEF the size of the image is used to determine
+# the size of the image i/o buffers.
+
+procedure dp_pcache (im, req_size, buf_size)
+
+pointer im #I the input image point
+int req_size #I the requested working set size in chars
+int buf_size #O the new image buffer size
+
+int def_size, new_imbufsize
+int sizeof(), imstati()
+
+begin
+ # Find the default buffer size.
+ def_size = imstati (im, IM_BUFSIZE)
+
+ # Return if the image is not 2-dimensional.
+ if (IM_NDIM(im) != 2) {
+ buf_size = def_size
+ return
+ }
+
+ # Compute the new required image i/o buffer size in chars.
+ if (IS_INDEFI(req_size)) {
+ new_imbufsize = IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ } else {
+ new_imbufsize = req_size
+ }
+
+ # If the default image i/o buffer size is already bigger than
+ # the requested size do nothing.
+ if (def_size >= new_imbufsize) {
+ buf_size = def_size
+ return
+ }
+
+ # Reset the image i/o buffer.
+ call imseti (im, IM_BUFSIZE, new_imbufsize)
+ call imseti (im, IM_BUFFRAC, 0)
+ buf_size = new_imbufsize
+ return
+end
diff --git a/noao/digiphot/daophot/daolib/dpppars.x b/noao/digiphot/daophot/daolib/dpppars.x
new file mode 100644
index 00000000..e1c86f58
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpppars.x
@@ -0,0 +1,94 @@
+include "../lib/daophotdef.h"
+
+# DP_PPPARS -- Store the daophot package parameters in the pset files.
+
+procedure dp_pppars (dao)
+
+pointer dao # pointer to daophot structure
+
+pointer sp, str, fstr, dap
+bool itob()
+int dp_stati(), strlen()
+pointer clopset()
+real dp_statr()
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+ call salloc (fstr, SZ_FNAME, TY_CHAR)
+
+ # Set the package parameter text.
+ call clputb ("text", itob (dp_stati (dao, TEXT)))
+
+ # Get and set the datapars parameter sets.
+ dap = clopset ("datapars")
+
+ # Store the data dependent parameters.
+ call clppsetr (dap, "scale", dp_statr (dao, SCALE))
+ call clppsetr (dap, "fwhmpsf", dp_statr (dao, SFWHMPSF))
+ call clppsetr (dap, "datamin", dp_statr (dao, MINGDATA))
+ call clppsetr (dap, "datamax", dp_statr (dao, MAXGDATA))
+
+ # Store the noise parameters.
+ call dp_stats (dao, CCDGAIN, Memc[str], SZ_FNAME)
+ call clppset (dap, "gain", Memc[str])
+ call clppsetr (dap, "epadu", dp_statr (dao, PHOTADU))
+ call dp_stats (dao, CCDREAD, Memc[str], SZ_FNAME)
+ call clppset (dap, "ccdread", Memc[str])
+ call clppsetr (dap, "readnoise", dp_statr (dao, READNOISE))
+
+ # Store the observing parameters.
+ call dp_stats (dao, EXPTIME, Memc[str], SZ_FNAME)
+ call clppset (dap, "exposure", Memc[str])
+ call clppsetr (dap, "itime", dp_statr (dao, ITIME))
+ call dp_stats (dao, AIRMASS, Memc[str], SZ_FNAME)
+ call clppset (dap, "airmass", Memc[str])
+ call clppsetr (dap, "xairmass", dp_statr (dao, XAIRMASS))
+ call dp_stats (dao, FILTER, Memc[str], SZ_FNAME)
+ call clppset (dap, "filter", Memc[str])
+ call dp_stats (dao, IFILTER, Memc[str], SZ_FNAME)
+ call clppset (dap, "ifilter", Memc[str])
+ call dp_stats (dao, OBSTIME, Memc[str], SZ_FNAME)
+ call clppset (dap, "obstime", Memc[str])
+ call dp_stats (dao, OTIME, Memc[str], SZ_FNAME)
+ call clppset (dap, "otime", Memc[str])
+
+ # Close the datapars parameter set.
+ call clcpset (dap)
+
+ # Open the daopars parameter set.
+ dap = clopset ("daopars")
+
+ # Store the psf function parameters.
+ call dp_stats (dao, FUNCLIST, Memc[fstr], SZ_FNAME)
+ call strcpy (Memc[fstr+1], Memc[str], strlen(Memc[fstr+1]) - 1)
+ call clppset (dap, "function", Memc[str])
+ call clppseti (dap, "varorder", dp_stati (dao, VARORDER))
+ #call clppsetb (dap, "fexpand", itob (dp_stati (dao, FEXPAND)))
+ call clppseti (dap, "nclean", dp_stati (dao, NCLEAN))
+ call clppsetb (dap, "saturated", itob (dp_stati (dao, SATURATED)))
+ call clppsetr (dap, "psfrad", dp_statr (dao, SPSFRAD))
+ call clppsetr (dap, "matchrad", dp_statr (dao, SMATCHRAD))
+
+ # Store the fitting algorithm parameters.
+ call clppsetr (dap, "fitrad", dp_statr (dao, SFITRAD))
+ call clppsetr (dap, "sannulus", dp_statr (dao, SANNULUS))
+ call clppsetr (dap, "wsannulus", dp_statr (dao, SDANNULUS))
+ call clppsetr (dap, "critsnratio", dp_statr (dao, CRITSNRATIO))
+ call clppseti (dap, "maxiter", dp_stati (dao, MAXITER))
+ call clppseti (dap, "maxgroup", dp_stati (dao, MAXGROUP))
+ call clppseti (dap, "maxnstar", dp_stati (dao, MAXNSTAR))
+ call clppsetb (dap, "recenter", itob (dp_stati (dao, RECENTER)))
+ call clppsetb (dap, "fitsky", itob (dp_stati (dao, FITSKY)))
+ call clppsetb (dap, "groupsky", itob (dp_stati (dao, GROUPSKY)))
+ call clppsetr (dap, "flaterr", dp_statr (dao, FLATERR))
+ call clppsetr (dap, "proferr", dp_statr (dao, PROFERR))
+ call clppsetr (dap, "cliprange", dp_statr (dao, CLIPRANGE))
+ call clppseti (dap, "clipexp", dp_stati (dao, CLIPEXP))
+ call clppsetr (dap, "mergerad", dp_statr (dao, SMERGERAD))
+
+ # Close the daopars parameter set.
+ call clcpset (dap)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dprdnoise.x b/noao/digiphot/daophot/daolib/dprdnoise.x
new file mode 100644
index 00000000..9e4baa3c
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dprdnoise.x
@@ -0,0 +1,36 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_RDNOISE - Read the readout noise value from the image header.
+
+procedure dp_rdnoise (im, dao)
+
+pointer im # pointer to IRAF image
+pointer dao # pointer to the daophot structure
+
+pointer sp, key
+real rdnoise
+real imgetr(), dp_statr()
+
+begin
+ call smark (sp)
+ call salloc (key, SZ_FNAME, TY_CHAR)
+ call dp_stats (dao, CCDREAD, Memc[key], SZ_FNAME)
+ if (Memc[key] == EOS)
+ rdnoise = dp_statr (dao, READNOISE)
+ else {
+ iferr {
+ rdnoise = imgetr (im, Memc[key])
+ } then {
+ rdnoise = dp_statr (dao, READNOISE)
+ call eprintf ("Warning: Image %s Keyword %s not found.\n")
+ call pargstr (IM_HDRFILE(im))
+ call pargstr (Memc[key])
+ }
+ }
+ if (IS_INDEFR(rdnoise) || rdnoise <= 0.0)
+ call dp_setr (dao, READNOISE, 0.0)
+ else
+ call dp_setr (dao, READNOISE, rdnoise)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dpreadpsf.x b/noao/digiphot/daophot/daolib/dpreadpsf.x
new file mode 100644
index 00000000..77aa0b74
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpreadpsf.x
@@ -0,0 +1,138 @@
+include <error.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_READPSF -- Read in the PSF from the specified image.
+
+procedure dp_readpsf (dao, im)
+
+pointer dao # pointer to the DAOPHOT Structure
+pointer im # image descriptor
+
+int i, ival, npsfstars
+pointer sp, str, v, psffit, psflut, buf
+real scale, rval
+bool imgetb(), streq()
+int imgeti(), imgnlr(), btoi()
+real imgetr()
+errchk imgetr(), imgeti()
+
+begin
+ # Allocate working memory.
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+ call salloc (v, IM_MAXDIM, TY_LONG)
+
+ # Set up needed daophot pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Read in the function parameters.
+ call imgstr (im, "FUNCTION", Memc[str], SZ_FNAME)
+ if (streq (Memc[str], "gauss")) {
+ DP_PSFUNCTION(psffit) = FCTN_GAUSS
+ call strcpy ("gauss", DP_FUNCTION(dao), SZ_FNAME)
+ } else if (streq (Memc[str], "moffat25")) {
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT25
+ call strcpy ("moffat25", DP_FUNCTION(dao), SZ_FNAME)
+ } else if (streq (Memc[str], "penny1")) {
+ DP_PSFUNCTION(psffit) = FCTN_PENNY1
+ call strcpy ("penny1", DP_FUNCTION(dao), SZ_FNAME)
+ } else if (streq (Memc[str], "moffat15")) {
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT15
+ call strcpy ("moffat15", DP_FUNCTION(dao), SZ_FNAME)
+ } else if (streq (Memc[str], "penny2")) {
+ DP_PSFUNCTION(psffit) = FCTN_PENNY2
+ call strcpy ("penny2", DP_FUNCTION(dao), SZ_FNAME)
+ } else if (streq (Memc[str], "lorentz")) {
+ DP_PSFUNCTION(psffit) = FCTN_LORENTZ
+ call strcpy ("lorentz", DP_FUNCTION(dao), SZ_FNAME)
+ } else
+ call error (0, "Unknown PSF function in PSF image\n")
+
+ # Read in the position and brightness parameters.
+ DP_PSFX (psffit) = imgetr (im, "PSFX")
+ DP_PSFY (psffit) = imgetr (im, "PSFY")
+ DP_PSFHEIGHT(psffit) = imgetr (im, "PSFHEIGHT")
+ DP_PSFMAG (psffit) = imgetr (im, "PSFMAG")
+
+ DP_PSFNPARS(psffit) = imgeti (im, "NPARS")
+ do i = 1, DP_PSFNPARS(psffit) {
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (i)
+ Memr[DP_PSFPARS(psffit)+i-1] = imgetr (im, Memc[str])
+ }
+
+ # Get the psfradius with which the psf was made. Make sure the
+ # psf radius requested by the user is less than or equal to the
+ # stored psf radius.
+
+ iferr {
+ scale = imgetr (im, "SCALE")
+ } then {
+ DP_PSFRAD(dao) = min (DP_RPSFRAD(dao) / DP_SCALE(dao),
+ imgetr (im, "PSFRAD"))
+ DP_SPSFRAD(dao) = DP_SCALE(dao) * DP_PSFRAD(dao)
+ } else {
+ DP_PSFRAD(dao) = min (DP_RPSFRAD(dao) / DP_SCALE(dao),
+ imgetr (im, "PSFRAD") / scale)
+ DP_SPSFRAD(dao) = DP_SCALE(dao) * DP_PSFRAD(dao)
+ }
+
+ # Get the lookup table(s) parameters.
+ DP_VARORDER(dao) = imgeti (im, "VARORDER")
+ switch (DP_VARORDER(dao)) {
+ case -1:
+ DP_NVLTABLE(psffit) = 0
+ case 0:
+ DP_NVLTABLE(psffit) = 1
+ case 1:
+ DP_NVLTABLE(psffit) = 3
+ case 2:
+ DP_NVLTABLE(psffit) = 6
+ }
+ DP_FEXPAND(dao) = btoi (imgetb (im, "FEXPAND"))
+ if (DP_FEXPAND(dao) == NO)
+ DP_NFEXTABLE(psffit) = 0
+ else
+ DP_NFEXTABLE(psffit) = 5
+
+ # Read in the lookup table(s).
+ if ((DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)) <= 0) {
+ DP_PSFSIZE(psffit) = 0
+ } else {
+ DP_PSFSIZE(psffit) = IM_LEN(im,1)
+ call realloc (DP_PSFLUT(psffit), DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit) * IM_LEN(im,3), TY_REAL)
+ psflut = DP_PSFLUT (psffit)
+ call amovkl (long(1), Meml[v], IM_MAXDIM)
+ while (imgnlr (im, buf, Meml[v]) != EOF) {
+ call amovr (Memr[buf], Memr[psflut], DP_PSFSIZE(psffit))
+ psflut = psflut + DP_PSFSIZE(psffit)
+ }
+ }
+
+ # Check that the complete header can be read.
+ iferr {
+ npsfstars = imgeti (im, "NPSFSTAR")
+ call sprintf (Memc[str], SZ_FNAME, "ID%d")
+ call pargi (npsfstars)
+ ival = imgeti (im, Memc[str])
+ call sprintf (Memc[str], SZ_FNAME, "X%d")
+ call pargi (npsfstars)
+ rval = imgetr (im, Memc[str])
+ call sprintf (Memc[str], SZ_FNAME, "Y%d")
+ call pargi (npsfstars)
+ rval = imgetr (im, Memc[str])
+ call sprintf (Memc[str], SZ_FNAME, "MAG%d")
+ call pargi (npsfstars)
+ rval = imgetr (im, Memc[str])
+ } then {
+ call eprintf ("PSF image header is too long to be read in.\n")
+ call eprintf (
+ "Reset min_lenusearea environment variable and try again.")
+ call erract (EA_ERROR)
+ }
+
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/daolib/dprmwhite.x b/noao/digiphot/daophot/daolib/dprmwhite.x
new file mode 100644
index 00000000..9c61969c
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dprmwhite.x
@@ -0,0 +1,22 @@
+include <ctype.h>
+
+# DP_RMWHITE -- Remove whitespace from a string.
+
+procedure dp_rmwhite (instr, outstr, maxch)
+
+char instr[ARB] # the input string
+char outstr[ARB] # the output string, may be the same as instr
+int maxch # maximum number of characters in outstr
+
+int ip, op
+
+begin
+ op = 1
+ for (ip = 1; (instr[ip] != EOS) && (op <= maxch); ip = ip + 1) {
+ if (IS_WHITE(instr[ip]))
+ next
+ outstr[op] = instr[ip]
+ op = op + 1
+ }
+ outstr[op] = EOS
+end
diff --git a/noao/digiphot/daophot/daolib/dpset.x b/noao/digiphot/daophot/daolib/dpset.x
new file mode 100644
index 00000000..ca5b1ad4
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpset.x
@@ -0,0 +1,181 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+# DP_SETS -- Set a daophot string parameter.
+
+procedure dp_sets (dao, param, str)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+char str[ARB] # string value
+
+begin
+ switch (param) {
+ case INIMAGE:
+ call strcpy (str, DP_INIMAGE(dao), SZ_FNAME)
+ case INPHOTFILE:
+ call strcpy (str, DP_INPHOTFILE(dao), SZ_FNAME)
+ case COORDS:
+ call strcpy (str, DP_COORDS(dao), SZ_FNAME)
+ case PSFIMAGE:
+ call strcpy (str, DP_PSFIMAGE(dao), SZ_FNAME)
+ case OUTPHOTFILE:
+ call strcpy (str, DP_OUTPHOTFILE(dao), SZ_FNAME)
+ case OUTREJFILE:
+ call strcpy (str, DP_OUTREJFILE(dao), SZ_FNAME)
+ case OUTIMAGE:
+ call strcpy (str, DP_OUTIMAGE(dao), SZ_FNAME)
+ case IFILTER:
+ call strcpy (str, DP_IFILTER(dao), SZ_FNAME)
+ case OTIME:
+ call strcpy (str, DP_OTIME(dao), SZ_FNAME)
+ case CCDGAIN:
+ call strcpy (str, DP_CCDGAIN(dao), SZ_FNAME)
+ case CCDREAD:
+ call strcpy (str, DP_CCDREAD(dao), SZ_FNAME)
+ case EXPTIME:
+ call strcpy (str, DP_EXPTIME(dao), SZ_FNAME)
+ case OBSTIME:
+ call strcpy (str, DP_OBSTIME(dao), SZ_FNAME)
+ case AIRMASS:
+ call strcpy (str, DP_AIRMASS(dao), SZ_FNAME)
+ case FILTER:
+ call strcpy (str, DP_FILTER(dao), SZ_FNAME)
+ case FUNCTION:
+ call strcpy (str, DP_FUNCTION(dao), SZ_FNAME)
+ case FUNCLIST:
+ call strcpy (str, DP_FUNCLIST(dao), SZ_FNAME)
+ default:
+ call error (0, "DP_SETS: Unknown daophot string parameter")
+ }
+end
+
+
+# DP_SETI -- Set a daophot integer parameter.
+
+procedure dp_seti (dao, param, ival)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+int ival # integer value
+
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dao)
+
+ switch (param) {
+ case MW:
+ DP_MW(dao) = ival
+ case WCSIN:
+ DP_WCSIN(dao) = ival
+ case WCSOUT:
+ DP_WCSOUT(dao) = ival
+ case WCSPSF:
+ DP_WCSPSF(dao) = ival
+ case CTIN:
+ DP_CTIN(dao) = ival
+ case CTOUT:
+ DP_CTOUT(dao) = ival
+ case CTPSF:
+ DP_CTPSF(dao) = ival
+ case MAXITER:
+ DP_MAXITER(dao) = ival
+ case VERBOSE:
+ DP_VERBOSE(dao) = ival
+ case TEXT:
+ DP_TEXT(dao) = ival
+ case MAXNSTAR:
+ DP_MAXNSTAR(dao) = ival
+ case MAXGROUP:
+ DP_MAXGROUP(dao) = ival
+ case CLIPEXP:
+ DP_CLIPEXP(dao) = ival
+ case RECENTER:
+ DP_RECENTER(dao) = ival
+ case FITSKY:
+ DP_FITSKY(dao) = ival
+ case GROUPSKY:
+ DP_GROUPSKY(dao) = ival
+ case VARORDER:
+ DP_VARORDER(dao) = ival
+ case FEXPAND:
+ DP_FEXPAND(dao) = ival
+ case SATURATED:
+ DP_SATURATED(dao) = ival
+ case NCLEAN:
+ DP_NCLEAN(dao) = ival
+ case APNUM:
+ DP_APNUM(apsel) = ival
+ default:
+ call error (0, "DP_SETI: Unknown integer daophot parameter")
+ }
+end
+
+
+# DP_SETR -- Set a real daophot parameter.
+
+procedure dp_setr (dao, param, rval)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+real rval # real value
+
+begin
+ switch (param) {
+ case SCALE:
+ DP_SCALE(dao) = rval
+ case SFWHMPSF:
+ DP_SFWHMPSF(dao) = rval
+ case FWHMPSF:
+ DP_FWHMPSF(dao) = rval
+ case MAXGDATA:
+ DP_MAXGDATA(dao) = rval
+ case MINGDATA:
+ DP_MINGDATA(dao) = rval
+ case READNOISE:
+ DP_READNOISE(dao) = rval
+ case PHOTADU:
+ DP_PHOTADU(dao) = rval
+ case RPSFRAD:
+ DP_RPSFRAD(dao) = rval
+ case SPSFRAD:
+ DP_SPSFRAD(dao) = rval
+ case PSFRAD:
+ DP_PSFRAD(dao) = rval
+ case SFITRAD:
+ DP_SFITRAD(dao) = rval
+ case FITRAD:
+ DP_FITRAD(dao) = rval
+ case SMATCHRAD:
+ DP_SMATCHRAD(dao) = rval
+ case MATCHRAD:
+ DP_MATCHRAD(dao) = rval
+ case SANNULUS:
+ DP_SANNULUS(dao) = rval
+ case ANNULUS:
+ DP_ANNULUS(dao) = rval
+ case SDANNULUS:
+ DP_SDANNULUS(dao) = rval
+ case DANNULUS:
+ DP_DANNULUS(dao) = rval
+ case CRITSNRATIO:
+ DP_CRITSNRATIO(dao) = rval
+ case CLIPRANGE:
+ DP_CLIPRANGE(dao) = rval
+ case XAIRMASS:
+ DP_XAIRMASS(dao) = rval
+ case ITIME:
+ DP_ITIME(dao) = rval
+ case FLATERR:
+ DP_FLATERR(dao) = rval
+ case PROFERR:
+ DP_PROFERR(dao) = rval
+ case SMERGERAD:
+ DP_SMERGERAD(dao) = rval
+ case MERGERAD:
+ DP_MERGERAD(dao) = rval
+ default:
+ call error (0, "DP_SETR: Unknown real daophot parameter")
+ }
+end
diff --git a/noao/digiphot/daophot/daolib/dpstat.x b/noao/digiphot/daophot/daolib/dpstat.x
new file mode 100644
index 00000000..45bcf82e
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpstat.x
@@ -0,0 +1,180 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+# DP_STATS -- Fetch a daophot string parameter.
+
+procedure dp_stats (dao, param, str, maxch)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+char str[ARB] # string value
+int maxch # maximum number of characters
+
+begin
+ switch (param) {
+ case INIMAGE:
+ call strcpy (DP_INIMAGE(dao), str, maxch)
+ case INPHOTFILE:
+ call strcpy (DP_INPHOTFILE(dao), str, maxch)
+ case COORDS:
+ call strcpy (DP_COORDS(dao), str, maxch)
+ case PSFIMAGE:
+ call strcpy (DP_PSFIMAGE(dao), str, maxch)
+ case OUTPHOTFILE:
+ call strcpy (DP_OUTPHOTFILE(dao), str, maxch)
+ case OUTIMAGE:
+ call strcpy (DP_OUTIMAGE(dao), str, maxch)
+ case OUTREJFILE:
+ call strcpy (DP_OUTREJFILE(dao), str, maxch)
+ case IFILTER:
+ call strcpy (DP_IFILTER(dao), str, maxch)
+ case OTIME:
+ call strcpy (DP_OTIME(dao), str, maxch)
+ case CCDGAIN:
+ call strcpy (DP_CCDGAIN(dao), str, maxch)
+ case CCDREAD:
+ call strcpy (DP_CCDREAD(dao), str, maxch)
+ case EXPTIME:
+ call strcpy (DP_EXPTIME(dao), str, maxch)
+ case OBSTIME:
+ call strcpy (DP_OBSTIME(dao), str, maxch)
+ case FILTER:
+ call strcpy (DP_FILTER(dao), str, maxch)
+ case AIRMASS:
+ call strcpy (DP_AIRMASS(dao), str, maxch)
+ case FUNCTION:
+ call strcpy (DP_FUNCTION(dao), str, maxch)
+ case FUNCLIST:
+ call strcpy (DP_FUNCLIST(dao), str, maxch)
+ default:
+ call error (0, "DP_STATS: Unknown daophot string parameter")
+ }
+end
+
+
+# DP_STATI -- Fetch a daophot integer parameter.
+
+int procedure dp_stati (dao, param)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dao)
+
+ switch (param) {
+ case MW:
+ return (DP_MW(dao))
+ case WCSIN:
+ return (DP_WCSIN(dao))
+ case WCSOUT:
+ return (DP_WCSOUT(dao))
+ case WCSPSF:
+ return (DP_WCSPSF(dao))
+ case CTIN:
+ return (DP_CTIN(dao))
+ case CTOUT:
+ return (DP_CTOUT(dao))
+ case CTPSF:
+ return (DP_CTPSF(dao))
+ case MAXITER:
+ return (DP_MAXITER(dao))
+ case VERBOSE:
+ return (DP_VERBOSE(dao))
+ case TEXT:
+ return (DP_TEXT(dao))
+ case MAXNSTAR:
+ return (DP_MAXNSTAR(dao))
+ case MAXGROUP:
+ return (DP_MAXGROUP(dao))
+ case CLIPEXP:
+ return (DP_CLIPEXP(dao))
+ case RECENTER:
+ return (DP_RECENTER(dao))
+ case FITSKY:
+ return (DP_FITSKY(dao))
+ case GROUPSKY:
+ return (DP_GROUPSKY(dao))
+ case VARORDER:
+ return (DP_VARORDER(dao))
+ case FEXPAND:
+ return (DP_FEXPAND(dao))
+ case SATURATED:
+ return (DP_SATURATED(dao))
+ case NCLEAN:
+ return (DP_NCLEAN(dao))
+ case APNUM:
+ return (DP_APNUM(apsel))
+ default:
+ call error (0, "DP_STATI: Unknown integer daophot parameter")
+ }
+end
+
+
+# DP_STATR -- Fetch a daophot real parameter.
+
+real procedure dp_statr (dao, param)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+
+begin
+ switch (param) {
+ case SCALE:
+ return (DP_SCALE(dao))
+ case FWHMPSF:
+ return (DP_FWHMPSF(dao))
+ case SFWHMPSF:
+ return (DP_SFWHMPSF(dao))
+ case MAXGDATA:
+ return (DP_MAXGDATA(dao))
+ case MINGDATA:
+ return (DP_MINGDATA(dao))
+ case READNOISE:
+ return (DP_READNOISE(dao))
+ case PHOTADU:
+ return (DP_PHOTADU(dao))
+ case RPSFRAD:
+ return (DP_RPSFRAD(dao))
+ case SPSFRAD:
+ return (DP_SPSFRAD(dao))
+ case PSFRAD:
+ return (DP_PSFRAD(dao))
+ case SFITRAD:
+ return (DP_SFITRAD(dao))
+ case FITRAD:
+ return (DP_FITRAD(dao))
+ case SMATCHRAD:
+ return (DP_SMATCHRAD(dao))
+ case MATCHRAD:
+ return (DP_MATCHRAD(dao))
+ case SANNULUS:
+ return (DP_SANNULUS(dao))
+ case ANNULUS:
+ return (DP_ANNULUS(dao))
+ case SDANNULUS:
+ return (DP_SDANNULUS(dao))
+ case DANNULUS:
+ return (DP_DANNULUS(dao))
+ case CRITSNRATIO:
+ return (DP_CRITSNRATIO(dao))
+ case CLIPRANGE:
+ return (DP_CLIPRANGE(dao))
+ case XAIRMASS:
+ return (DP_XAIRMASS(dao))
+ case ITIME:
+ return (DP_ITIME(dao))
+ case FLATERR:
+ return (DP_FLATERR(dao))
+ case PROFERR:
+ return (DP_PROFERR(dao))
+ case SMERGERAD:
+ return (DP_SMERGERAD(dao))
+ case MERGERAD:
+ return (DP_MERGERAD(dao))
+ default:
+ call error (0, "DP_STATR: Unknown real daophot parameter")
+ }
+end
diff --git a/noao/digiphot/daophot/daolib/dpverify.x b/noao/digiphot/daophot/daolib/dpverify.x
new file mode 100644
index 00000000..dcc721ad
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpverify.x
@@ -0,0 +1,563 @@
+include "../lib/daophotdef.h"
+
+# DP_VFUNCTION -- Verify the analytic psf function.
+
+procedure dp_vfunction (dao)
+
+pointer dao # pointer to the daophot structure.
+
+int len
+pointer sp, str, pstr
+int scan(), nscan(), strlen(), dp_fctdecode(), dp_strwrd()
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+ call salloc (pstr, SZ_FNAME, TY_CHAR)
+
+ # Print the current function list.
+ len = strlen (DP_FUNCLIST(dao))
+ call strcpy (DP_FUNCLIST(dao), Memc[pstr], len - 1)
+ call printf ("Analytic psf function(s) (%s): ")
+ call pargstr (Memc[pstr+1])
+ call flush (STDOUT)
+
+ # Confirm the PSF function type.
+ if (scan() == EOF)
+ ;
+ else {
+ call gargstr (Memc[str], SZ_FNAME)
+ if (nscan () != 1)
+ ;
+ else if (dp_fctdecode (Memc[str], Memc[pstr], SZ_FNAME) <= 0)
+ ;
+ else
+ call strcpy (Memc[pstr], DP_FUNCLIST(dao), SZ_FNAME)
+ }
+
+ # Print the confirmed function list.
+ len = strlen (DP_FUNCLIST(dao))
+ call strcpy (DP_FUNCLIST(dao), Memc[pstr], len - 1)
+ call printf ( "\tAnalytic psf function(s): %d\n")
+ call pargstr (Memc[pstr+1])
+
+ # Set the function type.
+ if (dp_strwrd (1, Memc[str], SZ_FNAME, DP_FUNCLIST(dao)) <= 0)
+ call strcpy ("gauss", DP_FUNCTION(dao), SZ_FNAME)
+ else
+ call strcpy (Memc[str], DP_FUNCTION(dao), SZ_FNAME)
+
+ call sfree (sp)
+end
+
+
+# DP_VVARORDER -- Verify the order of variability of the psf function.
+
+procedure dp_vvarorder (dao)
+
+pointer dao # pointer to the daophot structure.
+
+int varorder
+int scan(), nscan()
+
+begin
+ # Confirm that the psf is variable.
+ call printf ("Order of variable psf (%d): ")
+ call pargi (DP_VARORDER(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ varorder = DP_VARORDER(dao)
+ else {
+ call gargi (varorder)
+ if (nscan () != 1)
+ varorder = DP_VARORDER(dao)
+ else if (varorder < -1 || varorder > 2)
+ varorder = DP_VARORDER(dao)
+ }
+ DP_VARORDER(dao) = varorder
+ call printf ( "\tOrder of variable psf: %d\n")
+ call pargi (varorder)
+end
+
+
+# DP_VFEXPAND -- Verify whether or not to expand the analytics function.
+
+procedure dp_vfexpand (dao)
+
+pointer dao # pointer to the daophot structure.
+
+bool fexpand
+bool itob()
+int scan(), nscan(), btoi()
+
+begin
+ # Confirm whether of not to expand the analytic function.
+ call printf ("Expand the analytic function (%b): ")
+ call pargb (itob (DP_FEXPAND(dao)))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ fexpand = itob (DP_FEXPAND(dao))
+ else {
+ call gargb (fexpand)
+ if (nscan () != 1)
+ fexpand = itob (DP_FEXPAND(dao))
+ }
+ DP_FEXPAND(dao) = btoi (fexpand)
+ call printf ( "\tExpand analytic fucntion: %b\n")
+ call pargb (fexpand)
+end
+
+
+# DP_VSATURATED -- Verify whether or not to use saturated stars in the
+# psf computation.
+
+procedure dp_vsaturated (dao)
+
+pointer dao # pointer to the daophot structure.
+
+bool saturated
+bool itob()
+int scan(), nscan(), btoi()
+
+begin
+ # Confirm whether of not to use saturated psf stars.
+ call printf ("Use saturated psf stars (%b): ")
+ call pargb (itob (DP_SATURATED(dao)))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ saturated = itob (DP_SATURATED(dao))
+ else {
+ call gargb (saturated)
+ if (nscan () != 1)
+ saturated = itob (DP_SATURATED(dao))
+ }
+ DP_SATURATED(dao) = btoi (saturated)
+ call printf ( "\tUse saturated psf stars: %b\n")
+ call pargb (saturated)
+end
+
+
+# DP_VFWHMPSF -- Confirm the fwhm of the psf.
+
+procedure dp_vfwhmpsf (dao)
+
+pointer dao # pointer to the daophot structure
+
+real sfwhmpsf, fwhmpsf
+int scan(), nscan()
+
+begin
+ # Confirm the psf radius.
+ call printf ( "Fwhm of psf in scale units (%g): ")
+ call pargr (DP_SFWHMPSF(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ sfwhmpsf = DP_SFWHMPSF(dao)
+ else {
+ call gargr (sfwhmpsf)
+ if (nscan () != 1)
+ sfwhmpsf = DP_SFWHMPSF(dao)
+ }
+ fwhmpsf = sfwhmpsf / DP_SCALE(dao)
+
+ DP_SFWHMPSF(dao) = sfwhmpsf
+ DP_FWHMPSF(dao) = fwhmpsf
+
+ call printf ( "\tNew fwhm: %g scale units %g pixels\n")
+ call pargr (sfwhmpsf)
+ call pargr (fwhmpsf)
+end
+
+
+# DP_VPSFRAD -- Confirm the psf radius.
+
+procedure dp_vpsfrad (dao)
+
+pointer dao # pointer to the daophot structure
+
+real rpsfrad, psfrad
+int scan(), nscan()
+
+begin
+ # Confirm the psf radius.
+ call printf ( "Psf radius in scale units (%g): ")
+ call pargr (DP_RPSFRAD(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ rpsfrad = DP_RPSFRAD(dao)
+ else {
+ call gargr (rpsfrad)
+ if (nscan () != 1)
+ rpsfrad = DP_RPSFRAD(dao)
+ }
+ psfrad = rpsfrad / DP_SCALE(dao)
+
+ DP_RPSFRAD(dao) = rpsfrad
+ DP_SPSFRAD(dao) = rpsfrad
+ DP_PSFRAD(dao) = psfrad
+
+ call printf ( "\tNew psf radius: %g scale units %g pixels\n")
+ call pargr (rpsfrad)
+ call pargr (psfrad)
+end
+
+
+# DP_VFITRAD -- Confirm the fitting radius.
+
+procedure dp_vfitrad (dao)
+
+pointer dao # pointer to the daophot structures
+
+real sfitrad, fitrad
+int scan(), nscan()
+
+begin
+ # Confirm the fitting radius.
+ call printf ( "Fitting radius in scale units (%g): ")
+ call pargr (DP_SFITRAD(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ sfitrad = DP_SFITRAD(dao)
+ else {
+ call gargr (sfitrad)
+ if (nscan () != 1)
+ sfitrad = DP_SFITRAD(dao)
+ }
+ fitrad = sfitrad / DP_SCALE(dao)
+
+ DP_SFITRAD(dao) = sfitrad
+ DP_FITRAD(dao) = fitrad
+
+ call printf ( "\tNew fitting radius: %g scale units %g pixels\n")
+ call pargr (sfitrad)
+ call pargr (fitrad)
+end
+
+
+# DP_VMATCHRAD -- Confirm the matching radius.
+
+procedure dp_vmatchrad (dao)
+
+pointer dao # pointer to the daophot structure
+
+real smatchrad, matchrad
+int scan(), nscan()
+
+begin
+ # Confirm the matching radius.
+ call printf ( "Matching radius in scale units (%g): ")
+ call pargr (DP_SMATCHRAD(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ smatchrad = DP_SMATCHRAD(dao)
+ else {
+ call gargr (smatchrad)
+ if (nscan () != 1)
+ smatchrad = DP_SMATCHRAD(dao)
+ }
+ matchrad = smatchrad / DP_SCALE(dao)
+
+ DP_SMATCHRAD(dao) = smatchrad
+ DP_MATCHRAD(dao) = matchrad
+
+ call printf ( "\tNew matching radius: %g scale units %g pixels\n")
+ call pargr (smatchrad)
+ call pargr (matchrad)
+end
+
+
+# DP_VMERGERAD -- Confirm the merging radius.
+
+procedure dp_vmergerad (dao)
+
+pointer dao # pointer to the daophot structure
+
+real smergerad, mergerad
+int scan(), nscan()
+
+begin
+ # Confirm the merging radius.
+ call printf ( "Merging radius in scale units (%g): ")
+ call pargr (DP_SMERGERAD(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ smergerad = DP_SMERGERAD(dao)
+ else {
+ call gargr (smergerad)
+ if (nscan () != 1)
+ smergerad = DP_SMERGERAD(dao)
+ }
+ if (IS_INDEFR(smergerad))
+ mergerad = INDEFR
+ else
+ mergerad = smergerad / DP_SCALE(dao)
+
+ DP_SMERGERAD(dao) = smergerad
+ DP_MERGERAD(dao) = mergerad
+
+ call printf ( "\tNew merging radius: %g scale units %g pixels\n")
+ call pargr (smergerad)
+ call pargr (mergerad)
+end
+
+
+# DP_VFITRAD -- Confirm the fitting radius.
+
+
+# DP_VDATAMIN-- Verify the minimum good data value.
+
+procedure dp_vdatamin (dao)
+
+pointer dao # pointer to the daophot structure
+
+real datamin
+int scan(), nscan()
+
+begin
+ # Confirm the threshold parameter.
+ call printf ("Minimum good data value (%g) (CR or value): ")
+ call pargr (DP_MINGDATA(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ datamin = DP_MINGDATA(dao)
+ else {
+ call gargr (datamin)
+ if (nscan () != 1)
+ datamin = DP_MINGDATA(dao)
+ }
+ DP_MINGDATA(dao) = datamin
+
+ call printf ("\tNew minimum good data value: %g counts\n")
+ call pargr (datamin)
+end
+
+
+# DP_VDATAMAX-- Verify the maximum good data value.
+
+procedure dp_vdatamax (dao)
+
+pointer dao # pointer to the daophot structure
+
+real datamax
+int scan(), nscan()
+
+begin
+ # Confirm the threshold parameter.
+ call printf ("Maximum good data value (%g) (CR or value): ")
+ call pargr (DP_MAXGDATA(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ datamax = DP_MAXGDATA(dao)
+ else {
+ call gargr (datamax)
+ if (nscan () != 1)
+ datamax = DP_MAXGDATA(dao)
+ }
+ DP_MAXGDATA(dao) = datamax
+
+ call printf ("\tNew maximum good data value: %g counts\n")
+ call pargr (datamax)
+end
+
+
+# DP_VMAXGROUP -- Verify the maximum group size.
+
+procedure dp_vmaxgroup (dao)
+
+pointer dao # pointer to the daophot strucuture
+
+int maxgroup
+int scan(), nscan()
+
+begin
+ call printf ( "Maximum group size in number of stars (%d): ")
+ call pargi (DP_MAXGROUP(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ maxgroup = DP_MAXGROUP(dao)
+ else {
+ call gargi (maxgroup)
+ if (nscan () != 1)
+ maxgroup = DP_MAXGROUP(dao)
+ }
+ DP_MAXGROUP(dao) = maxgroup
+
+ call printf ( "\tNew maximum group size: %d stars\n")
+ call pargi (maxgroup)
+end
+
+
+# DP_VCRITSNRATIO -- Verify the critical signal-to-noise ratio.
+
+procedure dp_vcritnsratio (dao)
+
+pointer dao # pointer to the daophot structure
+
+real critsnratio
+int scan(), nscan()
+
+begin
+ # Confirm the critical signal-to-noise ratio.
+ call printf ( "Critical S/N ratio in stdevs per pixel (%g): ")
+ call pargr (DP_CRITSNRATIO(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ critsnratio = DP_CRITSNRATIO(dao)
+ else {
+ call gargr (critsnratio)
+ if (nscan () != 1)
+ critsnratio = DP_CRITSNRATIO(dao)
+ }
+ DP_CRITSNRATIO(dao) = critsnratio
+
+ call printf ( "\tNew critical S/N ratio: %g stdevs per pixel\n")
+ call pargr (critsnratio)
+end
+
+
+# DP_VRECENTER -- Verify whether or not to recenter the stars.
+
+procedure dp_vrecenter (dao)
+
+pointer dao # pointer to the daophot structure.
+
+bool recenter
+bool itob()
+int scan(), nscan(), btoi()
+
+begin
+ # Confirm whether of not to recenter the stars.
+ call printf ("Recenter the stars (%b): ")
+ call pargb (itob (DP_RECENTER(dao)))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ recenter = itob (DP_RECENTER(dao))
+ else {
+ call gargb (recenter)
+ if (nscan () != 1)
+ recenter = itob (DP_RECENTER(dao))
+ }
+ DP_RECENTER(dao) = btoi (recenter)
+ call printf ( "\tRecenter the stars: %b\n")
+ call pargb (recenter)
+end
+
+
+# DP_VFITSKY -- Verify whether or not to refit the sky value.
+
+procedure dp_vfitsky (dao)
+
+pointer dao # pointer to the daophot structure.
+
+bool fitsky
+bool itob()
+int scan(), nscan(), btoi()
+
+begin
+ # Confirm whether of not to refit the sky.
+ call printf ("Refit the sky (%b): ")
+ call pargb (itob (DP_FITSKY(dao)))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ fitsky = itob (DP_FITSKY(dao))
+ else {
+ call gargb (fitsky)
+ if (nscan () != 1)
+ fitsky = itob (DP_FITSKY(dao))
+ }
+ DP_FITSKY(dao) = btoi (fitsky)
+ call printf ( "\tRefit the sky: %b\n")
+ call pargb (fitsky)
+end
+
+
+# DP_VGROUPSKY -- Verify whether or not to fit group sky values.
+
+procedure dp_vgroupsky (dao)
+
+pointer dao # pointer to the daophot structure
+
+bool groupsky
+bool itob()
+int scan(), nscan(), btoi()
+
+begin
+ # Confirm whether of not to use group sky values.
+ call printf ("Use group sky values (%b): ")
+ call pargb (itob (DP_GROUPSKY(dao)))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ groupsky = itob (DP_GROUPSKY(dao))
+ else {
+ call gargb (groupsky)
+ if (nscan () != 1)
+ groupsky = itob (DP_GROUPSKY(dao))
+ }
+ DP_GROUPSKY(dao) = btoi (groupsky)
+ call printf ( "\tUse group sky values: %b\n")
+ call pargb (groupsky)
+end
+
+
+# DP_VSANNULUS -- Confirm the inner radius of the sky fitting annulus.
+
+procedure dp_vsannulus (dao)
+
+pointer dao # pointer to the daophot structure
+
+real sannulus, annulus
+int scan(), nscan()
+
+begin
+ # Confirm the inner radius of the sky annulus.
+ call printf ( "Inner radius of sky annulus in scale units (%g): ")
+ call pargr (DP_SANNULUS(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ sannulus = DP_SANNULUS(dao)
+ else {
+ call gargr (sannulus)
+ if (nscan () != 1)
+ sannulus = DP_SANNULUS(dao)
+ }
+ annulus = sannulus / DP_SCALE(dao)
+
+ DP_SANNULUS(dao) = sannulus
+ DP_ANNULUS(dao) = annulus
+
+ call printf ( "\tNew inner radius: %g scale units %g pixels\n")
+ call pargr (sannulus)
+ call pargr (annulus)
+end
+
+
+# DP_VWSANNULUS -- Confirm the width of the sky fitting annulus.
+
+procedure dp_vwsannulus (dao)
+
+pointer dao # pointer to the daophot structure
+
+real sdannulus, dannulus
+int scan(), nscan()
+
+begin
+ # Confirm the inner radius of the sky annulus.
+ call printf ( "Width of sky annulus in scale units (%g): ")
+ call pargr (DP_SDANNULUS(dao))
+ call flush (STDOUT)
+ if (scan() == EOF)
+ sdannulus = DP_SDANNULUS(dao)
+ else {
+ call gargr (sdannulus)
+ if (nscan () != 1)
+ sdannulus = DP_SDANNULUS(dao)
+ }
+ dannulus = sdannulus / DP_SCALE(dao)
+
+ DP_SDANNULUS(dao) = sdannulus
+ DP_DANNULUS(dao) = dannulus
+
+ call printf ( "\tNew annulus width: %g scale units %g pixels\n")
+ call pargr (sdannulus)
+ call pargr (dannulus)
+end
diff --git a/noao/digiphot/daophot/daolib/dpwcs.x b/noao/digiphot/daophot/daolib/dpwcs.x
new file mode 100644
index 00000000..9961b933
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpwcs.x
@@ -0,0 +1,234 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imio.h>
+include "../lib/daophotdef.h"
+
+# DP_WIN -- Convert the input coordinates to logical coordinates.
+
+procedure dp_win (dp, im, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+pointer im # the input image descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+int dp_stati()
+
+begin
+ # Transform the input coordinates.
+ switch (dp_stati (dp, WCSIN)) {
+ case WCS_WORLD, WCS_PHYSICAL:
+ call dp_itol (dp, xin, yin, xout, yout, npts)
+ case WCS_TV:
+ call dp_vtol (im, xin, yin, xout, yout, npts)
+ default:
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ }
+end
+
+
+# DP_WOUT -- Convert the logical coordinates to output coordinates.
+
+procedure dp_wout (dp, im, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+pointer im # the input image descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+int dp_stati()
+
+begin
+ # Transform the input coordinates.
+ switch (dp_stati (dp, WCSOUT)) {
+ case WCS_WORLD, WCS_PHYSICAL:
+ call dp_ltoo (dp, xin, yin, xout, yout, npts)
+ case WCS_TV:
+ call dp_ltov (im, xin, yin, xout, yout, npts)
+ default:
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ }
+end
+
+
+# DP_WPSF -- Convert the logical coordinates to psf coordinates.
+
+procedure dp_wpsf (dp, im, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+pointer im # the input image descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+int dp_stati()
+
+begin
+ # Transform the input coordinates.
+ switch (dp_stati (dp, WCSPSF)) {
+ case WCS_WORLD, WCS_PHYSICAL:
+ call dp_ltop (dp, xin, yin, xout, yout, npts)
+ case WCS_TV:
+ call dp_ltov (im, xin, yin, xout, yout, npts)
+ default:
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ }
+end
+
+
+# DP_ITOL -- Convert coordinates from the input coordinate system to the
+# logical coordinate system.
+
+procedure dp_itol (dp, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+double xt, yt
+pointer ct
+int i
+int dp_stati()
+
+begin
+ ct = dp_stati (dp, CTIN)
+ if (ct == NULL) {
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ return
+ }
+
+ do i = 1, npts {
+ call mw_c2trand (ct, double (xin[i]), double (yin[i]), xt, yt)
+ xout[i] = xt
+ yout[i] = yt
+ }
+end
+
+
+# DP_LTOO -- Convert coordinates from the logical coordinate system to the
+# output coordinate system.
+
+procedure dp_ltoo (dp, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+double xt, yt
+pointer ct
+int i
+int dp_stati()
+
+begin
+ ct = dp_stati (dp, CTOUT)
+ if (ct == NULL) {
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ return
+ }
+
+ do i = 1, npts {
+ call mw_c2trand (ct, double (xin[i]), double (yin[i]), xt, yt)
+ xout[i] = xt
+ yout[i] = yt
+ }
+end
+
+
+# DP_LTOP -- Convert coordinates from the logical coordinate system to the
+# output coordinate system.
+
+procedure dp_ltop (dp, xin, yin, xout, yout, npts)
+
+pointer dp # the apphot package descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+double xt, yt
+pointer ct
+int i
+int dp_stati()
+
+begin
+ ct = dp_stati (dp, CTPSF)
+ if (ct == NULL) {
+ call amovr (xin, xout, npts)
+ call amovr (yin, yout, npts)
+ return
+ }
+
+ do i = 1, npts {
+ call mw_c2trand (ct, double (xin[i]), double (yin[i]), xt, yt)
+ xout[i] = xt
+ yout[i] = yt
+ }
+end
+
+
+# DP_LTOV -- Convert coordinate from the logical coordinate system to the
+# output coordinate system.
+
+procedure dp_ltov (im, xin, yin, xout, yout, npts)
+
+pointer im # the input image descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+int i, index1, index2
+
+begin
+ index1 = IM_VMAP(im,1)
+ index2 = IM_VMAP(im,2)
+ do i = 1, npts {
+ xout[i] = xin[i] * IM_VSTEP(im,index1) + IM_VOFF(im,index1)
+ yout[i] = yin[i] * IM_VSTEP(im,index2) + IM_VOFF(im,index2)
+ }
+end
+
+
+# DP_VTOL -- Convert coordinate from the tv coordinate system to the
+# logical coordinate system.
+
+procedure dp_vtol (im, xin, yin, xout, yout, npts)
+
+pointer im # the input image descriptor
+real xin[ARB] # the input x coordinate
+real yin[ARB] # the input y coordinate
+real xout[ARB] # the output x coordinate
+real yout[ARB] # the output y coordinate
+int npts # the number of coordinates to convert
+
+int i, index1, index2
+
+begin
+ index1 = IM_VMAP(im,1)
+ index2 = IM_VMAP(im,2)
+ do i = 1, npts {
+ xout[i] = (xin[i] - IM_VOFF(im,index1)) / IM_VSTEP(im,index1)
+ yout[i] = (yin[i] - IM_VOFF(im,index2)) / IM_VSTEP(im,index2)
+ }
+end
diff --git a/noao/digiphot/daophot/daolib/dpwparam.x b/noao/digiphot/daophot/daolib/dpwparam.x
new file mode 100644
index 00000000..6e122dee
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/dpwparam.x
@@ -0,0 +1,98 @@
+# DP_RPARAM -- Encode a daophot real parameter.
+
+procedure dp_rparam (out, keyword, value, units, comments)
+
+int out # output file descriptor
+char keyword[ARB] # keyword string
+real value # parameter value
+char units[ARB] # units string
+char comments[ARB] # comment string
+
+begin
+ if (out == NULL)
+ return
+
+ call strupr (keyword)
+ call fprintf (out,
+ "#K%4t%-10.10s%14t = %17t%-23.7g%41t%-10.10s%52t%-10s\n")
+ call pargstr (keyword)
+ call pargr (value)
+ call pargstr (units)
+ call pargstr ("%-23.7g")
+ call pargstr (comments)
+end
+
+
+# DP_IPARAM -- Encode a daophot integer parameter.
+
+procedure dp_iparam (out, keyword, value, units, comments)
+
+int out # output file descriptor
+char keyword[ARB] # keyword string
+int value # parameter value
+char units[ARB] # units string
+char comments[ARB] # comment string
+
+begin
+ if (out == NULL)
+ return
+
+ call strupr (keyword)
+ call fprintf (out,
+ "#K%4t%-10.10s%14t = %17t%-23d%41t%-10.10s%52t%-10s\n")
+ call pargstr (keyword)
+ call pargi (value)
+ call pargstr (units)
+ call pargstr ("%-23d")
+ call pargstr (comments)
+end
+
+
+# DP_BPARAM -- Encode a daophot boolean parameter.
+
+procedure dp_bparam (out, keyword, value, units, comments)
+
+int out # output file descriptor
+char keyword[ARB] # keyword string
+bool value # parameter value
+char units[ARB] # units string
+char comments[ARB] # comment string
+
+begin
+ if (out == NULL)
+ return
+
+ call strupr (keyword)
+ call fprintf (out,
+ "#K%4t%-10.10s%14t = %17t%-23b%41t%-10.10s%52t%-10s\n")
+ call pargstr (keyword)
+ call pargb (value)
+ call pargstr (units)
+ call pargstr ("%-23b")
+ call pargstr (comments)
+end
+
+
+# DP_SPARAM -- Encode a daophot string parameter.
+
+procedure dp_sparam (out, keyword, value, units, comments)
+
+int out # output file descriptor
+char keyword[ARB] # keyword string
+char value[ARB] # parameter value
+char units[ARB] # units string
+char comments[ARB] # comment string
+
+begin
+ if (out == NULL)
+ return
+
+ call strupr (keyword)
+ call fprintf (out,
+ "#K%4t%-10.10s%14t = %17t%-23.23s%41t%-10.10s%52t%-10s\n")
+ call pargstr (keyword)
+ call pargstr (value)
+ call pargstr (units)
+ call pargstr ("%-23s")
+ call pargstr (comments)
+end
diff --git a/noao/digiphot/daophot/daolib/erf.x b/noao/digiphot/daophot/daolib/erf.x
new file mode 100644
index 00000000..d8a48f50
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/erf.x
@@ -0,0 +1,81 @@
+define NGL 4
+
+# DAOERF -- Numerically integrate a Gaussian function from xin-0.5 to xin+0.5
+# using 4 point Gauss-Legendre integration. Beta is the half-width at
+# half-maximum which is equal to 1.17741 * sigma. The Gaussian function is
+# shown below.
+#
+# erf = exp (-0.5 *((x - x0) / beta) ** 2))
+#
+# or
+#
+# erf = exp (-0.6931472 * [(x - xo) / beta] ** 2)
+#
+# Also provide the first derivative of the integral with respect to xo and beta.
+
+real procedure daoerf (xin, x0, beta, dfdx0, dfdbet)
+
+real xin # the input value
+real x0 # position of Gaussian peak
+real beta # sigma of the Gaussian
+real dfdx0 # derivative of Gaussian wrt x0
+real dfdbet # derivative of Gaussian wrt beta
+
+int i, npt
+real betasq, deltax, erfval, xsq, f, x, wf
+real dx[NGL,NGL], wt[NGL,NGL]
+data dx / 0.0, 0.0, 0.0, 0.0,
+ -0.28867513, 0.28867513, 0.0, 0.0,
+ -0.38729833, 0.0, 0.38729833, 0.0,
+ -0.43056816, -0.16999052, 0.16999052, 0.43056816 /
+data wt / 1.0, 0.0, 0.0, 0.0,
+ 0.5, 0.5, 0.0, 0.0,
+ 0.27777778, 0.44444444, 0.27777778, 0.0,
+ 0.17392742, 0.32607258, 0.32607258, 0.17392742 /
+
+begin
+ # Compute some constants.
+ betasq = beta ** 2
+ deltax = xin - x0
+
+ # Initialize.
+ erfval = 0.0
+ dfdx0 = 0.0
+ dfdbet = 0.0
+
+ xsq = deltax ** 2
+ f = xsq / betasq
+ if (f > 34.0)
+ return (erfval)
+
+ f = exp (-0.6931472 * f)
+ if (f >= 0.046) {
+ npt = 4
+ } else if (f >= 0.0022) {
+ npt = 3
+ } else if (f >= 0.0001) {
+ npt = 2
+ } else if (f >= 1.0e-10) {
+ erfval = f
+ dfdx0 = 1.3862944 * deltax * f / betasq
+ dfdbet = 1.3862944 * xsq * f / (betasq * beta)
+ return (erfval)
+ } else {
+ return (erfval)
+ }
+
+ do i = 1, npt {
+ x = deltax + dx[i,npt]
+ xsq = x ** 2
+ f = exp (-0.6931472 * xsq / betasq)
+ wf = wt[i,npt] * f
+ erfval = erfval + wf
+ dfdx0 = dfdx0 + x * wf
+ dfdbet = dfdbet + xsq * wf
+ }
+
+ dfdx0 = 1.3862944 * dfdx0 / betasq
+ dfdbet = 1.3862944 * dfdbet / (betasq * beta)
+
+ return (erfval)
+end
diff --git a/noao/digiphot/daophot/daolib/invers.f b/noao/digiphot/daophot/daolib/invers.f
new file mode 100644
index 00000000..97d9b582
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/invers.f
@@ -0,0 +1,112 @@
+c subroutine invers (a, max, n, iflag)
+c
+c Although it seems counter-intuitive, the tests that I have run
+c so far suggest that the 180 x 180 matrices that NSTAR needs can
+c be inverted with sufficient accuracy if the elements are REAL*4
+c rather than REAL*8.
+c
+c Arguments
+c
+c a (input/output) is a square matrix of dimension N. The inverse
+c of the input matrix A is returned in A.
+c
+c max (input) is the size assigned to the matrix A in the calling
+c routine. It is needed for the dimension statement below.
+c
+c iflag (output) is an error flag. iflag = 1 if the matrix could not
+c be inverted; iflag = 0 if it could.
+c
+ subroutine invers (a, max, n, iflag)
+c
+ implicit none
+ integer max, n, iflag
+ real a(max,max)
+ integer i, j, k
+c
+ iflag = 0
+ i = 1
+ 300 if (a(i,i) .eq. 0.0e0) go to 9100
+ a(i,i) = 1.0e0 / a(i,i)
+ j = 1
+ 301 if (j .eq. i) go to 304
+ a(j,i) = -a(j,i) * a(i,i)
+ k = 1
+ 302 if (k .eq. i) go to 303
+ a(j,k) = a(j,k) + a(j,i) * a(i,k)
+ 303 if (k .eq. n) go to 304
+ k = k + 1
+ go to 302
+ 304 if (j .eq. n) go to 305
+ j = j + 1
+ go to 301
+ 305 k = 1
+ 306 if (k .eq. i) go to 307
+ a(i,k) = a(i,k) * a(i,i)
+ 307 if (k .eq. n) go to 308
+ k = k + 1
+ go to 306
+ 308 if (i .eq. n) return
+ i = i+1
+ go to 300
+c
+c Error: zero on the diagonal.
+c
+ 9100 iflag = 1
+ return
+c
+ end
+c
+c
+c
+c subroutine dinvers (a, max, n, iflag)
+c
+c Arguments
+c
+c a (input/output) is a square matrix of dimension N. The inverse
+c of the input matrix A is returned in A.
+c
+c max (input) is the size assigned to the matrix A in the calling
+c routine. It's needed for the dimension statement below.
+c
+c iflag (output) is an error flag. iflag = 1 if the matrix could not
+c be inverted; iflag = 0 if it could.
+c
+ subroutine dinvers (a, max, n, iflag)
+c
+ implicit none
+ integer max, n, iflag
+ double precision a(max,max)
+ integer i, j, k
+c
+ iflag = 0
+ i = 1
+ 300 if (a(i,i) .eq. 0.0e0) go to 9100
+ a(i,i) = 1.0e0 / a(i,i)
+ j = 1
+ 301 if (j .eq. i) go to 304
+ a(j,i) = -a(j,i) * a(i,i)
+ k = 1
+ 302 if (k .EQ. i) go to 303
+ a(j,k) = a(j,k) + a(j,i) * a(i,k)
+ 303 if (k .eq. n) go to 304
+ k = k + 1
+ go to 302
+ 304 if (j .eq. n) go to 305
+ j = j + 1
+ go to 301
+ 305 k = 1
+ 306 if (k .eq. i) go to 307
+ a(i,k) = a(i,k) * a(i,i)
+ 307 if (k .eq. n) go to 308
+ k = k + 1
+ go to 306
+ 308 if (i .eq. n) return
+ i = i+1
+ go to 300
+c
+c Error: zero on the diagonal.
+c
+ 9100 iflag = 1
+ return
+c
+ end
diff --git a/noao/digiphot/daophot/daolib/invers2.x b/noao/digiphot/daophot/daolib/invers2.x
new file mode 100644
index 00000000..5393c6ea
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/invers2.x
@@ -0,0 +1,72 @@
+define TINY (1.0e-15)
+
+# INVERS
+#
+# Although it seems counter-intuitive, the tests that I have run
+# so far suggest that the 180 x 180 matrices that NSTAR needs can
+# be inverted with sufficient accuracy if the elements are REAL*4
+# rather than REAL*8.
+#
+# Arguments
+#
+# a (input/output) is a square matrix of dimension N. The inverse
+# of the input matrix A is returned in A.
+#
+# nmax (input) is the size assigned to the matrix A in the calling
+# routine. It is needed for the dimension statement below.
+#
+# iflag (output) is an error flag. iflag = 1 if the matrix could not
+# be inverted; iflag = 0 if it could.
+#
+# This is an SPP translation of the original fortran version with the
+# addition of a check for tiny numbers which could cause an FPE.
+
+procedure invers2 (a, nmax, n, iflag)
+
+real a[nmax,nmax]
+int nmax
+int n
+int iflag
+
+int i, j, k
+
+begin
+ # Check for tiny numbers.
+ do i = 1, n
+ do j = 1, n
+ if (abs (a[i,j]) < TINY)
+ a[i,j] = 0e0
+
+ # Original code.
+ iflag = 0
+ i = 1
+ 30 if (a[i,i] .eq. 0.0e0) goto 91
+ a[i,i] = 1.0e0 / a[i,i]
+ j = 1
+ 31 if (j .eq. i) goto 34
+ a[j,i] = -a[j,i] * a[i,i]
+ k = 1
+ 32 if (k .eq. i) goto 33
+ a[j,k] = a[j,k] + a[j,i] * a[i,k]
+ 33 if (k .eq. n) goto 34
+ k = k + 1
+ goto 32
+ 34 if (j .eq. n) goto 35
+ j = j + 1
+ goto 31
+ 35 k = 1
+ 36 if (k .eq. i) goto 37
+ a[i,k] = a[i,k] * a[i,i]
+ 37 if (k .eq. n) goto 38
+ k = k + 1
+ goto 36
+ 38 if (i .eq. n) return
+ i = i+1
+ goto 30
+
+# Error: zero on the diagonal.
+
+ 91 iflag = 1
+ return
+
+end
diff --git a/noao/digiphot/daophot/daolib/mkpkg b/noao/digiphot/daophot/daolib/mkpkg
new file mode 100644
index 00000000..44253943
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/mkpkg
@@ -0,0 +1,48 @@
+# DAOPHOT Library Tools
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpairmass.x <imhdr.h> ../lib/daophotdef.h
+ dpapheader.x
+ dpfilter.x <imhdr.h> ../lib/daophotdef.h
+ dpfree.x ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/allstardef.h
+ dpgetapert.x ../lib/apseldef.h ../lib/daophotdef.h \
+ <tbset.h> ../../lib/ptkeysdef.h
+ dpgppars.x <ctotok.h> ../lib/daophotdef.h
+ dpgsvw.x <imio.h> <imhdr.h> \
+ <math.h>
+ dpppars.x ../lib/daophotdef.h
+ dpimkeys.x ../lib/daophotdef.h
+ dpinit.x ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/allstardef.h
+ dpreadpsf.x <imhdr.h> ../lib/daophotdef.h \
+ <error.h>
+ dpset.x ../lib/daophotdef.h ../lib/apseldef.h
+ dpstat.x ../lib/daophotdef.h ../lib/apseldef.h
+ dpdate.x <time.h>
+ dpgsubrast.x <imhdr.h>
+ dpnames.x
+ dpotime.x <imhdr.h> ../lib/daophotdef.h
+ dppadu.x <imhdr.h> ../lib/daophotdef.h
+ dppcache.x <imhdr.h> <imset.h>
+ dprdnoise.x <imhdr.h> ../lib/daophotdef.h
+ dprmwhite.x <ctype.h>
+ dpverify.x ../lib/daophotdef.h
+ dpwparam.x
+ dpwcs.x <imio.h> ../lib/daophotdef.h
+ bicubic.x
+ daoran.x
+ erf.x
+ invers.f
+ invers2.x
+ mvmul.x
+ quick.f
+ pctile.f
+ profile.x ../lib/daophotdef.h
+ usepsf.x ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/daolib/mvmul.x b/noao/digiphot/daophot/daolib/mvmul.x
new file mode 100644
index 00000000..352def99
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/mvmul.x
@@ -0,0 +1,48 @@
+# MVMUL -- Multply a matrix (left-hand side) by a one dimensional vector
+# (right-hand side) and return the resultant vector.
+
+procedure mvmul (matrix, maxdim, dim, vector, result)
+
+real matrix [maxdim, maxdim] # input matrix
+int maxdim # maximum size of input matrix
+int dim # dimension of matrix and vectors
+real vector[maxdim] # input vector
+real result[maxdim] # iutput vector
+
+double sum
+int i, j
+
+begin
+ do i = 1, dim {
+ sum = 0.0
+ do j = 1, dim
+ sum = sum + double (matrix[j,i]) * double(vector[j])
+ result[i] = sum
+ }
+
+end
+
+
+# DMVMUL -- Multply a matrix (left-hand side) by a one dimensional vector
+# (right-hand side) and return the resultant vector.
+
+procedure dmvmul (matrix, maxdim, dim, vector, result)
+
+double matrix [maxdim, maxdim] # input matrix
+int maxdim # maximum size of input matrix
+int dim # dimension of matrix and vectors
+double vector[maxdim] # input vector
+double result[maxdim] # iutput vector
+
+double sum
+int i, j
+
+begin
+ do i = 1, dim {
+ sum = 0.0d0
+ do j = 1, dim
+ sum = sum + (matrix[j,i] * vector[j])
+ result[i] = sum
+ }
+
+end
diff --git a/noao/digiphot/daophot/daolib/pctile.f b/noao/digiphot/daophot/daolib/pctile.f
new file mode 100644
index 00000000..e8a3f2d7
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/pctile.f
@@ -0,0 +1,91 @@
+c function pctile (datum, n, npct)
+c
+c This is a modification of a quick-sorting algorithm, which is intended
+c to take in a vector of numbers, and return the value of the npct-th
+c element in that vector:
+c
+c dataum input vector
+c n number of elements in dataum
+c npct npct-th element
+c pctile output value of function
+c
+c
+c The array datum contains randomly ordered data
+c
+c
+ real function pctile (datum, n, npct)
+c
+ implicit none
+ integer n, npct
+ real datum(1)
+ integer min0, max0
+ real dkey
+ integer lo, hi, limlo, limhi
+c
+c Initialize the pointers.
+c
+ npct = max0 (1, min0 (n,npct))
+ limlo = 1
+ limhi = n
+c
+c Compare all elements in the sub-vector between limlo and limhi with
+c the current key datum.
+c
+ 100 dkey = datum (limlo)
+ lo = limlo
+ hi = limhi
+c
+c If lo equals hi, we have tested all the elements in the current search
+c interval.
+c
+ 101 continue
+ if (lo .eq. hi) go to 200
+ if (datum(hi) .le. dkey) go to 109
+c
+c The pointer hi is to be left pointing at a datum SMALLER than the
+c key, which is intended to be overwritten.
+c
+ hi = hi - 1
+c
+ goto 101
+ 109 datum(lo) = datum(hi)
+ lo = lo + 1
+ 110 continue
+ if (lo .eq. hi) goto 200
+ if (datum(lo) .ge. dkey) go to 119
+ lo = lo + 1
+c
+ goto 110
+ 119 datum(hi) = datum(lo)
+c
+c The pointer LO is to be left pointing at a datum LARGER than the
+c key, which is intended to be overwritten.
+c
+ hi = hi - 1
+c
+ go to 101
+c
+c lo and hi are equal, and point at a value which is intended to
+c be overwritten. Since all values below this point are less than
+c the key and all values above this point are greater than the key,
+c this is where we stick the key back into the vector.
+c
+ 200 continue
+c
+c At this point in the subroutine, all data between limlo and lo-1,
+c inclusive, are less than datum (lo), and all data between lo+1 and
+c limhi are larger than dataum(lo). If lo = npct, then datum(lo) is
+c the value we are looking for. If npct < lo, then we want to sort the
+c values of datum from limlo to lo-1, inclusive, whereas if npct > lo,
+c then we want to sort the values of datum from lo+1 to limhi,
+c inclusive.
+c
+ datum(lo) = dkey
+ if (npct - lo) 300, 900, 400
+ 300 limhi = lo - 1
+ go to 100
+ 400 limlo = lo + 1
+ go to 100
+ 900 pctile = datum(lo)
+ return
+ end
diff --git a/noao/digiphot/daophot/daolib/profile.x b/noao/digiphot/daophot/daolib/profile.x
new file mode 100644
index 00000000..96e1a531
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/profile.x
@@ -0,0 +1,506 @@
+include "../lib/daophotdef.h"
+
+define NGL 4
+
+# DP_PROFILE -- Evaluate the analytic part of the psf function and its
+# derivatives.
+
+real procedure dp_profile (ipstyp, dx, dy, par, dhdxc, dhdyc, term, ideriv)
+
+int ipstyp # the analytic psf function type
+real dx, dy # distance of point from center of function
+real par[ARB] # the current parameter values
+real dhdxc, dhdyc # derivatives of the function integral wrt x,y
+real term[ARB] # derivatives of the function wrt parameters
+int ideriv # compute the derivatives ?
+
+int npt, ix, iy
+real d[NGL,NGL], w[NGL,NGL], x[NGL], xsq[NGL], p1xsq[NGL]
+real p1p2, dhdsx, dhdsy, erfx, erfy, p1sq, p2sq, y, ysq, p2ysq, profile
+real xy, wt, denom, alpha, func, p4fod, wp4fod, f, e, rsq, wf
+real wfsq, onemp3, dfby, deby, dbyx0, dbyy0
+real daoerf()
+
+data d / 0.0, 0.0, 0.0, 0.0,
+ -0.28867513, 0.28867513, 0.0, 0.0,
+ -0.38729833, 0.0, 0.38729833, 0.0,
+ -0.43056816, -0.16999052, 0.16999052, 0.43056816 /
+data w / 1.0, 0.0, 0.0, 0.0,
+ 0.5, 0.5, 0.0, 0.0,
+ 0.27777778, 0.44444444, 0.27777778, 0.0,
+ 0.17392742, 0.32607258, 0.32607258, 0.17392742 /
+begin
+ # Initialize.
+ profile = 0.0
+ dhdxc = 0.0
+ dhdyc = 0.0
+
+ # Compute the analytic part of the profile for a given x and y.
+
+ switch (ipstyp) {
+
+ # Evaluate the Gaussian function
+ # f = erfx * erfy / (par[1] * par[2])
+ # par[1] is the hwhm in x; sigma(x) = 0.8493218 * hwhm
+ # par[2] is the hwhm in y; sigma(y) = 0.8493218 * hwhm
+
+ case FCTN_GAUSS:
+
+ p1p2 = par[1] * par[2]
+ erfx = daoerf (dx, 0.0, par[1], dhdxc, dhdsx)
+ erfy = daoerf (dy, 0.0, par[2], dhdyc, dhdsy)
+ profile = erfx * erfy / p1p2
+ dhdxc = dhdxc * erfy / p1p2
+ dhdyc = dhdyc * erfx / p1p2
+ if (ideriv > 0) {
+ term[1] = (dhdsx - erfx / par[1]) * erfy / p1p2
+ term[2] = (dhdsy - erfy / par[2]) * erfx / p1p2
+ }
+
+ # Evaluate the Moffat25 function
+ #
+ # f = (beta - 1) / (ax * ay * (1 + (x/ax) ** 2 + (y/ay) ** 2 +
+ # (xy * axy)) ** beta)
+ #
+ # par[1] is the hwhm in x at y = 0.0
+ # 1/2 = 1 / (1 + (par[1] / ax) ** 2) ** beta
+ # so
+ # 2 ** (1/ beta) - 1 = (par[1] / ax) ** 2
+ # ax ** 2 = par[1] ** 2 / (2 ** (1 / beta) - 1)
+ #
+ # when beta = 2.5 ax ** 2 = 3.129813 * par[1] ** 2
+ #
+ # f = 1 / par[1] * par[2] * (1 + 0.3195079 * ((x / par[1]) ** 2 +
+ # (y / par[2]) ** 2 + xy * par[3])) ** 2.5
+ #
+
+ case FCTN_MOFFAT25:
+
+ alpha = 0.3195079
+ #talpha = 0.6390158
+ p1sq = par[1] ** 2
+ p2sq = par[2] ** 2
+ p1p2 = par[1] * par[2]
+ xy = dx * dy
+ if (ideriv > 0)
+ call aclrr (term, 4)
+
+ denom = 1.0 + alpha * (dx ** 2 / p1sq + dy ** 2 / p2sq + xy *
+ par[3])
+ if (denom > 1.0e4)
+ return (profile)
+ func = 1.0 / (p1p2 * denom ** par[4])
+ if (func >= 0.046) {
+ npt = 4
+ } else if (func >= 0.0022) {
+ npt = 3
+ } else if (func >= 0.0001) {
+ npt = 2
+ } else if (func >= 1.0e-10) {
+ profile = (par[4] - 1.0) * func
+ p4fod = par[4] * alpha * profile / denom
+ dhdxc = p4fod * (2.0 * dx / p1sq + dy * par[3])
+ dhdyc = p4fod * (2.0 * dy / p2sq + dx * par[3])
+ if (ideriv > 0) {
+ term[1] = (2.0 * p4fod * dx ** 2 / p1sq - profile) /
+ par[1]
+ term[2] = (2.0 * p4fod * dy ** 2 / p2sq - profile) /
+ par[2]
+ term[3] = - p4fod * xy
+ term[4] = profile * (1.0 / (par[4] - 1.0) - log (denom))
+ }
+ return (profile)
+ } else {
+ return (profile)
+ }
+
+ do ix = 1, npt {
+ x[ix] = dx + d[ix,npt]
+ xsq[ix] = x[ix] ** 2
+ p1xsq[ix] = xsq[ix] / p1sq
+ }
+
+ do iy = 1, npt {
+ y = dy + d[iy,npt]
+ ysq = y ** 2
+ p2ysq = ysq / p2sq
+ do ix = 1, npt {
+ wt = w[iy,npt] * w[ix,npt]
+ xy = x[ix] * y
+ denom = 1.0 + alpha * (p1xsq[ix] + p2ysq + xy * par[3])
+ func = (par[4] - 1.0) / (p1p2 * denom ** par[4])
+ p4fod = par[4] * alpha * func / denom
+ wp4fod = wt * p4fod
+ wf = wt * func
+ profile = profile + wf
+ dhdxc = dhdxc + wp4fod * (2.0 * x[ix] / p1sq +
+ y * par[3])
+ dhdyc = dhdyc + wp4fod * (2. * y / p2sq + x[ix] *
+ par[3])
+ if (ideriv > 0) {
+ term[1] = term[1] + (2.0 * wp4fod * p1xsq[ix] - wf) /
+ par[1]
+ term[2] = term[2] + (2.0 * wp4fod * p2ysq - wf) /
+ par[2]
+ term[3] = term[3] - wp4fod * xy
+ term[4] = term[4] + wf * (1.0 / (par[4] - 1.0) -
+ log (denom))
+ }
+ }
+ }
+
+ #
+ # Penny function which has a gaussian core and lorentzian wings.
+ # The lorentzian is elongated along the x and y axes.
+
+ case FCTN_PENNY1:
+
+ p1sq = par[1] ** 2
+ p2sq = par[2] ** 2
+ onemp3 = 1.0 - par[3]
+ xy = dx * dy
+ if (ideriv > 0)
+ call aclrr (term, 4)
+
+ rsq = dx ** 2 / p1sq + dy ** 2 / p2sq
+ if (rsq > 1.0e10)
+ return (profile)
+
+ f = 1.0 / (1.0 + rsq)
+ rsq = rsq + xy * par[4]
+ if (rsq < 34.0) {
+ e = exp (-0.6931472 * rsq)
+ func = par[3] * e + onemp3 * f
+ } else {
+ e = 0.0
+ func = onemp3 * f
+ }
+
+ if (func >= 0.046) {
+ npt = 4
+ } else if (func >= 0.0022) {
+ npt = 3
+ } else if (func >= 0.0001) {
+ npt = 2
+ } else if (func >= 1.0e-10) {
+ profile = func
+ dfby = onemp3 * f ** 2
+ deby = 0.6931472 * par[3] * e
+ dbyx0 = 2.0 * dx / p1sq
+ dbyy0 = 2.0 * dy / p2sq
+ dhdxc = deby * (dbyx0 + dy * par[4]) + dfby * dbyx0
+ dhdyc = deby * (dbyy0 + dx * par[4]) + dfby * dbyy0
+ if (ideriv > 0) {
+ dbyx0 = dbyx0 * dx / par[1]
+ dbyy0 = dbyy0 * dy / par[2]
+ dfby = dfby + deby
+ term[1] = dfby * dbyx0
+ term[2] = dfby * dbyy0
+ term[3] = e - f
+ term[4] = - deby * xy / (0.5 - abs(par[4]))
+ }
+ return (profile)
+ } else {
+ return (profile)
+ }
+
+ do ix = 1, npt {
+ x[ix] = dx + d[ix,npt]
+ p1xsq[ix] = x[ix] / p1sq
+ }
+
+ do iy = 1, npt {
+ y = dy + d[iy,npt]
+ p2ysq = y / p2sq
+ do ix = 1, npt {
+ wt = w[iy,npt] * w[ix,npt]
+ xy = x[ix] * y
+ rsq = p1xsq[ix] * x[ix] + p2ysq * y
+ f = 1.0 / (1.0 + rsq)
+ rsq = rsq + xy * par[4]
+ if (rsq < 34.0) {
+ e = exp (- 0.6931472 * rsq)
+ func = par[3] * e + onemp3 * f
+ deby = 0.6931472 * wt * par[3] * e
+ } else {
+ e = 0.0
+ func = onemp3 * f
+ deby = 0.0
+ }
+ profile = profile + wt * func
+ dfby = wt * onemp3 * f ** 2
+ dbyx0 = 2.0 * p1xsq[ix]
+ dbyy0 = 2.0 * p2ysq
+ dhdxc = dhdxc + deby * (dbyx0 + dy * par[4]) + dfby * dbyx0
+ dhdyc = dhdyc + deby * (dbyy0 + dx * par[4]) + dfby * dbyy0
+ if (ideriv > 0) {
+ dbyx0 = dbyx0 * dx / par[1]
+ dbyy0 = dbyy0 * dy / par[2]
+ term[1] = term[1] + (dfby + deby) * dbyx0
+ term[2] = term[2] + (dfby + deby) * dbyy0
+ term[3] = term[3] + wt * (e - f)
+ term[4] = term[4] - deby * xy
+ }
+ }
+ }
+
+ # Penny function which has a gaussian core and lorentzian wings.
+ # The gaussian and lorentzian may be tilted in different directions.
+
+ case FCTN_PENNY2:
+
+ p1sq = par[1] ** 2
+ p2sq = par[2] ** 2
+ onemp3 = 1.0 - par[3]
+ xy = dx * dy
+ if (ideriv > 0)
+ call aclrr (term, 5)
+
+ rsq = dx ** 2 / p1sq + dy ** 2 / p2sq
+ dfby = rsq + par[5] * xy
+ if (dfby > 1.0e10)
+ return (profile)
+ f = 1.0 / (1.0 + dfby)
+
+ deby = rsq + par[4] * xy
+ if (deby < 34.0)
+ e = exp (-0.6931472 * deby)
+ else
+ e = 0.0
+
+ func = par[3] * e + onemp3 * f
+ if (func >= 0.046) {
+ npt = 4
+ } else if (func >= 0.0022) {
+ npt = 3
+ } else if (func >= 0.0001) {
+ npt = 2
+ } else if (func >= 1.0e-10) {
+ profile = func
+ dfby = onemp3 * f ** 2
+ deby = 0.6931472 * par[3] * e
+ dbyx0 = 2.0 * dx / p1sq
+ dbyy0 = 2.0 * dy / p2sq
+ dhdxc = deby * (dbyx0 + dy * par[4]) + dfby * (dbyx0 + dy *
+ par[5])
+ dhdyc = deby * (dbyy0 + dx * par[4]) + dfby * (dbyy0 + dx *
+ par[5])
+ if (ideriv > 0) {
+ dbyx0 = dbyx0 * dx / par[1]
+ dbyy0 = dbyy0 * dy / par[2]
+ term[5] = -dfby * xy
+ dfby = dfby + deby
+ term[1] = dfby * dbyx0
+ term[2] = dfby * dbyy0
+ term[3] = e - f
+ term[4] = - deby * xy
+ }
+ return (profile)
+ } else {
+ return (profile)
+ }
+
+ do ix = 1, npt {
+ x[ix] = dx + d[ix,npt]
+ p1xsq[ix] = x[ix] / p1sq
+ }
+
+ do iy = 1, npt {
+ y = dy + d[iy,npt]
+ p2ysq = y / p2sq
+ do ix = 1, npt {
+ wt = w[iy,npt] * w[ix,npt]
+ xy = x[ix] * y
+ rsq = p1xsq[ix] * x[ix] + p2ysq * y
+ f = 1.0 / (1.0 + rsq + par[5] * xy)
+ deby = rsq + par[4] * xy
+ if (deby < 34.0) {
+ e = exp (- 0.6931472 * deby)
+ func = par[3] * e + onemp3 * f
+ deby = 0.6931472 * wt * par[3] * e
+ } else {
+ e = 0.0
+ func = onemp3 * f
+ deby = 0.0
+ }
+ profile = profile + wt * func
+ dfby = wt * onemp3 * f ** 2
+ dbyx0 = 2.0 * p1xsq[ix]
+ dbyy0 = 2.0 * p2ysq
+ dhdxc = dhdxc + deby * (dbyx0 + dy * par[4]) + dfby *
+ (dbyx0 + dy * par[5])
+ dhdyc = dhdyc + deby * (dbyy0 + dx * par[4]) + dfby *
+ (dbyy0 + dx * par[5])
+ if (ideriv > 0) {
+ dbyx0 = dbyx0 * dx / par[1]
+ dbyy0 = dbyy0 * dy / par[2]
+ term[1] = term[1] + (dfby + deby) * dbyx0
+ term[2] = term[2] + (dfby + deby) * dbyy0
+ term[3] = term[3] + wt * (e - f)
+ term[4] = term[4] - deby * xy
+ term[5] = term[5] - dfby * xy
+ }
+ }
+ }
+
+ # Evaluate the Moffat15 function
+ #
+ # f = (beta - 1) / (ax * ay * (1 + (x/ax) ** 2 + (y/ay) ** 2 +
+ # (xy * axy)) ** beta)
+ #
+ # par[1] is the hwhm in x at y = 0.0
+ # 1/2 = 1 / (1 + (par[1] / ax) ** 2) ** beta
+ # so
+ # 2 ** (1/ beta) - 1 = (par[1] / ax) ** 2
+ # ax ** 2 = par[1] ** 2 / (2 ** (1 / beta) - 1)
+ #
+ # when beta = 1.5 ax ** 2 = 1.7024144 * par[1] ** 2
+ #
+ # f = 1 / par[1] * par[2] * (1 + 0.5874011 * ((x / par[1]) ** 2 +
+ # (y / par[2]) ** 2 + xy * par[3])) ** 2.5
+ #
+
+ case FCTN_MOFFAT15:
+
+ alpha = 0.5874011
+ #talpha = 1.1748021
+ p1sq = par[1] ** 2
+ p2sq = par[2] ** 2
+ p1p2 = par[1] * par[2]
+ xy = dx * dy
+ if (ideriv > 0)
+ call aclrr (term, 4)
+
+ denom = 1.0 + alpha * (dx ** 2 / p1sq + dy ** 2 / p2sq + xy *
+ par[3])
+ if (denom > 5.0e6)
+ return (profile)
+ func = 1.0 / (p1p2 * denom ** par[4])
+ if (func >= 0.046) {
+ npt = 4
+ } else if (func >= 0.0022) {
+ npt = 3
+ } else if (func >= 0.0001) {
+ npt = 2
+ } else if (func >= 1.0e-10) {
+ profile = (par[4] - 1.0) * func
+ p4fod = par[4] * alpha * profile / denom
+ dhdxc = p4fod * (2.0 * dx / p1sq + dy * par[3])
+ dhdyc = p4fod * (2.0 * dy / p2sq + dx * par[3])
+ if (ideriv > 0) {
+ term[1] = (2.0 * p4fod * dx ** 2 / p1sq - profile) /
+ par[1]
+ term[2] = (2.0 * p4fod * dy ** 2 / p2sq - profile) /
+ par[2]
+ term[3] = - p4fod * xy
+ term[4] = profile * (1.0 / (par[4] - 1.0) - log (denom))
+ }
+ return (profile)
+ } else {
+ return (profile)
+ }
+
+ do ix = 1, npt {
+ x[ix] = dx + d[ix,npt]
+ xsq[ix] = x[ix] ** 2
+ p1xsq[ix] = xsq[ix] / p1sq
+ }
+
+ do iy = 1, npt {
+ y = dy + d[iy,npt]
+ ysq = y ** 2
+ p2ysq = ysq / p2sq
+ do ix = 1, npt {
+ wt = w[iy,npt] * w[ix,npt]
+ xy = x[ix] * y
+ denom = 1.0 + alpha * (p1xsq[ix] + p2ysq + xy *
+ par[3])
+ func = (par[4] - 1.0) / (p1p2 * denom ** par[4])
+ p4fod = par[4] * alpha * func / denom
+ wp4fod = wt * p4fod
+ wf = wt * func
+ profile = profile + wf
+ dhdxc = dhdxc + wp4fod * (2.0 * x[ix] / p1sq + y *
+ par[3])
+ dhdyc = dhdyc + wp4fod * (2. * y / p2sq + x[ix] *
+ par[3])
+ if (ideriv > 0) {
+ term[1] = term[1] + (2.0 * wp4fod * p1xsq[ix] - wf) /
+ par[1]
+ term[2] = term[2] + (2.0 * wp4fod * p2ysq - wf) /
+ par[2]
+ term[3] = term[3] - wp4fod * xy
+ term[4] = term[4] + wf * (1.0 / (par[4] - 1.0) -
+ log (denom))
+ }
+ }
+ }
+
+ case FCTN_LORENTZ:
+
+ p1sq = par[1] ** 2
+ p2sq = par[2] ** 2
+ p1p2 = par[1] * par[2]
+ xy = dx * dy
+ if (ideriv > 0)
+ call aclrr (term, 3)
+
+ denom = 1.0 + dx ** 2 / p1sq + dy ** 2 / p2sq + xy * par[3]
+ if (denom > 1.0e10)
+ return (profile)
+ func = 1.0 / denom
+ if (func >= 0.046) {
+ npt = 4
+ } else if (func >= 0.0022) {
+ npt = 3
+ } else if (func >= 0.0001) {
+ npt = 2
+ } else if (func >= 1.0e-10) {
+ profile = func
+ wfsq = func ** 2
+ dhdxc = wfsq * (2.0 * dx / p1sq + dy * par[3])
+ dhdyc = wfsq * (2.0 * dy / p2sq + dx * par[3])
+ if (ideriv > 0) {
+ term[1] = wfsq * (2.0 * dx ** 2 / p1sq) / par[1]
+ term[2] = wfsq * (2.0 * dy ** 2 / p2sq) / par[2]
+ term[3] = - wfsq * xy
+ }
+ return (profile)
+ } else {
+ return (profile)
+ }
+
+ do ix = 1, npt {
+ x[ix] = dx + d[ix,npt]
+ xsq[ix] = x[ix] ** 2
+ p1xsq[ix] = xsq[ix] / p1sq
+ }
+
+ do iy = 1, npt {
+ y = dy + d[iy,npt]
+ ysq = y ** 2
+ p2ysq = ysq / p2sq
+ do ix = 1, npt {
+ wt = w[iy,npt] * w[ix,npt]
+ xy = x[ix] * y
+ denom = 1.0 + p1xsq[ix] + p2ysq + xy * par[3]
+ func = 1.0 / denom
+ wf = wt * func
+ wfsq = wf * func
+ profile = profile + wf
+ dhdxc = dhdxc + wfsq * (2.0 * x[ix] / p1sq + y * par[3])
+ dhdyc = dhdyc + wfsq * (2.0 * y / p2sq + x[ix] * par[3])
+ if (ideriv > 0) {
+ term[1] = term[1] + wfsq * (2.0 * p1xsq[ix]) / par[1]
+ term[2] = term[2] + wfsq * (2.0 * p2ysq) / par[2]
+ term[3] = term[3] - wfsq * xy
+ }
+ }
+ }
+
+ default:
+ profile = INDEFR
+ }
+
+ return (profile)
+end
diff --git a/noao/digiphot/daophot/daolib/quick.f b/noao/digiphot/daophot/daolib/quick.f
new file mode 100644
index 00000000..72a58fe5
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/quick.f
@@ -0,0 +1,202 @@
+c subroutine quick (dataum, n, index)
+c
+c
+c A quick-sorting algorithm suggested by the discussion on pages 114-119
+c of THE ART OF COMPUTER PROGRAMMING, Vol. 3, SORTING AND SEARCHING, by
+c D.E. Knuth, which was referenced in Don Wells' subroutine QUIK. This
+c is my own attempt at encoding a quicksort-- PBS.
+c
+c Arguments
+c
+c datum (input / output) is a vector of dimension n containing randomly
+c ordered real data upon input. Upon output the elements of
+c dataum will be in order of increasing value.
+c
+c
+c index (output) is an integer vector of dimension n. Upon return to
+c the calling program the i-th element of index will tell where
+c the i-th element of the sorted vector datum had been before
+c datum was sorted.
+c
+c
+c
+c parameter (maxstack = 28)
+c
+c Parameters
+c
+c maxstack is the maximum number of entries the stack can contain.
+c A limiting stack length of 28 restricts this quicksort
+
+ subroutine quick (datum, n, index, ier)
+c
+ implicit none
+ integer n, index(n), ier
+ real datum(n)
+c
+ real dkey
+ integer stklo(28), stkhi(28), i, lo, hi, nstak, limlo, limhi, ikey
+c
+c Initialize error code
+
+ ier = 0
+c
+c Initialize index.
+c
+ do 50 i = 1, n
+ 50 index(i) = i
+c
+c Initialize the pointers.
+c
+ nstak = 0
+ limlo = 1
+ limhi = n
+c
+ 100 dkey = datum(limlo)
+ ikey = index(limlo)
+c
+c Compare all elements in the sub-vector between limlo and limhi with
+c the current key datum.
+c
+ lo = limlo
+ hi = limhi
+ 101 continue
+c
+ if (lo .eq. hi) go to 200
+c
+ if (datum(hi) .le. dkey) go to 109
+ hi = hi - 1
+c
+c The pointer hi is to be left pointing at a datum smaller than the
+c key, which is intended to be overwritten.
+c
+ go to 101
+c
+ 109 datum(lo) = datum(hi)
+ index(lo) = index(hi)
+ lo = lo + 1
+ 110 continue
+c
+ if (lo .eq. hi) go to 200
+c
+ if (datum(lo) .ge. dkey) go to 119
+c
+ lo = lo + 1
+ go to 110
+c
+ 119 datum(hi) = datum(lo)
+ index(hi) = index(lo)
+ hi = hi - 1
+c
+c The pointer LO is to be left pointing at a datum LARGER than the
+c key, which is intended to be overwritten.
+c
+ go to 101
+c
+ 200 continue
+c
+c lo and hi are equal, and point at a value which is intended to
+c be overwritten. Since all values below this point are less than
+c the key and all values above this point are greater than the key,
+c this is where we stick the key back into the vector.
+c
+ datum(lo) = dkey
+ index(lo) = ikey
+c
+c At this point in the subroutine, all data between limlo and LO-1,
+c inclusive, are less than datum(LO), and all data between LO+1 and
+c limhi are larger than datum(LO).
+c
+c If both subarrays contain no more than one element, then take the most
+c recent interval from the stack (if the stack is empty, we're done).
+c If the larger of the two subarrays contains more than one element, and
+c if the shorter subarray contains one or no elements, then forget the
+c shorter one and reduce the other subarray. If the shorter subarray
+c contains two or more elements, then place the larger subarray on the
+c stack and process the subarray.
+c
+ if ((limhi - lo) .gt. (lo - limlo)) go to 300
+c
+c Case 1: the lower subarray is longer. If it contains one or no
+c elements then take the most recent interval from the stack and go
+c back and operate on it.
+c
+ if ((lo - limlo) .le. 1) go to 400
+c
+c If the upper (shorter) subinterval contains one or no elements, then
+c process the lower (longer) one, but if the upper subinterval contains
+c more than one element, then place the lower (longer) subinterval on
+c the stack and process the upper one.
+c
+ if ((limhi - lo) .ge. 2) go to 250
+c
+c Case 1a: the upper (shorter) subinterval contains no or one elements,
+c so we go back and operate on the lower (longer) subinterval.
+c
+ limhi = lo - 1
+ go to 100
+c
+ 250 continue
+c
+c Case 1b: the upper (shorter) subinterval contains at least two
+c elements, so we place the lower (longer) subinterval on the stack and
+c then go back and operate on the upper subinterval.
+c
+ nstak = nstak + 1
+ if (nstak .gt. 28) then
+ ier = -1
+ return
+ endif
+ stklo(nstak) = limlo
+ stkhi(nstak) = lo - 1
+ limlo = lo + 1
+ go to 100
+c
+ 300 continue
+c
+c Case 2: the upper subarray is longer. If it contains one or no
+c elements then take the most recent interval from the stack and
+c operate on it.
+c
+ if ((limhi - lo) .le. 1) go to 400
+c
+c If the lower (shorter) subinterval contains one or no elements, then
+c process the upper (longer) one, but if the lower subinterval contains
+c more than one element, then place the upper (longer) subinterval on
+c the stack and process the lower one.
+c
+ if ((lo - limlo) .ge. 2) go to 350
+c
+c Case 2a: the lower (shorter) subinterval contains no or one elements,
+c so we go back and operate on the upper (longer) subinterval.
+c
+ limlo = lo + 1
+ go to 100
+c
+ 350 continue
+c
+c Case 2b: the lower (shorter) subinterval contains at least two
+c elements, so we place the upper (longer) subinterval on the stack and
+c then go back and operate on the lower subinterval.
+c
+ nstak = nstak + 1
+ if (nstak .gt. 28) then
+ ier = -1
+ return
+ endif
+ stklo(nstak) = lo + 1
+ stkhi(nstak) = limhi
+ limhi = lo - 1
+ go to 100
+c
+ 400 continue
+c
+c Take the most recent interval from the stack. If the stack happens
+c to be empty, we are done.
+c
+ if (nstak .le. 0) return
+ limlo = stklo(nstak)
+ limhi = stkhi(nstak)
+ nstak = nstak - 1
+ go to 100
+c
+ end
diff --git a/noao/digiphot/daophot/daolib/ran3.x b/noao/digiphot/daophot/daolib/ran3.x
new file mode 100644
index 00000000..c8915e70
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/ran3.x
@@ -0,0 +1,63 @@
+define MBIG 1000000000
+define MSEED 161803398
+define MZ 0.0
+define FAC 1.0 / MBIG
+
+# RAN3 -- Returns a uniform random deviate between 0.0 and 1.0. Set
+# 'idum' to any negative value to initialize or reinitialize the sequence.
+# From Numerical Recipes (originally attributed to Donald Knuth, 1981;
+# Seminumerical Algorithms, 2nd edition, volume 2 of 'The Art of Computer
+# Programming' - Section 3.2-3.3.
+
+real procedure ran3 (idum)
+
+int idum
+
+int ma[55]
+int mj, mk, i, k, ii
+int iff, inext, inextp
+data iff /0/
+
+begin
+ if(idum < 0 || iff == 0) {
+ iff = 1
+ mj = MSEED - iabs(idum)
+ mj = mod(mj, MBIG)
+ ma[55] = mj
+ mk = 1
+
+ do i = 1, 54 {
+ ii = mod(21 * i , 55)
+ ma[ii] = mk
+ mk = mj - mk
+ if (mk < MZ)
+ mk = mk + MBIG
+ mj = ma[ii]
+ }
+
+ do k = 1, 4 {
+ do i = 1, 55 {
+ ma[i] = ma[i] - ma[1+mod(i+30, 55)]
+ if (ma[i] < MZ)
+ ma[i] = ma[i] + MBIG
+ }
+ }
+
+ inext = 0
+ inextp = 31
+ idum = 1
+ }
+
+ inext = inext + 1
+ if (inext == 56)
+ inext = 1
+ inextp = inextp + 1
+ if (inextp == 56)
+ inextp = 1
+ mj = ma[inext] - ma[inextp]
+ if (mj < MZ)
+ mj = mj + MBIG
+ ma[inext]= mj
+ return (mj * FAC)
+
+end
diff --git a/noao/digiphot/daophot/daolib/usepsf.x b/noao/digiphot/daophot/daolib/usepsf.x
new file mode 100644
index 00000000..f7a7db2f
--- /dev/null
+++ b/noao/digiphot/daophot/daolib/usepsf.x
@@ -0,0 +1,81 @@
+include "../lib/daophotdef.h"
+
+# DP_USEPSF -- Evaluate the psf at a given point.
+
+real procedure dp_usepsf (ipstyp, dx, dy, bright, par, psf, npsf, nexp,
+ nfrac, deltax, deltay, dvdxc, dvdyc)
+
+int ipstyp # analytic psf function type
+real dx, dy # distance for center of function
+real bright # the relative brightness of the object
+real par[ARB] # current values of the parameters
+real psf[npsf,npsf,ARB] # the psf lookup tables
+int npsf # size of the psf look-up table
+int nexp # number pf look-up tables
+int nfrac # fractional pixel expansion
+real deltax, deltay # distance from center of look-up tables
+real dvdxc, dvdyc # derivatives with respect to position
+
+int nterm, j, k, lx, ly
+real psfval, middle, junk[MAX_NEXPTERMS], xx, yy, corr, dfdx, dfdy
+real dp_profile(), bicubic()
+
+begin
+ nterm = nexp + nfrac
+ psfval = bright * dp_profile (ipstyp, dx, dy, par, dvdxc, dvdyc,
+ junk, 0)
+ dvdxc = bright * dvdxc
+ dvdyc = bright * dvdyc
+ if (nterm <= 0)
+ return (psfval)
+
+ # The PSF look-up tables are centered at (MIDDLE, MIDDLE).
+
+ switch (nexp) {
+ case 1:
+ junk[1] = 1.
+ case 3:
+ junk[1] = 1.
+ junk[2] = deltax
+ junk[3] = deltay
+ case 6:
+ junk[1] = 1.
+ junk[2] = deltax
+ junk[3] = deltay
+ junk[4] = 1.5 * deltax ** 2 - 0.5
+ junk[5] = deltax * deltay
+ junk[6] = 1.5 * deltay ** 2 - 0.5
+ }
+
+ if (nfrac > 0) {
+ j = nexp + 1
+ junk[j] = - 2. * (dx - real(nint(dx)))
+ j = j + 1
+ junk[j] = - 2. * (dy - real(nint(dy)))
+ j = j + 1
+ junk[j] = 1.5 * junk[j-2] ** 2 - 0.5
+ j = j + 1
+ junk[j] = junk[j-3] * junk[j-2]
+ j = j + 1
+ junk[j] = 1.5 * junk[j-3] ** 2 - 0.5
+ }
+
+ # This point in the stellar profile lies between columns LX and LX+1,
+ # and between rows LY and LY+1 in the look-up tables.
+
+ middle = (npsf + 1) / 2
+ xx = (2. * dx) + middle
+ lx = int (xx)
+ yy = (2. * dy) + middle
+ ly = int (yy)
+
+ do k = 1, nterm {
+ corr = bicubic (psf[lx-1,ly-1,k], npsf, xx - real(lx),
+ yy - real(ly), dfdx, dfdy)
+ psfval = psfval + junk[k] * corr
+ dvdxc = dvdxc - junk[k] * dfdx
+ dvdyc = dvdyc - junk[k] * dfdy
+ }
+
+ return (psfval)
+end
diff --git a/noao/digiphot/daophot/daopars.par b/noao/digiphot/daophot/daopars.par
new file mode 100644
index 00000000..acfb3f3f
--- /dev/null
+++ b/noao/digiphot/daophot/daopars.par
@@ -0,0 +1,25 @@
+# The DAOPHOT fitting parameters
+
+function,s,h,"gauss",,,"Form of analytic component of psf model"
+varorder,i,h,0,-1,2,"Order of empirical component of psf model"
+nclean,i,h,0,,,Number of cleaning iterations for computing psf model
+saturated,b,h,no,,,"Use wings of saturated stars in psf model computation?"
+matchrad,r,h,3.0,0.0,,"Object matching radius in scale units"
+psfrad,r,h,11.0,0.0,,"Radius of psf model in scale units"
+
+fitrad,r,h,3.0,0.0,,"Fitting radius in scale units"
+recenter,b,h,yes,,,"Recenter stars during fit?"
+fitsky,b,h,no,,,"Recompute group sky value during fit?"
+groupsky,b,h,yes,,,"Use group rather than individual sky values?"
+sannulus,r,h,0.0,,,"Inner radius of sky fitting annulus in scale units"
+wsannulus,r,h,11.0,,,"Width of sky fitting annulus in scale units"
+flaterr,r,h,0.75,0.0,100.0,"Flat field error in percent"
+proferr,r,h,5.0,0.0,100.0,"Profile error in percent"
+maxiter,i,h,50,1,100,"Maximum number of fitting iterations"
+clipexp,i,h,6,0,8,"Bad data clipping exponent"
+cliprange,r,h,2.5,0.0,10.0,"Bad data clipping range in sigma"
+mergerad,r,h,INDEF,0.0,,"Critical object merging radius in scale units"
+critsnratio,r,h,1.0,0.0,,"Critical S/N ratio for group membership"
+maxnstar,i,h,10000,,50000,"Maximum number of stars to fit"
+maxgroup,i,h,60,,100,"Maximum number of stars to fit per group"
+mode,s,h,"ql",,,
diff --git a/noao/digiphot/daophot/daophot.cl b/noao/digiphot/daophot/daophot.cl
new file mode 100644
index 00000000..ad72db45
--- /dev/null
+++ b/noao/digiphot/daophot/daophot.cl
@@ -0,0 +1,77 @@
+# Package script task for the DAOPHOTX package.
+#{ DAOPHOTX -- Point Spread Function photometry package.
+
+
+
+# Load other packages
+
+dataio # rfits task is required for the daotest script
+;
+
+package daophot
+
+task setimpars = "daophot$setimpars.cl"
+task daotest = "daophot$daotest.cl"
+
+task daofind,
+ phot = "daophot$x_apphot.e"
+
+task addstar,
+ allstar,
+ group,
+ grpselect,
+ nstar,
+ peak,
+ pfmerge,
+ psf,
+ pstselect,
+ seepsf,
+ daoedit,
+ substar = "daophot$x_daophot.e"
+
+task datapars = "daophot$datapars.par"
+task findpars = "daophot$findpars.par"
+task centerpars = "daophot$centerpars.par"
+task fitskypars = "daophot$fitskypars.par"
+task photpars = "daophot$photpars.par"
+task daopars = "daophot$daopars.par"
+
+# PTOOLS tasks
+
+task pconvert,
+ istable,
+ txcalc,
+ txconcat,
+ txdump,
+ txrenumber,
+ txselect,
+ txsort = "ptools$x_ptools.e"
+
+task pexamine = "daophot$x_ptools.e"
+
+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"
+
+# PTOOLS scripts which depend on PTOOLS and TTOOLS tasks
+
+task pcalc = "ptools$pcalc.cl"
+task pconcat = "ptools$pconcat.cl"
+task pdump = "ptools$pdump.cl"
+task prenumber = "ptools$prenumber.cl"
+task pselect = "ptools$pselect.cl"
+task psort = "ptools$psort.cl"
+
+# PTOOLS Scripts which depend only on TTOOLS tasks
+
+task tbconcat = "ptools$tbconcat.cl"
+task tbcalc = "ptools$tbcalc.cl"
+task tbdump = "ptools$tbdump.cl"
+
+hidetask istable, txcalc, txconcat, txdump, txrenumber, txselect, txsort
+hidetask xyplot, histplot, radplot, surfplot, cntrplot
+hidetask tbcalc, tbconcat, tbdump
+
+clbye()
diff --git a/noao/digiphot/daophot/daophot.hd b/noao/digiphot/daophot/daophot.hd
new file mode 100644
index 00000000..a7a8b4a6
--- /dev/null
+++ b/noao/digiphot/daophot/daophot.hd
@@ -0,0 +1,42 @@
+# Help directory for the DAOPHOT package
+
+$doc = "./doc/"
+
+$addstar = "daophot$addstar/"
+$allstar = "daophot$allstar/"
+$daoedit = "daophot$daoedit/"
+$daofind = "apphot$daofind/"
+$group = "daophot$group/"
+$select = "daophot$select/"
+$nstar = "daophot$nstar/"
+$peak = "daophot$peak/"
+$pexamine = "ptools$pexamine/"
+$phot = "apphot$phot/"
+$psf = "daophot$psf/"
+$seepsf = "daophot$seepsf/"
+$substar = "daophot$substar/"
+
+addstar hlp=doc$addstar.hlp, src=addstar$t_addstar.x
+allstar hlp=doc$allstar.hlp, src=allstar$t_allstar.x
+centerpars hlp=doc$centerpars.hlp, src=daophot$centerpars.par
+daoedit hlp=doc$daoedit.hlp, src=daoedit$t_daoedit.x
+daofind hlp=doc$daofind.hlp, src=daofind$t_daofind.x
+daopars hlp=doc$daopars.hlp, src=daophot$daopars.par
+daotest hlp=doc$daotest.hlp, src=daophot$daotest.cl
+datapars hlp=doc$datapars.hlp, src=daophot$datapars.par
+findpars hlp=doc$findpars.hlp, src=daophot$findpars.par
+fitskypars hlp=doc$fitskypars.hlp, src=daophot$fitskypars.par
+group hlp=doc$group.hlp, src=group$t_group.x
+grpselect hlp=doc$grpselect.hlp, src=select$t_grpselect.x
+nstar hlp=doc$nstar.hlp, src=nstar$t_nstar.x
+peak hlp=doc$peak.hlp, src=peak$t_peak.x
+pexamine hlp=doc$pexamine.hlp, src=pexamine$t_pexamine.x
+phot hlp=doc$phot.hlp, src=phot$t_phot.x
+photpars hlp=doc$photpars.hlp, src=daophot$photpars.par
+pfmerge hlp=doc$pfmerge.hlp, src=select$t_pfmerge.x
+psf hlp=doc$psf.hlp, src=psf$t_psf.x
+pstselect hlp=doc$pstselect.hlp, src=psf$t_pstselect.x
+seepsf hlp=doc$seepsf.hlp, src=seepsf$t_seepsf.x
+setimpars hlp=doc$setimpars.hlp, src=daophot$setimpars.cl
+substar hlp=doc$substar.hlp, src=substar$t_substar.x
+revisions sys=Revisions
diff --git a/noao/digiphot/daophot/daophot.men b/noao/digiphot/daophot/daophot.men
new file mode 100644
index 00000000..ea6ffb3c
--- /dev/null
+++ b/noao/digiphot/daophot/daophot.men
@@ -0,0 +1,31 @@
+ addstar - Add artificial stars to an image using the computed psf
+ allstar - Group and fit psf to multiple stars simultaneously
+ centerpars - Edit the centering algorithm parameters
+ daoedit - Review/edit algorithm parameters interactively
+ daofind - Find stars in an image using the DAO algorithm
+ daopars - Edit the daophot algorithms parameter set
+ daotest - Run basic tests on the daophot package tasks
+ datapars - Edit the image data dependent parameters
+ findpars - Edit the star detection parameters
+ fitskypars - Edit the sky fitting algorithm parameters
+ group - Group stars based on positional overlap and signal/noise
+ nstar - Fit the psf to predefined groups of stars
+ peak - Fit the psf to single stars
+ phot - Compute sky values and initial magnitudes for a list of stars
+ photpars - Edit the aperture photometry parameters
+ psf - Compute the point spread function
+ seepsf - Compute an image from the point spread function
+ setimpars - Save/restore parameter sets for a particular image
+ substar - Subtract the fitted stars from the original image
+
+ pcalc - Do arithmetic operations on a list of daophot databases
+ pconcat - Concatenate a list of daophot databases
+ pconvert - Convert a text database to a tables database
+ pdump - Print selected fields from a list of daophot databases
+ pfmerge - Merge a list of photometry databases
+ pstselect - Select candidate psf stars based on proximity
+ grpselect - Select groups of a specified size from a daophot database
+ pexamine - Interactively examine and edit a daophot database
+ prenumber - Renumber stars in a daophot database
+ pselect - Select records from a daophot database
+ psort - Sort a daophot database
diff --git a/noao/digiphot/daophot/daophot.par b/noao/digiphot/daophot/daophot.par
new file mode 100644
index 00000000..f9c38f21
--- /dev/null
+++ b/noao/digiphot/daophot/daophot.par
@@ -0,0 +1,13 @@
+# DAOPHOTX package parameter file
+
+version,s,h,"May00"
+text,b,h,yes,,,"Set the default output photfile format to text?"
+wcsin,s,h,logical,"logical|tv|physical|world",,"The input coordinates wcs"
+wcsout,s,h,logical,"logical|tv|physical",,"The output coordinates wcs"
+wcspsf,s,h,logical,"logical|tv|physical",,"The psf coordinates wcs"
+cache,b,h,no,,,"Cache image in memory?"
+verify,b,h,yes,,,"Verify critical parameters?"
+update,b,h,no,,,"Update critial parameters?"
+verbose,b,h,yes,,,"Print verbose output?"
+graphics,s,h,stdgraph,,,"Default graphics device"
+display,s,h,stdimage,,,"Default display device"
diff --git a/noao/digiphot/daophot/daotest.cl b/noao/digiphot/daophot/daotest.cl
new file mode 100644
index 00000000..15153b5f
--- /dev/null
+++ b/noao/digiphot/daophot/daotest.cl
@@ -0,0 +1,308 @@
+# DAOTEST - Self testing procedure for the DAOPHOT package.
+
+procedure daotest (imname)
+
+string imname {prompt="Name of the output test image"}
+string daologfile {"", prompt="Name of the output log file"}
+string daoplotfile {"", prompt="Name of the output plot file"}
+
+begin
+ # Declare local variables.
+ string im, daolog, daoplot
+
+ # Check that the user truly wants to proceed.
+ s1 = ""
+ print ("")
+ print ("DAOTEST INITIALIZES THE DAOPHOT 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 DAOTEST TASK")
+ bye
+ }
+ }
+ print ("")
+
+ # Define the image name and the log and plot file names.
+ im = imname
+ daolog = daologfile
+ if (daolog == "") {
+ daolog = im // ".log"
+ }
+ daoplot = daoplotfile
+ if (daoplot == "") {
+ daoplot = im // ".plot"
+ }
+
+ # Read in the FITS file and check for the existance of the log and
+ # plot files.
+
+ if (! access (im // ".imh") && ! access (im // ".hhh")) {
+ rfits ("daophot$test/fits3.fits", "0", im, make_image=yes,
+ long_header=no, short_header=yes, datatype="",blank=0,
+ scale=yes,oldirafname=no,offset=0, >& "dev$null")
+ } else {
+ error (0, "Error: The image already exists on disk")
+ }
+ if (access (daolog)) {
+ error (0, "Error: The log file already exists on disk")
+ }
+ if (access (daoplot)) {
+ error (0, "Error: The plot file already exists on disk")
+ }
+
+ # Initialize the DAOPHOT package.
+
+ print ("INITIALIZE THE DAOPHOT PACKAGE", >> daolog)
+ print ("", >> daolog)
+ print ("")
+ print ("INITIALIZE THE DAOPHOT PACKAGE")
+ print ("")
+
+ daophot.text=yes
+
+ unlearn ("addstar")
+ unlearn ("allstar")
+ unlearn ("centerpars")
+ unlearn ("cntrplot")
+ unlearn ("daofind")
+ unlearn ("daopars")
+ unlearn ("datapars")
+ unlearn ("findpars")
+ unlearn ("fitskypars")
+ unlearn ("group")
+ unlearn ("grpselect")
+ unlearn ("histplot")
+ unlearn ("nstar")
+ unlearn ("pconcat")
+ unlearn ("pconvert")
+ unlearn ("pdump")
+ unlearn ("peak")
+ unlearn ("pexamine")
+ unlearn ("pfmerge")
+ unlearn ("phot")
+ unlearn ("photpars")
+ unlearn ("prenumber")
+ unlearn ("pselect")
+ unlearn ("psf")
+ unlearn ("pstselect")
+ unlearn ("psort")
+ unlearn ("radplot")
+ unlearn ("seepsf")
+ unlearn ("substar")
+ unlearn ("surfplot")
+ unlearn ("xyplot")
+
+ # Test the DAOFIND task.
+
+ print ("TESTING THE DAOFIND TASK", >> daolog)
+ print ("TESTING THE DAOFIND TASK")
+ print ("", >> daolog)
+
+ datapars.fwhmpsf=2.0
+ datapars.sigma=10.0
+ findpars.threshold=3.0
+
+ daofind (im, "default", interactive-, verify-, verbose-)
+ concat (im // ".coo.1", daolog, append=yes)
+
+ # Test the PHOT task.
+
+ print ("", >> daolog)
+ print ("TESTING THE PHOT TASK", >> daolog)
+ print ("TESTING THE PHOT TASK")
+ print ("", >> daolog)
+
+ fitskypars.annulus=6.0
+ fitskypars.dannulus=12.0
+ photpars.apertures="3.0,5.0"
+
+ phot (im, "default", "default", interactive-, verify-, verbose-)
+ concat (im // ".mag.1", daolog, append=yes)
+
+ # Test the PSTSELECT task.
+
+ print ("", >> daolog)
+ print ("TESTING THE PSTSELECT TASK", >> daolog)
+ print ("TESTING THE PSTSELECT TASK")
+ print ("", >> daolog)
+
+ pstselect (im, im // ".mag.1", "default", 1, verify-, verbose-)
+ concat (im // ".pst.1", daolog, append=yes)
+
+ # Test the PSF task.
+
+ print ("", >> daolog)
+ print ("TESTING THE PSF TASK", >> daolog)
+ print ("TESTING THE PSF TASK")
+ print ("", >> daolog)
+
+ daopars.psfrad=5.0
+ daopars.fitrad=3.0
+
+ psf (im, "default", "", "default", "default", "default",
+ plotfile=daoplot, icommands="daophot$test/cmds.dat", verify-,
+ verbose-, >> daolog)
+ imheader (im //".psf.1", longheader+, userfields+, >> daolog)
+ print ("", >> daolog)
+ concat (im // ".psg.1", daolog, append=yes)
+ print ("", >> daolog)
+ concat (im // ".pst.2", daolog, append=yes)
+
+ # Test the PEAK task.
+
+ print ("", >> daolog)
+ print ("TESTING THE PEAK TASK", >> daolog)
+ print ("TESTING THE PEAK TASK")
+ print ("", >> daolog)
+
+ peak (im, "default", "default", "default", "", verify-, verbose-,
+ >> daolog)
+ print ("", >> daolog)
+ concat (im // ".pk.1", daolog, append=yes)
+
+ # Test the GROUP task.
+
+ daopars.critsnratio = 0.2
+
+ print ("", >> daolog)
+ print ("TESTING THE GROUP TASK", >> daolog)
+ print ("TESTING THE GROUP TASK")
+ print ("", >> daolog)
+
+ group (im, "default", "default", "default", verify-, verbose+,
+ >> daolog)
+ print ("", >> daolog)
+ concat (im // ".grp.1", daolog, append=yes)
+
+ # Test the GRPSELECT task.
+
+ print ("", >> daolog)
+ print ("TESTING THE GRPSELECT TASK", >> daolog)
+ print ("TESTING THE GRPSELECT TASK")
+ print ("", >> daolog)
+
+ grpselect (im // ".grp.1", im // ".grp.2", 1, 1, verbose+, >> daolog)
+ print ("", >> daolog)
+ concat (im // ".grp.2", daolog, append=yes)
+ delete (im // ".grp.2", ver-, >& "dev$null")
+
+ # Test the NSTAR task.
+
+ print ("", >> daolog)
+ print ("TESTING THE NSTAR TASK", >> daolog)
+ print ("TESTING THE NSTAR TASK")
+ print ("", >> daolog)
+
+ nstar (im, "default", "default", "default", "", verify-, verbose-,
+ >> daolog)
+ print ("", >> daolog)
+ concat (im // ".nst.1", daolog, append=yes)
+
+ # Test the ALLSTAR task with cache set to yes.
+
+ print ("", >> daolog)
+ print ("TESTING THE ALLSTAR TASK (CACHE=YES)", >> daolog)
+ print ("TESTING THE ALLSTAR TASK (CACHE=YES)")
+ print ("", >> daolog)
+
+ daopars.fitrad=3.0
+
+ allstar (im, "default", "default", "default", "", "default", verify-,
+ verbose-, cache=yes, >> daolog)
+ print ("", >> daolog)
+ concat (im // ".als.1", daolog, append=yes)
+ imdelete (im // ".sub.1", go+, verify-, def+, >& "dev$null")
+
+ # Test the ALLSTAR task with cache set to no.
+
+ print ("", >> daolog)
+ print ("TESTING THE ALLSTAR TASK (CACHE=NO)", >> daolog)
+ print ("TESTING THE ALLSTAR TASK (CACHE=NO)")
+ print ("", >> daolog)
+
+ allstar (im, "default", "default", "default", "", "default", verify-,
+ verbose-, cache=no, >> daolog)
+ print ("", >> daolog)
+ concat (im // ".als.2", daolog, append=yes)
+ imdelete (im // ".sub.1", go+, verify-, def+, >& "dev$null")
+
+ # Test the SUBSTAR task.
+
+ print ("", >> daolog)
+ print ("TESTING THE SUBSTAR TASK", >> daolog)
+ print ("TESTING THE SUBSTAR TASK")
+ print ("", >> daolog)
+
+ substar (im, "default", "", "default", "default", verify-, verbose-,
+ >> daolog)
+ imheader (im //".sub.1", longheader+, userfields+, >> daolog)
+ print ("", >> daolog)
+
+ # Test the ADDSTAR task.
+
+ print ("", >> daolog)
+ print ("TESTING THE ADDSTAR TASK", >> daolog)
+ print ("TESTING THE ADDSTAR TASK")
+ print ("", >> daolog)
+
+ addstar (im, "", "default", "default", minmag=16.0, maxmag=18.0,
+ nstar=3, verify-, verbose-, >> daolog)
+ imheader (im //".add.1", longheader+, userfields+, >> daolog)
+ print ("", >> daolog)
+ concat (im // ".art.1", daolog, append=yes)
+ print ("", >> daolog)
+
+ # Clean up.
+ delete (im // ".coo.1", ver-, >& "dev$null")
+ delete (im // ".mag.1", ver-, >& "dev$null")
+ delete (im // ".pst.1", ver-, >& "dev$null")
+ delete (im // ".psg.1", ver-, >& "dev$null")
+ delete (im // ".pst.2", ver-, >& "dev$null")
+ delete (im // ".pk.1", ver-, >& "dev$null")
+ delete (im // ".grp.1", ver-, >& "dev$null")
+ delete (im // ".nst.1", ver-, >& "dev$null")
+ delete (im // ".als.1", ver-, >& "dev$null")
+ delete (im // ".als.2", ver-, >& "dev$null")
+ delete (im // ".art.1", ver-, >& "dev$null")
+
+ unlearn ("addstar")
+ unlearn ("allstar")
+ unlearn ("centerpars")
+ unlearn ("cntrplot")
+ unlearn ("daofind")
+ unlearn ("daopars")
+ unlearn ("datapars")
+ unlearn ("findpars")
+ unlearn ("fitskypars")
+ unlearn ("group")
+ unlearn ("grpselect")
+ unlearn ("histplot")
+ unlearn ("nstar")
+ unlearn ("pconcat")
+ unlearn ("pconvert")
+ unlearn ("pdump")
+ unlearn ("peak")
+ unlearn ("pexamine")
+ unlearn ("pfmerge")
+ unlearn ("phot")
+ unlearn ("photpars")
+ unlearn ("prenumber")
+ unlearn ("pselect")
+ unlearn ("psf")
+ unlearn ("pstselect")
+ unlearn ("psort")
+ unlearn ("radplot")
+ unlearn ("seepsf")
+ unlearn ("substar")
+ unlearn ("surfplot")
+ unlearn ("xyplot")
+
+ print ("DAOPHOT PACKAGE TESTS COMPLETED", >> daolog)
+ print ("", >> daolog)
+ print ("")
+ print ("DAOPHOT PACKAGE TESTS COMPLETED")
+ print ("")
+
+ bye
+end
diff --git a/noao/digiphot/daophot/datapars.par b/noao/digiphot/daophot/datapars.par
new file mode 100644
index 00000000..4c575bfe
--- /dev/null
+++ b/noao/digiphot/daophot/datapars.par
@@ -0,0 +1,25 @@
+# DATAPARS
+
+scale,r,h,1.0,0.0,,Image scale in units per pixel
+fwhmpsf,r,h,2.5,0.0,,FWHM of the PSF in scale units
+emission,b,h,y,,,Features are positive?
+sigma,r,h,0.0,0.0,,Standard deviation of background in counts
+datamin,r,h,INDEF,,,Minimum good data value
+datamax,r,h,INDEF,,,Maximum good data value
+
+noise,s,h,"poisson","|poisson|",,Noise model
+ccdread,s,h,"",,,CCD readout noise image header keyword
+gain,s,h,"",,,CCD gain image header keyword
+readnoise,r,h,0.0,,,CCD readout noise in electrons
+epadu,r,h,1.0,,,Gain in electrons per count
+
+exposure,s,h,"",,,Exposure time image header keyword
+airmass,s,h,"",,,Airmass image header keyword
+filter,s,h,"",,,Filter image header keyword
+obstime,s,h,"",,,Time of observation image header keyword
+itime,r,h,1.0,,,Exposure time
+xairmass,r,h,INDEF,,,Airmass
+ifilter,s,h,"INDEF",,,Filter
+otime,s,h,"INDEF",,,Time of observation
+
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/doc/addstar.hlp b/noao/digiphot/daophot/doc/addstar.hlp
new file mode 100644
index 00000000..f2e08a45
--- /dev/null
+++ b/noao/digiphot/daophot/doc/addstar.hlp
@@ -0,0 +1,365 @@
+.help addstar May00 noao.digiphot.daophot
+.ih
+NAME
+addstar -- add artificial stars to images
+.ih
+USAGE
+addstar image photfile psfimage addimage
+.ih
+PARAMETERS
+.ls image
+The list of images to which artificial stars are to be added.
+.le
+.ls photfile
+The list of photometry files containing the x and y coordinates and magnitudes
+of the artificial stars to be added to \fIimage\fR. If photfile is undefined,
+then \fInstar\fR artificial stars uniformly distributed in position, and in
+magnitude between \fIminmag\fR and \fImaxmag\fR are added to \fIimage\fR. If
+photfile is defined, there must be one photometry file for every input image.
+Photfile may be a simple text file containing x, y, magnitude, and id number in
+columns 1, 2, 3, and 4 respectively (\fIsimple_text\fR = yes), an APPHOT/DAOPHOT
+text database file (\fIsimple_text\fR = no), or an STSDAS binary table file.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification, then PEAK
+will look for an image with the name image.psf.?, where ? is the highest
+existing version number.
+.le
+.ls addimage
+The root name of the output images. There must be one output root image name
+ for every input image. If addimage is "default", "dir$default" or a directory
+specification, then an output artificial image and artificial star list called
+image.add.? and image.art.? respectively are created, where ? is the next
+available version number. If the DAOPHOT package parameter \fItext\fR is "yes",
+then an APPHOT/DAOPHOT text database file is written, otherwise an STSDAS binary
+table is written.
+.le
+.ls minmag
+The minimum magnitude of the computer generated artificial stars to be
+added to the image. The actual intensities of the pixels in the artificial
+stars are computed with respect to the magnitude of the PSF stored in
+\fIpsfimage\fR.
+.le
+.ls maxmag
+The maximum magnitude of the computer generated artificial stars to be
+added to the image. The actual intensities of the pixels in the artificial
+stars are computed with respect to the magnitude of the PSF stored in
+\fIpsfimage\fR.
+.le
+.ls nstar
+The number of computer generated artificial stars to be added to the input
+image.
+.le
+.ls datapars = ""
+The text file in which the data dependent parameters are stored. The gain
+parameter \fIepadu\fR in electrons per ADU is stored here. If datapars is
+undefined then the default parameter set in the user's uparm directory is used.
+.le
+.ls daopars = ""
+The text file in which the daophot fitting parameters are stored. The PSF
+radius parameter \fIpsfrad\fR in scale units is stored here. If daopars is
+undefined then the default parameter set in the user's uparm directory is used.
+.le
+.ls simple_text = no
+If \fIphotfile\fR is a text file and \fIsimple_text\fR = "no", then ADDSTAR
+expects an APPHOT/DAOPHOT database. Otherwise ADDSTAR expects a simple list
+format with x, y, magnitude, and id in columns 1, 2,3, and 4 respectively.
+.le
+.ls seed = 0
+The seed for the random number generator used to generate the positions
+and magnitudes of the artificial stars.
+.le
+.ls nimage = 1
+The number of output images to be created per input image.
+.le
+.ls idoffset = 0
+The integer offset to be added to the id numbers of stars in the output
+artificial photometry file. By default the artificial stars are numbered from 1
+to N where N is the number of artificial stars added to the input frame.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIphotfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+\fIaddimage\fR respectively. The image header coordinate system is used to
+transform from the input coordinate system to the "logical" pixel coordinate
+system used internally, from the internal logical system to the PSF model
+system, and from the internal "logical" pixel coordinate system to the output
+coordinate system. The input coordinate system options are "logical", "tv",
+"physical", and "world". The PSF model and output coordinate system options
+are "logical", "tv", and "physical". The image cursor coordinate system is
+assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical ADDSTAR task parameters? Verify may be set to the
+daophot package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the critical ADDSTAR task parameters if \fIverify\fR = "yes"?
+Update may be set to the daophot package parameter value (the default),
+"yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of ADDSTAR? Verbose may be set to the
+daophot package parameter value (the default), "yes", or "no".
+.le
+
+.ih
+DESCRIPTION
+
+ADDSTAR adds artificial stars, whose positions and magnitudes are listed in
+\fIphotfile\fR or generated at random by the computer, to the input image
+\fIimage\fR using the PSF in \fIpsfimage\fR, and writes the result to the
+output image and output photometry file \fIaddimage\fR. If \fIphotfile\fR is
+undefined then ADDSTAR generates an artificial photometry list containing
+\fInstar\fR stars uniformly distributed in position over the image and in
+magnitude between \fIminmag\fR and \fImaxmag\fR. The input photometry file
+may be an STSDAS binary table or an APPHOT/DAOPHOT text database file (the
+output of the PHOT, PSF, PEAK, NSTAR, or ALLSTAR tasks) or a simple text file
+with the x and y positions, magnitude, and id in columns 1, 2, 3 and 4
+respectively. The ids of stars in the output photometry file may be set to
+numbers outside the range of the real data by setting the parameter
+\fIoffset\fR. Several output images may be written for each input image by
+setting the parameter \fInimage\fR greater than 1.
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. If photfile is undefined the input coordinate
+system is logical. The options are "logical", "tv", "physical", and "world"
+and the transformation from the input coordinate system to the internal
+"logical" system is defined by the image coordinate system. The simplest
+default is the "logical" pixel system. Users working on with image sections but
+ importing pixel coordinate lists generated from the parent image must use the
+"tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to \fIaddimage\fR are in the coordinate system defined
+by \fIwcsout\fR. The options are "logical", "tv", and "physical". The simplest
+default is the "logical" system. Users wishing to correlate the output
+coordinates of objects measured in image sections or mosaic pieces with
+coordinates in the parent image must use the "tv" or "physical" coordinate
+systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the output image pixels are cached in memory. If caching
+is enabled and the first artificial star addition will appear
+to take a long time as the entire input image must be read into the output
+image before the first artificial star addition is actually made. All
+subsequent measurements will be very fast because ADDSTAR is accessing memory
+not disk. The point of caching is to speed up random image access by making
+the internal image i/o buffers the same size as the image itself. However if
+the input object lists are sorted in row order and sparse caching may actually
+worsen not improve the execution time. Also at present there is no point in
+enabling caching for images that are less than or equal to 524288 bytes, i.e.
+the size of the test image dev$ypix, as the default image i/o buffer is exactly
+that size. However if the size of dev$ypix is doubled by converting it to a
+real image with the chpixtype task then the effect of caching in interactive
+is can be quite noticeable if measurements of objects in the top and bottom
+halves of the image are alternated.
+
+The intensities in the artificial stellar images are computed relative to the
+intensities in the PSF image, by scaling the magnitudes of the artificial stars
+to the magnitude of the PSF in \fIpsfimage\fR. Poisson noise is added to the
+artificial stars using the value of the gain stored in the image header keyword
+specified by the DATAPARS parameter \fIgain\fR if present, or the value of the
+DATAPARS parameter \fIepadu\fR.
+
+.ih
+OUTPUT
+
+If \fIverbose\fR = yes, a line of output is written to the terminal for each
+artificial star added to the input image.
+
+Full output is written to the output photometry file \fIaddimage\fR. At the
+beginning of each file is a header listing the current values of all the
+parameters. For each artificial star added to the input image the following
+record is written.
+
+.nf
+ id xcenter ycenter mag
+.fi
+
+Id is the id number of the star, xcenter and ycenter are its coordinates, and
+mag is its magnitude.
+
+.ih
+EXAMPLES
+
+1. Add 30 stars uniformly distributed between 17 and 20th magnitude and in
+position to the input image m92. Display the new image and mark the
+artificial stars. Good stars for making the PSF model can be found at
+(442,410), (348,189), and (379,67).
+
+.nf
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 5.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> psf dev$ypix default "" default default default psfrad=9.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+ da> addstar dev$ypix "" default default 12.0 17.0 30 epadu=14.0
+
+ ... verify the critical parameters
+
+ da> display ypix.add.1 2
+
+ ... display the artificial image
+
+ da> pdump ypix.art.1 xcenter,ycenter yes | tvmark 2 STDIN col=204
+
+ ... mark the stars on the artificial image
+.fi
+
+
+2. Repeat example 1 using the output starlist as input.
+
+.nf
+ da> addstar dev$ypix ypix.art.1 default default simple- epadu=14.0
+
+ ... the answers will appear in ypix.add.2 and ypix.art.2
+.fi
+
+
+3. Repeat example 1 using a simple text file as input.
+
+.nf
+ da> pdump ypix.art.1 xc,yc,mag yes > artdata
+
+ ... create a simple text file from the addstar output
+
+ da> addstar dev$ypix artdata default default simple+ epadu=14.0
+
+ ... the answers will appear in ypix.add.3 and ypix.art.3
+.fi
+
+
+4. Run addstar on a section of the input image using the PSF model derived in
+example 1 for the parent image, the artificial star list from examples 2 and
+3, and write the results in the coordinate system of the image section
+not the parent image.
+
+.nf
+ da> addstar dev$ypix[150:450,150:450] artdata default default simple+ \
+ epadu=14.0 wcsin=tv wcspsf=tv wcsout=logical
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.add.4 and ypix.art.4
+
+ da> display ypix.add.4 1
+
+ ... display the image
+
+ da> pdump ypix.art.4 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+.fi
+
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/allstar.hlp b/noao/digiphot/daophot/doc/allstar.hlp
new file mode 100644
index 00000000..ab70ff00
--- /dev/null
+++ b/noao/digiphot/daophot/doc/allstar.hlp
@@ -0,0 +1,519 @@
+.help allstar May00 noao.digiphot.daophot
+.ih
+NAME
+allstar -- group and fit psf to multiple stars simultaneously
+.ih
+USAGE
+allstar image photfile psfimage allstarfile rejfile subimage
+.ih
+PARAMETERS
+.ls image
+The list of images containing the stars to be fit.
+.le
+.ls photfile
+The input photometry files containing the initial estimates of the positions,
+sky values, and magnitudes of the stars to be fit. There must be one input
+photometry file for every input image. If photfile is "default", "dir$default",
+or a directory specification, then ALLSTAR looks for a file with the name
+image.mag.? where ? is the highest existing version number. Photfile is usually
+the output of the DAOPHOT PHOT task but may also be the output of the PSF, PEAK
+and NSTAR tasks, or the ALLSTAR task itself.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification, then PEAK
+will look for an image with the name image.psf.?, where ? is the highest
+existing version number.
+.le
+.ls allstarfile
+The list of output photometry files. There must be one output photometry
+file for every input image. If allstarfile is "default", "dir$default", or a
+directory specification, then ALLSTAR will write an output file with the name
+image.als.? where ? is the next available version number. Allstarfile is a text
+database if the DAOPHOT package parameter text is "yes", an STSDAS table
+database if it is "no".
+.le
+.ls rejfile
+The list of output rejected photometry files containing the positions and sky
+values of stars that could not be fit. If rejfile is undefined, results for all
+the stars in photfile are written to \fIallstarfile\fR, otherwise only the stars
+which were successfully fit are written to \fIallstarfile\fR and the remainder
+are written to rejfile. If rejfile is "default", "dir$default", or a directory
+specification ALLSTAR writes an output file with the name image.als.? where ? is
+the next available version number. Otherwise rejfile must specify one output
+photometry file for every input image. Rejfile is a text database if the
+DAOPHOT package parameter \fItext\fR is "yes", an STSDAS binary table database
+if it is "no".
+.le
+.ls subimage
+The list of output images with the fitted stars subtracted. There must be one
+subtracted image for every input image. If subimage is "default", "dir$default",
+or a directory specification, then ALLSTAR will create an image with the name
+image.sub.? where ? is the next available version number. Otherwise
+\fIsubimage\fR must specify one output image for every image in \fIimage\fR.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIphotfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+\fIallstarfile\fR and \fIrejfile\fR respectively. The image header coordinate
+system is used to transform from the input coordinate system to the "logical"
+pixel coordinate system used internally, from the internal logical system to
+the PSF model system, and from the internal "logical" pixel coordinate system
+to the output coordinate system. The input coordinate system options are
+"logical", "tv", "physical", and "world". The PSF model and output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = yes
+Cache all the data in memory ? If \fIcache\fR is "yes", then ALLSTAR attempts
+to preallocate sufficient space to store the input image plus the two
+image-sized working arrays it requires, plus space for the starlist, in memory.
+This can significantly reduce the total execution time. Users should however
+beware of creating a situation where excessive paging occurs. If \fIcache\fR =
+"no", ALLSTAR operates on subrasters containing the group currently being
+reduced, and writes the intermediate results to temporary scratch images. This
+option will work on any-sized image (unless a single group becomes the size of
+the entire image!) but can become slow of there are a large number of disk
+accesses. Users may wish to experiment to see which mode of operation suits
+their system best.
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ls verify = ")_.verify"
+Verify the critical ALLSTAR task parameters. Verify can be set to the daophot
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the critical ALLSTAR task parameters if \fIverify\fR = "yes". Update
+can be set to the daophot package parameter value (the default), "yes", or
+"no".
+.le
+
+.ih
+DESCRIPTION
+
+ALLSTAR computes x and y centers, sky values, and magnitudes for the stars in
+\fIphotfile\fR by fitting the PSF \fIpsfimage\fR to groups of stars in the IRAF
+image \fIimage\fR. Initial estimates of the centers, sky values, and
+magnitudes, are read from the photometry list \fIphotfile\fR. ALLSTAR groups
+the stars dynamically, performing a regrouping operation after every iteration.
+The new computed centers, sky values, and magnitudes are written to
+\fIallstarfile\fR along with the number of iterations it took to fit the
+star, the goodness of fit statistic chi, and the image sharpness statistic
+sharp. If \fIrejfile\fR is not null (""), only stars that are successfully fit
+are written to \fIallstarfile\fR, and the remainder are written to
+\fIrejfile\fR. Otherwise all the stars are written to \fIallstarfile\fR.
+\fIAllstarfile\fR and \fIrejfile\fR are text databases if the DAOPHOT package
+parameter \fItext\fR is "yes", STSDAS table databases if it is "no". An image
+with all the fitted stars subtracted out is written to \fIsubimage\fR. In
+effect ALLSTAR performs the combined operations of GROUP, GRPSELECT, NSTAR,
+and SUBSTAR.
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to the
+internal "logical" system is defined by the image coordinate system. The
+simplest default is the "logical" pixel system. Users working on with image
+sections but importing pixel coordinate lists generated from the parent image
+must use the "tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to \fIallstarfile\fR and \fIrejfile\fR are in the
+coordinate system defined by \fIwcsout\fR. The options are "logical", "tv", and
+"physical". The simplest default is the "logical" system. Users wishing to
+correlate the output coordinates of objects measured in image sections or
+mosaic pieces with coordinates in the parent image must use the "tv" or
+"physical" coordinate systems.
+
+By default ALLSTAR computes new centers for all the stars in \fIphotfile\fR.
+However if the DAOPARS parameter \fIrecenter\fR is "no", ALLSTAR assumes that
+the x and y centers in \fIphotfile\fR are the true centers and does not refit
+them. This option can be quite useful in cases where accurate center values
+have been derived from an image that has been through some non-linear image
+restoration algorithm, but the photometry must be derived from the original
+unrestored image.
+
+By default (\fIgroupsky\fR = "yes") ALLSTAR computes the sky value for each
+group by averaging the individual sky values in \fIphotfile\fR for all the
+stars in the group. If \fIgroupsky\fR = "no", the sky value for each pixel
+which contributes to the group fit is set equal to the mean of the sky values
+for those stars for which the pixel falls within one fitting radius. If the
+DAOPARS parameter \fIfitksy\fR is "yes", then ALLSTAR recomputes the individual
+sky values before averaging over the group, by, every third iteration,
+subtracting off the current best fit for the star and using the pixel values in
+the annulus defined by the DAOPARS parameters \fIsannulus\fR and \fIwsannulus\fR
+to recompute the sky. The actual sky recomputation is done by averaging forty
+percent of the sky pixels centered on the median of the distribution.
+Recomputing the sky can significantly reduce the scatter in the magnitudes in
+regions where the sky background is varying rapidly.
+
+Only pixels within the good data range defined by the DATAPARS task parameters
+\fIdatamin\fR and \fIdatamax\fR are included in the fit. Most users set
+\fIdatamin\fR and \fIdatamax\fR so as to exclude pixels outside the linearity
+regime of the detector. By default all the data is fit. Users are advised to
+determine accurate values for these parameters for their detector and set the
+values in DATAPARS before beginning any DAOPHOT reductions.
+
+Only pixels within the fitting radius parameter \fIfitrad\fR / \fIscale\fR are
+included in the fit for each star. \fIFitrad\fR is located in the DAOPARS task
+and \fIscale\fR is located in the DATAPARS task. Since the non-linear
+least-squares fits normally compute three unknowns, the x and y position of
+the star's centroid and its brightness, the value of \fIfitrad\fR must be
+sufficiently large to include at least three pixels in the fit for each star.
+To accelerate the convergence of the non-linear least-squares fitting algorithm
+pixels within \fIfitrad\fR are assigned weights which are inversely
+proportional to the radial distance of the pixel from the x and y centroid of
+the star, falling from a maximum at the centroid to zero at the fitting radius.
+\fIFitrad\fR must be sufficiently large to include at least three pixels with
+non-zero radial weights in the fit for each star. ALLSTAR arbitrarily imposes a
+minimum number of good pixels limit of four. Values of \fIfitrad\fR close to
+the full-width at half-maxima of the PSF are recommended.
+
+ALLSTAR computes a weighted fit to the PSF. The weight of each pixel is
+computed by combining, the radial weighting function described above, with
+weights derived from the random errors ALLSTAR predicts based on the detector
+noise characteristics specified by the DATAPARS parameters \fIreadnoise\fR and
+\fIepadu\fR, and the flat-fielding and profile interpolation errors specified
+by the DAOPARS task \fIflaterr\fR and \fIproferr\fR parameters. Both to obtain
+optimal fits, and because ALLSTAR employs a conservative formula for reducing
+the weights of deviant pixels (parametrized by the \fIclipexp\fR and
+\fIcliprange\fR parameters in the DAOPARS task) which do not approach the model
+as the fit proceeds, which depends on \fIreadnoise\fR, \fIepadu\fR,
+\fIflaterr\fR, and \fIproferr\fR, users are strongly advised to determine those
+parameters accurately and to enter their values in DATAPARS and DAOPARS before
+beginning any DAOPHOT reductions.
+
+By default for each group of stars to be fit during each iteration, ALLSTAR
+extracts a subraster from \fIimage\fR which extends approximately \fIfitrad\fR
+/ \fIscale\fR + 1 pixels wide past the limiting values of x and y coordinates
+of the stars in the group. \fIFitrad\fR is the fitting radius specified in the
+DAOPARS task. \fIScale\fR is the image scale specified by the DATAPARS task.
+\fIFitrad\fR may be less than or equal to but can never exceed the value of the
+image header parameter "PSFRAD" in \fIpsfimage\fR.
+
+If the \fIcache\fR parameter is set to "yes" then ALLSTAR attempts to store all
+the vectors and arrays in memory. This can significantly reduce the system
+overhead but may cause excessive paging on machines with a small amount of
+memory. For large images it may be necessary to set \fIcache\fR to "no", and
+use the disk for scratch storage. Users should experiment to see what suits
+them best.
+
+As well as the computed x and y centers, sky values, and magnitudes, ALLSTAR
+outputs the number of times the PSF fit had to be iterated before convergence
+was achieved. The minimum number of iterations is four. The maximum number of
+iteration permitted is specified by the \fImaxiter\fR parameter in the DAOPARS
+task. Obviously the results for stars which have reached the maximum iteration
+count should be viewed with suspicion. However since the convergence criteria
+are quite strict, (the computed magnitude must change by less than .0005
+magnitudes or 0.10 sigma whichever is larger and the x and y centroids must
+change by less than 0.002 pixels from one iteration to the next), even these
+stars may be reasonably well measured.
+
+ALLSTAR computes a goodness of fit statistic chi which is essentially the ratio
+of the observed pixel-to-pixel scatter in the fitting residuals to the expected
+scatter. Since the expected scatter is dependent on the DATAPARS task parameters
+\fIreadnoise\fR and \fIepadu\fR, and the DAOPARS parameters \fIflaterr\fR and
+\fIproferr\fR, it is important for these values to be set correctly. A plot of
+chi versus magnitude should scatter around unity with little or no trend in chi
+with magnitude, except at the bright end where saturation effects may be
+present.
+
+Finally ALLSTAR computes the statistic sharp which estimates the intrinsic
+angular size of the measured object outside the atmosphere. Sharp is roughly
+defined as the difference between the square of the width of the object and the
+square of the width of PSF. Sharp has values close to zero for single stars,
+large positive values for blended doubles and partially resolved galaxies and
+large negative values for cosmic rays and blemishes.
+
+ALLSTAR implements a sophisticated star rejection algorithm. First of all any
+group of stars which is more than a certain size is not reduced. This maximum
+group size is specified by the \fImaxgroup\fR parameter in the DAOPARS task.
+Large groups may run into numerical precision problems during the fits, so
+users should increase this parameter with caution. ALLSTAR however, in
+contrast to NSTAR, attempts to subdivide large groups. If the group is too
+dense to reduce in size, ALLSTAR throws out the faintest star in the group
+and tries to rereduce it. If two stars in a group have centroids separated
+by a critical distance currently set arbitrarily to 0.37 * the FWHM of the
+stellar core and their photocentric position and combined magnitude is assigned
+to the brighter of the two and the fainter is eliminated. Any star which
+converges to magnitude 12.5 magnitudes greater than the magnitude of the PSF
+is considered to be non-existent and eliminated from the group.
+
+After iteration 5, if the faintest star in the group has a brightness less
+than one sigma above zero it is eliminated. After iteration 10 if the faintest
+star in the group has a brightness less than 1.5 sigma above zero it is
+eliminated. After iteration 15, or whenever the solutions has converged
+whichever comes first, if the faintest star in the group has a brightness less
+than 2.0 sigma above zero it is eliminated. After iterations 5, 10 and 15 if
+two stars are separated by more than 0.37 * FWHM and less than 1.0 * FWHM and
+if the fainter of the two is more uncertain than 1.0, 1.5 or 2.0 sigma
+respectively the fainter one is eliminated.
+
+ALLSTAR replaces the functionality of the GROUP, GRPSELECT, NSTAR and SUBSTAR
+task. However the user has little control over the grouping process and does
+not know at the end which stars were fit together. The grouping process is
+dynamic, as the groups are recomputed after each iteration, and stars can be
+fit and leave the group at any point after the fourth iteration. Therefore the
+quality of the fits may vary over the image as a function of crowding in an
+unknown way. However ALLSTAR is in most cases the routine of choice. NSTAR
+is the task of choice when a user wants to maintain control over the
+composition of the stellar groups.
+
+.ih
+OUTPUT
+
+If \fIverbose\fR = yes, a single line is output to the terminal for each star
+fit or rejected. Full output is written to \fIallstarfile\fR and \fIrejfile\fR.
+At the beginning of these two files a header listing the current values of the
+parameters is written. For each star fit/rejected the following quantities are
+written to the output file.
+
+.nf
+ id xcenter ycenter mag merr msky niter sharpness chi
+ pier perr
+.fi
+
+Id is the id number of the star. Xcenter and ycenter are the fitted coordinates
+in pixels. Mag and merr are the fitted magnitude and magnitude error
+respectively. Msky is the individual sky value for the star. Niter is the
+number of iterations it took to fit the star and sharpness and chi are the
+sharpness and goodness of fit statistic respectively. Pier and perror are the
+photometry error code and accompanying error message respectively.
+
+.ih
+ERRORS
+
+If no errors occur during the fitting process then pier is 0. Non-zero
+values of pier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 1 # The star is in a group too large to fit
+ 2 # The sky is undefined
+ 3 # There are too few good pixels to fit the star
+ 4 # The fit is singular
+ 5 # The star is too faint
+ 6 # The star has merged with a brighter star
+ 7 # The star is off the image
+.fi
+
+.ih
+EXAMPLES
+
+1. Fit the PSF to a list stars in the test image dev$ypix. Good stars for
+making the PSF model can be found at (442,410), (348,189), and (379,67).
+
+.nf
+ da> datapars.epadu = 14.0
+ da> datapars.readnoise = 75.0
+
+ ... set the gain and readout noise for the detector
+
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 3.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ da> psf dev$ypix default "" default default default psfrad=11.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+ da> allstar dev$ypix default default default default default
+
+ ... verify the prompts
+
+ ... the results will appear in ypix.als.1 and ypix.arj.1
+
+ da> pdump ypix.als.1 sharpness,chi yes | graph
+
+ ... plot chi versus sharpness, the stars should cluster around
+ sharpness = 0.0 and chi = 1.0, note that the frame does
+ not have a lot of stars
+
+ da> display ypix.sub.1 2
+
+ ... note that the psf stars subtract reasonably well but other
+ objects which are not stars don't
+.fi
+
+
+2. Repeat example 1 but refit the sky using an annulus with an inner sky
+radius of 3.0 and an outer radius of 15.0.
+
+.nf
+ da> allstar dev$ypix default default default default default fitsky+ \
+ sannulus=3.0 wsannulus=12.0
+
+ ... verify the prompts
+
+ ... the results will appear in ypix.als.2 and ypix.arj.2
+
+ da> pdump ypix.als.2 sharpness,chi yes | graph
+
+ ... plot chi versus sharpness, the stars should cluster around
+ sharpness = 0.0 and chi = 1.0, note that the frame does
+ not have a lot of stars
+
+ da> display ypix.sub.2 2
+
+ ... note that the psf stars subtract reasonably well but other
+ objects which are not stars don't
+.fi
+
+
+
+3. Run allstar on a section of the input image using the group file and PSF
+model derived in example 1 for the parent image and writing the results
+in the coordinate system of the parent image.
+
+.nf
+ da> allstar dev$ypix[150:450,150:450] default default default default \
+ default wcsin=tv wcspsf=tv wcsout=tv
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.als.3 and ypix.arj.3
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.als.3 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars on the original image
+
+ da> display ypix.sub.3 2
+
+ ... display the subtracted image section
+
+.fi
+
+
+4. Run allstar exactly as in example 1 but submit the task to the background.
+Turn off verify and verbose.
+
+.nf
+ da> allstar dev$ypix default default default default default verbose- \
+ verify- &
+
+ ... the results will appear in ypix.als.4 and ypix.arj.4
+.fi
+
+
+4. Run ALLSTAR exactly as in example 3 but turn caching off.
+
+.nf
+ da> allstar m92 m92.grp.1 m92.psf.1 default "" default verb+ veri- \
+ cache- > allstar.out &
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,peak,nstar
+.endhelp
diff --git a/noao/digiphot/daophot/doc/centerpars.hlp b/noao/digiphot/daophot/doc/centerpars.hlp
new file mode 100644
index 00000000..7b461cb1
--- /dev/null
+++ b/noao/digiphot/daophot/doc/centerpars.hlp
@@ -0,0 +1,207 @@
+.help centerpars May00 noao.digiphot.daophot
+.ih
+NAME
+centerpars -- edit the centering algorithm parameters
+.ih
+USAGE
+centerpars
+.ih
+PARAMETERS
+.ls calgorithm = "none"
+The centering algorithm. The "gauss" and "ofilter" centering algorithms
+depend critically on the value of the fwhmpsf parameter in the DATAPARS task.
+The centering options are:
+.ls none
+The initial positions are assumed to be the true centers. Users should
+select this option if the initial centers are known to be accurate,
+e.g. they were computed by DAOFIND task.
+.le
+.ls centroid
+The object centers are determined by computing the intensity weighted means
+of the marginal profiles in x and y. Centroid is the recommended centering
+algorithm for users running PHOT interactively and selecting objects
+with the image display cursor, or when the input coordinates may be inaccurate.
+.le
+.ls gauss
+The object centers are computed by fitting a Gaussian of fixed fwhmpsf,
+specified by the DATAPARS fwhmpsf parameter, to the marginal profiles in
+x and y using non-linear least squares techniques.
+.le
+.ls ofilter
+The object centers are computed using optimal filtering techniques,
+a triangular weighting function of half width equal to fwhmpsf as
+specified by the DATAPARS fwhmpsf parameter, and the marginal distributions
+in x and y.
+.le
+.le
+.ls cbox = 5.0 (scale units)
+The width of the subraster used for object centering in units of the
+scale parameter. Cbox needs to be big enough to include sufficient
+pixels for centering but not so large as to include a lot of noise.
+Reasonable starting values are 2.5-4.0 * FWHM of the PSF.
+.le
+.ls cthreshold = 0.0 (sigma units)
+xels cthreshold * sigma above (emission features) or below (absorption
+features) the data minimum or maximum respectively are used by the centering
+algorithms where sigma is equal to the value of the DATAPARS sigma parameter.
+features) the data minimum or maximum are used by the centering algorithms.
+DAOPHOT users should leave this value at 0.0 which invokes the appropriate
+default thresholding technique for each centering algorithm. Setting
+cthreshold to INDEF turns off thresholding altogether for all the centering
+algorithms.
+.le
+.ls minsnratio = 1.0
+The minimum signal to noise ratio for object centering. If the estimated signal
+to noise ratio is less than minsnratio the computed center will be returned
+with an error flag.
+.le
+.ls cmaxiter = 10
+The maximum number of iterations performed by the centering algorithm.
+All the centering algorithms use this parameter.
+.le
+.ls maxshift = 1.0 (scale units)
+The maximum permissible shift of the center with respect to the initial
+coordinates in units of the scale parameter. If the shift produced by the
+centering algorithms is larger than maxshift, the computed center is returned
+with an error flag.
+.le
+.ls clean = no
+Symmetry-clean the centering subraster before centering? DAOPHOT users should
+leave clean set to "no".
+.le
+.ls rclean = 1.0 (scale units)
+The cleaning radius for the symmetry-clean algorithm in units of
+the scale parameter.
+.le
+.ls rclip = 2.0 (scale units)
+The clipping radius for the symmetry-clean algorithm in units of
+the scale parameter.
+.le
+.ls kclean = 3.0 (sigma)
+The number of standard sky deviations for the symmetry-clean algorithm.
+.le
+.ls mkcenter = no
+Mark the fitted centers on the displayed image ?
+.le
+.ih
+DESCRIPTION
+
+The centering algorithm parameters control the action of the centering
+algorithms. The default parameters values have been proven to produce
+reasonable results in the majority of cases. Several of the centering
+parameters are defined in terms of the DATAPARS parameter \fIscale\fR,
+the scale of the image, and \fIsigma\fR the standard deviation of
+the sky pixels.
+
+For each object to be measured a subraster of data \fIcbox\fR / \fIscale\fR
+pixels wide around the initial position supplied by the user is extracted
+from the IRAF image. If scale is defined in units of the number
+the half-width half-maximum of the psf per pixel, then a single value of
+cbox can be used for centering objects in images with different psfs.
+
+If \fIclean\fR is "yes" the symmetry-clean algorithm is applied to the
+centering subraster prior to centering. The cleaning algorithm attempts
+to correct defects in the centering subraster by assuming that the image
+is radially symmetric and comparing pixels on opposite sides of the center
+of symmetry. The center of symmetry is assumed to be the maximum pixel
+in the subraster, unless the maximum pixel is more than \fImaxshift /
+scale\fR from the initial center, in which case the initial center is used
+as the center of symmetry. Pixels inside the cleaning radius are not edited.
+Pairs of pixels in the cleaning region, r > \fIrclean\fR / \fIscale\fR
+and r <= \fIrclip\fR / \fIscale\fR and diametrically opposed about the
+center of symmetry are tested for equality. If the difference between the
+pixels is greater than \fIkclean * sigma\fR, the larger value is replaced
+by the smaller. In the cleaning region the sigma is determined by the
+noise model assumed for the data. Pairs of pixels in the clipping region,
+r > \fIrclip\fR / \fIscale\fR are tested in the same manner as those in
+the cleaning region. However the sigma employed is the sigma of the
+sky background. DAOPHOT users should leave clean set to "no".
+
+
+
+
+New centers are computed using the centering algorithm specified by
+\fIcalgorithm\fR, the data specified by \fIcbox / scale\fR, and pixels
+that are some threshold above (below) an estimate of the local minimum
+(maximum). \fICthreshold\fR values of 0.0, a positive number, and INDEF
+invoke the default thresholding algorithm, a threshold equal to the
+local minimum (maximum) plus (minus) \fIdatapars.sigma * cthreshold\fR,
+and a threshold exactly equal to the local minimum (maximum) respectively.
+
+After thresholding the signal to noise ratio of the subraster is estimated.
+If the SNR < \fIminsnratio\fR the new center is still computed but an error
+flag is set.
+
+The default centering algorithm is \fInone\fR is which case the initial
+centers are assumed to be accurate and no recentering is done.
+
+The simplest centering algorithm is \fIcentroid\fR. Centroid computes the
+intensity weighted mean and mean error of the centering box x and y marginal
+distributions using points in the marginal arrays above (below) the minimum
+(maximum) data pixel plus (minus) a threshold value. The threshold value is
+either the mean, \fIdatapars.sigma * cthreshold\fR above (below) the local
+minimum (maximum) if \fIcthreshold\fR is greater than zero, or zero above
+(below) the local minimum (maximum) if \fIcthreshold\fR is INDEF. The centroid
+algorithm is similar to that by the old KPNO Mountain Photometry Code.
+Note that centroid is the only centering algorithm which does not depend
+on the value of \fIdatapars.fwhmpsf\fR.
+
+The centering algorithm \fIgauss\fR computes the new centers by fitting a
+1D Gaussian function to the marginal distributions in x and y using a
+fixed fwhmpsf set by \fIdatapars.fwhmpsf\fR. Initial guesses for the fit
+parameters are derived from the data. The gauss algorithm iterates until
+a best fit solution is achieved.
+
+The final centering algorithm choice \fIofilter\fR employs a variation of the
+optimal filtering technique in which the profile is simulated by a triangle
+function of width \fIdatapars.fwhmpsf\fR.
+
+The default thresholding algorithm for all centering algorithms other
+than "centroid" is no thresholding.
+
+If the computed shift in either coordinate > \fImaxshift\fR / \fIscale\fR,
+the new center is returned but an error flag is set.
+
+
+1. List the centering parameters.
+
+.nf
+ da> lpar centerpars
+.fi
+
+2. Edit the centering parameters.
+
+.nf
+ da> centerpars
+.fi
+
+3. Edit the CENTERPARS parameters from with the PHOT task.
+
+.nf
+ da> epar phot
+
+ ... edit a few phot parameters
+
+ ... move to the centerpars parameter and type :e
+
+ ... edit the centerpars parameters and type :wq
+
+ ... finish editing the phot parameters and type :wq
+.fi
+
+4. Save the current CENTERPARS parameter set in a text file ctrnite1.par.
+This can also be done from inside a higher level task as in the
+above example.
+
+.nf
+ da> epar centerpars
+
+ ... type ":w ctrnite1.par" from within epar
+.fi
+.ih
+BUGS
+
+.ih
+SEE ALSO
+epar,lpar,datapars,phot
+.endhelp
diff --git a/noao/digiphot/daophot/doc/daoedit.hlp b/noao/digiphot/daophot/doc/daoedit.hlp
new file mode 100644
index 00000000..fa3ed38d
--- /dev/null
+++ b/noao/digiphot/daophot/doc/daoedit.hlp
@@ -0,0 +1,164 @@
+.help daoedit May00 noao.digiphot.daophot
+.ih
+NAME
+daoedit -- edit the daophot package parameters interactively
+.ih
+USAGE
+daoedit image
+.ih
+PARAMETERS
+.ls image
+.le
+.ls icommands = ""
+The image display cursor or image cursor commands file.
+.le
+.ls gcommands = ""
+The graphics cursor or graphics cursor commands file.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls graphics = ")_.graphics"
+The standard graphics device.
+.le
+.ls display = ")_.display"
+The standard display device.
+.le
+.ih
+DESCRIPTION
+
+DAOEDIT is a general purpose tool for interactively examining and editing
+the DAOPHOT algorithm parameters located in the parameter sets DATAPARS,
+FINDPARS, CENTERPARS, FITSKYPARS, PHOTPARS, and DAOPARS. These five parameter
+sets can be listed, edited, and/or unlearned as a group from within DAOEDIT
+using the IRAF LPAR, EPAR and UNLEARN utilities. Any parameter in each of
+these five parameter sets can be examined or edited individual using a simple
+command. Parameters which are defined in terms of radial distance from the
+center of a star or in terms of image counts can be examined and edited
+interactively using radial profile plots and the graphics cursor.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled the first data measurement will appear to take a long time as the
+entire image must be read in before the measurement is actually made. All
+subsequent measurements will be very fast because DAOEDIT is accessing memory
+not disk. The point of caching is to speed up random image access by making
+the internal image i/o buffers the same size as the image itself. At present
+there is no point in enabling caching for images that are less than or equal
+to 524288 bytes, i.e. the size of the test image dev$ypix, as the default image
+ i/o buffer is exactly that size. However if the size of dev$ypix is doubled by
+ converting it to a real image with the chpixtype task then the effect of
+caching in interactive is can be quite noticeable if measurements of objects
+in the top and bottom halves of the image are alternated.
+
+.ih
+CURSOR COMMANDS
+
+.nf
+ Interactive Keystroke Commands
+
+? Print help
+: Colon commands
+a Estimate center, sky, skysigma, fwhmpsf and magnitude of a star
+r Plot the radial profile of a star and its integral
+i Set selected parameters interactively using a radial profile plot
+g Toggle between image and graphics cursor
+x Toggle the radial profile plot between pixel and scale units
+y Toggle the radial profile plot between counts and normal units
+q Quit task
+
+ Colon Commands
+
+:lparam/eparam/unlearn pset List/edit/unlearn the named pset
+:parameter [value] List or set an individual pset parameter
+
+
+ Psets
+
+datapars The data dependent parameters
+findpars The daofind task object detection parameters
+centerpars The phot task centering algorithm parameters
+fitskypars The phot task sky fitting algorithm parameters
+photpars The phot task photometry algorithm parameters
+daopars The psf fitting algorithm parameters
+
+
+The following commands are available from within the interactive setup
+menu.
+
+
+ Interactive Daoedit Setup Menu
+
+? Print help
+spbar Mark/verify critical parameters (f, s, a, d, r, w, b)
+q Quit
+
+f Mark/verify the fwhm of the psf on the radial profile plot
+s Mark/verify the sky sigma on the radial profile plot
+l Mark/verify the minimum good data value on the radial profile plot
+u Mark/verify the maximum good data value on the radial profile plot
+
+c Mark/verify the centering box half-width on the radial profile plot
+n Mark/verify the cleaning radius on the radial profile plot
+p Mark/verify the clipping radius on the radial profile plot
+
+a Mark/verify the inner sky annulus radius on the radial profile plot
+d Mark/verify the width of the sky annulus on the radial profile plot
+g Mark/verify the sky region growing radius on the radial profile plot
+
+r Mark/verify the photometry aperture(s) on the radial profile plot
+w Mark/verify the psf function radius on the radial profile plot
+b Mark/verify the psf fitting radius on the radial profile plot
+
+.fi
+
+.ih
+EXAMPLES
+
+1. Setup the daophot package parameters interactively for the image m92.
+This example assumes that the parameters are all initially at their
+default values.
+
+.nf
+ da> display dev$ypix 1
+ da> daoedit dev$ypix
+
+ ... type :e datapars to edit the data dependent parameters
+ ... leave scale at 1.0 and datamin at INDEF but set the
+ datamax, readnoise, epadu, exposure, airmass, filter,
+ and obstime parameters to appropriate values
+ ... type :l datapars to check the results of the editing
+
+ ... type :e findpars to check the object detection parameters
+ ... change the findpars threshold parameter from 4.0 to 5.0
+ using the command :threshold 5.0
+
+ ... type i to enter the interactive setup menu
+ set the fwhmpsf, sigma, inner radius of the sky annulus,
+ width of the sky annulus, photometry aperture(s), psf
+ radius, and fitting radius using the radial profile
+ plot and graphics cursor
+
+ ... select a bright non-saturated star and check that its
+ radial profile is normal using the r keystroke command
+ ... note the value of the standard deviation of the sky
+ background written in the plot header
+ ... set the datapars sigma parameter to this value using
+ the command :sigma <value>
+
+ ... check the data definition, centering, sky fitting,
+ photometry, and psf fitting parameters with the commands
+ :l datapars, :l centerpars, :l fitskypars, :l photpars,
+ and :l daopars
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,findpars,centerpars,fitskypars,photpars,daopars,setimpars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/daofind.hlp b/noao/digiphot/daophot/doc/daofind.hlp
new file mode 100644
index 00000000..a2b1c3f8
--- /dev/null
+++ b/noao/digiphot/daophot/doc/daofind.hlp
@@ -0,0 +1,601 @@
+.help daofind May00 noao.digiphot.daophot
+.ih
+NAME
+daofind -- automatically detect objects in images
+.ih
+USAGE
+daofind image output
+.ih
+PARAMETERS
+.ls image
+The list of images in which objects are to be detected.
+.le
+.ls output
+The name of the results file or the results directory. If output is
+"default", "dir$default" or a directory specification then a results file
+name of the form dir$root.extension.version is constructed, where
+dir is the directory, root is the root image name, extension is "coo"
+and version is the next available version number for the file. If the
+output string is undefined then no output file is created. One output
+file is created for every input image.
+.le
+.ls starmap = ""
+The name of the image prefix and/or directory where the density enhancement
+image will be stored. If starmap is undefined or a directory,
+DAOFIND will create a temporary image which is deleted on exit from
+the program. Otherwise starmap is prefixed to the image name
+and the density enhancement image will be saved for use in a subsequent
+run of DAOFIND.
+.le
+.ls skymap = ""
+The name of the image prefix and/or directory where the mean density
+image will be stored. If skymap is undefined or a directory, no mean density
+image is created. Otherwise skymap is prefixed to the image name
+and the mean density image will be saved on disk. Skymap is not used by
+the DAOFIND algorithms, but may be used by the user as a check on DAOFIND,
+since the sum of starmap and skymap is a type of best fit to the original
+image.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The critical
+parameters \fIfwhmpsf\fR and \fIsigma\fR are located here. If \fIdatapars\fR
+is undefined then the default parameter set in the user's uparm directory is
+used.
+.le
+.ls findpars = ""
+The name of the file containing the object detection parameters. The
+parameter \fIthreshold\fR is located here. If findpars is undefined then
+the default parameter set in the user's uparm directory is used.
+.le
+.ls boundary = "nearest"
+The type of boundary extension. The choices are:
+.ls nearest
+Use the value of the nearest boundary pixel.
+.le
+.ls constant
+Use a constant value.
+.le
+.ls reflect
+Generate a value by reflecting around the boundary.
+.le
+.ls wrap
+Generate a value by wrapping around to the other side of the image.
+.le
+.le
+.ls constant = 0
+The constant for constant boundary extension.
+.le
+.ls interactive = no
+Interactive or batch mode?
+.le
+.ls icommands = ""
+The image display cursor or image cursor command file.
+.le
+.ls gcommands = ""
+The graphics cursor or graphics cursor command file.
+.le
+.ls wcsout = ")_.wcsout"
+The coordinate system of the output coordinates written to \fIoutput\fR. The
+image header coordinate system is used to transform from the internal "logical"
+pixel coordinate system to the output coordinate system. The output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+ system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+The wcsout parameter defaults to the value of the package parameter of the same
+ name. The default values of the package parameters wcsin and wcsout are
+"logical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Automatically confirm the critical parameters when running in non-interactive
+mode ? Verify may be set to the daophot package parameter value (the default),
+"yes", or "no".
+.le
+.ls update = ")_.update"
+Automatically update the parameters when running in non-interactive mode if
+verify is "yes"? Update may be set to the daophot package parameter value
+(the default), "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print out information about the progress of the task in non-interactive mode.
+Verbose may be set to the daophot package parameter value (the default), "yes",
+or "no".
+.le
+.ls graphics = ")_.graphics"
+The standard graphics device. Graphics may be set to the apphot package
+parameter value (the default), "yes", or "no".
+.le
+.ls display = ")_.display"
+The standard image display device. Display may be set to the apphot package
+parameter value (the default), "yes", or "no". By default graphics overlay is
+disabled. Setting display to one of "imdr", "imdg", "imdb", or "imdy" enables
+graphics overlay with the IMD graphics kernel. Setting display to "stdgraph"
+enables DAOFIND to work interactively from a contour plot.
+.le
+
+.ih
+DESCRIPTION
+
+DAOFIND searches the IRAF images \fIimage\fR for local density maxima,
+with a full-width half-maxima of \fIdatapars.fwhmpsf\fR, and a peak amplitude
+greater than \fIfindpars.threshold\fR * \fIdatapars.sigma\fR above the local
+background, and writes a list of detected objects in the file \fIoutput\fR.
+The detected objects are also listed on the standard output if the program is
+running in interactive mode or if the \fIverbose\fR switch is enabled in
+non-interactive mode.
+
+The coordinates written to \fIoutput\fR are in the coordinate
+system defined by \fIwcsout\fR. The options are "logical", "tv",
+and "physical". The simplest default is the "logical" system. Users
+wishing to correlate the output coordinates of objects measured in
+image sections or mosaic pieces with coordinates in the parent
+image must use the "tv" or "physical" coordinate systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input and output image pixels are cached in memory. If
+caching is enabled and DAOFIND is run interactively the first measurement
+will appear to take a long time as the entire image must be read in before the
+measurement is actually made. All subsequent measurements will be very fast
+because DAOFIND is accessing memory not disk. The point of caching is to speed
+up random image access by making the internal image i/o buffers the same size
+as the image itself. However if the input object lists are sorted in row order
+and sparse caching may actually worsen not improve the execution time. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+DAOFIND can be run either interactively or in batch mode by setting the
+parameter \fIinteractive\fR. In interactive mode the user can examine,
+adjust and save algorithm parameters, and fit or refit the entire list
+with the chosen parameter set. The \fIverify\fR parameter can be used to
+automatically confirm the critical parameters \fIdatapars.fwhmpsf\fR and
+\fIdatapars.sigma\fR when running in non-interactive mode.
+
+
+.ih
+CURSOR COMMANDS
+
+.nf
+
+ Interactive Keystroke Commands
+
+? Print help
+: Colon commands
+v Verify critical parameters
+w Save the current parameters
+d Plot radial profile of star near cursor
+i Interactively set parameters using star near cursor
+f Find stars in the image
+spbar Find stars in the image and output results
+q Exit task
+
+
+ Colon Commands
+
+:show [data/find] List the parameters
+
+ Colon Commands
+
+# Image and file name parameters
+
+:image [string] Image name
+:output [string] Output file name
+
+# Data dependent parameters
+
+:scale [value] Image scale (units per pixel)
+:fwhmpsf [value] Full width half maximum of psf (scale units)
+:emission [y/n] Emission feature (y), absorption (n)
+:sigma [value] Standard deviation of sky (counts)
+:datamin [value] Minimum good data value (counts)
+:datamax [value] Maximum good data value (counts)
+
+# Noise description parameters
+
+:noise [string] Noise model (constant|poisson)
+:gain [string] Gain image header keyword
+:ccdread [string] Readout noise image header keyword
+:epadu [value] Gain (electrons per adu)
+:readnoise [value] Readout noise (electrons)
+
+# Observation parameters
+
+:exposure [string] Exposure time image header keyword
+:airmass [string] Airmass image header keyword
+:filter [string] Filter image header keyword
+:obstime [string] Time of observation image header keyword
+:itime [value] Exposure time (time units)
+:xairmass [value] Airmass value (number)
+:ifilter [string] Filter id string
+:otime [string] Time of observation (time units)
+
+# Object detection parameters
+
+:nsigma [value] Size of Gaussian kernel (sigma)
+:threshold [value] Detection intensity threshold (counts)
+:ratio [value] Sigmay / sigmax of Gaussian kernel
+:theta [value] Position angle of Gaussian kernel
+:sharplo [value] Lower bound on sharpness
+:sharphi [value] Upper bound on sharpness
+:roundlo [value] Lower bound on roundness
+:roundhi [value] Upper bound on roundness
+
+# Plotting and marking commands
+
+:mkdetections [y/n] Mark detections on the image display
+
+
+
+The following commands are available from inside the interactive setup menu.
+
+
+ Interactive Daofind Setup Menu
+
+ v Mark and verify critical daofind parameters (f,s)
+
+ f Mark and verify the full-width half-maximum of the psf
+ s Mark and verify the standard deviation of the background
+ l Mark and verify the minimum good data value
+ u Mark and verify the maximum good data value
+
+.fi
+
+.ih
+ALGORITHMS
+
+DAOFIND approximates the stellar point spread function with an elliptical
+Gaussian function, whose sigma along the semi-major axis is 0.42466 *
+\fIdatapars.fwhmpsf\fR / \fIdatapars.scale\fR pixels, semi-minor to semi-major
+axis ratio is \fIratio\fR, and major axis position angle is \fItheta\fR.
+Using this model, a convolution kernel, truncated at \fInsigma\fR sigma,
+and normalized so as to sum to zero, is constructed.
+
+The density enhancement image \fIstarmap\fR is computed by convolving the input
+image with the Gaussian kernel. This operation is mathematically equivalent to
+fitting, in the least-squares sense, the image data at each point with a
+truncated, lowered elliptical Gaussian function. After convolution each point
+in \fIstarmap\fR contains as estimate of the amplitude of the best fitting
+Gaussian function at that point. Each point in \fIskymap\fR, if the user
+chooses to compute it, contains an estimate of the best fitting sky value
+at that point.
+
+After image convolution , DAOFIND steps through \fIstarmap\fR searching
+for density enhancements greater than \fIfindpars.threshold\fR *
+\fIdatapars.sigma\fR, and brighter than all other density enhancements within
+a semi-major axis of 0.42466 \fIfindpars.nsigma\fR * \fIdatapars.fwhmpsf\fR.
+As the program selects candidates, it computes three shape characteristics,
+sharpness and 2 estimates of roundness. The sharpness statistic measures the
+ratio of, the difference between the height of the central pixel and the mean
+of the surrounding non-bad pixels, to the height of the best fitting Gaussian
+function at that point. The first roundness characteristic computes the ratio
+of a measure of the bilateral symmetry of the object to a measure of the
+four-fold symmetry of the object. The second roundness statistic measures the
+ratio of, the difference in the height of the best fitting Gaussian function
+in x minus the best fitting Gaussian function in y, over the average of the
+best fitting Gaussian functions in x and y. The limits on these parameters
+\fIfindpars.sharplo\fR, \fIfindpars.sharphi\fR \fIfindpars.roundlo\fR, and
+\fIfindpars.roundhi\fR, are set to weed out non-astronomical objects and
+brightness enhancements that are elongated in x and y respectively.
+
+Lastly the x and y centroids of the detected objects are computed by estimating
+the x and y positions of the best fitting 1D Gaussian functions in x and y
+respectively, a rough magnitude is estimated by computing the ratio of the
+amplitude of the best fitting Gaussian at the object position to
+\fIfindpars.threshold\fR * \fIdatapars.sigma\fR, and the object is added to
+the output coordinate file.
+
+
+.ih
+OUTPUT
+
+In interactive mode or in non-interactive with the verbose switch turned on
+the following quantities are written to the terminal as each object is
+detected.
+
+.nf
+ xcenter ycenter mag sharpness sround ground id
+
+ where
+
+ mag = -2.5 * log10 (peak density / detection threshold)
+.fi
+
+
+The object centers are in pixels and the magnitude estimate measures the
+ratio of the maximum density enhancement to the detection threshold.
+Sharpness is typically around .5 to .8 for a star with a fwhmpsf similar to
+the pattern star. Both sround and ground are close to zero for a truly
+round star. Id is the sequence number of the star in the list.
+
+In both interactive and batch mode the full output is written to the text
+file \fIoutput\fR. At the beginning of each file is a header, listing
+the current values of the parameters when the first stellar record was
+written. The parameters can subsequently be altered.
+
+
+.ih
+EXAMPLES
+
+1. Run daofind on the test image dev$ypix.
+
+.nf
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20
+
+ ... answer the verify prompts
+
+ ... the output will appear in ypix.coo.1
+.fi
+
+
+2. Run daofind interactively on dev$ypix using the image display
+and image display cursor. Set the fwhmpsf and sigma parameters
+with the graphics cursor, radial profile plot, and the interactive
+setup key i.
+
+.nf
+ da> display dev$ypix 1 fi+
+
+ ... display the image
+
+ da> daofind dev$ypix default interactive+
+
+ ... type ? to see help screen
+
+ ... move display cursor to a star
+ ... type i to enter the interactive setup menu
+ ... enter maximum radius in pixels of the radial profile or
+ accept default with a CR
+ ... type v to enter the default setup menu
+ ... set the fwhmpsf and sigma using the graphics cursor and the
+ radial profile plot
+ ... typing <CR> leaves the parameters at their default values
+ ... type q to quit setup menu
+
+ ... type the v key to verify the critical parameters
+
+ ... type the w key to save the parameters in the parameter files
+
+ ... type the space bar to detect stars in the image
+
+ ... a 1 line summary of the answers will appear on the standard
+ output for each star measured
+
+ ... type q to quit and q again to confirm the quit
+
+ ... full output will appear in the text file ypix.coo.2
+
+.fi
+
+
+3. Run daofind interactively on a single image using a contour plot in place
+of the image and the graphics cursor in place of the image cursor.
+This option is only useful for those (now very few) users who have access to
+a graphics terminal but not to an image display server. Set the fwhmpsf and
+sigma parameters with the graphics cursor and radial profile plot and the
+interactive setup key i.
+
+.nf
+ da> show stdimcur
+
+ ... record the default value of stdimcur
+
+ da> set stdimcur = stdgraph
+
+ ... define the image cursor to be the graphics cursor
+
+ da> contour dev$ypix
+
+ ... make a contour plot of dev$ypix
+
+ da> contour dev$ypix >G ypix.plot1
+
+ ... store the contour plot of ypix in the file ypix.plot
+
+ da> daofind dev$ypix default display=stdgraph interactive+
+
+ ... type ? to see the help screen
+
+ ... move graphics cursor to a setup star
+ ... type i to enter the interactive setup menu
+ ... enter maximum radius in pixels of the radial profile or
+ accept the default with a CR
+ ... type v to enter the default setup menu
+ ... set the fwhmpsf and sigma using the graphics cursor and the
+ radial profile plot
+ ... typing <CR> leaves the parameters at their default values
+ ... type q to quit the setup menu
+
+ ... type the v key to confirm the critical parameters
+
+ ... type the w key to save the parameters in the parameter files
+
+ ... retype :.read ypix.plot1 to reload the contour plot
+
+ ... type the space bar to detect stars in the image
+
+ ... a 1 line summary of the answers will appear on the standard
+ output for each star measured
+
+ ... full output will appear in the text file ypix.coo.3
+
+ da> set stdimcur = <default>
+
+ ... reset the image cursor to its default value
+
+.fi
+
+
+4. Run DAOFIND interactively without using the image display cursor.
+
+.nf
+ da> show stdimcur
+
+ ... record the default value of stdimcur
+
+ da> set stdimcur = text
+
+ ... set the image cursor to the standard input
+
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> daofind dev$ypix default interactive+
+
+ ... type ? for help
+
+ ... type "442 409 101 i" in response to the image cursor query where
+ x and y are the coordinates of the star to be used as setup,
+ 101 is the default world coordinate system, and i enters the
+ interactive setup menu.
+ ... enter maximum radius in pixels of the radial profile or
+ type CR to accept the default
+ ... type v to enter the default setup menu
+ ... set the fwhmpsf and sigma using the graphics cursor and the
+ radial profile plot
+ ... typing <CR> leaves the parameters at their default values
+ ... type q to quit the setup menu
+
+ ... type the v key to verify the parameters
+
+ ... type the w key to save the parameters in the parameter files
+
+ ... type the space bar to detect stars in the image
+
+ ... a 1 line summary of the answers will appear on the standard
+ output for each star measured
+
+ ... type q to quit and q again to confirm
+
+ ... full output will appear in the text file ypix.coo.4
+
+ da> set stdimcur = <default>
+
+ ... reset the image cursor to its default value
+.fi
+
+
+5. Run daofind on a list of 3 images contained in the file imlist in batch mode.
+The program will ask the user to verify that the fwhmpsf and the threshold are
+correct before beginning execution.
+
+.nf
+ da> type imlist
+ dev$ypix
+ dev$wpix
+ dev$pix
+
+ da> daofind @imlist default
+
+ ... answer the verify prompts
+
+ ... the output will appear in ypix.coo.5, wpix.coo.1, pix.coo.1
+.fi
+
+
+6. Display and find stars in an image section. Write the output coordinates
+in the coordinate system of the parent image. Mark the detected stars on
+the displayed image.
+
+.nf
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image section
+
+ da> daofind dev$ypix[150:450,150:450] default wcsout=tv
+
+ ... answer the verify prompts
+
+ ... output will appear in ypix.coo.6
+
+ da> tvmark 1 ypix.coo.6 col=204
+.fi
+
+
+7. Repeat example 5 but submit the job to the background and turn off the
+verify and verbose switches.
+
+.nf
+ da> daofind @imlist default verify- verbose- &
+
+ ... the output will appear in ypix.coo.7, wpix.coo.2, pix.coo.2
+.fi
+
+
+8. Use an image cursor command file to drive the daofind task. The cursor
+command file shown below sets the fwhmpsf, sigma, and threshold parameters,
+located stars in the image, updates the parameter files, and quits the task.
+
+.nf
+ da> type cmdfile
+ : fwhmpsf 2.5
+ : sigma 5.0
+ : threshold 10.0
+ \040
+ w
+ q
+
+ da> daofind dev$ypix default icommands=cmdfile verify-
+
+ ... full output will appear in ypix.coo.8
+.fi
+
+
+.ih
+TIME REQUIREMENTS
+
+.ih
+BUGS
+
+It is currently the responsibility of the user to make sure that the
+image displayed in the frame is the same as that specified by the image
+parameter.
+
+Commands which draw to the image display are disabled by default.
+To enable graphics overlay on the image display, set the display
+parameter to "imdr", "imdg", "imdb", or "imdy" to get red, green,
+blue or yellow overlays and set the findpars mkdetections switch to
+"yes". It may be necessary to run gflush and to redisplay the image
+to get the overlays position correctly.
+
+.ih
+SEE ALSO
+datapars,findpars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/daopars.hlp b/noao/digiphot/daophot/doc/daopars.hlp
new file mode 100644
index 00000000..80f340b6
--- /dev/null
+++ b/noao/digiphot/daophot/doc/daopars.hlp
@@ -0,0 +1,331 @@
+.help daopars May00 noao.digiphot.daophot
+.ih
+NAME
+daopars -- edit the daophot fitting parameters
+.ih
+USAGE
+daopars
+.ih
+PARAMETERS
+.ls function = "gauss"
+The functional form of the analytic component of the PSF model computed by the
+DAOPHOT PSF task. The better this function matches the true PSF, especially in
+the cores of the stars, the smaller the interpolation errors will be. The
+choices are the following.
+
+.ls gauss
+An elliptical Gaussian function aligned along the x and y axes of the
+input image.
+.le
+.ls moffat15
+An elliptical Moffat function with a beta parameter of 1.5.
+.le
+.ls moffat25
+An elliptical Moffat function with a beta parameter of 2.5.
+.le
+.ls lorentz
+An elliptical Lorentzian function with beta parameter of 1.0.
+.le
+.ls penny1
+A Gaussian core with Lorentzian wings function, where the Gaussian core may be
+tilted, but the Lorentzian wings are elongated along the x or y axes. The
+Lorentzian wings have a beta parameter of 1.0.
+.le
+.ls penny2
+A Gaussian core with Lorentzian wings function, where the Gaussian core and
+Lorentzian wings may be tilted in different directions. The Lorentzian wings
+have a beta parameter of 1.0.
+.le
+.ls auto
+The PSF task computes the analytic PSF model for each of the six analytic model
+PSFs in turn and selects the one that produces the smallest standard deviation
+for the model fit.
+.le
+.ls func1,func2,...
+The PSF task computes the analytic PSF model for each of a subset of the six
+defined functions in turn, and selects the one that produces the smallest
+standard deviation for the model fit.
+.le
+
+In general "gauss" is the best and most efficient choice for a well-sampled
+ground-based image, "lorentz" is best for old ST images, and "moffat15" or
+"moffat25" are best for under-sampled ground-based images.
+.le
+.ls varorder = 0
+The order of variability of the PSF model computed by the DAOPHOT PSF task.
+Varorder sets the number of look-up tables containing the deviations of the
+true PSF from the analytic model PSF that are computed by the model.
+.ls "-1"
+Only the analytic function specified by \fIfunction\fR is used to compute
+the PSF model. The PSF model is constant over the image.
+.le
+.ls "0"
+The analytic function and one look-up table are used to compute the
+PSF model. The PSF model is constant over the image.
+.le
+.ls "1"
+The analytic function and three look-up tables are used to compute the PSF
+model. The PSF model is linearly variable over the image, with terms
+proportional to 1, x and y.
+.le
+.ls "2"
+The analytic function and six look-up tables are used to compute the
+PSF model. The PSF model is quadratically variable over the image, with terms
+proportional to 1, x, y, x**2, xy, y**2.
+.le
+.le
+.ls nclean = 0
+The number of additional iterations the PSF task performs to compute the PSF
+look-up tables. If \fInclean\fR is > 0, stars which contribute deviant
+residuals to the PSF look-up tables in the first iteration, will be
+down-weighted in succeeding iterations.
+.le
+.ls saturated = no
+Use saturated stars to improve the signal-to-noise in the wings of the PSF
+model computed by the PSF task? This parameter should only be set to
+"yes" where there are too few high signal-to-noise unsaturated stars
+in the image to compute a reasonable model for the stellar profile wings.
+.le
+.ls matchrad = 3.0 (scale units)
+The tolerance in scale units for matching the stellar x and y centroids in the
+input photometry file with the image cursor position. Matchrad is currently
+used by the PSTSELECT and PSF tasks to match stars shown on the image display
+with stars in the photometry list.
+.le
+.ls psfrad = 11.0 (scale units)
+The radius of the circle in scale units within which the PSF model is defined.
+Psfrad should be a pixel or two larger than the radius at which the intensity
+of the brightest star of interest fades into the noise. Psfrad can never be
+set larger than the size of the PSF model but may set smaller in tasks
+like GROUP, ALLSTAR, SUBSTAR, and ADDSTAR.
+.le
+.ls fitrad = 3.0 (scale units)
+The fitting radius in scale units. Only pixels within the fitting radius of
+the center of a star will contribute to the fits computed by the PEAK, NSTAR
+and ALLSTAR tasks. For most images the fitting radius should be approximately
+equal to the FWHM of the PSF. Under severely crowded conditions a somewhat
+smaller value may be used in order to improve the fit. If the PSF is variable,
+the FWHM is very small, or sky fitting is enabled in PEAK and NSTAR on the
+other hand, it may be necessary to increase the fitting radius to achieve a
+good fit.
+.le
+.ls recenter = yes (peak, nstar, and allstar)
+Compute new positions as well as magnitudes for all the stars in the input
+photometry list?
+.le
+.ls fitsky = no (peak, nstar, and allstar)
+Compute new sky values for the stars in the input list (peak, nstar, allstar).
+If fitsky = "no", the PEAK, NSTAR, and ALLSTAR tasks compute a group sky value
+by averaging the sky values of the stars in the group. If fitsky = "yes",
+PEAK and NSTAR fit the group sky simultaneously with the positions and
+magnitudes. If fitsky = yes the ALLSTAR task computes new sky values for each
+star every third iteration by subtracting off the best current fit for the star
+and and estimating the median of the pixels in the annulus defined by
+\fIsannulus\fR and \fIwsannulus\fR. The new group sky value is the average of
+the new individual values.
+.le
+.ls groupsky = yes (nstar and allstar)
+If groupsky is "yes", then the sky value for every pixel which contributes to
+the fit is identical and equal to the mean of the sky values of all the stars
+in the group. If \fIgroupsky\fR is "no", then the sky value for every pixel
+which contributes to the fit is equal to the mean of the sky values of all the
+stars in the group for which that pixel is within one fitting radius.
+.le
+.ls sannulus = 0.0 (scale units, allstar)
+The inner radius of the sky annulus used by ALLSTAR to recompute the sky
+values.
+.le
+.ls wsannulus = 11 (scale units, allstar)
+The width of the sky annulus used by ALLSTAR to recompute the sky values.
+.le
+.ls flaterr=0.75 (percent, peak, nstar, allstar)
+The image flat-fielding error in percent used to compute the predicted
+errors of the fit.
+.le
+.ls proferr = 5.0 (percent, peak, nstar, allstar)
+The profile or interpolation fitting error in percent used to compute
+the predicted errors of the fit.
+.le
+.ls maxiter = 50 (peak, nstar, allstar)
+The maximum number of times that the PSF fitting tasks PEAK, NSTAR, and ALLSTAR
+will iterate on the PSF fit before giving up.
+.le
+.ls cliprange = 2.5, clipexp = 6.0 (peak, nstar, allstar)
+The parameters of the down-weighting scheme in the fitting code used to resist
+bad data. For values of clipexp greater than 1 a residual small compared to
+cliprange standard deviations does not have its weight significantly altered,
+one with exactly \fIcliprange\fR standard deviations is assigned half its
+normal weight, and large residuals are assigned weights which fall off as the
+standard deviation to the minus clipexp power. For normal applications users
+should leave these parameter at their default value.
+.le
+.ls critsnratio = 1.0 (group)
+The ratio of the model intensity of the brighter star computed at a distance of
+one fitting radius from the center of the fainter star, to the expected random
+error computed from the readout noise, gain and value of the PSF. The critical
+signal-to-noise ratio parameter is used to group stars. In general if a small
+value such as 0.1 divides all the stars in an image into groups less than
+\fImaxgroup\fR, then the expected random errors will determine the accuracy
+of the photometry. On the other hand if a value of critical overlap much
+greater than one is required to divide up the stars, crowding errors will
+dominate random errors. If a value of 1 is sufficient then crowding and
+random errors are roughly equivalent.
+.le
+.ls mergerad = INDEF (scale units, nstar, allstar)
+The critical separation in scale units between two objects for an object merger
+to be considered. Objects with separations > mergerad will not be merged; faint
+objects with separations <= mergerad will be considered for merging. The
+default value of mergerad is sqrt (2 *(PAR1**2 + PAR2**2)), where PAR1 and PAR2
+are the half-width at half-maximum along the major and minor axes of the psf
+model. Merging can be turned off altogether by setting mergerad to 0.0.
+.le
+.ls maxnstar = 10000 (pstselect, psf, group, allstar, substar)
+The initial star list buffer size. If there are more than maxnstar stars in the
+input photometry file buffer, DAOPHOT will resize the buffers as needed.
+The only limitation is the memory and configuration of the host computer.
+.le
+.ls maxgroup = 60 (nstar, allstar)
+The maximum numbers of stars that the multiple star fitting tasks NSTAR and
+ALLSTAR will fit simultaneously. NSTAR will not to fit groups large than
+maxgroup. ALLSTAR dynamically regroups the stars in large groups until the
+group is either maxgroup or smaller in size or becomes too dense to group,
+after which the faintest stars are rejected until the group is less than
+maxgroup ins size.
+.le
+
+.ih
+DESCRIPTION
+
+DAOPARS is a parameter set task which stores the DAOPHOT parameters
+required by all those DAOPHOT tasks which compute the PSF model, fit stars
+to the PSF model, or evaluate the PSF model.
+
+Typing DAOPARS on the terminal invokes the EPAR parameter editing task. The
+DAOPARS parameters may also be edited from within an EPAR command on task,
+for example PSF, which references them. The DAOPARS parameters may also
+be changed on the command line in the usual manner when any task which
+references them is executed.
+
+Any given set of DAOPARS parameters may stored in a text file along with
+the data being reduced by typing the :w command from within the EPAR task. If
+the user then sets the value of the \fIdaopars\fR parameter to the name of
+the file containing the stored parameter set, the stored parameters will be
+used instead of the default set in the uparm directory.
+
+.ih
+ALGORITHMS
+
+The functional forms of the analytic PSF functions are as follows. The
+A is simply an amplitude or normalization constant The Pn are parameters
+which are fit during the PSF model generation process.
+
+.nf
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2
+ gauss = A * exp (-0.5 * z)
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p3
+ moffat15 = A / (1 + z) ** 1.5
+ moffat25 = A / (1 + z) ** 2.5
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p3
+ lorentz = A / (1.0 + z)
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2
+ e = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p4
+ penny1 = A * ((1 - p3) / (1.0 + z) + p3 * exp (-0.693*e))
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + p5 * x * y
+ e = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p4
+ penny2 = A * ((1 - p3) / (1.0 + z) + p3 * exp (-0.693*e))
+.fi
+
+
+The predicted errors in the DAOPHOT photometry are computed per
+pixel as follows, where terms 1, 2, 3, and 4 represent the readout
+noise, the poisson noise, the flat-fielding error, and the interpolation
+error respectively. The quantities readnoise, epadu, I, M, p1, and p2
+are the readout noise in electrons, the gain in electrons per ADU,
+the pixel intensity in ADU, the PSF model intensity in ADU, the FWHM
+in x and the FWHM in y, both in pixels.
+
+.nf
+ error = sqrt (term1 + term2 + term3 + term4) (ADU)
+ term1 = (readnoise / epadu) ** 2
+ term2 = I / epadu
+ term3 = (.01 * flaterr * I) ** 2
+ term4 = (.01 * proferr * M / p1 / p2) ** 2
+.fi
+
+The radial weighting function employed by all the PSF fitting tasks is
+the following, where dx and dy are the distance of the pixel from the
+centroid of the star being fit.
+
+.nf
+ wtr = 5.0 / (5.0 + rsq / (1.0 - rsq))
+ rsq = (dx ** 2 + dy ** 2) / fitrad ** 2
+.fi
+
+The weight assigned each pixel in the fit then becomes the following.
+
+.nf
+ wtp = wtr / error ** 2
+.fi
+
+After a few iterations and if clipexp > 0, a clipping scheme to reject bad
+data is enabled. The weights of the pixels are recomputed as follows.
+
+.nf
+ wt = wtp / (1.0 + (residual / error / chiold /
+ cliprange) ** clipexp)
+.fi
+
+Pixels having a residual of cliprange sigma will have their weight reduced
+by half.
+
+.ih
+EXAMPLES
+
+1. Print the DAOPARS task parameters.
+
+.nf
+ da> lpar daopars
+.fi
+
+2. Edit the DAOPARS parameters.
+
+.nf
+ da> daopars
+.fi
+
+3. Edit the DAOPARS parameters from with the PSF task.
+
+.nf
+ da> epar psf
+
+ ... edit a few psf parameters
+
+ ... move to the daopars parameter and type :e
+
+ ... edit the daopars parameters and type :wq
+
+ ... finish editing the psf parameters and type :wq
+.fi
+
+4. Save the current DAOPARS parameter set in a text file daonite1.par.
+ This can also be done from inside a higher level task as in the
+ above example.
+
+.nf
+ da> epar daopars
+
+ ... type ":w daonite1.par" from within epar
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+pstselect,psf,peak,group,nstar,allstar,substar,addstar,setimpars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/daotest.hlp b/noao/digiphot/daophot/doc/daotest.hlp
new file mode 100644
index 00000000..e7d455ae
--- /dev/null
+++ b/noao/digiphot/daophot/doc/daotest.hlp
@@ -0,0 +1,89 @@
+.help daotest Dec92 noao.digiphot.daophot
+.ih
+NAME
+daotest -- run basic tests on the daophot package tasks
+.ih
+USAGE
+daotest imname
+.ih
+PARAMETERS
+.ls imname
+The root name of the output test images. The input test image is stored in
+fits format in the DAOPHOT package test directory. If the image already exists
+DAOTEST will exit with a warning message.
+.le
+.ls daologfile = ""
+The name of the output log file. By default all the output image header
+listings and photometry file output is logged in a file
+called \fI"imname.log"\fR. If the log file already exists DAOTEST will
+exit with a warning message.
+.le
+.ls daoplotfile = ""
+The name of the output plot file. By default all the graphics output is
+logged in a file called \fI"imname.plot"\fR. If the plot file already exists
+DAOTEST will exit with a warning message.
+.le
+.ih
+DESCRIPTION
+DAOTEST is a simple script which exercises each of the major tasks in the
+DAOPHOT package in turn. At startup DAOTEST reads a small fits image stored
+in the DAOPHOT test subdirectory and creates the image \fIimname\fR in
+the user's working directory. DAOTEST initializes the DAOPHOT package by
+returning
+all the parameters to their default state, runs each of the DAOPHOT
+tasks in non-interactive mode, spools the text output to the file
+\fIdaologfile\fR, the graphics output from the PSF task to the plot
+metacode file \fIapplotfile\fR, and the image output from PSF, SUBSTAR
+and ADDSTAR to \fIimname.psf.1\fR, \fIimname.sub.1\fR, and \fIimname.add.1\fR
+respectively.
+.ih
+EXAMPLES
+
+1. Check to see that all the DAOPHOT tasks are functioning correctly.
+.nf
+ da> daophot
+
+ ... load the daophot package
+
+ da> daotest testim
+
+ ... run the test script
+
+ da> lprint testim.log
+
+ ... print the text output
+
+ da> gkidir testim.plot
+
+ ... list the contents of the plot file
+
+ da> gkiextract testim.plot 1-N | stdplot
+
+ ... send the plots to the plotter
+
+ da> display testim 1
+
+ ... display the original image
+
+ da> surface testim.psf.1
+
+ ... make a surface plot of the psf look-up table
+
+ da> display testim.sub.1 1
+
+ ... display the image with all the stars fitted by ALLSTAR
+ subtracted out
+
+ da> display testim.add.1 1
+
+ ... display the image containing three additional artificial
+ stars added by the ADDSTAR routine
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+.endhelp
diff --git a/noao/digiphot/daophot/doc/datapars.hlp b/noao/digiphot/daophot/doc/datapars.hlp
new file mode 100644
index 00000000..3e4345a1
--- /dev/null
+++ b/noao/digiphot/daophot/doc/datapars.hlp
@@ -0,0 +1,289 @@
+.help datapars May00 noao.digiphot.daophot
+.ih
+NAME
+datapars -- edit the data dependent parameters
+.ih
+USAGE
+datapars
+.ih
+PARAMETERS
+.ls scale = 1.0
+The scale of the image in user units, e.g. arcseconds per pixel. All DAOPHOT
+distance dependent parameters are assumed to be in units of scale. If
+\fIscale\fR = 1.0 these parameters are assumed to be in units of pixels. Most
+DAOPHOT users should leave \fIscale\fR set to 1.0 unless they intend to compare
+their aperture photometry results directly with data in the literature.
+.le
+.ls fwhmpsf = 2.5 (scale units)
+The full-width half-maximum of the point spread function in scale units.
+The DAOFIND task and the PHOT task "gauss" and "ofilter" centering algorithms
+depend on the value of fwhmpsf. DAOPHOT users can either determine a value
+for fwhmpsf using an external task such as IMEXAMINE, or make use of the
+interactive capabilities of the DAOPHOT tasks to set and store it.
+.le
+.ls emission = yes
+The features to be measured are above sky. By default the DAOPHOT package
+considers all features to be emission features. DAOPHOT users should
+leave this parameter set to "yes".
+.le
+.ls sigma = 0.0
+The standard deviation of the sky pixels. The DAOFIND task and the PHOT task
+"constant" sky fitting algorithm error estimate depend on the value of sigma.
+DAOPHOT users should set sigma to a value representative of the noise in
+the sky background.
+.le
+.ls datamin = INDEF
+The minimum good pixel value. Datamin defaults to -MAX_REAL the minimum
+floating point number supported by the host computer. Datamin is used
+to detect and remove bad data from the sky aperture, detect and flag
+bad data in the aperture photometry aperture, and detect and remove bad
+data from the PSF fitting aperture. DAOPHOT users should either leave
+datamin set to INDEF or set it to a number between 5-7 sigma below the
+sky background value.
+.le
+.ls datamax = INDEF
+The maximum good pixel value. Datamax defaults to MAX_REAL the maximum
+floating point number supported by the host computer. Datamax is used
+to detect and remove bad data from the sky aperture, detect and flag
+bad data in the aperture photometry aperture, and detect and remove bad
+data from the PSF fitting aperture. DAOPHOT users should either leave
+datamax set to INDEF or set it to the linearity or saturation
+limit of the detector.
+.le
+.ls noise = "poisson"
+The noise model used to estimate the uncertainties in the computed
+magnitudes. DAOPHOT users must leave noise set to "poisson".
+.le
+.ls ccdread = ""
+The image header keyword defining the readout noise parameter whose units
+are assumed to be electrons.
+.le
+.ls gain = ""
+The image header keyword defining the gain parameter whose units are assumed to
+be electrons per adu.
+.le
+.ls readnoise = 0.0
+The readout noise of the detector in electrons. DAOPHOT users should set
+readnoise or ccdread to its correct value before running any of the DAOPHOT
+package tasks in order to ensure that the PSF fitting weights, magnitude
+error estimates, and chi values are correct.
+.le
+.ls epadu = 1.0
+The gain of the detector in electrons per adu. DAOPHOT users should set this
+epadu or gain to its correct value before running any of the DAOPHOT package
+tasks in order to ensure that the PSF fitting weights, magnitude error
+estimates, and chi values are correct.
+.le
+.ls exposure = ""
+The image header exposure time keyword. The time units are arbitrary but
+must be consistent for any list of images whose magnitudes are to be compared.
+The computed magnitudes are normalized to one timeunit by the PHOT task.
+As the magnitude scale of the DAOPHOT package is set by the PHOT task,
+setting exposure can save DAOPHOT users a lot of unnecessary zero point
+corrections in future analysis and calibration steps.
+.le
+.ls airmass = ""
+The image header airmass keyword. The airmass parameter is not used
+directly by DAOPHOT but the airmass value is stored in the output file
+and its presence there will simplify future calibration steps.
+.le
+.ls filter = ""
+The image header filter id keyword. The filter parameter is not used
+directly by DAOPHOT but the filter id is stored in the output file
+and its presence there will simplify future calibration steps.
+.le
+.ls obstime = ""
+The image header time of observation keyword. The obstime parameter is not used
+directly by DAOPHOT but the obstime value is stored in the output file
+and its presence there will simplify future calibration steps.
+.le
+.ls itime = 1.0
+The exposure time for the image in arbitrary units. The DAOPHOT magnitudes are
+normalized to 1 timeunit by the PHOT task using the value of exposure in the
+image header if exposure is defined or the value of itime.
+.le
+.ls xairmass = INDEF
+The airmass value. The airmass is read from the image header if airmass
+is defined or from xairmass. The airmass value is stored in the DAOPHOT
+output files.
+.le
+.ls ifilter = "INDEF"
+The filter id string. The filter id is read from the image header if filter
+is defined otherwise from ifilter. The filter id is stored in the DAOPHOT
+output files.
+.le
+.ls otime = "INDEF"
+The value of the time of observation. The time of observation is read from
+the image header if obstime is defined otherwise from otime. The time of
+observation is stored in the DAOPHOT output files.
+.le
+
+.ih
+DESCRIPTION
+
+\fIDatapars\fR sets the image data dependent parameters. These parameters are
+functions, of the instrument optics, the noise characteristics and range of
+linearity of the detector, and the observing conditions. Many of the
+centering, sky fitting, and photometry algorithm parameters in the CENTERPARS,
+FITSKYPARS, PHOTPARS, and DAOPARS parameter sets scale with the data dependent
+parameters.
+
+The parameter \fIscale\fR sets the scale of the apertures used by the
+centering, sky fitting, aperture photometry, and psf fitting algorithms.
+Scale converts radial distance measurements in pixels to radial distance
+measurements in scale units. The DAOPHOT parameters cbox, maxshift, rclean
+and rclip in the CENTERPARS parameter set; annulus, dannulus, and rgrow in
+FITSKYPARS parameter set; apertures in the PHOTPARS parameter set; and psfrad,
+fitrad, sannulus, wsannulus, and matchrad in the DAOPARS parameter set are
+expressed in units of the scale. The scale parameter is useful in cases where
+the observations are to be compared to published aperture photometry
+measurements in the literature.
+
+The parameter \fIfwhmpsf\fR defines the full-width at half-maximum of the
+stellar point spread function. The DAOFIND task, the PHOT task centering
+algorithms "gauss" and "ofilt", and the PSF modeling task PSF all require
+an accurate estimate for this parameter.
+
+By setting the \fIscale\fR and \fIfwhmpsf\fR appropriately the aperture
+sizes and radial distances may be expressed in terms of the half-width
+at half-maximum of the stellar point spread function. The way to do this
+is to define the scale parameter in units of the number of half-width at
+half-maximum per pixel, set the fwhmpsf parameter to 2.0, and then
+set the remaining scale dependent centering, sky fitting, aperture photometry,
+and psf fitting algorithm parameters in CENTERPARS, FITSKYPARS, PHOTPARS,
+and DAOPARS to appropriate values in units of the half-width at half-maximum
+of the point-spread function. Once an optimum set of algorithm parameters is
+chosen, the user need only alter the DATAPARS scale parameter before
+executing a DAOPHOT task on a new image.
+
+If \fIemission\fR is "yes", the features to be measured are assumed to
+be above sky. By default the DAOPHOT package considers all features to be
+emission features. DAOPHOT users should leave this parameter set to "yes".
+Although the DAOFIND and PHOT tasks can detect and measure absorption features
+the PSF fitting tasks currently cannot.
+
+The parameter \fIsigma\fR estimates the standard deviation of the sky
+background pixels. The star finding algorithm in DAOFIND uses sigma
+and the \fIfindpars.threshold\fR parameter to define the stellar
+detection threshold in adu. The PHOT task centering algorithms use sigma,
+1) with the \fIcenterpars.kclean\fR parameter to define deviant pixels
+if \fIcenterpars.clean\fR is enabled; 2) to estimate the signal to
+noise ratio in the centering box; 3) and with the \fIcenterpars.cthreshold\fR
+parameter to define a lower intensity limit for the pixels to be used
+for centering. If sigma is undefined or <= 0.0 1) no cleaning is performed
+regardless of the value of centerpars.clean; 2) the background noise in the
+centering box is assumed to be 0.0; and 3) default cutoff intensity is used
+for centering.
+
+The \fIdatamin\fR and \fIdatamax\fR parameters define the good data range.
+If datamin or datamax are defined bad data is removed from the sky pixel
+distribution before the sky is fit, data containing bad pixels in the
+photometry apertures is flagged and the corresponding aperture photometry
+magnitudes are set to INDEF, and bad data removed from the PSF fitting
+aperture. DAOPHOT users should set datamin and datamax to appropriate values
+before running the DAOPHOT tasks.
+
+DAOPHOT users must leave \fInoise\fR set to "poisson". This model includes
+Poisson noise from the object and both Poisson and readout noise in the sky
+background.
+
+The parameters \fIgain\fR and \fIepadu\fR define the image gain.
+The gain parameter specifies which keyword in the image header contains
+the gain value. If gain is undefined or not present in the image header
+the value of epadu is used. Epadu must be in units of electrons per adu.
+DAOPHOT users should set either gain or epadu to a correct value before
+running any of the DAOPHOT package tasks to ensure that the aperture
+photometry magnitude error estimates, and the PSF fitting weights, chis, and
+magnitude error estimates are computed correctly.
+
+The two parameters \fIccdread\fR and \fIreadnoise\fR define the image
+readout noise. The ccdread parameter specifies which keyword in the
+image header contains the readout noise value. If ccdread is undefined or
+not present in the image header the value of readnoise is used.
+Readnoise is assumed to be in units of electrons.
+DAOPHOT users should set either ccdread or readnoise before running any
+DAOPHOT tasks to insure that the PSF fitting weights, chis, and magnitude
+error estimates are computed correctly.
+
+The magnitudes computed by PHOT are normalized to an exposure time of 1
+timeunit using the value of the exposure time in the image header parameter
+\fIexposure\fR or \fIitime\fR. If exposure is undefined or not present
+in the image header a warning message is issued and the value of itime
+is used. The itime units are arbitrary but must be consistent for images
+analyzed together. As the magnitude scale in DAOPHOT is determined by the
+PHOT task setting either exposure or itime can save DAOPHOT users a lot
+of unnecessary zero point corrections in future analysis and calibration
+steps.
+
+The parameters \fIairmass\fR and \fIxairmass\fR define the airmass
+of the observation. The airmass parameter specifies which keyword in the
+image header contains the airmass value. If airmass is undefined or
+not present in the image header the value of xairmass is used.
+The airmass values are not used in any DAOPHOT computations, however their
+presence in the DAOPHOT output files will simplify future reduction steps.
+
+The parameters \fIfilter\fR and \fIifilter\fR define the filter
+of the observation. The filter parameter specifies which keyword in the
+image header contains the filter id. If filter is undefined or not present
+in the image header the value of ifilter is used. The filter id values are
+not used in any DAOPHOT computations, however their presence in the DAOPHOT
+output files can will simplify future reduction steps.
+
+The parameters \fIobstime\fR and \fIotime\fR define the time
+of the observation (e.g. UT). The obstime parameter specifies which keyword
+in the image header contains the time stamp of the observation. If obstime is
+undefined or not present in the image header the value of otime is used.
+The time of observations values are not used in any DAOPHOT
+computations, however their presence in the DAOPHOT output files can
+greatly simplify future reduction steps.
+
+
+.ih
+EXAMPLES
+
+1. List the data dependent parameters.
+
+.nf
+ da> lpar datapars
+.fi
+
+2. Edit the data dependent parameters.
+
+.nf
+ da> datapars
+.fi
+
+3. Edit the data dependent parameters from within the PSF task.
+
+.nf
+ da> epar psf
+
+ ... edit a few parameters
+
+ ... move to the datapars parameter and type :e
+
+ ... edit the datapars parameters and type :wq
+
+ ... finish editing the psf parameter and type :wq
+.fi
+
+4. Save the current DATAPARS parameter set in a text file datnite1.par.
+This can also be done from inside a higher level task as in the previous
+example.
+
+.nf
+ da> epar datapars
+
+ ... edit a few parameters
+
+ ... type ":w datnite1.par" from within epar
+.fi
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+
+.ih
+SEE ALSO
+epar,lpar,daofind,phot,pstselect,psf,group,peak,nstar,allstar,substar,addstar
+.endhelp
diff --git a/noao/digiphot/daophot/doc/findpars.hlp b/noao/digiphot/daophot/doc/findpars.hlp
new file mode 100644
index 00000000..1c0bfe1a
--- /dev/null
+++ b/noao/digiphot/daophot/doc/findpars.hlp
@@ -0,0 +1,135 @@
+.help findpars May00 noao.digiphot.daophot
+.ih
+NAME
+findpars -- edit the object detection parameters
+.ih
+USAGE
+findpars
+.ih
+PARAMETERS
+.ls threshold = 4.0 (sigma)
+The object detection threshold above local background in units of
+\fIdatapars.sigma\fR.
+.le
+.ls nsigma = 1.5
+The semi-major axis of the Gaussian convolution kernel used to computed the
+density enhancement and mean density images in Gaussian sigma. This semi-
+major axis is equal to min (2.0, 0.42466 * \fInsigma\fR *
+\fIdatapars.fwhmpsf\fR / \fIdatapars.scale\fR) pixels.
+.le
+.ls ratio = 1.0
+The ratio of the sigma of the Gaussian convolution kernel along the minor axis
+direction to the sigma along the major axis direction. \fIRatio\fR defaults
+to 1.0 in which case the image is convolved with a circular Gaussian.
+.le
+.ls theta = 0.0
+The position of the major axis of the elliptical Gaussian. \fITheta\fR is
+measured counter-clockwise from the x axis.
+.le
+.ls sharplo = .2, sharphi = 1.0
+\fISharplo\fR and \fIsharphi\fR are numerical cutoffs on the image sharpness
+statistic chosen to eliminate brightness maxima which are due to bad pixels
+rather than to astronomical objects.
+.le
+.ls roundlo = -1.0 roundhi = 1.0
+\fIRoundlo\fR and \fIroundhi\fR are numerical cutoffs on the image roundness
+statistic chosen to eliminate brightness maxima which are due to bad rows or
+columns rather than to astronomical objects.
+.le
+.ls mkdetections = no
+Mark the positions of the detected objects on the displayed image ?
+.le
+
+.ih
+DESCRIPTION
+
+DAOFIND approximates the stellar point spread function with an elliptical
+Gaussian function, whose sigma along the semi-major axis is 0.42466 *
+\fIdatapars.fwhmpsf\fR / \fIdatapars.scale\fR pixels, semi-minor to semi-major
+axis ratio is \fIratio\fR, and major axis position angle is \fItheta\fR.
+Using this model, a convolution kernel, truncated at \fInsigma\fR sigma,
+and normalized to sum to zero, is constructed.
+
+The density enhancement image \fIstarmap\fR is computed by convolving the input
+image with the Gaussian kernel. This operation is mathematically equivalent to
+fitting, in the least-squares sense, the image data at each point with a
+truncated, lowered elliptical Gaussian function. After convolution each point
+in \fIstarmap\fR contains as estimate of the amplitude of the best fitting
+Gaussian function at that point. Each point in \fIskymap\fR, if the user
+chooses to compute it, contains an estimate of the best fitting sky value
+at that point.
+
+After image convolution DAOFIND steps through \fIstarmap\fR searching
+for density enhancements greater than \fIfindpars.threshold\fR *
+\fIdatapars.sigma\fR, and brighter than all other density enhancements
+within a semi-major axis of 0.42466 \fIfindpars.nsigma\fR *
+\fIdatapars.fwhmpsf\fR. As the program selects candidates, it computes two
+shape characteristics sharpness and roundness. The sharpness statistic
+measures the ratio of the difference between the height of the central pixel
+and the mean of the surrounding non-bad pixels, to the height of the best
+fitting Gaussian function at that point. The roundness statistics measures
+the ratio of, the difference in the height of the best fitting Gaussian
+function in x minus the best fitting Gaussian function in y, over the average
+of the best fitting Gaussian functions in x and y. The limits on these
+parameters \fIfindpars.sharplo\fR, \fIfindpars.sharphi\fR,
+\fIfindpars.roundlo\fR, and \fIfindpars.roundhi\fR, are set to weed out
+non-astronomical objects and brightness enhancements that are elongated in
+x and y respectively.
+
+Lastly the x and y centroids of the detected objects are computed by
+estimating the x and y positions of the best fitting 1D Gaussian
+functions in x and y respectively, a rough magnitude is estimated
+by computing the ratio of the amplitude of the best fitting Gaussian at
+the object position to \fIfindpars.threshold\fR * \fIdatapars.sigma\fR,
+and the object is added to the output coordinate file.
+
+
+.ih
+EXAMPLES
+
+1. List the object detection parameters.
+
+.nf
+ da> lpar findpars
+.fi
+
+2. Edit the object detection parameters.
+
+.nf
+ da> findpars
+.fi
+
+3. Edit the FINDPARS parameters from within the DAOFIND task.
+
+.nf
+ da> epar daofind
+
+ ... edit a few daofind parameters
+
+ ... move to the findpars parameter and type :e
+
+ ... edit the findpars parameter and type :wq
+
+ ... finish editing the daofind parameters and type :wq
+.fi
+
+4. Save the current FINDPARS parameter set in a text file fndnite1.par.
+This can also be done from inside a higher level task as in the previous
+example.
+
+.nf
+ da> findpars
+
+ ... edit the parameters
+
+ ... type ":w fndnite1.par" from within epar
+.fi
+
+.ih
+BUGS
+daofind
+
+.ih
+SEE ALSO
+epar,lpar,daofind,datapars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/fitskypars.hlp b/noao/digiphot/daophot/doc/fitskypars.hlp
new file mode 100644
index 00000000..6642a551
--- /dev/null
+++ b/noao/digiphot/daophot/doc/fitskypars.hlp
@@ -0,0 +1,212 @@
+.help fitskypars May00 noao.digiphot.daophot
+.ih
+NAME
+fitskypars - edit the sky fitting algorithm parameters
+.ih
+USAGE
+fitskypars
+.ih
+PARAMETERS
+.ls salgorithm = "mode"
+The sky fitting algorithm. The sky fitting options are:
+.ls constant
+Use a user supplied constant sky value.
+This algorithm is useful for measuring large resolved objects on flat
+backgrounds such as galaxies or comets.
+.le
+.ls file
+Read sky values from a text file. This option is useful for importing
+user determined sky values into DAOPHOT.
+.le
+.ls mean
+Compute the mean of the sky pixel distribution. This algorithm is useful
+for computing sky values in regions with few background counts.
+.le
+.ls median
+Compute the median of the sky pixel distribution. This algorithm is a useful
+for computing sky values in regions with rapidly varying sky backgrounds
+and is a good alternative to "centroid".
+.le
+.ls mode
+Compute the mode of the sky pixel distribution using the mean and median.
+This is the recommended algorithm for DAOPHOT users measuring stellar objects in
+crowded stellar fields. Mode may not perform well in regions with
+rapidly varying sky backgrounds.
+.le
+.ls centroid
+Compute the intensity weighted mean of the sky pixel histogram. This algorithm
+is reasonably robust in regions with rapidly varying or crowded sky backgrounds
+and is a good alternative to "median".
+.le
+.ls gauss
+Fit a Gaussian function to the sky pixel histogram using non-linear least-
+squares techniques to determine the peak.
+.le
+.ls ofilter
+Optimally filter the sky pixel histogram using a triangular weighting
+function to determine the peak.
+.le
+.ls crosscor
+Compute the peak of the cross-correlation function of the pixel distribution
+and a Gaussian noise function to determine the peak.
+.le
+.ls histplot
+Mark the peak of the sky pixel histogram with the graphics cursor.
+This algorithm is useful for making careful interactive sky measurements
+for a small number of objects in complicated regions or for checking the
+behavior of other sky algorithms.
+.le
+.ls radplot
+Mark the sky level on a radial profile plot with the graphics cursor.
+This algorithm is useful for making careful interactive sky measurements
+for a small number of objects in complicated regions or for checking the
+behavior of other sky algorithms.
+.le
+.le
+.ls annulus = 10.0 (scale units)
+The inner radius of the annular sky fitting region in units of the DATAPARS
+scale parameter.
+.le
+.ls dannulus = 10.0 (scale units)
+The width of the annular sky fitting region in units of the DATAPARS scale
+parameter.
+.le
+.ls skyvalue = 0.0
+The constant for constant sky subtraction.
+.le
+.ls smaxiter = 10
+The maximum number of iterations performed by the sky fitting algorithm.
+Smaxiter is required by the "gauss" and "ofilter" sky fitting algorithms.
+.le
+.ls sloclip = 0.0, shiclip = 0.0 (percent)
+The high and low side clipping parameters in percent of the total number
+of pixels. If either of these parameters > 0.0 then the specified
+percentage of the pixels will be removed from the sky pixel distribution
+before any sky fitting is done.
+.le
+.ls snreject = 50
+The maximum number of sky pixel rejection cycles.
+.le
+.ls sloreject = 3.0, shireject = 3.0
+The k-sigma clipping factors for the pixel rejection phase of the
+sky fitting algorithm. Sloreject and shireject are in units of the
+computed sky sigma.
+.le
+.ls khist = 3.0
+The k-sigma clipping factor for computing the sky pixels histogram. Khist is in
+units of sigma of the local sky pixel distribution. The histogram will be
+2.0 * khist * sigma wide. Khist is used by the "centroid", "gauss",
+"crosscor", "ofilter", and "histplot" sky fitting algorithms.
+.le
+.ls binsize = 0.10
+The width of a single bin of the sky pixel histogram. Binsize is in units of
+the sigma of the local sky pixel distribution. Binsize is used by the
+"centroid", "gauss", "crosscor", "ofilter", and "histplot" sky fitting
+algorithms.
+.le
+.ls smooth = no
+Boxcar smooth the sky pixel histogram before computing a sky value.
+Smooth is used by the "centroid", "gauss", "crosscor", "ofilter", and
+"histplot" sky fitting algorithms.
+.le
+.ls rgrow = 0.0 (scale units)
+The region growing radius for pixel rejection in the sky region in units
+of the DATAPARS scale parameter. When a bad sky_pixel is detected, all pixels
+within rgrow / scale pixels of the bad pixel will be rejected. If rgrow is
+0.0 region growing is disabled.
+.le
+.ls mksky = no
+Mark the sky annuli on the displayed image ?
+.le
+.ih
+DESCRIPTION
+The sky fitting algorithm parameters control the action of the sky fitting
+algorithms. The default parameter settings should give reasonable results in
+the majority of cases. Several of the sky fitting parameters scale with
+image scale, \fIscale\fR which is data dependent.
+\fIScale\fR is defined in the DATAPARS parameter set.
+
+Sky pixels in an annular region of inner radius \fIannulus / scale\fR pixels
+and a width of \fIdannulus / scale\fR pixels are extracted from the IRAF image.
+If the \fIscale\fR parameter is defined in terms of the number of half-width
+at half-maximum of the point spread function per pixel, then single values of
+annulus and dannulus will work well for images with different seeing and
+detector characteristics.
+
+Pixels outside of the good data range specified by \fIdatamin\fR and
+\fIdatamax\fR are rejected from the sky pixel distribution. After bad
+data rejection \fIPloclip\fR and \fIphiclip\fR percent pixels are rejected
+from the low and high sides of the sorted pixel distribution before any
+sky fitting is done.
+
+Sky values are computed using the sky fitting algorithm specified by
+\fIsalgorithm\fR. The default value is "centroid". If \fIsalgorithm\fR
+= "mean", "median" or "mode", the sky value is computed directly from the
+array of sky pixels. The remaining sky fitting algorithms use the histogram
+of the object sky pixels. The computed histogram is \fIkhist\fR * sigma wide
+with a bin width of \fIbinsize\fR * sigma where sigma is the computed
+standard deviation of the sky pixels for each object. If \fIsmooth\fR = yes,
+boxcar smoothing is performed on the computed histogram before sky fitting.
+The mode of the histogram is computed using, a non-linear least squares
+fit to a Gaussian (salgorithm = "gauss"), optimal filtering of the histogram
+(salgorithm = "ofilter"), computing the centroid of the histogram
+(salgorithm = "centroid"), or by cross-correlation techniques
+(salgorithm = "crosscor").
+
+Two interactive methods of fitting sky are also available. If \fIsalgorithm\fR
+is "radplot" or "histplot", the user must interactively set
+the value of the sky using a radial profile or a histogram plot.
+
+Pixels which deviate from the sky value by more than \fIkreject times the
+computed sky sigma are rejected from the fit. If \fIrgrow\fR > 0, pixels
+within a radius of rgrow / scale of the rejected pixel are also rejected from
+the fit. The rejection procedure iterates until no further pixels are rejected,
+all pixels are rejected, or the maximum number of rejection cycles
+\fIsnreject\fR iterations is reached.
+
+.ih
+EXAMPLES
+
+1. List the sky fitting parameters.
+
+.nf
+ da> lpar fitskypars
+.fi
+
+2. Edit the sky fitting parameters.
+
+.nf
+ da> fitskypars
+.fi
+
+3. Edit the FITSKYPARS parameters from with the PHOT task.
+
+.nf
+ da> epar phot
+
+ ... edit a few phot parameters
+
+ ... move to the fitskypars parameter and type :e
+
+ ... edit the fitskypars parameters and type :wq
+
+ ... finish editing the phot parameters and type :wq
+.fi
+
+4. Save the current FITSKYPARS parameter set in a text file skynite1.par.
+This can also be done from inside a higher level task as in the
+above example.
+
+.nf
+ da> epar fitskypars
+
+ ... type ":w skynite1.par" from within epar
+.fi
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+epar,lpar,datapars,phot
+.endhelp
diff --git a/noao/digiphot/daophot/doc/group.hlp b/noao/digiphot/daophot/doc/group.hlp
new file mode 100644
index 00000000..a8cc35d5
--- /dev/null
+++ b/noao/digiphot/daophot/doc/group.hlp
@@ -0,0 +1,304 @@
+.help group May00 noao.digiphot.daophot
+.ih
+NAME
+group -- group stars in a photometry file
+.ih
+USAGE
+group image photfile psfimage groupfile
+.ih
+PARAMETERS
+.ls image
+The list of images containing the stars to be grouped.
+.le
+.ls photfile
+The list of input photometry files containing initial estimates of the
+positions and magnitudes of the stars to be fit. The number of photometry
+files must be equal to the number of input images. If photfile is "default",
+"dir$default", or a directory specification PSF searches for a file called
+dir$image.mag.# where # is the highest available version number for the file.
+Photfile is normally the output of the PHOT task but may also be the output of
+the PSF, PEAK, NSTAR and ALLSTAR tasks. Photfile may be an APPHOT/DAOPHOT
+text database or an STSDAS binary table.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification,
+then PEAK will look for an image with the name image.psf.?, where
+? is the highest existing version number.
+.le
+.ls groupfile =
+The list of output grouped photometry files. There must be one output group
+photometry file for every input image. If groupfile is "default",
+"dir$default", or a directory specification then GROUP writes a file called
+image.grp.? where ? is the next available version number. If the DAOPHOT
+package parameter \fItext\fR is "yes" then an APPHOT/DAOPHOT text database is
+written, otherwise an STSDAS table is written.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIphotfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+\fIgroupfile\fR. The image header coordinate system is used to transform from
+the input coordinate system to the "logical" system used internally, from the
+internal logical system to the PSF model system, and from the internal
+"logical" pixel coordinate system to the output coordinate system. The input
+coordinate system options are "logical", "tv", "physical", and "world". The PSF
+model and output coordinate system options are "logical", "tv", and "physical".
+The image cursor coordinate system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical GROUP task parameters? Verify can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the GROUP task parameters if \fIverify\fR is "yes"? Update can be
+set to the default daophot package parameter value, "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ih
+DESCRIPTION
+GROUP takes the photometry file \fIphotfile\fR file containing the stellar
+coordinates and photometry and associates the stars into natural groups based
+upon proximity and the magnitude level at which they overlap. The results are
+written into \fIgroupfile\fR. If the DAOPHOT package parameter \fItext\fR is
+"yes" then \fIgroupfile\fR is a text database, otherwise it is an STSDAS table.
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to the
+internal "logical" system is defined by the image coordinate system. The
+simplest default is the "logical" pixel system. Users working on with image
+sections but importing pixel coordinate lists generated from the parent image
+must use the "tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to \fIgroupfile\fR are in the coordinate system
+defined by \fIwcsout\fR. The options are "logical", "tv", and "physical". The
+simplest default is the "logical" system. Users wishing to correlate the
+output coordinates of objects measured in image sections or mosaic pieces
+with coordinates in the parent image must use the "tv" or "physical"
+coordinate systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and the first data access will appear to take a long time as the
+entire image must be read in before the measurement is actually made. All
+subsequent data requests will be very fast because GROUP is accessing memory
+not disk. The point of caching is to speed up random image access by making
+the internal image i/o buffers the same size as the image itself. There is
+no point in turning caching on unless a lot of the input magnitudes are INDEF.
+In that case GROUP must access the image to estimate a magnitude. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+
+The algorithm works in the following manner. If two stars are within a
+distance R pixels of one another, where R = \fIpsfrad\fR / \fIscale\fR +
+\fIfitrad\fR / \fIscale\fR + 1, the PSF of the brighter one is evaluated at
+a distance d pixels, where d = \fIfitrad\fR / \fIscale\fR + 1 away from the
+fainter. If this value is larger than \fIcritsnratio\fR times the expected
+noise per pixel then the two stars are put into the same group since the
+brighter star is capable of affecting the photometry of the fainter.
+\fIPsfrad\fR, \fIfitrad\fR and \fIcritsnratio\fR are the psf radius, the
+fitting radius, and the critical S/N ratio respectively and are located
+in the DAOPARS task. \fIScale\fR is the image scale parameter and is located
+in the DATAPARS task. In order for this algorithm to work correctly it is
+imperative that the DATAPARS readnoise and gain parameters \fIreadnoise\fR
+and \fIgain\fR be set correctly as these values are used to compute the
+expected random noise per pixel.
+
+The correct value of \fIcritsnratio\fR must be determined by trial and error.
+For example if a critical S/N ratio of 0.1 divides all the stars in the image
+into groups smaller than the \fImaxgroup\fR parameter in the DAOPARS task, then
+unavoidable random errors will dominate over crowding errors. If a critical
+S/N ratio of 1.0 works, then crowding errors will be no worse than the random
+errors. If a critical S/N ratio much greater than 1 is required then in most
+cases crowding will be the dominant source or error.
+
+If \fIverbose\fR is set to "yes", GROUP will write a table on the terminal
+showing the number of groups as a function of group size. If any group is
+larger than \fImaxgroup\fR then \fIcritnsratio\fR must be increased or
+the GRPSELECT task used to cut large groups out of the file. When crowding
+conditions vary across the frame, GROUP and GRPSELECT can be used together
+to get the best possible photometry for stars in different crowding regimes.
+
+If any stars in \fIphotfile\fR have INDEF magnitudes, GROUP will attempt
+to estimate a magnitude for them based on the weighted sum of the pixels
+of a radial weighting function and the value of the PSF at that point.
+
+
+.ih
+EXAMPLES
+
+1. Group the PHOT task output results for the test image dev$ypix using
+a critical S/N ratio of 1 and printing the output summary on the terminal.
+Good stars for making the PSF model can be found at (442,410), (348,189),
+and (379,67).
+
+.nf
+ da> datapars.epadu = 14.0
+ da> datapars.readnoise = 75.0
+
+ ... set the gain and readout noise for the detector
+
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 3.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ da> psf dev$ypix default "" default default default psfrad=11.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+
+ da> group dev$ypix default default default crit=1.0 verbose+
+
+ ... verify the critical parameters
+
+ ... answers will appear in ypix.grp.1
+
+.fi
+
+
+2. Run group on a section of the input image using the photometry file and PSF
+model derived in example 1 for the parent image and writing the results
+in the coordinate system of the parent image. Note that the results for
+example 2 are identical to those in example 1.
+
+.nf
+ da> group dev$ypix[150:450,150:450] default default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.grp.2
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.grp.2 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+.fi
+
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+psf,grpselect,nstar
+.endhelp
diff --git a/noao/digiphot/daophot/doc/grpselect.hlp b/noao/digiphot/daophot/doc/grpselect.hlp
new file mode 100644
index 00000000..f2381fb7
--- /dev/null
+++ b/noao/digiphot/daophot/doc/grpselect.hlp
@@ -0,0 +1,73 @@
+.help grpselect May00 noao.digiphot.daophot
+.ih
+NAME
+grpselect -- select groups from a group file by group size
+.ih
+USAGE
+grpselect ingroupfile outgroupfile min_group max_group
+.ih
+PARAMETERS
+.ls ingroupfile
+The list of input group files. Ingroupfile must have been written by the
+DAOPHOT PSF, GROUP, or NSTAR tasks. Ingroupfile may be an APPHOT/DAOPHOT text
+database or an STSDAS table.
+.le
+.ls outgroupfile
+The list of output group files. There must be one output group file for every
+input group file. Outgroupfile has the same file type as \fIingroupfile\fR.
+.le
+.ls min_group
+The minimum group size to select from the input group file(s).
+.le
+.ls max_group
+The maximum group size to select from the input group file(s).
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task? Verbose may be set to the value
+of the daophot package parameter (the default), "yes", or "no".
+.le
+.ih
+DESCRIPTION
+GRPSELECT creates a new GROUP file \fIoutgroupfile\fR by selecting groups from
+the input GROUP file \fIingroupfile\fR within a range of group sizes specified
+by \fImin_group\fR and \fImax_group\fR. If \fIingroupfile\fR is a DAOPHOT text
+database, \fIoutgroupfile\fR is a text database. Conversely if \fIingroupfile\fR
+is a DAOPHOT STSDAS table database, \fIoutgroupfile\fR is an STSDAS table
+database.
+
+A typical use for GRPSELECT is to create a new database containing only groups
+which are less than the value of the \fImaxgroup\fR parameter in the DAOPARS
+task for direct input into the NSTAR task. The remaining stars in the larger
+groups are reduced by running GRPSELECT once more, selecting only groups
+greater than \fImaxgroup\fR, rerunning GROUP on the output with a less
+stringent value of the DAOPARS parameter task \fIcritovlap\fR to reduce the
+group sizes and inputting the result into NSTAR.
+
+.ih
+EXAMPLES
+
+1. Select groups with between 1 and 70 stars from the GROUP task output file
+ypix.grp.1 and write them into a new file named ypixsmall.grp.
+
+.nf
+ da> grpselect ypix.grp.1 ypixsmall.grp 1 70
+
+.fi
+
+2. Select groups larger than 70 from the same input group file and rerun
+group with a new value of the critoverlap parameter on the results.
+
+.nf
+ da> grpselect ypix.grp.1 ypixlarge.grp 71 400
+ da> group dev$ypix ypixlarge.grp ypix.psf.1 default crit=5.0
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+group
+.endhelp
diff --git a/noao/digiphot/daophot/doc/nstar.hlp b/noao/digiphot/daophot/doc/nstar.hlp
new file mode 100644
index 00000000..cf7c9936
--- /dev/null
+++ b/noao/digiphot/daophot/doc/nstar.hlp
@@ -0,0 +1,501 @@
+.help nstar May00 noao.digiphot.daophot
+.ih
+NAME
+nstar -- fit the PSF to groups of stars simultaneously
+.ih
+USAGE
+nstar image groupfile psfimage nstarfile rejfile
+.ih
+PARAMETERS
+.ls image
+The list of images containing the stellar groups to be fit.
+.le
+.ls groupfile
+The list of input group photometry files containing the group membership
+information and initial estimates for the positions and magnitudes of the stars
+to be measured. There must be one group file for every input image. If
+groupfile is "default", "dir$default", or a directory specification then NSTAR
+will look for a file with the name image.grp.? where ? is the highest existing
+version number. Groupfile is usually the output of the DAOPHOT GROUP task, but
+may also be the output of the NSTAR and PSF tasks. Groupfile may be an
+APPHOT/DAOPHOT text database or an STSDAS binary table.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification,
+then PEAK will look for an image with the name image.psf.?, where
+? is the highest existing version number.
+.le
+.ls nstarfile
+The list of output photometry files. There must be one output photometry
+file for every input image. If nstarfile is "default", "dir$default", or a
+directory specification, then NSTAR will write an output file with the name
+image.nst.? where ? is the next available version number. Nstarfile is a text
+database if the DAOPHOT package parameter text is "yes", an STSDAS table
+database if it is "no".
+.le
+.ls rejfile
+The list of output rejected photometry files containing the positions and sky
+values of stars that could not be fit. If rejfile is undefined, results for all
+the stars in photfile are written to \fInstarfile\fR, otherwise only the stars
+which were successfully fit are written to \fInstarfile\fR and the remainder are
+written to rejfile. If rejfile is "default", "dir$default", or a directory
+specification NSTAR writes an output file with the name image.nst.? where ? is
+the next available version number. Otherwise rejfile must specify one output
+photometry file for every input image. Rejfile is a text database if the
+DAOPHOT package parameter \fItext\fR is "yes", an STSDAS binary table database
+if it is "no".
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIgroupfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+\fInstarfile\fR and \fIrejfile\fR respectively. The image header coordinate
+system is used to transform from the input coordinate system to the "logical"
+pixel coordinate system used internally, from the internal logical system to
+the PSF model system, and from the internal "logical" pixel coordinate system
+to the output coordinate system. The input coordinate system options are
+"logical", "tv", "physical", and "world". The PSF model and output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical NSTAR task parameters? Verify can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the NSTAR task parameters if \fIverify\fR is "yes"? Update can be
+set to the default daophot package parameter value, "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ih
+DESCRIPTION
+NSTAR computes x and y centers and magnitudes for all the stellar groups in
+\fIgroupfile\fR by fitting the PSF \fIpsfimage\fR to the data in \fIimage\fR.
+NSTAR reads the group membership information along with initial estimates of
+the centers and magnitudes, and the sky values from the photometry file
+\fIgroupfile\fR. \fIGroupfile\fR is usually the output of the DAOPHOT GROUP
+task but may also be the output of the PSF and NSTAR tasks. The computed
+centers and magnitudes are written to \fInstarfile\fR along with the sky
+values, the number of iterations it took to fit the star, the goodness of fit
+statistic chi and the image sharpness statistic sharp. If \fIrejfile\fR is
+undefined, only stars that are successfully fit are written to \fInstarfile\fR,
+and the remainder are written to \fIrejfile\fR. Otherwise all the stars are
+written to \fInstarfile\fR. \fINstarfile\fR and \fIrejfile\fR are text
+databases if the DAOPHOT package parameter \fItext\fR is "yes", an STSDAS table
+database if it is "no".
+
+The coordinates read from \fIgroupfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to the
+internal "logical" system is defined by the image coordinate system. The
+simplest default is the "logical" pixel system. Users working on with image
+sections but importing pixel coordinate lists generated from the parent image
+must use the "tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to \fInstarfile\fR and \fIrejfile\fR are in the
+coordinate system defined by \fIwcsout\fR with the exception of the psf model
+center coordinates PSFX and PSFY which are always in the logical system of
+the input image. The options are "logical", "tv", and "physical". The simplest
+default is the "logical" system. Users wishing to correlate the output
+coordinates of objects measured in image sections or mosaic pieces with
+coordinates in the parent image must use the "tv" or "physical" coordinate
+systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and NSTAR is run interactively the first measurement will appear
+to take a long time as the entire image must be read in before the measurement
+is actually made. All subsequent measurements will be very fast because NSTAR
+is accessing memory not disk. The point of caching is to speed up random
+image access by making the internal image i/o buffers the same size as the
+image itself. However if the input object lists are sorted close to row order
+and sparse caching may actually worsen not improve the execution time. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+By default NSTAR computes new centers for all the stars in \fIgroupfile\fR.
+However if the DAOPARS parameter \fIrecenter\fR is "no", NSTAR assumes that the
+x and y centers in \fIgroupfile\fR are the true centers and does not refit
+them. This option can be quite useful in cases where accurate center values
+have been derived from an image that has been through some non-linear image
+restoration algorithm, but the photometry must be derived from the original
+unrestored image.
+
+By default NSTAR computes the sky value for each group by averaging the
+individual sky values in \fIgroupfile\fR for all the stars in the group. If
+\fIgroupsky\fR is "no" then the sky value for a particular pixel which
+contributes to the group fit is set to the mean of the sky values of only those
+stars for which the pixel is within one fitting radius. However if the DAOPARS
+parameter \fIfitksy\fR is "yes", then NSTAR computes a new group sky value as
+part of the non-linear least-squares fit. Recomputing the sky can significantly
+reduce the scatter in the magnitudes in regions where the sky background is
+varying rapidly, but users may need to increase \fIfitrad\fR to include more
+sky pixels in the fit. Users should experiment cautiously with this option.
+
+Only pixels within the good data range delimited by the DATAPARS task
+parameters \fIdatamin\fR and \fIdatamax\fR are included in the fit. Most users
+set \fIdatamin\fR and \fIdatamax\fR so as to exclude pixels outside the
+linearity regime of the detector. By default all the data is fit. Users are
+advised to determine accurate values for these parameters and set the
+appropriate parameters in DATAPARS before beginning any DAOPHOT reductions.
+
+Only pixels within the fitting radius \fIfitrad\fR / \fIscale\fR are included
+in the fit for each star. \fIFitrad\fR is located in the DAOPARS task and
+\fIscale\fR is located in the DATAPARS task. Since the non-linear least-squares
+fitting algorithm determines three unknowns, the x and y position of the star's
+ centroid and its brightness, the value of \fIfitrad\fR must be sufficiently
+large to include at least three pixels in the fit for each star. To accelerate
+the convergence of the non-linear least-squares fitting algorithm pixels within
+\fIfitrad\fR are assigned weights which are inversely proportional to the
+radial distance of the pixel from the x and y centroid of the star, falling
+from a maximum at the centroid to zero at the fitting radius. \fIFitrad\fR must
+ be sufficiently large to include at least three pixels with non-zero weights
+in the fit for each star. Values of \fIfitrad\fR close to the full-width at
+half-maxima of the PSF are recommended. In actual fact NSTAR imposes a minimum
+number of pixel limit of four.
+
+NSTAR performs a weighted fit to the PSF. The weight of each pixel is computed
+by combining, the radial weighting function described above, with weights
+derived from the random errors NSTAR predicts based on the values of the
+DATAPARS parameters \fIreadnoise\fR and \fIepadu\fR, and the flat-fielding and
+profile interpolation errors specified by the DAOPARS \fIflaterr\fR and
+\fIproferr\fR parameters. To obtain optimal fits, users are strongly advised
+to determine those parameters accurately and to enter their values in DATAPARS
+and DAOPARS before beginning any DAOPHOT reductions.
+
+For each group of stars to be fit, NSTAR extracts a subraster from \fIimage\fR
+which extends approximately \fIpsfrad\fR / \fIscale\fR + 1 pixels wide past
+the limiting values of the x and y coordinates of the stars in the group.
+\fIPsfrad\fR is the PSF radius specified in the DAOPARS task, and \fIscale\fR
+is the image scale specified by the DATAPARS task. \fIPsfrad\fR may be less
+than or equal to but can never exceed the value of the image header parameter
+"PSFRAD" in \fIpsfimage\fR. \fIPsfrad\fR should always be several pixels larger
+than \fIfitrad\fR to permit the x and y centroids to wander during the fitting
+process.
+
+As well as the computed x and y centers and magnitudes, NSTAR outputs the number
+ of times the PSF fit had to be iterated before reaching convergence. The
+minimum number of iterations is four. The maximum number of iteration permitted
+is specified by the \fImaxiter\fR parameter in the DAOPARS task. Obviously the
+results for stars which have reached the maximum iteration count should be
+viewed with suspicion. However since the convergence criteria are quite strict,
+(the computed magnitude must change by less than .0005 magnitudes or 0.10
+sigma whichever is larger, and the x and y centroids must change by less than
+0.002 pixels from one iteration to the next), even these stars may be
+reasonably well measured. It must be emphasized that every star in the group
+must individually satisfy the convergence criteria in order for the group to be
+ considered adequately reduced.
+
+NSTAR computes a goodness of fit statistic chi which is essentially the ratio
+of the observed pixel-to-pixel scatter in the fitting residuals to the expected
+scatter. Since the expected scatter is dependent on the DATAPARS task parameters
+\fIreadnoise\fR and \fIepadu\fR, and the DAOPARS parameters \fIflaterr\fR and
+\fIproferr\fR it is important for these values to be set correctly. A plot of
+chi versus magnitude should scatter around unity with little or no trend in
+chi with magnitude, except at the bright end where saturation effects may be
+present.
+
+Finally NSTAR computes the statistic sharp which estimates the intrinsic angular
+size of the measured object outside the atmosphere. Sharp is roughly defined as
+the difference between the square of the width of the object and the square of
+the width of PSF. Sharp has values close to zero for single stars, large
+positive values for blended doubles and partially resolved galaxies and large
+negative values for cosmic rays and blemishes.
+
+NSTAR implements a highly sophisticated star rejection algorithm. First of all,
+ any group of stars which is more than a certain size is simply not fit. The
+maximum group size is specified by the \fImaxgroup\fR parameter in the DAOPARS
+task. Larger groups may run into numerical precision problems during the fits.
+Users should exercise care in increasing the \fImaxgroup\fR parameter. If two
+stars in a group have centroids separated by a critical distance, currently set
+arbitrarily to 0.37 * the FWHM of the stellar core, their photocentric position
+and combined magnitude is assigned to the brighter of the two stars, and the
+fainter is eliminated. Any star which converges to 12.5 magnitudes greater than
+ the magnitude of the PSF is considered to be non-existent and eliminated from
+the group.
+
+After iteration 5, if the faintest star in the group has a brightness less than
+ one sigma above zero, it is eliminated. After iterations 10, if the faintest
+star in the group has a brightness less than 1.5 sigma above zero, it is
+eliminated. After iterations 15 to 50 or whenever the solutions has converged
+whichever comes first, if the faintest star in the group has a brightness less
+than 2.0 sigma above zero, it is eliminated. After iterations 5, 10 and 15,
+if two stars are separated by more than 0.37 * FWHM and less than 1.0 * FWHM
+and if the fainter of the two is more uncertain than 1.0, 1.5 or 2.0 sigma
+respectively the fainter one is eliminated.
+
+Whenever a star is eliminated the iteration counter is backed up by one and
+reduction proceeds with a smaller set of stars. Backing up the counter gives
+the second least certain star in the group two iterations to settle into a new
+fit before its fate is decided. The star rejection algorithm depends upon the
+DATAPARS \fIreadnoise\fR and \fIgain\fR parameters and the DAOPARS parameter
+\fIflaterr\fR and \fIproferr\fR. Therefore these parameters should be set to
+reasonable values before running NSTAR.
+
+NSTAR operates in a very similar manner to PEAK. However because it fits groups
+ of stars simultaneously it is much more accurate than PEAK in crowded regions.
+The ALLSTAR task also fits groups of stars simultaneously, both grouping the
+stars dynamically as well as producing a subtracted image. Essentially it
+replaces GROUP, GRPSELECT, NSTAR and SUBSTAR. However the user has little
+control over the grouping process and does not know at the end which stars were
+actually fit together. NSTAR is the task of choice when a user wants to
+maintain rigorous control over the composition of the stellar groups.
+
+.ih
+OUTPUT
+
+If \fIverbose\fR = yes, a single line is output to the terminal for each star
+fit or rejected. Full output is written to \fInstarfile\fR and \fIrejfile\fR.
+At the beginning of these two files a header listing the current values of the
+parameters is written. For each star fit/rejected the following quantities are
+written to the output file.
+
+.nf
+ id group xcenter ycenter mag merr msky niter sharpness
+ chi pier perr
+.fi
+
+Id is the id number of the star and group is its group number. Xcenter and
+ycenter are the fitted coordinates in pixels. Mag and merr are the fitted
+magnitude and magnitude error respectively. Msky is the individual sky value
+for the star. Niter is the number of iterations it took to fit the star and
+sharpness and chi are the sharpness and goodness of fit statistic respectively.
+Pier and perror are the photometry error code and accompanying error message
+respectively.
+
+.ih
+ERRORS
+
+If no errors occur during the fitting process then pier is 0. Non-zero
+values of pier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 1 # The star is in a group too large to fit
+ 2 # The sky is undefined
+ 3 # There are too few good pixels to fit the star
+ 4 # The fit is singular
+ 5 # The star is too faint
+ 6 # The star has merged with a brighter star
+ 7 # The star is off the image
+.fi
+
+.ih
+EXAMPLES
+
+1. Fit the PSF to a list stars in the test image dev$ypix. Good stars for
+making the PSF model can be found at (442,410), (348,189), and (379,67).
+
+.nf
+ da> datapars.epadu = 14.0
+ da> datapars.readnoise = 75.0
+
+ ... set the gain and readout noise for the detector
+
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 3.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ da> psf dev$ypix default "" default default default psfrad=11.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+ da> group dev$ypix default default default
+
+ ... verify the prompts
+
+ ... the output will appear in ypix.grp.1
+
+ da> nstar dev$ypix default default default default
+
+ ... verify the prompts
+
+ ... the results will appear in ypix.nst.1 and ypix.nrj.1
+
+ da> pdump ypix.nst.1 sharpness,chi yes | graph
+
+ ... plot chi versus sharpness, the stars should cluster around
+ sharpness = 0.0 and chi = 1.0, note that the frame does
+ not have a lot of stars
+
+ da> substar dev$ypix default "" default default
+
+ ... subtract the fitted stars
+
+ da> display ypix.sub.1 2
+
+ ... note that the psf stars subtract reasonably well but other
+ objects which are not stars don't
+.fi
+
+
+2. Run nstar on a section of the input image using the group file and PSF
+model derived in example 1 for the parent image and writing the results
+in the coordinate system of the parent image.
+
+.nf
+ da> nstar dev$ypix[150:450,150:450] default default default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.nst.2 and ypix.nrj.2
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.nst.2 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+ da> substar dev$ypix ypix.nst.2 "" default default
+
+ ... subtract stars from parent image
+
+ ... the output images is ypix.sub.2
+
+
+ da> substar dev$ypix[150:450,150:450] ypix.nst.2 "" default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... subtract stars from the nstar input image
+
+ ... the output images is ypix.sub.3
+
+.fi
+
+
+
+3. Run nstar exactly as in example 1 but submit the task to the background.
+Turn off verify and verbose.
+
+.nf
+ da> nstar dev$ypix default default default default verbose- \
+ verify- &
+
+ ... the results will appear in ypix.nst.3 and ypix.nrj.3
+.fi
+
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,peak,allstar
+.endhelp
diff --git a/noao/digiphot/daophot/doc/peak.hlp b/noao/digiphot/daophot/doc/peak.hlp
new file mode 100644
index 00000000..9017dcb2
--- /dev/null
+++ b/noao/digiphot/daophot/doc/peak.hlp
@@ -0,0 +1,439 @@
+.help peak May00 noao.digiphot.daophot
+.ih
+NAME
+peak -- fit the PSF model to single stars
+.ih
+USAGE
+peak image photfile psfimage peakfile rejfile
+.ih
+PARAMETERS
+.ls image
+The list of images containing the stars to be fit.
+.le
+.ls photfile
+The list of input photometry files containing initial estimates of the
+positions and magnitudes of the stars to be fit. The number of photometry
+files must be equal to the number of input images. If photfile is "default",
+"dir$default", or a directory specification PSF searches for a file called
+dir$image.mag.# where # is the highest available version number for the file.
+Photfile is usually the output of the DAOPHOT PHOT task, but may also be the
+ output of PEAK itself, or of the DAOPHOT package GROUP, NSTAR, ALLSTAR or
+PSF tasks. Photfile may be an APPHOT/DAOPHOT text database or an STSDAS table.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification,
+then PEAK will look for an image with the name image.psf.?, where
+? is the highest existing version number.
+.le
+.ls peakfile
+The list of output photometry files. There must be one output photometry
+file for every input image. If peakfile is "default", "dir$default", or a
+directory specification, then PEAK will write an output file with the name
+image.pk.? where ? is the next available version number. Peakfile is a text
+database if the DAOPHOT package parameter text is "yes", an STSDAS table
+database if it is "no".
+.le
+.ls rejfile
+The list of output rejected photometry files containing the positions and sky
+values of stars that could not be fit. If rejfile is undefined, results for all
+the stars in photfile are written to \fIpeakfile\fR, otherwise only the stars
+which were successfully fit are written to \fIpeakfile\fR and the remainder are
+written to rejfile. If rejfile is "default", "dir$default", or a directory
+specification PEAK writes an output file with the name image.prj.? where ? is
+the next available version number. Otherwise rejfile must specify one output
+photometry file for every input image. Rejfile is a text database if the
+DAOPHOT package parameter \fItext\fR is "yes", an STSDAS binary table database
+if it is "no".
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIphotfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+\fIpeakfile\fR and \fIrejfile\fR respectively. The image header coordinate
+system is used to transform from the input coordinate system to the "logical"
+pixel coordinate system used internally, from the internal logical system to
+the PSF model system, and from the internal "logical" pixel coordinate system
+to the output coordinate system. The input coordinate system options are
+"logical", "tv", "physical", and "world". The PSF model and output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical PEAK task parameters? Verify can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the PEAK task parameters if \fIverify\fR is "yes"? Update can be
+set to the default daophot package parameter value, "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ih
+DESCRIPTION
+PEAK computes x and y centers, sky values and magnitudes for all the stars in
+\fIphotfile\fR by fitting the PSF model in \fIpsfimage\fR to single stars in
+\fIimage\fR. PEAK reads initial estimates of the centers and magnitudes along
+with the sky values from the photometry file \fIphotfile\fR. \fIPhotfile\fR is
+usually the output of the DAOPHOT PHOT task but may also be the output of PEAK
+itself, NSTAR, ALLSTAR, GROUP or PSF. The computed centers, sky values, and
+magnitudes are written to \fIpeakfile\fR along with the number of iterations
+it took to fit the star, the goodness of fit statistic chi, and the image
+sharpness statistic sharp. If \fIrejfile\fR is defined only stars that are
+successfully fit are written to \fIpeakfile\fR. The remainder are written to
+\fIrejfile\fR. Otherwise all the stars are written to \fIpeakfile\fR.
+\fIPeakfile\fR and \fIrejfile\fR are APPHOT/DAOPHOT text databases if the
+DAOPHOT package parameter \fItext\fR is "yes", STSDAS binary table databases
+if it is "no".
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to the
+internal "logical" system is defined by the image coordinate system. The
+simplest default is the "logical" pixel system. Users working on with image
+sections but importing pixel coordinate lists generated from the parent image
+must use the "tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to \fIpeakfile\fR and \fIrejfile\fR are in the
+coordinate system defined by \fIwcsout\fR. The options are "logical", "tv",
+and "physical". The simplest default is the "logical" system. Users wishing to
+correlate the output coordinates of objects measured in image sections or
+mosaic pieces with coordinates in the parent image must use the "tv" or
+"physical" coordinate systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and the first measurement will appear to take a long time as the
+entire image must be read in before the measurement is actually made. All
+subsequent measurements will be very fast because PEAK is accessing memory not
+disk. The point of caching is to speed up random image access by making the
+internal image i/o buffers the same size as the image itself. However if the
+input object lists are sorted in row order and sparse caching may actually
+worsen not improve the execution time. Also at present there is no point in
+enabling caching for images that are less than or equal to 524288 bytes, i.e.
+the size of the test image dev$ypix, as the default image i/o buffer is exactly
+that size. However if the size of dev$ypix is doubled by converting it to a
+real image with the chpixtype task then the effect of caching in interactive
+is can be quite noticeable if measurements of objects in the top and bottom
+halves of the image are alternated.
+
+By default PEAK computes new centers for all the stars in \fIphotfile\fR.
+However if the DAOPARS parameter \fIrecenter\fR is "no", PEAK assumes that the
+x and y centers in \fIphotfile\fR are the true centers and does not refit them.
+This option can be quite useful in cases where accurate center values have been
+derived from an image that has been through some non-linear image restoration
+algorithm, but the photometry must be derived from the original unrestored
+image.
+
+By default PEAK uses the sky value in \fIphotfile\fR. However if the DAOPARS
+parameter \fIfitsky\fR is "yes", then PEAK computes a new sky value as part of
+the non-linear least-squares fit. Recomputing the sky can significantly reduce
+the scatter in the magnitudes in regions where the sky background is varying
+rapidly, but users may need to increase the \fIfitrad\fR parameter to include
+more sky pixels in the fit. Users should experiment cautiously with this option.
+
+Only pixels within the good data range delimited by the DATAPARS task parameters
+\fIdatamin\fR and \fIdatamax\fR are included in the fit. Most users set
+\fIdatamin\fR and \fIdatamax\fR to exclude pixels outside the linearity
+regime of the detector. By default all the data is fit. Users are advised to
+determine the values of these parameters for their detector and set the values
+in DATAPARS before beginning DAOPHOT reductions.
+
+Only pixels within the fitting radius set by the DAOPARS task parameter
+\fIfitrad\fR divided by the DATAPARS parameter \fIscale\fR are included in the
+fit. Since the non-linear least-squares fits determine three unknowns, the x
+and y position of the star's centroid and its brightness, the value of
+\fIfitrad\fR must be sufficiently large to include at least three pixels in
+the fit. To accelerate the convergence of the non-linear least-squares fitting
+algorithm, pixels within \fIfitrad\fR are assigned weights which are inversely
+proportional to the radial distance of the pixel from the x and y centroid of
+the star, falling from a maximum at the centroid to zero at the fitting radius.
+\fIFitrad\fR must be sufficiently large to include at least three pixels with
+non-zero weights in the fit. Values of \fIfitrad\fR close to the full-width at
+half-maxima of the PSF are recommended.
+
+PEAK performs a weighted fit to the PSF. The weight of each pixel is computed
+by combining the radial weighting function described above with weights derived
+from the expected random errors computed using the values of the DATAPARS
+parameters \fIreadnoise\fR and \fIepadu\fR specified by the user. Both to
+obtain optimal fits, and because PEAK employs a conservative formula, dependent
+on \fIreadnoise\fR and \fIepadu\fR, for reducing the weights of deviant pixels
+which do not approach the model as the fit proceeds, users are strongly
+advised to determine the values of these parameters accurately, and to enter
+these values in DATAPARS before beginning any DAOPHOT reductions.
+
+For each star to be fit, PEAK extracts a subraster from \fIimage\fR which is N
+by N pixels square where N is approximately 2 * \fIpsfrad\fR / \fIscale\fR + 1
+pixels wide. \fIPsfrad\fR is the PSF radius specified in the DAOPARS task and
+\fIscale\fR is the scale factor specified in the DATAPARS task. \fIPsfrad\fR may
+be less than or equal to, but can never exceed the value of the image header
+parameter "PSFRAD" in \fIpsfimage\fR. \fIPsfrad\fR should be set to a value
+several pixels larger than \fIfitrad\fR in order to permit the x and y
+centroids to wander during the fitting process.
+
+Along with the computed x and y centers and magnitudes, PEAK outputs the number
+of times the PSF fit had to be iterated to reach convergence for each star. The
+minimum number of iterations is three. The maximum number of iteration permitted
+is specified by the \fImaxiter\fR parameter in the DAOPARS task. Obviously the
+results for stars which have reached the maximum iteration count should be
+viewed with suspicion. However since the convergence criteria are quite strict,
+(the computed magnitude must change by less than .001 magnitudes or 0.05 sigma
+whichever is larger and the x and y centroids must change by less than 0.01
+pixels from one iteration to the next), even these stars may be reasonably well
+measured.
+
+PEAK computes a goodness of fit statistic chi which is essentially the ratio of
+the observed pixel-to-pixel scatter in the fit residuals to the expected
+scatter. Since the expected scatter is dependent on the DATAPARS task parameters
+\fIreadnoise\fR and \fIepadu\fR, it is important for these values to be set
+correctly. A plot of chi versus magnitude should scatter around unity with
+little or no trend in chi with magnitude, except at the bright end where
+saturation effects may be present.
+
+Finally PEAK computes the statistic sharp which estimates the intrinsic angular
+size of the measured object outside the atmosphere. Sharp is roughly defined as
+the difference between the square of the width of the object and the square of
+the width of PSF. Sharp has values close to zero for single stars, large
+positive values for blended doubles and partially resolved galaxies, and large
+negative values for cosmic rays and blemishes.
+
+Because PEAK cannot fit stars in crowded fields with overlapped images like the
+NSTAR and ALLSTAR tasks do, and for sparsely populated frames aperture
+photometry produced by PHOT is often just as good and faster to compute, PEAK
+has few unique functions. PEAK is often useful however for fitting and removing
+single stars in images where the stars are interfering with the real object of
+interest such as a galaxy. In that case the PEAK results can be input to SUBSTAR
+which will then remove the interfering stars. Another potential use of PEAK
+is the removal of stars from sparsely populated sky flats in preparation
+for smoothing.
+
+.ih
+OUTPUT
+
+If \fIverbose\fR = yes, a single line is output to the terminal for each star
+fit or rejected. Full output is written to \fIallstarfile\fR and \fIrejfile\fR.
+At the beginning of these two files a header listing the current values of the
+parameters is written. For each star fit/rejected the following quantities are
+written to the output file.
+
+.nf
+ id xcenter ycenter mag merr msky niter sharpness chi
+ pier perr
+.fi
+
+Id is the id number of the star. Xcenter and ycenter are the fitted coordinates
+in pixels. Mag and merr are the fitted magnitude and magnitude error
+respectively. Msky is the individual sky value for the star. Niter is the
+number of iterations it took to fit the star and sharpness and chi are the
+sharpness and goodness of fit statistic respectively. Pier and perror are the
+photometry error code and accompanying error message respectively.
+
+.ih
+ERRORS
+
+If no errors occur during the fitting process then pier is 0. Non-zero
+values of pier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 1 # The sky is undefined
+ 2 # There are too few good pixels to fit the star
+ 3 # The fit is singular
+ 4 # The star is too faint
+.fi
+
+.ih
+EXAMPLES
+
+
+1. Compute the PSF model for the test image dev$ypix. Good stars for making the
+PSF model can be found at (442,410), (348,189), and (379,67).
+
+
+.nf
+ da> datapars.epadu = 14.0
+ da> datapars.readnoise = 75.0
+
+ ... set the gain and readout noise for the detector
+
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 3.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ da> psf dev$ypix default "" default default default psfrad=11.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+ da> peak dev$ypix default default default default
+
+ ... the results will appear in ypix.pk.1 and ypix.prj.1
+
+ da> pdump ypix.pk.1 sharpness,chi yes | graph
+
+ ... plot chi versus sharpness, the stars should cluster around
+ sharpness = 0.0 and chi = 1.0, note that the frame does
+ not have a lot of stars
+
+ da> substar dev$ypix ypix.pk.1 "" default default
+
+ ... subtract the fitted stars
+
+ da> display ypix.sub.1 2
+
+ ... note that the psf stars subtract reasonably well but other
+ objects which are not stars don't
+.fi
+
+
+2. Run peak on a section of the input image using the photometry file and PSF
+model derived in example 1 for the parent image and writing the results
+in the coordinate system of the parent image.
+
+.nf
+ da> peak dev$ypix[150:450,150:450] default default default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.pk.2 and ypix.prj.2
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.pk.2 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+ da> substar dev$ypix ypix.pk.2 "" default default
+
+ ... subtract stars from parent image
+
+ ... the output images is ypix.sub.2
+
+
+ da> substar dev$ypix[150:450,150:450] ypix.pk.2 "" default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... subtract stars from the peak input image
+
+ ... the output images is ypix.sub.3
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,nstar,allstar
+.endhelp
diff --git a/noao/digiphot/daophot/doc/pexamine.hlp b/noao/digiphot/daophot/doc/pexamine.hlp
new file mode 100644
index 00000000..920634bc
--- /dev/null
+++ b/noao/digiphot/daophot/doc/pexamine.hlp
@@ -0,0 +1,780 @@
+.help pexamine May00 noao.digiphot.daophot
+.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. Input 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. Output is either an APPHOT/DAOPHOT text
+database or an STSDAS binary table database depending on the file type of
+\fIinput\fR. If output = "" 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. Deletions is either
+an APPHOT/DAOPHOT text database or an STSDAS binary table database depending on
+the file type of \fIinput\fR. If deletions 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
+Photcolumns 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. Xcolumn and
+ycolumn must be listed in \fIphotcolumns\fR or \fIusercolumns\fR but may be
+changed interactively by the user. If either xcolumn or ycolumn 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. Hcolumn
+must be listed in \fIphotcolumns\fR or \fIusercolumns\fR but may be changed
+interactively by the user. If hcolumn 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 hcolumn, 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.
+Xposcolumn and yposcolumn 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. Usercolumns can be changed
+interactively from within PEXAMINE at the cost of rereading the database.
+.le
+.ls first_star = 1
+The index of the first object to be read out of the catalog.
+.le
+.ls max_nstars = 5000
+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 max_nstars in the
+catalog only the first max_nstars objects are read in.
+.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 use_display = yes
+Use the image display? Users without access to an image display should set
+use_display to "no".
+.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.
+.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 graphics = "stdgraph"
+The default graphics device.
+.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. Top_closed decides whether those pixels with
+values equal to z2 are to be counted in the histogram. If top_closed 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)
+Grayscale 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 histogramed.
+.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 \fIyposcolumn\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] Grayscale 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 ypix.mag.1 ypix.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 ypix.als.1 ypix.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 ypix.sub.1 1
+
+ ... display the subtracted image
+
+ pt> pexamine ypix.als.1 ypix.als.ed dev$ypix 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
+
+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/daophot/doc/pfmerge.hlp b/noao/digiphot/daophot/doc/pfmerge.hlp
new file mode 100644
index 00000000..a85b60ee
--- /dev/null
+++ b/noao/digiphot/daophot/doc/pfmerge.hlp
@@ -0,0 +1,65 @@
+.help pfmerge May00 noao.digiphot.daophot
+.ih
+NAME
+pfmerge -- merge a list of photometry files
+.ih
+USAGE
+pfmerge inphotfiles outphotfile
+.ih
+PARAMETERS
+.ls inphotfiles
+The list of photometry files to be merged. Inphotfiles may be the output of the
+DAOPHOT tasks PHOT, PSTSELECT, PSF, PEAK, GROUP, GRPSELECT, NSTAR, or ALLSTAR.
+Inphotfiles may be either a list of APPHOT/DAOPHOT text databases or a list of
+STSDAS binary tables.
+.le
+.ls outphotfile
+The output photometry file. Outphotfile consists of the header of the first
+input photometry file, followed by a list of records, one per input file
+record, each consisting of five fields: ID, XCENTER, YCENTER, MAG, and MSKY.
+Outphotfile is a an APPHOT/DAOPHOT text database if the first photometry file
+is a text database, an STSDAS binary table if the first photometry file is an
+ST table.
+.le
+.ls verbose
+Print messages about the progress of the task ?
+.le
+.ih
+DESCRIPTION
+PFMERGE creates a new photometry file suitable for input to PSF, PEAK, GROUP,
+or ALLSTAR by extracting the header of the first input photometry file and the
+values of the five fields: ID, XCENTER, YCENTER, MAG, and MSKY from each
+photometry record in each input file, and writing them to \fIoutphotfile\fR.
+\fIInphotfiles\fR may be either APPHOT/DAOPHOT text databases or STSDAS binary
+tables, but \fIoutphotfile\fR inherits the type of the first input photometry
+file.
+
+The principal application of PFMERGE is to combine the results of one of the
+DAOPHOT fitting tasks, e.g. ALLSTAR, with the results of the aperture photometry
+task PHOT, to create a new photometry file suitable for input to the fitting
+task. e.g. ALLSTAR, since it if often the case that the user wishes to combine
+preliminary results for a few additional stars with the best fit results to
+date on the original star list.
+
+PFMERGE is intended to combine photometry files from different DAOPHOT tasks.
+The task PCONCAT can be used to combine photometry files produced by the same
+task.
+
+.ih
+EXAMPLES
+
+1. Combine the results of the first allstar run with phot task results
+on a small list of stars detected after the first list of stars was
+subtracted from the original image.
+
+.nf
+ cl> pfmerge m92.als.1,m92.mag.5 m92.als.2
+.fi
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+pconcat
+.endhelp
diff --git a/noao/digiphot/daophot/doc/phot.hlp b/noao/digiphot/daophot/doc/phot.hlp
new file mode 100644
index 00000000..cc0033c8
--- /dev/null
+++ b/noao/digiphot/daophot/doc/phot.hlp
@@ -0,0 +1,831 @@
+.help phot May00 noao.digiphot.daophot
+.ih
+NAME
+phot -- do aperture photometry on a list of stars
+.ih
+USAGE
+phot image coords output
+.ih
+PARAMETERS
+.ls image
+The list of images containing the objects to be measured.
+.le
+.ls coords
+The list of text files containing initial coordinates for the objects to
+be centered. Objects are listed in coords one object per line with the
+initial coordinate values in columns one and two. The number of coordinate
+files must be zero, one, or equal to the number of images. If coords is
+"default", "dir$default", or a directory specification then a coords file name
+of the form dir$root.extension.version is constructed and searched for,
+where dir is the directory, root is the root image name, extension is "coo"
+and version is the highest available version number for the file.
+.le
+.ls output
+The name of the results file or results directory. If output is
+"default", "dir$default", or a directory specification then an output file name
+of the form dir$root.extension.version is constructed, where dir is the
+directory, root is the root image name, extension is "mag" and version is
+the next available version number for the file. The number of output files
+must be zero, one, or equal to the number of image files. In both interactive
+and batch mode full output is written to output. In interactive mode
+an output summary is also written to the standard output.
+.le
+.ls skyfile = ""
+The list of text files containing the sky values, of the measured objects,
+one object per line with x, y, the sky value, sky sigma, sky skew, number of sky
+pixels and number of rejected sky pixels in columns one to seven respectively.
+The number of sky files must be zero, one, or equal to the number of input
+images. A skyfile value is only requested if \fIfitskypars.salgorithm\fR =
+"file" and if PHOT is run non-interactively.
+.le
+.ls plotfile = ""
+The name of the file containing radial profile plots of the stars written
+to the output file. If plotfile is defined then a radial profile plot
+is written to plotfile every time a record is written to \fIoutput\fR.
+The user should be aware that this can be a time consuming operation.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The critical
+parameters \fIfwhmpsf\fR and \fIsigma\fR are located here. If \fIdatapars\fR
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls centerpars = ""
+The name of the file containing the centering parameters. The critical
+parameters \fIcalgorithm\fR and \fIcbox\fR are located here.
+If \fIcenterpars\fR is undefined then the default parameter set in
+uparm directory is used.
+.le
+.ls fitskypars = ""
+The name of the text file containing the sky fitting parameters. The critical
+parameters \fIsalgorithm\fR, \fIannulus\fR, and \fIdannulus\fR are located here.
+If \fIfitskypars\fR is undefined then the default parameter set in uparm
+directory is used.
+.le
+.ls photpars = ""
+The name of the file containing the photometry parameters. The critical
+parameter \fIapertures\fR is located here. If \fIphotpars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls interactive = no
+Run the task interactively ?
+.le
+.ls radplots = no
+If \fIradplots\fR is "yes" and PHOT is run in interactive mode, a radial
+profile of each star is plotted on the screen after the star is measured.
+.le
+.ls icommands = ""
+The image display cursor or image cursor command file.
+.le
+.ls gcommands = ""
+The graphics cursor or graphics cursor command file.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout"
+The coordinate system of the input coordinates read from \fIcoords\fR and
+of the output coordinates written to \fIoutput\fR respectively. The image
+header coordinate system is used to transform from the input coordinate
+system to the "logical" pixel coordinate system used internally,
+and from the internal "logical" pixel coordinate system to the output
+coordinate system. The input coordinate system options are "logical", "tv",
+"physical", and "world". The output coordinate system options are "logical",
+"tv", and "physical". The image cursor coordinate system is assumed to
+be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin and wcsout are "logical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical PHOT parameters in non-interactive mode ? Verify can be set
+to the DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the algorithm parameter values if \fIverify\fR is "yes" and
+\fIinteractive\fR is "no" ? Update can be set to the DAOPHOT package parameter
+value (the default), "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print results on the screen in non-interactive mode ? Verbose can be set to
+the DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ls graphics = ")_.stdgraph"
+The default graphics device. Graphics may be set to the DAOPHOT package
+parameter value (the default), "yes", or "no".
+.le
+.ls display = ")_.display"
+The default display device. Display may be set to the DAOPHOT package
+parameter value (the default), "yes", or "no". By default graphics overlay is
+disabled. Setting display to one of "imdr", "imdg", "imdb", or "imdy" enables
+graphics overlay with the IMD graphics kernel. Setting display to "stdgraph"
+enables PHOT to work interactively from a contour plot.
+
+.le
+
+.ih
+DESCRIPTION
+
+PHOT computes accurate centers, sky values, and magnitudes for a list of
+objects in the IRAF image \fIimage\fR whose coordinates are read from
+the text file \fIcoords\fR or the image display cursor, and writes the
+computed x and y coordinates, sky values, and magnitudes to the text
+file \fIoutput\fR.
+
+The coordinates read from \fIcoords\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to
+the internal "logical" system is defined by the image coordinate system.
+The simplest default is the "logical" pixel system. Users working on with
+image sections but importing pixel coordinate lists generated from the parent
+image must use the "tv" or "physical" input coordinate systems.
+Users importing coordinate lists in world coordinates, e.g. ra and dec,
+must use the "world" coordinate system and may need to convert their
+equatorial coordinate units from hours and degrees to degrees and degrees first.
+
+The coordinates written to \fIoutput\fR are in the coordinate
+system defined by \fIwcsout\fR. The options are "logical", "tv",
+and "physical". The simplest default is the "logical" system. Users
+wishing to correlate the output coordinates of objects measured in
+image sections or mosaic pieces with coordinates in the parent
+image must use the "tv" or "physical" coordinate systems.
+
+In interactive mode the user may either define the list of objects to be
+measured interactively with the image cursor or create an object list prior
+to running PHOT. In either case the user may adjust the centering, sky fitting,
+ and photometry algorithm parameters until a satisfactory fit is achieved
+and optionally store the final results in \fIoutput\fR. In batch mode the
+initial positions are read from the text file \fIcoords\fR or the image
+cursor parameter \fIicommands\fR can be redirected to a text file containing
+a list of cursor commands. In batch mode the current set of algorithm
+parameters is used.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and PHOT is run interactively the first measurement will appear
+to take a long time as the entire image must be read in before the measurement
+is actually made. All subsequent measurements will be very fast because PHOT
+is accessing memory not disk. The point of caching is to speed up random
+image access by making the internal image i/o buffers the same size as the
+image itself. However if the input object lists are sorted in row order and
+sparse caching may actually worsen not improve the execution time. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+
+PHOT computes accurate centers for each object using the centering
+parameters defined in \fIcenterpars\fR, computes an accurate sky value
+for each object using the sky fitting parameters defined in \fIfitskypars\fR,
+ and computes magnitudes using the photometry parameters defined in
+\fIphotpars\fR. The image data characteristics of the data are specified
+in \fIdatapars\fR.
+
+Unlike the APPHOT versions of PHOT the DAOPHOT version of PHOT does NOT
+recenter the stars, as the default input coordinate list is created
+by the DAOFIND task which itself computes accurate centers for the stars.
+DAOPHOT users should set the CENTERPARS task parameter \fIcalgorithm\fR
+to "centroid" if they need to measure stars interactively with the
+image display and image display cursor. The PHOT tasks centers provide
+initial guesses for the PSF modeling and fitting routines in the PSF,
+PEAK, NSTAR, and ALLSTAR tasks.
+
+The DAOPHOT version of PHOT sets the sky fitting algorithm to "mode".
+This algorithm which uses the mean and median to estimate the value
+that the sky would have if the star of interest wasn't there, is in most
+cases the one which will give the best results in crowded fields. Users
+interested in reducing small stellar groups should realizes that they can,
+fix the sky by setting the FITSKYPARS parameter \fIsalgorithm\fR to "constant"
+and setting \fIskyvalue\fR to the desired sky value, or set the sky
+interactively using the "radplot" or "histplot" options. Users with rapidly
+varying sky backgrounds may wish to explore the "median" or "centroid" sky
+fitting algorithm which can be more stable than the "mode" algorithm
+against complex sky pixel histograms. Users with very few counts in their
+data or with quantized data where the standard deviation is small with
+respect to the quantization level may wish to explore the "mean",
+and "centroid" sky fitting algorithms.
+
+The PHOT task sets the instrumental magnitude scale for all the subsequent
+DAOPHOT tasks. Users should be sure they have set the PHOTPARS \fIapertures\fR
+parameter to a reasonable value, and that they have accounted for the
+exposure time by setting either the DATAPARS \fIexposure\fR or \fIitime\fR
+parameters.
+
+
+.ih
+CURSOR COMMANDS
+
+The following list of cursor commands are currently available.
+
+.nf
+ Interactive Keystroke Commands
+
+? Print help
+: Colon commands
+v Verify critical parameters
+w Save current parameters
+d Plot radial profile of current star
+i Set parameters interactively using current star
+c Fit center for current star
+t Fit sky around cursor
+s Fit sky around current centered star
+p Do photometry for current star, using current sky
+o Do photometry for current star, using current sky, output results
+f Do photometry for current star
+spbar Do photometry for current star, output results
+m Move to next star in coordinate list
+n Do photometry for next star in coordinate list, output results
+l Do photometry for remaining stars in coordinate list, output results
+e Print error messages
+r Rewind coordinate list
+q Exit task
+
+
+Photometry parameters are listed or set with the following commands.
+
+ Colon commands
+
+:show [data/center/sky/phot] List the parameters
+:m [n] Move to next [nth] star in coordinate list
+:n [n] Measure next [nth] star in coordinate list, output results
+
+ Colon Parameter Editing Commands
+
+# Image and file name parameters
+
+:image [string] Image name
+:coords [string] Coordinate file name
+:output [string] Output file name
+
+# Data dependent parameters
+
+:scale [value] Image scale (units per pixel)
+:fwhmpsf [value] Full width half maximum of PSF (scale units)
+:emission [y/n] Emission feature (y), absorption (n)
+:sigma [value] Standard deviation of sky (counts)
+:datamin [value] Minimum good data value (counts)
+:datamax [value] Maximum good data value (counts)
+
+# Noise parameters
+
+:noise [string] Noise model (constant|poisson)
+:gain [string] Gain image header keyword
+:ccdread [string] Readout noise image header keyword
+:epadu [value] Gain (electrons per adu)
+:readnoise [value] Readout noise (electrons)
+
+# Observations parameters
+
+:exposure [string] Exposure time image header keyword
+:airmass [string] Airmass image header keyword
+:filter [string] Filter image header keyword
+:obstime [string] Time of observation image header keyword
+:itime [value] Integration time (time units)
+:xairmass [value] Airmass value (number)
+:ifilter [string] Filter id string
+:otime [string] Time of observation (time units)
+
+# Centering algorithm parameters
+
+:calgorithm [string] Centering algorithm
+:cbox [value] Width of the centering box (scale units)
+:cthreshold [value] Centering intensity threshold (sigma)
+:cmaxiter [value] Maximum number of iterations
+:maxshift [value] Maximum center shift (scale units)
+:minsnratio [value] Minimum S/N ratio for centering
+:clean [y/n] Clean subraster before centering
+:rclean [value] Cleaning radius (scale units)
+:rclip [value] Clipping radius (scale units)
+:kclean [value] Clean K-sigma rejection limit (sigma)
+
+# Sky fitting algorithm parameters
+
+:salgorithm [string] Sky fitting algorithm
+:skyvalue [value] User supplied sky value (counts)
+:annulus [value] Inner radius of sky annulus (scale units)
+:dannulus [value] Width of sky annulus (scale units)
+:khist [value] Sky histogram extent (+/- sky sigma)
+:binsize [value] Resolution of sky histogram (sky sigma)
+:smooth [y/n] Lucy smooth the sky histogram
+:sloclip [value] Low-side clipping factor in percent
+:shiclip [value] High-side clipping factor in percent
+:smaxiter [value] Maximum number of iterations
+:snreject [value] Maximum number of rejection cycles
+:sloreject [value] Low-side pixel rejection limits (sky sigma)
+:shireject [value] High-side pixel rejection limits (sky sigma)
+:rgrow [value] Region growing radius (scale units)
+
+# Photometry parameters
+
+:apertures [string] List of aperture radii (scale units)
+:zmag [value] Zero point of magnitude scale
+
+# Plotting and marking parameters
+
+:mkcenter [y/n] Mark computed centers on display
+:mksky [y/n] Mark the sky annuli on the display
+:mkapert [y/n] Mark apertures on the display
+:radplot [y/n] Plot radial profile of object
+
+
+The following commands are available from inside the interactive setup menu.
+
+ Interactive Phot Setup Menu
+
+ v Mark and verify the critical parameters (f,s,c,a,d,r)
+
+ f Mark and verify the full-width half-maximum of psf
+ s Mark and verify the standard deviation of the background
+ l Mark and verify the minimum good data value
+ u Mark and verify the maximum good data value
+
+ c Mark and verify the centering box width
+ n Mark and verify the cleaning radius
+ p Mark and verify the clipping radius
+
+ a Mark and verify the inner radius of the sky annulus
+ d Mark and verify the width of the sky annulus
+ g Mark and verify the region growing radius
+
+ r Mark and verify the aperture radii
+.fi
+
+.ih
+ALGORITHMS
+
+A brief description of the data dependent parameters, centering algorithms,
+sky fitting algorithms and photometry parameters can be found in the
+online help pages for the DATAPARS, CENTERPARS, FITSKYPARS, and PHOTPARS
+tasks.
+
+.ih
+OUTPUT
+
+In interactive mode the following quantities are printed on the standard
+output as each object is measured. Err is a simple string indicating whether
+or not an error was detected in the centering algorithm, the sky fitting
+algorithm or the photometry algorithm. Mag are the magnitudes in apertures 1
+through N respectively and xcenter, ycenter and msky are the x and y centers
+and the sky value respectively.
+
+.nf
+ image xcenter ycenter msky mag[1 ... N] error
+.fi
+
+In both interactive and batch mode full output is written to the text file
+\fIoutput\fR. At the beginning of each file is a header listing the
+current values of the parameters when the first stellar record was written.
+These parameters can be subsequently altered. For each star measured the
+following record is written
+
+.nf
+ image xinit yinit id coords lid
+ xcenter ycenter xshift yshift xerr yerr cier error
+ msky stdev sskew nsky nsrej sier serror
+ itime xairmass ifilter otime
+ rapert sum area mag merr pier perr
+.fi
+
+Image and coords are the name of the image and coordinate file respectively.
+Id and lid are the sequence numbers of stars in the output and coordinate
+files respectively. Cier and cerror are the centering algorithm error code
+and accompanying error message respectively. Xinit, yinit, xcenter, ycenter,
+xshift, yshift, and xerr, yerr are self explanatory and output in pixel units.
+The sense of the xshift and yshift definitions is the following.
+
+
+.nf
+ xshift = xcenter - xinit
+ yshift = ycenter - yinit
+.fi
+
+Sier and serror are the sky fitting error code and accompanying error
+message respectively. Msky, stdev and sskew are the best estimate of the sky
+value (per pixel), standard deviation and skew respectively. Nsky and nsrej
+are the number of sky pixels and the number of sky pixels rejected respectively.
+
+Itime is the exposure time, xairmass is self-evident, ifilter is an
+id string identifying the filter used in the observations, and otime is
+a string containing the time of the observation in whatever units the
+user has set up.
+
+Rapert, sum, area, and flux are the radius of the aperture in scale units,
+the total number of counts including sky in the aperture, the area of the
+aperture in square pixels, and the total number of counts excluding sky
+in the aperture. Mag and merr are the magnitude and error in the magnitude
+in the aperture (see below).
+
+.nf
+ flux = sum - area * msky
+ mag = zmag - 2.5 * log10 (flux) + 2.5 * log10 (itime)
+ merr = 1.0857 * err / flux
+ err = sqrt (flux / epadu + area * stdev**2 +
+ area**2 * stdev**2 / nsky)
+.fi
+
+Pier and perror are photometry error code and accompanying error message.
+
+In interactive mode a radial profile of each measured object is plotted
+in the graphics window if \fIradplots\fR is "yes".
+
+In interactive and batchmode a radial profile plot is written to
+\fIplotfile\fR if it is defined each time the result of an object
+measurement is written to \fIoutput\fR .
+
+
+.ih
+ERRORS
+
+If the object centering was error free then the field cier will be zero.
+Non-zero values of cier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 101 # The centering box is off image
+ 102 # The centering box is partially off the image
+ 103 # The S/N ratio is low in the centering box
+ 104 # There are two few points for a good fit
+ 105 # The x or y center fit is singular
+ 106 # The x or y center fit did not converge
+ 107 # The x or y center shift is greater than maxshift
+ 108 # There is bad data in the centering box
+.fi
+
+If all goes well during the sky fitting process then the error code sier
+will be 0. Non-zero values of sier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 201 # There are no sky pixels in the sky annulus
+ 202 # Sky annulus is partially off the image
+ 203 # The histogram of sky pixels has no width
+ 204 # The histogram of sky pixels is flat or concave
+ 205 # There are too few points for a good sky fit
+ 206 # The sky fit is singular
+ 207 # The sky fit did not converge
+ 208 # The graphics stream is undefined
+ 209 # The file of sky values does not exist
+ 210 # The sky file is at EOF
+ 211 # Cannot read the sky value correctly
+ 212 # The best fit parameter are non-physical
+.fi
+
+If no error occurs during the measurement of the magnitudes then pier is
+0. Non-zero values of pier flag the following error conditions.
+
+.nf
+ 0 # No error
+ 301 # The aperture is off the image
+ 302 # The aperture is partially off the image
+ 303 # The sky value is undefined
+ 305 # There is bad data in the aperture
+.fi
+
+.ih
+EXAMPLES
+
+1. Run PHOT on the image dev$ypix using the coordinate list ypix.coo.1
+created by DAOFIND and the default setup.
+
+.nf
+ da> daofind dev$ypix default fwhmpsf=2.6 sigma=5.0 threshold=20. \
+ verify-
+
+ ... make the coordinate list ypix.coo.1
+
+ da> phot dev$ypix default default
+
+ ... answer the verify prompts
+
+ ... the results will appear in ypix.mag.1
+.fi
+
+
+2. Compute the magnitudes for a few stars in dev$ypix using the display
+and the image cursor. Setup the task parameters using the interactive
+setup menu defined by the i key command and a radial profile plot.
+
+.nf
+ da> display dev$ypix 1 fi+
+
+ ... display the image
+
+ da> phot dev$ypix "" default calgorithm=centroid interactive+
+
+ ... type ? to print an optional help page
+
+ ... move the image cursor to a star
+ ... type i to enter the interactive setup menu
+ ... enter maximum radius in pixels of the radial profile or hit
+ CR to accept the default
+ ... type v to enter the default menu
+ ... set the fwhmpsf, centering radius, inner and outer sky annuli,
+ photometry apertures, and sigma using the graphics cursor and
+ the stellar radial profile plot
+ ... typing <CR> leaves everything at the default value
+ ... type q to quit the setup menu
+
+ ... type the v key to verify the parameters
+
+ ... type the w key to save the parameters in the parameter files
+
+ ... move the image cursor to the stars of interest and tap
+ the space bar
+
+ ... a one line summary of the fitted parameters will appear on the
+ standard output for each star measured
+
+ ... type q to quit and q again to confirm the quit
+
+ ... the output will appear in ypix.mag.2
+.fi
+
+
+3. Compute the magnitudes for a few stars in dev$ypix using a contour plot
+and the graphics cursor. This option is only useful for those (now very few)
+users who have access to a graphics terminal but not to an image display
+server. Setup the task parameters using the interactive setup menu defined by
+the i key command as in example 1.
+
+.nf
+ da> show stdimcur
+
+ ... record the default value of stdimcur
+
+ da> set stdimcur = stdgraph
+
+ ... define the image cursor to be the graphics cursor
+
+ da> contour dev$ypix
+
+ ... make a contour plot of dev$ypix
+
+ da> contour dev$ypix >G ypix.plot1
+
+ ... store the contour plot of dev$ypix in the file ypix.plot1
+
+ da> phot dev$ypix "" default calgorithm="centroid" interactive+ \
+ display=stdgraph
+
+ ... type ? to get an optional help page
+
+ ... move graphics cursor to a star
+ ... type i to enter the interactive setup menu
+ ... enter maximum radius in pixels of the radial profile or CR
+ to accept the default value
+ ... type v to enter the default menu
+ ... set the fwhmpsf, centering radius, inner and outer sky annuli,
+ apertures, and sigma using the graphics cursor and the
+ stellar radial profile plot
+ ... typing <CR> leaves everything at the default value
+ ... type q to quit the setup menu
+
+ ... type the v key to verify the critical parameters
+
+ ... type the w key to save the parameters in the parameter files
+
+ ... retype :.read ypix.plot1 to reload the contour plot
+
+ ... move the graphics cursor to the stars of interest and tap
+ the space bar
+
+ ... a one line summary of the fitted parameters will appear on the
+ standard output for each star measured
+
+ ... type q to quit and q again to verify
+
+ ... full output will appear in the text file ypix.mag.3
+
+ da> set stdimcur = <default>
+
+ ... reset stdimcur to its previous value
+.fi
+
+
+4. Setup and run PHOT interactively on a list of objects temporarily
+overriding the fwhmpsf, sigma, cbox, annulus, dannulus, and apertures
+parameters determined in examples 1 or 2.
+
+.nf
+
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> phot dev$ypix ypix.coo.1 default calgorithm="centroid" \
+ cbox=7.0 annulus=12.0 dannulus=5.0 apertures="3.0,5.0" \
+ interactive+
+
+ ... type ? for optional help
+
+
+ ... move the graphics cursor to the stars and tap space bar
+
+ or
+
+ ... select stars from the input coordinate list with m / :m #
+ and measure with spbar
+
+ ... measure stars selected from the input coordinate list
+ with n / n #
+
+ ... a one line summary of results will appear on the standard output
+ for each star measured
+
+ ... type q to quit and q again to confirm the quit
+
+ ... the output will appear in ypix.mag.4 ...
+.fi
+
+
+5. Display and measure some stars in an image section and write the output
+coordinates in the coordinate system of the parent image.
+
+.nf
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image section
+
+ da> phot dev$ypix[150:450,150:450] "" default wcsout=tv \
+ calgorithm="centroid" interactive+
+
+ ... move cursor to stars and type spbar
+
+ ... type q to quit and q again to confirm quit
+
+ ... output will appear in ypix.mag.5
+
+ da> pdump ypix.mag.5 xc,yc yes | tvmark 1 STDIN col=204
+.fi
+
+
+6. Run PHOT in batch mode using the coordinate file and the previously
+saved parameters. Verify the critical parameters.
+
+.nf
+ ap> phot dev$ypix default default
+
+ ... output will appear in ypix.mag.6...
+.fi
+
+
+7. Repeat example 6 but assume that the input coordinate are ra and dec
+in degrees and degrees, turn off verification, and submit the task to to
+the background.
+
+.nf
+ da> display dev$ypix 1
+
+ ap> rimcursor wcs=world > radec.coo
+
+ ... move to selected stars and type any key
+
+ ... type ^Z to quit
+
+ da> phot dev$ypix radec.coo default wcsin=world verify- verbose- &
+
+ ... output will appear in ypix.mag.7
+
+ da> pdump ypix.mag.7 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars on the display
+.fi
+
+
+8. Run PHOT interactively without using the image display cursor.
+
+.nf
+ da> show stdimcur
+
+ ... record the default value of stdimcur
+
+ da> set stdimcur = text
+
+ ... set the image cursor to the standard input
+
+ da> phot dev$ypix default default interactive+
+
+ ... type ? for optional help
+
+ ... type :m 3 to set the initial coordinates to those of the
+ third star in the list
+
+ ... type i to enter the interactive setup menu
+ ... enter the maximum radius in pixels for the radial profile or
+ accept the default with a CR
+ ... type v to enter the default menu
+ ... set the fwhmpsf, centering radius, inner and outer sky annuli,
+ apertures, and sigma using the graphics cursor and the
+ stellar radial profile plot
+ ... typing <CR> after the prompt leaves the parameter at its default
+ value
+ ... type q to quit the setup menu
+
+ ... type r to rewind the coordinate list
+
+ ... type l to measure all the stars in the coordinate list
+
+ ... a one line summary of the answers will appear on the standard
+ output for each star measured
+
+ ... type q to quit followed by q to confirm the quit
+
+ ... full output will appear in the text file ypix.mag.8
+
+ da> set stdimcur = <default>
+
+ ... reset the value of stdimcur
+
+.fi
+
+8. Use a image cursor command file to drive the PHOT task. The cursor command
+file shown below sets the cbox, annulus, dannulus, and apertures parameters
+computes the centers, sky values, and magnitudes for 3 stars, updates the
+parameter files, and quits the task.
+
+.nf
+ da> type cmdfile
+ : calgorithm centroid
+ : cbox 9.0
+ : annulus 12.0
+ : dannulus 5.0
+ : apertures 5.0
+ 442 410 101 \040
+ 349 188 101 \040
+ 225 131 101 \040
+ w
+ q
+
+ da> phot dev$ypix "" default icommands=cmdfile verify-
+
+ ... full output will appear in ypix.mag.9
+.fi
+
+
+
+
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+
+It is currently the responsibility of the user to make sure that the
+image displayed in the frame is the same as that specified by the image
+parameter.
+
+Commands which draw to the image display are disabled by default.
+To enable graphics overlay on the image display, set the display
+parameter to "imdr", "imdg", "imdb", or "imdy" to get red, green,
+blue or yellow overlays and set the centerpars mkcenter switch to
+"yes", the fitskypars mksky switch to"yes", or the photpars mkapert
+switch to "yes". It may be necessary to run gflush and to redisplay the image
+to get the overlays position correctly.
+
+.ih
+SEE ALSO
+datapars, centerpars, fitskypars, photpars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/photpars.hlp b/noao/digiphot/daophot/doc/photpars.hlp
new file mode 100644
index 00000000..98f4e5f1
--- /dev/null
+++ b/noao/digiphot/daophot/doc/photpars.hlp
@@ -0,0 +1,100 @@
+.help photpars May00 noao.digiphot.daophot
+.ih
+NAME
+photpars -- edit the photometry parameters
+.ih
+USAGE
+photpars
+.ih
+PARAMETERS
+.ls weighting = "constant"
+The type of weighting. The weighting is ignored by the PHOT task. The options
+are:
+.ls constant
+Uniform weights of 1 for each pixel are used.
+.le
+.ls cone
+A conical weighting function of full width half maximum \fIfwhmpsf\fR as
+defined in the DATAPARS parameter set is used.
+.le
+.ls gauss
+A Gaussian weighting function of full width half maximum \fIfwhmpsf\fR as
+defined in the DATAPARS parameter set is used.
+.le
+.le
+.ls apertures = "3" (scale units)
+A list of aperture radii in units of the scale parameter or the name of the
+file containing the list of apertures. List elements may be separated by
+whitespace or commas. A ranges syntax of the form ap1:apN:apstep is also
+supported.
+.le
+.ls zmag = 25.00
+The zero point offset for the magnitude scale.
+.le
+.ls mkapert = no
+Mark the photometry apertures on the displayed image?
+.le
+
+.ih
+DESCRIPTION
+
+The integral of the flux within the circular apertures specified by
+\fIapertures\fR is computed by summing pixels in the aperture with
+the specified weighting function \fIweighting\fR. The fraction of each pixel
+lying within the aperture is computed by an approximation and all the
+approximations are summed. The zero point of the magnitude
+scale is determined by \fIzmag\fR.
+
+\fRApertures\fR is specified in units of the image scale. If \fIscale\fR
+is specified in units of the half-width at half-maximum of the point
+spread function the aperture per pixel a single value of apertures
+will work well on images with differing psfs.
+
+
+.ih
+EXAMPLES
+
+1. List the PHOTPARS parameters.
+
+.nf
+ da> lpar photpars
+.fi
+
+2. Edit the PHOTPARS parameters.
+
+.nf
+ da> photpars
+.fi
+
+3. Edit the PHOTPARS parameters from with the PHOT task.
+
+.nf
+ da> epar phot
+
+ ... edit a few phot parameters
+
+ ... move to the photpars parameter and type :e
+
+ ... edit the photpars parameters and type :wq
+
+ ... finish editing the phot parameters and type :wq
+.fi
+
+4. Save the current PHOTPARS parameter set in a text file photnite1.par.
+ This can also be done from inside a higher level task as in the above
+ example.
+
+.nf
+ da> photpars
+
+ ... type ":w photnite1.par" from within epar
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+epar,datapars,centerpars,fitskypars,phot
+.endhelp
diff --git a/noao/digiphot/daophot/doc/psf.hlp b/noao/digiphot/daophot/doc/psf.hlp
new file mode 100644
index 00000000..5613a8b2
--- /dev/null
+++ b/noao/digiphot/daophot/doc/psf.hlp
@@ -0,0 +1,752 @@
+.help psf May00 noao.digiphot.daophot
+.ih
+NAME
+psf -- build the point spread function for an image
+.ih
+USAGE
+psf image photfile pstfile psfimage opstfile groupfile
+.ih
+PARAMETERS
+.ls image
+The images for which the PSF model is to be built.
+.le
+.ls photfile
+The list of input photometry files. The number of photometry files must
+be equal to the number of input images. If photfile is "default", "dir$default",
+or a directory specification PSF searches for a file called dir$image.mag.#
+where # is the highest available version number for the file. Photfile is
+normally the output of the PHOT task but may also be the output of the PSF,
+PEAK, NSTAR and ALLSTAR tasks. Photfile may be an APPHOT/DAOPHOT text database
+or an STSDAS binary table.
+.le
+.ls pstfile
+The list of input psf star photometry files. The ids of the psf stars in these
+files must be the same as their ids in \fIphotfile\fR. The number of psf
+star files must be zero or equal to the number of input images. If pstfile
+is "default", "dir$default" or a directory specification, PSF searches for
+a file called image.pst.? where ? is the highest existing version number.
+Pstfile is usually the output of the DAOPHOT PSTSELECT task but may also be
+the appropriately edited output psf file produced by PSF itself, or the output
+of the GROUP, NSTAR, PEAK or ALLSTAR tasks. Photfile may be an APPHOT/DAOPHOT
+text database or an STSDAS table.
+.le
+.ls psfimage
+The output PSF model image names or directory. The must be one PSF image name
+for every input image. If psfimage is "default", "dir$default", or a directory
+specification, then PSF creates an image called image.psf.? where ? is the next
+available version number.
+.le
+.ls opstfile
+The output psf star files containing lists of the stars actually used to
+compute the PSF model. There must be one output psf star file for every input
+image. If opstfile is "default", "dir$default", or a directory specification
+then PSF creates a file called image.pst.? where ? is the next available
+version number. If the DAOPHOT package parameter \fItext\fR is "yes" then an
+APPHOT/DAOPHOT text database is written, otherwise an STSDAS binary table is
+written.
+.le
+.ls groupfile
+The output psf star group files listing the PSF stars and their neighbors that
+were used to create the PSF models. There must be one output group file for
+every input image. If groupfile is "default", "dir$default", or a directory
+specification then PSF creates a file called image.psg.? where ? is the
+next available version number. If the DAOPHOT package parameter \fItext\fR is
+"yes" then an APPHOT/DAOPHOT text database is written, otherwise an STSDAS
+table database is written.
+.le
+.ls plotfile = ""
+The name of the output file containing mesh, contour, or profile plots of the
+selected PSF stars. If plotfile is undefined no plot file is created,
+otherwise a mesh, contour, or profile plot is written to this file for each PSF
+star selected. Plotfile is opened in append mode and may become very large.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls matchbyid = yes
+Match the stars in the psf star list(s) if any to the stars in the input
+photometry files using id numbers (matchbyid = yes) or x and y positions
+(matchbyid = no).
+.le
+.ls interactive = yes
+Fit the PSF interactively ? If interactive = yes and \fIicommands\fR is
+undefined, PSF reads selects the initial list of PSF stars from \fIpstfile\fR
+and waits for commands from the user. If interactive = no and \fIicommands\fR
+is undefined, PSF reads in the candidate PSF stars from \fIpstfile\fR, computes
+ the PSF, and writes it to \fIpsfimage\fR without input from the user. If
+\fIicommands\fR is defined, then interactive = no, and commands are read from
+the image cursor command file.
+.le
+.ls mkstars = no
+Mark the selected or deleted psf stars on the image display ?
+.le
+.ls showplots = yes
+Show plots of the selected PSF stars? After each star is selected
+interactively by the user, a mesh, contour, or profile plot of the data
+subraster around the candidate star is displayed. At this point the user
+can accept or reject the star. In interactive mode the user can set showplots
+to "yes" or "no". In non-interactive mode showplots is always "no".
+.le
+.ls plottype = "mesh"
+The default type of plot displayed when selecting PSF stars. The choices
+are "mesh", "contour", or "radial".
+.le
+.ls icommands = ""
+The image display cursor or the name of the image cursor command file.
+.le
+.ls gcommands = ""
+The graphics cursor or the name of the graphics cursor command file.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout"
+The coordinate system of the input coordinates read from \fIphotfile\fR and
+\fIpstfile\fR, and of the output coordinates written to \fIpsfimage\fR,
+\fIopstfile\fR, \fIgroupfile\fR respectively. The image header coordinate
+system is used to transform from the input coordinate system to the "logical"
+pixel coordinate system used internally, and from the internal "logical" pixel
+coordinate system to the output coordinate system. The input coordinate system
+options are "logical", tv", "physical", and "world". The output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin and wcsout are "logical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical PSF task parameters? Verify can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_.update"
+Update the PSF task parameters if \fIverify\fR is "yes"? Update can be
+set to the default daophot package parameter value, "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+.ls graphics = ")_.graphics"
+The default graphics device. Graphics can be set to the default DAOPHOT package
+parameter value, "yes", or "no".
+.le
+.ls display = ")_.display"
+The default image display device. Display can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no". By default graphics
+overlay is disabled. Setting display to one of "imdr", "imdg", "imdb", or
+"imdy" enables graphics overlay with the IMD graphics kernel.
+.le
+
+.ih
+DESCRIPTION
+
+The PSF task builds the point spread function for the IRAF image \fIimage\fR
+using stars selected, from the input photometry file \fIphotfile\fR with the
+image cursor, and/or by their ids stored in the psf star file \fIpstfile\fR,
+and writes the PSF model out to the IRAF image \fIpsfimage\fR, the final
+PSF star list to \fIopstfile\fR, and group membership information for the
+selected PSF stars to \fIgroupfile\fR. If the DAOPHOT package parameter
+\fItext\fR is "yes", then \fIgroupfile\fR is an APPHOT/DAOPHOT text database,
+otherwise it is an STSDAS binary table.
+
+The coordinates read from \fIphotfile\fR and \fIpstfile\fR are assumed to be
+in coordinate system defined by \fIwcsin\fR. The options are "logical", "tv",
+"physical", and "world" and the transformation from the input coordinate
+system to the internal "logical" system is defined by the image coordinate
+system. The simplest default is the "logical" pixel system. Users working on
+with image sections but importing pixel coordinate lists generated from the
+parent image must use the "tv" or "physical" input coordinate systems.
+
+The coordinates written to \fIpsfimage\fR, \fIpstfile\fR and \fIgroupfile\fR
+are in the coordinate system defined by \fIwcsout\fR with the exception
+of the psf model center coordinates PSFX and PSFY which are always in the
+logical system of the input image. The options are "logical", "tv", and
+"physical". The simplest default is the "logical" system. Users wishing to
+correlate the output coordinates of objects measured in image sections or
+mosaic pieces with coordinates in the parent image must use the "tv"
+or "physical" coordinate systems.
+
+Suitable PSF stars are normally selected interactively using the image display
+and image cursor and matched with the stars in \fIphotfile\fR using the cursor
+position and a tolerance specified by the \fImatchrad\fR parameter in the
+DAOPARS task. A star must be in the photometry file before it can be used as
+a PSF star. If a match is found, PSF checks that the candidate star is not too
+close to the edge of the image and that it contains no bad pixels as defined
+by \fIdatamin\fR and \fIdatamax\fR in the DATAPARS task. After selection a
+mesh, contour, or profile plot of the data subraster around the candidate star
+is displayed in the graphics window, PSF enters graphics cursor command mode
+and the user is given the option to accept or reject the star. If the user
+accepts the star it is added to the PSF star list. Commands in the graphics
+cursor menu permit the user to manipulate the floor and ceiling levels of the
+contour plot and the viewing angles for the mesh plot interactively.
+
+Users who know which stars they wish to use as PSF stars ahead of time or
+who are without access to an image display can also select PSF stars by id
+number, after which mesh, contour, or radial profile plots will be displayed in
+the graphics window in the usual way.
+
+If the user does not wish to see any plots of the PSF stars or interact with
+the fitting process, the image cursor may be redirected to a text
+file containing cursor commands \fIicommands\fR which specify the PSF stars
+to be used in the fit. If \fIplotfile\fR is defined contour, mesh, or profile
+plots of the selected psf stars can be saved in a metacode plot file for later
+examination.
+
+In interactive mode the PSF star may be initialized by setting \fIpstfile\fR
+to a file created by the PSTSELECT task. If \fIshowplot\fR = "yes" the user is
+asked to accept or delete each star in the input psf star list. Other stars
+may also be added or deleted from this list at any time with the image cursor.
+If \fIinteractive\fR=no or \fIicommands\fR is defined, the PSF stars are read
+in from \fIpstfile\fR, and the PSF model is computed and saved without
+input from the user.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and PSF is run interactively the first data access will appear
+to take a long time as the entire image must be read in before the data
+is actually read. All subsequent measurements will be very fast because PSF
+is accessing memory not disk. The point of caching is to speed up random
+image access by making the internal image i/o buffers the same size as the
+image itself. However if the input object lists are sorted in row order and
+sparse caching may actually worsen not improve the execution time. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+The output PSF image \fIpsfimage\fR is normally a 2D image containing the
+image header parameters, "XPSF", "YPSF", "PSFMAG" and "PSFRAD" which define the
+centroid, magnitude and size of the PSF model, the parameters "FUNCTION",
+"PSFHEIGH", "NPARS", and "PAR#" which define the analytic component of the PSF,
+and a single look-up table of residuals from the analytic fit subsampled by a
+factor of 2 with respect to the parent image.
+
+If the DAOPARS parameter \fIvarorder\fR = -1, the PSF is fit by the analytic
+function and \fIpsfimage\fR has no pixel file.
+
+If the DAOPARS parameter \fIvarorder\fR = 1 or 2, then two or five additional
+lookup tables are computed and \fIpsfimage\fR is a 3D image with 3 or 6 planes
+respectively. The first two additional look-up tables contain the first
+derivatives of the PSF wrt the x and y positions in the image (varorder = 1),
+and the next three contains the second derivatives with respect to x ** 2, xy,
+and y ** 2 (varorder = 2).
+
+The positions and magnitudes of each of the stars contributing to the PSF model
+are also stored in the PSF image header.
+
+\fIGroupfile\fR contains a list of the PSF stars, their nearest neighbors, and
+friends of the neighbors. A neighbor is defined to be any star within a
+distance of 1.5 * \fIpsfrad\fR / \fIscale\fR + 2.0 * \fIfitrad\fR /
+\fIscale\fR + 1 pixels of the PSF star. Friends of the neighbors are defined
+to be any stars within 2.0 * \fIfitrad\fR / \fIscale\fR + 1.0 of a neighbor
+star. \fIFitrad\fR and \fIpsfrad\fR are respectively the fitting radius and psf
+radius parameters in the DAOPARS task. \fIScale\fR is the scale factor defined
+in the DATAPARS task.
+
+.ih
+CURSOR COMMANDS
+
+The following cursor commands are available once the image cursor has
+been activated.
+
+.nf
+ Keystroke Commands
+
+? Print help
+p Print photometry for star nearest the cursor
+l List the current psf stars
+a Add star nearest cursor to psf star list
+f Fit the psf
+r Review the fit for all the psf stars
+s Subtract fitted psf from psf star nearest cursor
+d Delete psf star nearest cursor from psf star list
+w Write the psf to the psf image
+z Rebuild the psf from scratch
+q Quit task
+
+ Colon Commands
+
+:p [n] Print photometry for star n
+:a [n] Add star n to psf star list
+:d [n] Delete star n from psf star list
+:s [n] Subtract fitted psf from psf star n
+
+ Colon Parameter Editing Commands
+
+# Data dependent parameters which affect the psf computation
+
+:scale [value] Show/set the image scale (units / pixel)
+:fwhmpsf [value] Show/set the fwhm of psf (scale units)
+:datamin [value] Show/set the minimum good data value (counts)
+:datamax [value] Show/set the maximum good data value (counts)
+:matchrad [value] Show/set matching radius (scale units)
+
+# Psf computation parameters
+
+:psfimage [name,name] Show/set the psf image and groupfile
+:function [string] Show/set the analytic psf function
+:varorder [integer] Show/set order of psf function variability
+:nclean [integer] Show/set number of cleaning iterations
+:saturated [y/n] Show/set the use saturated star flag
+:psfrad [value] Show/set the psf radius (scale units)
+:fitrad [value] Show/set the fitting radius (scale units)
+
+
+The following cursor commands are available once a star has been selected
+and the graphics cursor has been activated.
+
+ Interactive Graphics Keystroke Commands
+
+? Print help
+p Print the photometry for this star
+t Print the plot parameters and data minimum and maximum
+a Accept star and proceed
+d Reject star and select another with image cursor
+m Plot the default mesh plot for this star
+n Increase vertical angle by 15 degrees (mesh plot only)
+s Decrease vertical angle by 15 degrees (mesh plot only)
+w Decrease horizontal angle by 15 degrees (mesh plot only)
+e Increase horizontal angle by 15 degrees (mesh plot only)
+c Plot the default contour plot for this star
+r Plot the radial profile for this star
+
+
+ Colon Graphics Commands
+
+:m [val] [val] Set the mesh plot vertical and horizontal viewing angles
+:v [val] Set the mesh plot vertical viewing angle
+:h [val] Set the mesh plot horizontal viewing angle
+:c [val] [val] Set the contour plot floor and ceiling levels
+:l [value] Set the contour plot floor level
+:u [value] Set the contour plot ceiling level
+.fi
+
+.ih
+ALGORITHMS
+The PSF is determined from the actual observed brightness values as a function
+of x and y
+for one or more stars in the frame and stored as a two-component model.
+The first component is an analytic function which approximates
+the light distribution in the cores of the PSF stars. There are
+currently 6 choices for the analytic component of the model:
+"gauss", "moffat15", "moffat25", "lorentz", "penny1", and "penny2".
+The parameters of the analytic component of the psf model are stored
+in the psf image header parameters "FUNCTION", "PSFHEIGH", "NPARS",
+and "PARN". The magnitude, size, and centroid of the PSF are stored
+in the image header parameters "PSFMAG", "PSFRAD",
+"XPSF", "and "YPSF". If \fImatchbyid\fR is "no" or there is no input psf star list "PSFMAG" is
+set to the magnitude of the first PSF star in the input photometry file. If \fImatchbyid\fR
+is "yes", and there is an input psf star list "PSFMAG" is set to the magnitude of the first psf star
+in the psf star list. "XPSF" and "YPSF" are the center of the image.
+If \fIvarorder\fR >= 0,
+the residuals from this fit are stored as a lookup
+table with twice the sampling interval of the original image.
+This lookup table is used as additive corrections from the integrated
+analytic function to actual observed empirical PSF.
+The parameters of the analytic function are computed by fitting
+all the stars weighted by their signal-to-noise.
+so that the signal-to-noise ratio in
+the PSF does not deteriorate as fainter stars are added in. The more
+crowded the field the more PSF stars are required to lower the noise
+generated by neighbor subtraction.
+
+If the \fIvarorder\fR parameter in the DAOPARS task is set to 1 or 2, two
+or five additional lookup
+tables containing the first derivatives of the PSF in x and y
+and the second order derivatives of the image with respect to
+x ** 2, x * y, and y ** 2 are also written.
+This model
+permits the PSF fitting process to take account of smooth linear
+or quadratic changes in the PSF across the frame caused for example by a tilt in
+the detector with respect to the optical axis or low order optical
+aberrations.
+Users of this option should ensure that the PSF varies in a systematic
+way across the frame and that the chosen PSF stars span the entire
+region of interest in the frame. To avoid mistaking
+neighbor stars for variations in the PSF it is recommended that the
+first few iterations of PSF be run with a constant PSF. Only after
+neighbor stars have been subtracted reasonably cleanly should
+the variable PSF option be enabled.
+
+The brightness of any hypothetical pixel at any arbitrary point within
+the PSF is computed as follows. The analytic function
+is integrated over the area of the pixel, a correction is determined
+by bicubic interpolation within the lookup table and added to the
+integral. Since the values in the table of residuals differ by smaller
+amounts between adjacent grid points than the original brightness data
+would have, the errors in the interpolation are much less than they would
+have been if one had tried to interpolate directly within the original
+data.
+
+.ih
+GUIDE TO COMPUTING A PSF IN A CROWDED FIELD
+
+The following is a rough guide to the methodology of computing the
+PSF in a crowded field. The procedure outlined below assumes
+that the user can either make use of the IRAF display facilities or
+has access to a local display program. At a minimum the display program
+should be able to display an image, read back the coordinates of objects in the
+image, and mark objects in the image.
+
+The crowded field PSF fitting procedure makes use of many of the
+DAOPHOT tasks. Details on the setup and operation of each task can be found
+in the appropriate manual pages.
+
+.ls [1]
+RUN THE DAOFIND and PHOT TASKS ON THE IMAGE OF INTEREST.
+.le
+.ls [2]
+EXAMINE THE IMAGE. Load the image on the display with the IRAF display task.
+Using the display itself, the DAOEDIT task, or the IRAF IMEXAMINE task, estimate the radius
+at which
+the stellar light distribution disappears into the noise for the
+brightest candidate PSF star. Call this parameter \fIpsfrad\fR and record it.
+Mark the objects detected by DAOFIND with dots on the image display using the
+IRAF TVMARK
+task. Users at sites with display devices not currently supported by
+IRAF should substitute their local versions of DISPLAY and TVMARK.
+.le
+.ls [3]
+SELECT CANDIDATE PSF STARS.
+Good PSF stars should have no neighbors
+within the fitting radius stored in the DAOPARS task parameter \fIfitrad\fR.
+In addition all stars within 1.5 times the psf radius,
+(stored in the DAOPARS task parameter
+\fIpsfrad\fR), should be significantly fainter than the candidate star.
+There should be no bad columns, bad rows or blemishes
+near the candidate star. A sufficient number of stars should be
+selected in order to reduce the increased noise resulting from the
+neighbor subtraction process. Users of the variable PSF option should
+take care that the list of PSF stars span the area of interest on the
+image. Twenty-five to thirty stars is not unreasonable in this case.
+
+The task PSTSELECT can be used to preselect candidate PSF stars.
+These candidate PSF stars can be marked on the image display using the
+PDUMP, and TVMARK tasks. Be sure to mark the PSF stars in another
+color from the stars found by DAOFIND. Stars can be added to or
+subtracted from this list interactively when PSF is run.
+.le
+.ls [4]
+EXAMINE THE PSF STARS FOR NEIGHBORS MISSED BY DAOFIND AND ADD THESE TO
+THE PHOT FILE.
+Examine the vicinity of the PSF stars on the display checking for neighbor
+stars which do not have dots on them indicating that they were
+missed by DAOFIND.
+If IRAF supports the local display device simply run PHOT interactively
+selecting the missing stars with the image cursor.
+Be sure to use the same set of PHOT parameters used in step [1] with
+the exception of the CENTERPARS
+task parameter \fIcalgorithm\fR which should be temporarily set to "centroid".
+If IRAF does not support the
+local display generate a list of the approximate coordinates of the
+missing stars.
+Run PHOT in batch mode with this coordinate list as input and with the
+parameters set as described above.
+Create a new PHOT file by using PCONCAT to add the new PHOT output to the
+PHOT output from [1] and renumber using PRENUMBER. Do not resort.
+.le
+.ls [5]
+ESTIMATE OF THE PSF.
+Run PSF using the combined PHOT output from [4] and
+the list of candidate stars from [3].
+Write out the PSF image (extension .psf.#) and the psf group file
+(extension .psg.#). The PSF image is the current estimate of the PSF.
+.le
+.ls [6]
+FIT ALL THE STARS IN EACH PSF STAR GROUP IN THE ORIGINAL IMAGE.
+Run NSTAR on the image using the output group file (extension .psg.#)
+of [5] as the input photometry list. To help prevent the bumps in the initial
+PSF from interfering with the profile fits in NSTAR, it may
+be necessary to temporarily set the psf radius,
+\fIpsfrad\fR in the DAOPARS task,
+to about one pixel greater than the separation of the nearest neighbor
+to a PSF star.
+The fitting radius, \fIfitrad\fR in the
+DAOPARS task, should be sufficiently large to include enough
+pixels for a good fit but not so large as to include any neighbors
+inside the fitting radius.
+.le
+.ls [7]
+SUBTRACT ALL THE FITTED STARS FROM THE ORIGINAL IMAGE.
+Run SUBSTAR to subtract the NSTAR results from the original image.
+Use the IRAF DISPLAY task or the local display program to display
+the subtracted image. If you decreased the value of \fIpsfrad\fR
+in [6] use this smaller value when you subtract as well.
+.le
+.ls [8]
+CHECK FOR PREVIOUSLY INVISIBLE FAINT COMPANIONS.
+Check to see whether the PSF stars and neighbors subtracted
+cleanly or whether there are faint companions that were not previously
+visible before.
+.le
+.ls [9]
+APPEND THESE COMPANIONS TO THE PHOT FILE.
+Run PHOT on the faint companions in the subtracted image
+and append the results to the PHOT file created in [4] using PCONCAT.
+Renumber the stars using PRENUMBER.
+.le
+.ls [10]
+SUBTRACT ALL THE PSF NEIGHBOR STARS FROM THE ORIGINAL IMAGE.
+Edit the nstar output file (extension .nst.#) removing all the PSF stars
+from the file. The PSF stars is the first one in each group. In the
+near future this will be done with the PEXAMINE task but at the
+moment the text editor can be used for text databases and the TTOOLS
+package task TEDIT can be used for tables. PSELECT can also be used
+to remove stars with specific id numbers. Run SUBSTAR using the edited
+nstar output file as input.
+.le
+.ls [11]
+RECOMPUTE THE PSF.
+Run PSF on the subtracted image from [10] using the PHOT file from [9]
+as the input stellar photometry file.
+Temporarily set the minimum good data value, the \fIdatamin\fR parameter
+in the DATAPARS task to a large negative number, to avoid the
+enhanced noise where the
+stars were subtracted from triggering the bad pixel detector in PSF.
+A new psf (extension .psf.#) and new psf group file (extension .psg.#)
+will be created. Be sure to increase the \fIpsfrad\fR value to the
+original large value found in [2].
+.le
+.ls [12]
+RERUN NSTAR.
+Rerun NSTAR on the original image with the newly created group file
+(extension .psg.#) as the input stellar photometry file and the newly
+computed PSF image (extension .psf.#).
+It should not be necessary to reduce the psf radius as in [6]
+but the fitting radius should be left at a generous number.
+.le
+.ls [13]
+REPEAT STEPS [7-12] UNTIL THE PSF FIT IS ACCEPTABLE.
+If any neighbors are still visible iterate on this process by repeating
+steps [7] to [12] until the neighbors completely disappear. The main
+point to remember is that each time through the loop the PSF is obtained
+from an image in which the neighbors but not the PSF stars have been
+subtracted out while NSTAR and SUBSTAR should be run on the original
+picture with all the stars still in it.
+.le
+
+.ih
+EXAMPLES
+
+1. Compute the PSF for the image dev$ypix. Select stars using the display and
+the image cursor and show plots of the data and the residuals from the fit
+for each star. Good stars for making the PSF model can be found at (442,410),
+(348,189), and (379,67).
+
+.nf
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 5.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> psf dev$ypix default "" default default default psfrad=9.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+.fi
+
+
+2. Run PSF non-interactively using the photometry file and psf star file
+created in the previous example.
+
+.nf
+ da> psf dev$ypix default default default default default \
+ psfrad=9.0 fitrad=3.0 interactive- plotfile=psf.plots
+
+ ... the output will appear in ypix.psf.2, ypix.psg.2, and
+ ypix.pst.2
+
+ da> gkidir psf.plots
+
+ ... list the plots created by psf
+
+ da> gkiextract psf.plots 1 | stdgraph
+
+ ... display the surface plots of the first psf star
+
+ da> seepsf ypix.psf.2 ypixpsf
+
+ ... convert the sampled PSF look-up table to a PSF image
+.fi
+
+
+3. Setup and run PSF interactively without using the image display cursor.
+Use the photometry file created in example 1. Before running PSF in this
+manner the user should have a list of the candidate PSF star ids.
+
+.nf
+ da> show stdimcur
+
+ ... store the default value
+
+ da> set stdimcur = text
+
+ ... define the image cursor to be the standard input
+
+ da> epar psf
+
+ ... edit the psf parameters
+
+ ... move to the datapars line and type :e edit the data dependent
+ parameters, type :q to quit the datapars menu
+
+ ... move to the daopars line and type :e edit the daophot fitting
+ parameters, type :q to quit the daopars menu
+
+ ... finish editing the psf parameters
+
+ da> psf dev$ypix default "" default default default \
+ plottype=radial
+
+ ... verify critical parameters
+
+ ... type :a # where # stands for the id number of the star,
+ a plot of the stellar data appears
+
+ ... type a to accept the star, d to reject it
+
+ ... repeat for all the PSF stars
+
+ ... type l to list the psf stars
+
+ ... type f to fit the PSF
+
+ ... type :s # where # stands for the id of the psf star, a plot
+ of the model residuals appears
+
+ ... type w to save the PSF
+
+ ... type q to quit PSF and q again to confirm the quit
+
+ ... the output will appear in ypix.psf.3, ypix.pst.3, ypix.psg.3
+
+ da> set stdimcur = stdimage
+
+ ... reset the image cursor
+.fi
+
+
+4. Run PSF in non-interactive mode using an image cursor command file of
+instructions called icmds.
+
+.nf
+ da> type icmds
+ :a 106
+ :a 24
+ :a 16
+ :a 68
+ f
+ w
+ q
+
+ da> psf dev$ypix default "" default default default \
+ icommands=icmds
+
+ ... verify the critical parameters
+
+ ... the PSF will be constructed from stars 106, 24, 16, 68
+ in the input photometry file
+
+ ... the output will appear in ypix.psf.4, ypix.pst.4, ypix.psg.4
+
+.fi
+
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,pstselect,seepsf
+.endhelp
diff --git a/noao/digiphot/daophot/doc/pstselect.hlp b/noao/digiphot/daophot/doc/pstselect.hlp
new file mode 100644
index 00000000..2dd110bd
--- /dev/null
+++ b/noao/digiphot/daophot/doc/pstselect.hlp
@@ -0,0 +1,418 @@
+.help pstselect May00 noao.digiphot.daophot
+.ih
+NAME
+pstselect -- select candidate psf stars from a photometry file
+.ih
+USAGE
+pstselect image photfile pstfile maxnpsf
+.ih
+PARAMETERS
+.ls image
+The list of images containing the candidate psf stars.
+.le
+.ls photfile
+The list of input photometry files. The number of photometry files must
+be equal to the number of input images. If photfile is "default", "dir$default",
+or a directory specification PSTSELECT searches for a file called
+dir$image.mag.# where # is the highest available version number for the file.
+Photfile is normally the output of the PHOT task but may also be the output
+of the PSF, PEAK, NSTAR and ALLSTAR tasks. Photfile may be a
+text file or an STSDAS binary table.
+.le
+.ls pstfile
+The list of output psf star photometry files. There must be one output
+psf star photometry file for every input image. If pstfile is "default",
+"dir$default", or a directory specification then PSTSELECT writes
+a file called dir$image.pst.# where # is the next available version number.
+Pstfile inherits its file type, it may be either an APPHOT/DAOPHOT
+text or STSDAS binary file, from photfile.
+.le
+.ls maxnpsf = 25
+The maximum number of candidate psf stars to be selected.
+.le
+.ls mkstars = no
+Mark the selected or deleted psf stars on the image display ?
+.le
+.ls plotfile = ""
+The name of the output file containing mesh, contour, or profile plots of the
+selected PSF stars. If plotfile is undefined no plot file is created; otherwise
+a mesh, contour, or profile plot is written to this file for each PSF star
+selected. Plotfile is opened in append mode and may become very large.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameter
+\fIscale\fR is located here. If \fIdatapars\fR is undefined then the default
+parameter set in uparm directory is used.
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls interactive = no
+Select the psf stars interactively ? If interactive = yes and icommands is
+undefined, PSTSELECT reads in the star list from \fIphotfile\fR, sorts the
+stars by magnitude and waits for commands from the user. If interactive = no
+and icommands="", PSTSELECT selects candidate PSF stars from \fIphotfile\fR
+automatically. If icommands is not undefined then interactive is automatically
+set to "no", and commands are read from the image cursor command file.
+.le
+.ls plottype = "mesh"
+The default plot type displayed when a psf star is selected interactively.
+The choices are "mesh", "contour", or "radial".
+.le
+.ls icommands = ""
+The image display cursor or image cursor command file.
+.le
+.ls gcommands = ""
+The graphics cursor or graphics cursor command file.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout"
+The coordinate system of the input coordinates read from \fIphotfile\fR and
+of the output coordinates written to \fIpstfile\fR respectively. The image
+header coordinate system is used to transform from the input coordinate
+system to the "logical" pixel coordinate system used internally,
+and from the internal "logical" pixel coordinate system to the output
+coordinate system. The input coordinate system options are "logical", "tv",
+"physical", and "world". The output coordinate system options are "logical",
+"tv", and "physical". The image cursor coordinate system is assumed to
+be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin and wcsout are "logical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical PSTSELECT parameters ?
+Verify can be set to the DAOPHOT package parameter value (the default),
+"yes", or "no".
+.le
+.ls update = ")_.update"
+Update the algorithm parameters if verify is "yes"?
+Update can be set to the DAOPHOT package parameter value (the default),
+"yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task in non-interactive mode ?
+Verbose can be set to the DAOPHOT package parameter value (the default),
+"yes", or "no".
+.le
+.ls
+graphics = ")_.graphics"
+The default graphics device. Graphics can be set to the default
+daophot package parameter value, "yes", or "no".
+.le
+.ls display = ")_.display"
+The default image display device. Display can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no". By default graphics
+overlay is disabled. Setting display to one of "imdr", "imdg", "imdb", or
+"imdy" enables graphics overlay with the IMD graphics kernel.
+.le
+
+.ih
+DESCRIPTION
+
+PSTSELECT reads the input photometry file \fIphotfile\fR, extracts the ID,
+XCENTER, YCENTER, MAG, and MSKY fields for up to \fImaxnpsf\fR psf stars,
+and the results to \fIpstfile\fR. \fIPstfile\fR automatically inherits the
+file format of \fIphotfile\fR.
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to
+the internal "logical" system is defined by the image coordinate system.
+The simplest default is the "logical" pixel system. Users working on with
+image sections but importing pixel coordinate lists generated from the parent
+image must use the "tv" or "physical" input coordinate systems.
+
+The coordinates written to \fIpstfile\fR are in the coordinate system defined
+by \fIwcsout\fR. The options are "logical", "tv", and "physical". The simplest
+default is the "logical" system. Users wishing to correlate the output
+coordinates of objects measured in image sections or mosaic pieces with
+coordinates in the parent image must use the "tv" or "physical" coordinate
+systems.
+
+After reading the star list from \fIphotfile\fR, PSTSELECT sorts the list in
+order of increasing magnitude, after rejecting any stars that have INDEF
+valued magnitudes, or which lie less than \fIfitrad\fR / \fIscale\fR
+pixels from the edge of the \fIimage\fR. From this list the brightest
+\fImaxnpsf\fR stars which have no brighter neighbor stars within (\fIpsfrad\fR +
+\fIfitrad\fR) / \fIscale\fR + 1 pixels are selected as candidate psf stars.
+\fIPsfrad\fR and \fIfitrad\fR are the psf radius and fitting radius parameters
+respectively and are stored in the DAOPARS parameter set. \fIScale\fR is the
+image scale parameter and is located in the DATAPARS parameter set. Plots,
+either mesh, contour or radial profile depending on the value of
+\fIplottype\fR, of the selected stars may be saved in the file \fIplotfile\fR.
+
+If \fIinteractive\fR = "no", PSTSELECT reads the star list in \fIphotfile\fR,
+selects the candidate psf stars as described above, and writes the results to
+\fIpstfile\fR automatically. If interactive = "yes", PSTSELECT reads
+the star list, selects the candidate psf stars and waits for further
+instruction from the user. At this point the user can step through the stars
+chosen by PSTSELECT, check their surface, contour, or radial profile plots
+for blemishes, neighbors etc, and accept the good candidates and reject
+the poor ones, or use the image cursor and/or id number to select psf
+stars until a maximum of \fImaxnpsf\fR stars is reached. At any point in
+this process a previously selected psf star can be deleted.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough, the input image pixels are cached in memory. If caching
+is enabled and PSTSELECT is run interactively the first data access will appear
+to take a long time as the entire image must be read in before the data
+is actually fetched. All subsequent measurements will be very fast because
+PSTSELECT is accessing memory not disk. The point of caching is to speed up
+random image access by making the internal image i/o buffers the same size as
+the image itself. However if the input object lists are sorted in row order and
+sparse caching may actually worsen not improve the execution time. Also at
+present there is no point in enabling caching for images that are less than
+or equal to 524288 bytes, i.e. the size of the test image dev$ypix, as the
+default image i/o buffer is exactly that size. However if the size of dev$ypix
+is doubled by converting it to a real image with the chpixtype task then the
+effect of caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+
+.ih
+CURSORS
+
+ The following cursor commands are available once the image cursor
+ has been activated.
+
+.nf
+
+ Keystroke Commands
+
+? Print help
+p Print photometry for star nearest the cursor
+l List the current psf stars
+n Select the next good candidate psf star from the list
+a Add star nearest cursor to psf star list
+d Delete psf star nearest cursor from psf star list
+q Quit task
+
+ Colon Commands
+
+:p [n] Print photometry for star n
+:a [n] Add star n to psf star list
+:d [n] Delete star n from psf star list
+
+The following cursor commands are available once a star has been selected
+and the graphics cursor has been activated.
+
+ Interactive Graphics Keystroke Commands
+
+? Print help
+p Print the photometry for this star
+t Print the plot parameters and data minimum and maximum
+a Accept star and proceed
+d Reject star and select another with image cursor
+m Plot the default mesh plot for this star
+n Increase vertical angle by 15 degrees (mesh plot only)
+s Decrease vertical angle by 15 degrees (mesh plot only)
+w Decrease horizontal angle by 15 degrees (mesh plot only)
+e Increase horizontal angle by 15 degrees (mesh plot only)
+c Plot the default contour plot for this star
+r Plot the radial profile for this star
+
+
+ Colon Graphics Commands
+
+:m [val] [val] Set the mesh plot vertical and horizontal viewing angles
+:v [val] Set the mesh plot vertical viewing angle
+:h [val] Set the mesh plot horizontal viewing angle
+:c [val] [val] Set the contour plot floor and ceiling levels
+:l [value] Set the contour plot floor level
+:u [value] Set the contour plot ceiling level
+.fi
+
+.ih
+OUTPUT
+
+If \fIverbose\fR = "yes" a single line is written to the terminal for each
+star added to the candidate psf star list. Full output is written to the
+file \fIpstfile\fR. At the beginning of this file is a header listing the
+values of all the important parameters. For each star included in the candidate
+psf star list the following quantities are written.
+
+.nf
+ id xcenter ycenter mag msky
+.fi
+
+Id, xcenter, ycenter, mag, and msky are the id, x and y coordinates,
+magnitudes and sky values for the candidate psf stars listed in
+\fIphotfile\fR.
+
+.ih
+EXAMPLES
+
+1. Select up to 10 psf stars from the PHOT task output non-interactively.
+Save surface plots of the selected stars in the file "psf.plots".
+
+.nf
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 5.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> pstselect dev$ypix default default 10 psfrad=9.0 fitrad=3.0 \
+ plotfile=psf.plots
+
+ ... answer verify prompts
+
+ ... select candidate psf stars
+
+ ... the output will appear in ypix.pst.1
+
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> pdump ypix.pst.1 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+ da> gkiextract psf.plots 1 | stdgraph
+
+ ... make a surface plot of the first candidate psf star
+.fi
+
+
+2. Repeat the previous results for an image section while preserving the
+coordinate system of the original image.
+
+
+.nf
+ da> daofind dev$ypix[150:450,150:450] default wcsout=tv fwhmpsf=2.5 \
+ sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.2
+
+ da> phot dev$ypix[150:450,150:450] default default wcsin=tv wcsout=tv \
+ annulus=10. dannulus=5. apertures = 5.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.2
+
+ da> pstselect dev$ypix[150:450,150:450] default default 10 wcsin=tv \
+ wcsout=tv psfrad=9.0 fitrad=3.0 plotfile=psf.plots2
+
+ ... answer verify prompts
+
+ ... select candidate psf stars
+
+ ... the output will appear in ypix.pst.2
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.pst.2 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+ da> gkiextract psf.plots2 4 | stdgraph
+
+ ... make a surface plot of the 4th candidate psf star
+.fi
+
+
+3. Repeat example 1 but run pstselect in interactive mode and do not save the
+plots.
+
+.nf
+ da> display dev$ypix 1
+
+ ... display the image
+
+ da> pstselect dev$ypix ypix.mag.1 default 10 psfrad=9. fitrad=3. \
+ interactive+ mkstars+ display=imdr
+
+ ... verify the critical parameters as instructed
+
+ ... when the image cursor appears type the n keystroke
+ command to select the first suitable candidate psf
+ star, examine its surface plot, and type a or d to
+ accept or reject the candidate
+
+ ... repeat the previous command until 10 psf stars have
+ been selected, the end of the star list is reached,
+ or a sufficient number of stars but fewer than maxnpsf
+ have been selected
+
+ ... if fewer than maxnpsf stars are found automatically
+ add psf stars to the list with the a keystroke command
+
+ ... type q to quit
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,phot,psf
+.endhelp
diff --git a/noao/digiphot/daophot/doc/seepsf.hlp b/noao/digiphot/daophot/doc/seepsf.hlp
new file mode 100644
index 00000000..ed7a5728
--- /dev/null
+++ b/noao/digiphot/daophot/doc/seepsf.hlp
@@ -0,0 +1,101 @@
+.help seepsf May00 noao.digiphot.daophot
+.ih
+NAME
+seepsf -- convert a sampled PSF lookup table to a PSF image
+.ih
+USAGE
+seepsf psfimage image
+.ih
+PARAMETERS
+.ls psfimage
+The list of input PSF images computed by the PSF task. Each PSF image consists
+of the parameters of a 2D analytic function stored in the image header and an
+optional sampled lookup table of residuals from that fit stored in the image
+pixels.
+.le
+.ls image
+The list of output PSF images consisting of the sum of the analytic function
+and the residuals in the lookup table. There must be one output PSF image for
+each input PSF image.
+.le
+.ls dimension = INDEF
+The dimensions of the output PSF image. By default \fIimage\fR is a 2D image
+with dimensions of N by N where N = 2 * nint (psfrad / scale) + 1 with the
+same scale as the original image from which \fIpsfimage\fR was derived.
+\fIPsfrad\fR is the PSF fitting radius stored in the \fIpsfimage\fR image
+header parameter "PSFRAD". \fIScale\fR is the image scale stored in the image
+header parameter "SCALE".
+.le
+.ls xpsf = INDEF
+The x coordinate of the output PSF. \fIXpsf\fR is only used if \fIpsfimage\fR
+was computed with the variable PSF parameter \fIvarorder\fR in the DAOPARS task
+set to > 0.
+.le
+.ls ypsf = INDEF
+The y coordinate of the output PSF. \fIYpsf\fR is only used if \fIpsfimage\fR
+was computed with the variable PSF parameter \fIvarorder\fR in the DAOPARS task
+set to > 0.
+.le
+.ls magnitude = INDEF
+The intensity scale of the output PSF. By default the intensity scale is set by
+the magnitude of the first star used by the PSF task to compute \fIpsfimage\fR.
+This parameter is stored in the keyword "PSFMAG" in \fIpsfimage\fR.
+.le
+.ih
+DESCRIPTION
+SEEPSF takes the input PSF \fIpsfimage\fR computed by the PSF task, consisting
+of the parameters of a 2D analytic function stored in the image header and an
+optional lookup table of residuals from the fit stored in the image pixels, and
+computes an output PSF, \fIimage\fR, consisting of the sum of the analytic
+function and the residuals.
+
+By default \fIimage\fR is a 2D image of dimensions N by N where N = 2 * nint
+(psfrad) + 1 and the scale of \fIimage\fR is the same as the scale of the
+original image from which \fIpsfimage\fR was derived. If \fIdimension\fR is
+greater or less than N then the output PSF is block-averaged or subsampled with
+respect to the original image. \fIPsfrad\fR is the value of the psf radius
+parameter in the task DAOPARS used to compute \fIpsfimage\fR and is stored in
+the \fIpsfimage\fR header parameter "PSFRAD".
+
+If \fIpsfimage\fR was computed with the variable PSF parameter \fIvarorder\fR
+set to > 0, then \fIimage\fR is computed at a point (xpsf, ypsf) defined
+relative to the original image. By default \fIimage\fR is computed at the
+centroid of the PSF defined by the \fIpsfimage\fR header parameters "XPSF"
+and "YPSF".
+
+The intensity scale of \fIimage\fR is determined by the value of \fImagnitude\fR
+relative to the magnitude of the PSF. By default the output PSF has the
+magnitude of the first PSF star stored in the \fIpsfimage\fR header parameter
+"PSFMAG".
+
+SEEPSF is most commonly used for visualizing the PSF in image scale coordinates
+and checking the form of any variability as a function of position. However
+\fIimage\fR can also be used as input to other image processing program, for
+example it might be used as the kernel in a convolution operation.
+
+.ih
+EXAMPLES
+
+1. Compute the output PSF in image scale coordinates of PSF function
+for image dev$ypix.
+
+.nf
+ da> seepsf ypix.psf.3 ypixpsf
+.fi
+
+2. Compute the output PSF in image scale coordinates of the variable
+PSF for the image m92b at position (113.63,50.48) pixels relative to the
+original image.
+
+.nf
+ da> seepsf m92b.psf.2 m92psf xpsf=113.63 ypsf=50.48
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,psf
+.endhelp
diff --git a/noao/digiphot/daophot/doc/setimpars.hlp b/noao/digiphot/daophot/doc/setimpars.hlp
new file mode 100644
index 00000000..dad0d4d1
--- /dev/null
+++ b/noao/digiphot/daophot/doc/setimpars.hlp
@@ -0,0 +1,165 @@
+.help setimpars May00 noao.digiphot.daophot
+.ih
+NAME
+setimpars -- save / restore the daophot parameters for a particular image
+.ih
+USAGE
+setimpars image restore update
+.ih
+PARAMETERS
+.ls image
+The image for which the daophot parameters are to be saved or restored.
+.le
+.ls restore
+If restore = yes, parfile is "", and the file "image.pars" exists, SETIMPARS
+sets the current algorithm parameters by reading in the file "image.pars". If
+parfile is not "", then restore is automatically assumed to be yes.
+.le
+.ls update
+If update = yes, SETIMPARS saves the new current values of the DAOPHOT algorithm
+parameters in the file \fIimage.pars\fR and any previously existing file of the same name is overwritten.
+.le
+.ls review = no
+Review and/or edit the values of the parameters in the parameter sets DATAPARS,
+FINDPARS, CENTERPARS, FITSKYPARS, PHOTPARS, and DAOPARS by calling up the EPAR
+task for each of the named parameter sets in turn?
+.le
+.ls parfile
+The name of the input file containing the values of the DAOPHOT algorithm
+parameters to be restored. If defined \fIparfile\fR must have been written
+by SETIMPARS. If parfile is null (""), SETIMPARS searches for a file named
+\fIimage.pars\fR in the user's current directory. If no file is found, the
+DAOPHOT algorithm parameters are restored from the files \fIdatapars\fR,
+\fIfindpars\fR, \fIcenterpars\fR, \fIfitskypars\fR, \fIphotpars\fR, and
+\fIdaopars\fR.
+.le
+.ls datapars = ""
+The name of the file containing the DATAPARS parameter values. Datapars must be
+a named DATAPARS parameter set file written by the EPAR task, or "" in which
+case the default DATAPARS parameter set in the user's uparm directory is used.
+If the parameter \fIunlearn\fR is "yes" and datapars is "", DATAPARS is
+unlearned.
+.le
+.ls findpars = ""
+The name of the file containing the FINDPARS parameter values. Findpars
+must be a named FINDPARS parameter set file written by the EPAR task, or ""
+in which case the default FINDPARS parameter set in the user's uparm
+directory is used. If the parameter \fIunlearn\fR is "yes" and findpars
+is "", FINDPARS is unlearned.
+.le
+.ls centerpars = ""
+The name of the file containing the CENTERPARS parameter values. Centerpars
+must be a named CENTERPARS parameter set file written by the EPAR task, or ""
+in which case the default CENTERPARS parameter set in the user's uparm
+directory is used. If the parameter \fIunlearn\fR is "yes" and centerpars
+is "", CENTERPARS is unlearned.
+.le
+.ls fitskypars = ""
+The name of the file containing the FITSKYPARS parameter values. Fitskypars
+must be a named FITSKYPARS parameter set file written by the EPAR task, or ""
+in which case the default FITSKYPARS parameter set in the user's uparm
+directory is used. If the parameter \fIunlearn\fR is "yes" and fitskypars
+is "", FITSKYPARS is unlearned.
+.le
+.ls photpars = ""
+The name of the file containing the PHOTPARS parameter values. Photpars must be
+a named PHOTPARS parameter set file written by the EPAR task, or "" in which
+case the default PHOTPARS parameter set in the user's uparm directory is used.
+If the parameter \fIunlearn\fR is "yes" and photpars is "", PHOTPARS is
+unlearned.
+.le
+.ls daopars = ""
+The name of the file containing the DAOPARS parameter values. Daopars must be a
+named DAOPARS parameter set file written by the EPAR task, or "" in which case
+the default DAOPARS parameter set in the user's uparm directory is used. If the
+parameter \fIunlearn\fR is "yes" and daopars is "", DAOPARS is unlearned.
+.le
+.ls unlearn = no
+Return the values of the parameters in the parameter sets DATAPARS, FINDPARS,
+CENTERPARS, FITSKYPARS, PHOTPARS, and DAOPARS to their default values?
+.le
+.ih
+DESCRIPTION
+
+SETIMPARS saves and restores the DAOPHOT task and algorithm parameters for the
+image \fIimage\fR. On startup SETIMPARS initializes all the DAOPHOT package
+input and output coordinates and photometry file names, input and output images,
+and input and output plot files to their default values or \fIimage\fR whichever
+is appropriate. Next SETIMPARS reads in the values of the algorithm parameters
+from \fIparfile\fR if it is defined, or from the file \fIimage.pars\fR if it
+exists and \fIrestore\fR is "yes", or from the named parameter set files
+\fIdatapars\fR, \fIfindpars\fR, \fIcenterpars\fR, \fIfitskypars\fR,
+\fIphotpars\fR, and \fIdaopars\fR if they exist, or from the default parameters
+sets in the user's uparm directory. If \fIunlearn\fR is "yes", these default
+parameter sets are unlearned.
+
+If \fIreview\fR is "yes", the user can review and or edit the newly set
+algorithm parameters in DATAPARS, FINDPARS, CENTERPARS, FITSKYPARS, PHOTPARS,
+and DAOPARS using the IRAF EPAR task.
+
+If \fIupdate\fR is "yes", SETIMPARS saves the new current values of the DAOPHOT
+algorithm parameters DATAPARS, FINDPARS, CENTERPARS, FITSKYPARS, PHOTPARS, and
+DAOPARS in the file \fIimage.pars\fR. Any previously existing file of the same
+name is overwritten.
+
+.ih
+EXAMPLES
+
+1. Save the current values of the daophot task and algorithm parameters for
+the image m92v.
+
+.nf
+ da> setimpars m92v no yes
+
+ ... m92v parameters are saved in m92v.pars
+.fi
+
+2. Make some minor alterations in the current values of the m92v algorithm
+parameters and save the new parameters set.
+
+.nf
+ da> setimpars m92v no yes
+
+ ... m92v parameters are saved in new version of m92v.pars
+.fi
+
+3. Begin work on the image m92b. Initialize the values of the daophot task
+and algorithm parameters for m92b using those stored for m92v. After doing
+some preliminary editing and reductions for m92b, save the parameters,
+and return to work on m92v.
+
+.nf
+ da> setimpars m92b yes no parfile=m92v.pars
+
+ ... current parameters for m92v are set using saved
+ m92v parameters
+
+ da> daoedit m92b
+
+ ... edit the parameters as necessary for the new image
+
+ da> daofind m92b
+
+ ... find the stars in m92b
+
+ da> phot m92b
+
+ ... do the initial photometry for stars in m92b
+
+ da> setimpars m92b no yes
+
+ ... current m92b parameters are saved in m92b.pars
+
+ da> setimpars m92v yes no
+
+ ... m92v parameters are restored from m92v.pars
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+daoedit,datapars,findpars,centerpars,fitskypars,photpars,daopars
+.endhelp
diff --git a/noao/digiphot/daophot/doc/specs/daophot.spc b/noao/digiphot/daophot/doc/specs/daophot.spc
new file mode 100644
index 00000000..221630d5
--- /dev/null
+++ b/noao/digiphot/daophot/doc/specs/daophot.spc
@@ -0,0 +1,1047 @@
+.help daophot Sep87 "Crowded Field Stellar Photometry'
+.sh
+1. Introduction
+
+ The DAOPHOT package will provide a set of routines for performing
+stellar photometry on crowded fields in either interactive or batch mode.
+DAOPHOT works by fitting an empirical point spread function (PSF)
+to each object in the field
+allowing for overlap of closely spaced images. This document presents the
+the requirements and specifications for the package and describes some of
+the algorithms to be used. Most of the algorithms are described in
+the original article by Peter Stetson (1987 P.A.S.P. 99,191).
+
+.sh
+2. Requirements
+.ls 4
+.ls (1)
+The tasks in the DAOPHOT package shall take as input an IRAF imagefile
+containing two-dimensional image data which has been corrected for
+pixel to pixel gain variations, high frequency variations in the background,
+any nonlinearitys in the data except for those which can be specified as
+a lower and/or upper bound,
+and any other instrumental defects affecting the intensity value of an
+individual pixel. However, it shall be possible to exclude bad pixels,
+rows or columns from analysis by DAOPHOT routines in a very crude manner.
+.le
+.ls (2)
+The tasks in the package which produce tabular output shall use the
+SDAS Tables for their output and those tasks which read output from other
+DAOPHOT tasks will be able to read SDAS Tables. In the future the input/output
+shall make use of the DBIO package.
+.le
+.ls (3)
+The DAOPHOT package shall work in conjunction with the APPHOT package produced
+at NOAO. DAOPHOT will not have any provision to do aperture photometry of its
+own. The output format from DAOPHOT tasks will be consistent with APPHOT.
+.le
+.ls (4)
+Given as input a reduced two-dimensional image which has been processed by the
+APPHOT package, the DAOPHOT package shall be able to perform the following
+functions:
+.ls 4
+.ls o
+Interactively define a PSF for the data frame. The PSF will be defined
+empirically from one or more stars in the field. The task to determine the
+PSF shall be interactive and the user shall be able to use a
+graphics terminal and/or an image display device to select the stars which
+will make up the PSF. The user will be able to evaluate the PSF through
+different means including contour plots, 3-d mesh plots, and displaying the
+PSF on an image display device.
+The user shall be able to "mask" out parts of the PSF which may be contaminated
+by nearby stars, bad pixels etc. Only the non-masked portions of the PSF will
+be used in the fitting routines.
+.le
+.ls o
+Fit the PSF simultaneously to groups of stars in the image frame whose
+images overlap to some degree. The parameters in the fit shall include the
+the object brightness, X and Y position of the star and potentially the sky
+background. The sky shall be able to be specified as either a flat uniform
+background or a simple tilted planar sky. The photometry routines shall
+produce realistic errors in the photometry assuming that realistic numbers
+for the characteristics of the data are input.
+.le
+.ls o
+Subtract the fitted stars from the data frame to produce a subtracted
+image for further analysis.
+.le
+.ls o
+Add artificial stars to the data frame in order to check accuracy and
+completeness in the photometry. The user shall have control over the
+number of stars added, the brightness range, the area of the image to contain
+the added stars and the noise characteristics of the added stars.
+.le
+.le
+.ls (5)
+The DAOPHOT package shall include tasks to inspect and edit the results from the
+photometry routines. These shall include tasks such as interactively
+rejecting particular stars from the results,
+producing plots of errors versus brightness, errors versus position etc.
+.le
+.ls (6)
+The DAOPHOT package shall provide utility packages to handle the output
+data from the fitting routines. These shall include such tasks as
+aperture growth curves, photometric calibrations, color-magnitude and
+color-color diagrams.
+.le
+.ls (7)
+The DAOPHOT routines shall optionally keep a history file to keep
+track of the processing done on the images. This will include the values of
+various parameters used in the various tasks of the DAOPHOT package.
+.le
+.ls (8)
+The tasks shall be able to be run in batch mode as well as interative
+mode. In batch mode use of a graphics terminal or image display shall not
+be required.
+.le
+.ls (9)
+The DAOPHOT package shall be written in the SPP language in conformance with
+the standards and conventions of IRAF. The code shall be portable and
+device independent.
+.le
+.le
+.sh
+2.1 Limitations of the Initial DAOPHOT Package
+
+The DAOPHOT package shall perform PSF fitting photometry with the following
+restrictions:
+.ls
+.ls (1)
+The PSF used will be determined empirically and analytic specification of
+the PSF will not be possible. This restricts the use of DAOPHOT to image
+data which is not too badly undersampled.
+.le
+.ls (2)
+There will be an upper limit to the number of stars for which the PSF will
+be fit simultaneously. The initial version of DAOPHOT will have this limit
+set to 60 stars.
+.le
+.ls (3)
+The initial version of DAOPHOT will not have the sky included as a parameter
+in the fitting routines.
+.le
+.ls (4)
+Initially the use will not be able to mask out bad portions of the PSF for
+fitting.
+.le
+.le
+
+.sh
+3. Specifications
+
+ The DAOPHOT package performs stellar photometry on digital data, maintained
+as IRAF image files. DAOPHOT performs this photometry by fitting the PSF
+to the stellar images in the image file. DAOPHOT works by fitting the PSF to
+a maximum number of stars simultaneously thus allowing for overlapping images.
+Input to the package consists of an imagefile and the output from the APPHOT
+package, which contains simple aperture photometry for the objects which have
+been identified in the image frame, and numerous parameters controlling the
+analysis algorithms. Output from the analysis tasks consists of tabular data
+containing the results of the analysis routines. The output will be in the
+form of SDAS tables and will thus be able to be manipulated by various
+other utility tasks available in IRAF.
+
+The CL callable part of the DAOPHOT package consists of the following routines:
+
+.ks
+.nf
+ addstar -- adds synthetic stars to an image file
+ allstar -- fits multiple, overlapping PSFs to star images
+ *calibrate -- apply photometric calibration
+ *cmd -- color-magnitude, color-color diagrams
+ daopars -- DAOPHOT pset parameters
+ examine -- interactively examine/edit photometry results
+ group -- divides stars into natural groupings
+ *growth -- aperture growth curves <--> PSF magnitudes
+ peak -- fit PSF to single stars in an image file
+ psf -- interactively construct a PSF for the frame
+ nstar -- fits multiple, overlapping PSFs to star images
+ seepsf -- converts a PSF file into a IRAF image file
+ select -- selects natural groups with a certain range of sizes
+ substar -- subtract fitted profiles from an image file
+.fi
+.ke
+
+There are routines available in other IRAF/STSDAS tasks for manipulating
+SDAS Tables or DBIO. The capabilities inside the DAOPHOT are specifically
+suited to dealing with large tables of results from these photometry routines.
+
+.sh
+3.1 Standard Analysis Procedures
+
+ Before performing DAOPHOT photometry one must perform certain other tasks
+beforehand. This includes using the APPHOT package to produce an object list
+and aperture photometry for objects in this list. The DAOPHOT package contains
+an additional object finder but one must use APPHOT to obtain the aperture
+photometry results. The standard analysis procedure, including APPHOT, is as
+follows:
+.ls
+.ls (1)
+Use an object finder to produce a list of object coordinates. This may be done
+in many ways:
+.ls
+.ls o
+By using the interactive cusrsor routines available elsewhere in IRAF and
+redirecting the output into a list file.
+.le
+.ls o
+By transforming an existing list using an existing IRAF task or the OFFSET
+task in the DAOPHOT package.
+.le
+.ls o
+By using an automatic object finding procedure such as the one available
+in the APPHOT package or the one in the DAOPHOT package.
+.le
+.ls o
+By any other program which generates a list of objects in suitable format (SDAS
+Tables) for input to the APPHOT routines.
+.le
+.le
+.ls (2)
+The APPHOT package is run to measure the objects identified in the above
+step. One should refer to the APPHOT documentation to understand the
+algorithms and procedures which are used in APPHOT.
+.le
+.ls (3)
+One needs to set up the parameters in the analysis routines for this particular
+image file. OPTIONS allows you to set such parameters as the number of
+electrons/ADC, the fitting radius, and the radius within which the PSF
+is defined.
+.le
+.ls (4)
+The next step is to produce a PSF for the image file currently being processed.
+In crowed fields this is a tricky, iterative procedure which should be done very
+carefully. This is best done using a graphics terminal and/or an image display
+device.
+.le
+.ls (5)
+If one plans on using NSTAR, then the GROUP task must be run. This task
+divides the stars in the output from the APPHOT into natural groups. The size
+of the groups produced depends upon how crowded the field is and what degree of
+overlap of the images one considers.
+.le
+.ls (6)
+Use either NSTAR, if you have grouped the objects using GROUP, or
+ALLSTAR which will dynamically group the stars as the image file is
+processed. These routines will produce the objects' positions and
+intrumental magnitudes by means of multiple-profile fits.
+.le
+.ls (7)
+Use SUBSTAR to subtract the fitted profiles from the image file, thus producing
+a new image file containing the fitting residuals. This will usually contain
+many stars which were missed in the original identification because they lie
+in the wings of brighter objects.
+.le
+.ls (8)
+One now basically runs through steps (1) - (6) one or more times,
+merging the identified object lists each time to produce a master object list,
+until one is satisfied with the final results. There are many subtlties in this
+procedure which are described in the DAOPHOT User's Manual.
+.le
+.ls (9)
+After obtaining the photometry results one may edit the results by throwing out
+those results which do not meet certain criteria. EXAMINE is an interactive
+task which allows the user to examine the results for each individual object
+in the list and either accept or reject that object. There are also routines
+available for courser rejection of results, e.g. reject all objects with
+errors larger than 0.2 magnitudes.
+.le
+.ls (10)
+One may wish to use the tasks to plot up color-color or color-magnitude
+diagrams. Other general purpose list processing tools available in
+IRAF/SDAS may also be used for analysis of DAOPHOT output.
+.le
+.le
+
+.sh
+3.2 The ADDSTAR Task
+
+ The function of ADDSTAR is to add synthetic stars to the image file.
+These stars may be placed randomly by the computer, placed with a certain
+distribution as specifed by the user or at predetermined locations specified
+by the user. Likewise the brightness of these added objects may be completely
+random or may follow a specified distribution.
+
+Objects are added by taking the specified PSF, scaling it, and moving it
+to the desired location. ADDSTAR will also add Poisson noise to the star
+images to make them more realistic.
+
+.sh
+3.2.1 ADDSTAR Parameters
+
+ ADDSTAR has several parameters which control the addition of stars
+into a image file. All data dependent parameters are query mode to ensure
+that they get set properly for the particular image under consideration.
+The data independent parameters are hidden mode, and are given reasonable
+default values. The names, datatypes, and default values of the ADDSTAR
+parameters are shown below.
+
+.ks
+.nf
+Positional or query mode parameters:
+
+ input_image filename
+ output_image filename
+ minmag real
+ maxmag real
+.fi
+.ke
+
+.ks
+.nf
+List structured parameter (filename may be given on command line):
+
+ add_data *imcur
+.fi
+.ke
+
+.ks
+.nf
+Hidden Parameters:
+
+ daopars pset "daophot$daopars.par"
+ nstar integer 100
+ nframe integer 1
+ xmin integer 1
+ ymin integer 1
+ xmax integer NX
+ ymax integer NY
+ verbose boolean false
+.fi
+.ke
+
+The function and format of each of these parameters is explained in
+more detail below.
+
+.ls
+.ls 16 input_image
+The name of the image or image section to which artificial stars will be added
+.le
+.ls output_image
+The name of outout image which will contain the added stars.
+.le
+.ls minmag
+The minumum magnitude of artificial star to add to the data. The magnitude
+scale is set by the magnitude of the PSF.
+.le
+.ls maxmag
+The maximum magnitude of artificial star to add to the data. The magnitude
+scale is set by the magnitude of the PSF.
+.le
+.ls add_data
+This parameter is used to specify a file as input to the ADDSTAR task. This
+file should contain centroid positions and magnitudes for the stars you
+want to add. It is possible to specify the positions of the added stars
+interactively with the image display by setting this parameter to *imcur.
+In this case the user is prompted for the magnitude of each star to be added.
+If this parameter is the null string then the stars are added in a random
+fashion by the ADDSTAR routine.
+.le
+.ls nstar
+The number of artificial stars to add to the input image file.
+.le
+.ls daopars
+This is the name of a file containing parameters which are common to
+many DAOPHOT tasks. This pset parameter serves as a pointer to the external
+parameter set for the DAOPHOT algorithms. The parameters contained in this
+pset and their function are described in section 3.6.1.
+.le
+.ls nframe
+The number of new image files to create. If this parameter is greater
+than one then the new image files will use the output image name as
+a root and produce image files with '.xxx' appended to the root, where
+xxx will range from 001 to nframe. If nframe is one then the output image
+name will be used as is.
+.le
+.ls xmin, ymin, xmax, ymax
+These define the subsection of the image in which to add the artificial
+stars. The default is to add artificial stars to the complete image.
+.le
+.ls verbose
+Controls the amount of output from the ALLSTAR function. The default is
+to have minimal output to STDOUT.
+.le
+.le
+
+.sh
+3.2.2 ADDSTAR Output
+
+ The output of ADDSTAR consists of two parts, an image file and an
+output SDAS Table. The image file is a copy of the input image file but
+with the artificial stars generated by ADDSTAR added. The output table
+contains the x,y position and magnitude of each of the added stars. When the
+nframe parameter is set greater than one then there will be nframe pairs of
+output files generated.
+
+.sh
+3.3 ALLSTAR
+
+ ALLSTAR fits multiple, overlapping point-spread functions to stars images
+in the input image file. It uses as input the results from APPHOT and an
+input PSF and will automatically reduce the entire image performing the necessary
+grouping. It will recalculate the grouping after each iteration. ALLSTAR will
+also produce the star-subtracted image file.
+
+.sh
+3.3.1 ALLSTAR Parameters
+
+ALLSTAR has several parameters which control the fitting algorithms. The
+names, datatypes, default values for the ALLSTAR parameters are given below.
+
+.ks
+.nf
+Positional parameters:
+
+ input_image filename
+ photometry filename
+ output filename
+ sub_image filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ daopars pset "daophot$daopars.par"
+ max_group integer 60
+ redeterm_cent boolean true
+ max_crit real 2.5
+ min_crit real 1.2
+ clip_exp integer 6
+ clip_range real 2.5
+ verbose boolean false
+.fi
+.ke
+
+These parameters perform the following functions:
+
+.ls 4
+.ls 16 input_image
+The name of the input image file.
+.le
+.ls photometry
+The name of the input photometry SDAS table. This may contain output from either
+the APPHOT package or from NSTAR or previous ALLSTAR runs.
+.le
+.ls output
+The name of the SDAS table to contain the results of the psf fittting.
+.le
+.ls sub_image
+The name of the output image file which will have all of the fitted stars
+subtracted from it. If this file is the null string then no star-subtracted
+image file will be produced.
+.le
+.ls daopars
+The pset parameter file containing the DAOPHOT parameter set.
+.le
+.ls max_group
+The maximum size group which ALLSTAR will process. The absolute maximum
+is 60 stars.
+.le
+.ls redeterm_cent
+If true then the centers of the stars are redetermined before each
+iteration.
+.le
+.ls max_crit
+The initial value which ALLSTAR uses as the critical separation for
+use in grouping stars together. For groups larger than "max_group" ALLSTAR
+will use progressively smaller values for the critical separation until the
+group breaks up into units containing fewer than "max_group" stars or until
+the value of "min_crit" is reached.
+.le
+.ls min_crit
+The smallest value of the critical separation which ALLSTAR will use in
+grouping stars together.
+.le
+.ls clip_exp, clip_range
+These parameters are used to "resist bad data". These two
+parameters control the weighting of each pixel as a function of it's
+residual from the fit. Clip_range us variable "a" and clip_exp is
+variable "b" in the paper by Stetson (P.A.S.P. 99, 191)
+.le
+.le
+
+.sh
+3.3.2 The ALLSTAR PSF Fitting Algorithm
+
+ The algorithms which ALLSTAR uses to do the psf fitting photometry are
+very nearly the same as those used by NSTAR. One is referred to Stetson,
+P.A.S.P. 99, 191, for the details on the various fitting, star rejection,
+and weighting algorithms used in this task.
+.sh
+3.3.3 The Output from ALLSTAR
+
+ The output from ALLSTAR consists of three parts. There is the output
+photometry results, an SDAS Table, and a subtracted image file. The subtracted
+image file is a copy of the input image file minus the fitted stars.
+
+For each object processed by ALLSTAR there is one row in the output SDAS
+Table. Each measured object will have entries for the following items:
+
+.nf
+ star, x, y, mag, magerr, sky, niter, chi, sharp
+
+where
+
+ star star ID number
+ x,y coordinates of the stellar centroid
+ mag magnitude relative to the magnitude of the PSF star
+ magerr estimated standard error of the star's magnitude
+ sky estimated sky as returned by APPHOT
+ niter number of iterations for convergence
+ chi observed pixel to pixel scatter DIVIDED BY the expected
+ pixel to pixel scatter
+ sharp an index describing the spatial distribution of the residuals
+ around the star. Objects with SHARP significantly greater
+ than zero are extended (possibly galaxies), while objects with
+ SHARP significantly less than zero may be bad pixels or cosmic
+ rays
+.fi
+
+Other noteworthy pieces of information will be stored in the output SDAS
+Table header. This includes such things as the time and date of processing,
+the name of the PSF file, the name of the input photometry file, the
+fitting radius etc.
+
+.sh
+3.4 The CALIBRATE Task
+
+.sh
+3.5 The CMD Task
+
+.sh
+3.6 The DAOPARS Task
+
+ This is a pset-task which is used to describe a particular image file
+for use with the DAOPHOT package. This pset contains parameters which describe the
+data, e.g. the read out noise, the background sky value, the number of photons
+per ADC unit, etc., and also parameters which control the DAOPHOT tasks, e.g.
+the fitting radius to use. The parameters in this pset are used by several
+DAOPHOT tasks, hence their grouping into a pset.
+
+.sh
+3.6.1 daopars Parameters
+
+ The parameters in this task either describe the data in
+a particular image file
+or are parameters which are used by more algorithms in more than one
+DAOPHOT task. The following parameters make up this pset:
+
+.ks
+.nf
+
+ fitrad real 2.5 (pixels)
+ psfrad real 11.0(pixels)
+ phot_adc real 10.0
+ read_noise real 20.0
+ max_good real 32766.
+ min_good real 0.0
+ sky_val real 0.0
+ numb_exp integer 1
+ comb_type string "average"
+ var_psf boolean false
+.fi
+.ke
+
+The function and format of each of these parameters is described below:
+
+.ls 4
+.ls 16 fitrad
+The fitting radius to use in the PEAK, NSTAR, ALLSTAR and PSF tasks. Only
+the pixels within one fitting radius are actually used in the fit. This should
+normally be on the order of the FWHM of the stellar images.
+.le
+.ls psfrad
+The radius of the circle within which the PSF is defined. This should be
+somewhat larger than the actual radius of the brightest star you are
+interested in.
+.le
+.ls maxgood
+The maximum data value in ADC units at which the CCD or other detector
+is believed to operate linearly.
+.le
+.ls mingood
+The minimum data value in ADC units which should be used as "real" data.
+Dead pixels, bad columns etc. in the image file can be excluded from use in
+the analysis by setting this parameters properly. Any data value which
+falls below this minimum is ignored by DAOPHOT tasks.
+.le
+.ls sky_val
+The typical sky brightness in ADC units for the image file. This parameter is
+updated by the SKY task within the DAOPHOT package.
+.le
+.ls phot_adc
+The number of photons per ADC unit of the CCD or other detector.
+.le
+.ls read_noise
+The readout noise in ADC units of the CCD or other detector.
+.le
+.ls numb_exp
+The number of individual exposures which have been combined to produce the
+current image file. This number combined with information on whether the
+exposures were summed or averaged is used to get a better handle on the
+error estimates of the photometry.
+.le
+.ls comb_type
+Describes whether the individual exposures which went into making up this
+image file were "summed" or "averaged"
+.le
+.ls var_psf
+Controls whether the shape of the PSF is to be regarded as constant over the
+complete image file. Slight and smooth variations can be accomodated by the
+DAOPHOT tasks.
+.le
+.le
+
+ These parameters should be initially set by the user before starting any
+analysis with the DAOPHOT package. Each image file may have it's own set of
+parameters and these should be stored in separate pset files.
+.sh
+3.7 The EXAMINE Task
+
+ EXAMINE allows the user to interactively examine the results of the
+DAOPHOT reduction and to accept or reject individual stars. EXAMINE will
+accept as input the output photometry list from either ALLSTAR or NSTAR.
+For each star in the input list the user can examine either a 3-d meshplot
+or a contour diagram of both the input image and the star-subtracted image.
+The results of the photometry for the star under consideration is also
+displayed.
+
+Two output star lists are produced using this task. One is a list
+of stars which have been "accepted" by the user, the other being a list
+of stars which have been "rejected".
+
+If the TV option is selected then both the original image and subtracted
+image are displayed on the "stdimage" and the star under consideration is
+identified. The user has the ability to blink these two frames to
+evaluate the results of the photometry.
+
+This task is controlled via input from the terminal with various keys
+performing a variety of functions.
+
+.sh
+3.7.1 EXAMINE Parameters
+ There are several parameters which control various aspects of the
+EXAMINE task. The parameters control such things as the input photometry
+list, the type of graphical display desired and whether to use the
+display capabilities.
+
+.ks
+.nf
+Query mode parameters:
+
+ phot_list filename
+
+ fwhm real (pixels)
+ threshold real (in units of sigma)
+ output_file filename
+.fi
+.ke
+
+.sh
+3.9 The GROUP Task
+
+ GROUP is used to divide the stars in the image file into natural
+groups prior to analysis with NSTAR. GROUP works on the following
+principle: if two stars are close enough that the light of one will
+influence the profile fit of the other, then they belong in the same
+group.
+
+.sh
+3.9.1 GROUP Parameters
+
+ GROUP only has a few parameters which govern its operation. These
+are:
+
+.ks
+.nf
+Query mode parameters:
+
+ input_image filename
+ psf_file filename
+ crit_overlap real
+ output filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden mode parameters:
+
+ daopars pset "daophot$daopars.par"
+.fi
+.ke
+
+These parameters perform the following functions:
+
+.ls 4
+.ls 16 input_image
+The name of the input image file.
+.le
+.ls psf_file
+The name of the file containing the PSF.
+.le
+.ls crit_overlap
+The "critical overlap" before one star is determined to influence
+another. When GROUP examines two stars to see whether they might influence
+each others' fits, it firts identifies the fainter of the two stars. It then
+calculates the brightness of the brighter star at a distanceof one fitting
+radius plus one pixel from the center of the fainter. If this brightness is
+greater than the "critical overlap" times the random error per pixel, then
+the brighter star is deemed to be capable of affecting the photometry of the
+fainter, and the two stars are grouped together.
+.le
+.ls output
+The name of the SDAS table which will contain the stellar groups.
+.le
+.ls daopars
+The name of of a pset file containing the daophot parameters. The specific
+parameters which are used from this include the following:
+.le
+.le
+.sh
+3.10 The GROWTH Task
+
+.sh
+3.11 The OFFSET task
+
+.sh
+3.12 The PEAK Task
+
+ PEAK fits the PSF to a single star. It is useful for sparsely populated
+image files where the stars of interest are not blended. In this cases aperture
+photometry is often fine and the use of PEAK is of limited interest. This task
+is included in the DAOPHOT package mainly for completeness.
+
+.sh
+3.12.1 PEAK Parameters
+
+ The parameters specific to the PEAK task are used for specifying the
+input and output from this routine. The names of the parameters and their
+functions are:
+
+.ks
+.nf
+Positional or query parameters:
+
+ input_image filename
+ psf_file filename
+ output filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ daopars pset "daophot$daopars.par"
+ verbose boolean false
+.fi
+.ke
+
+.ls 4
+.ls 16 input_image
+The name of the input image file.
+.le
+.ls psf_file
+The name of the input file containing the point-spread function.
+.le
+.ls output
+The name of the SDAS table to contain the output from PEAK.
+.le
+.ls verbose
+If true then PEAK outputs more information about what it is doing.
+.le
+.ls daopars
+The name of a pset file which contains the parameters specific to the
+input image file. The parameters which PEAK uses from this pset include:
+sthe fitting radius, the maximum and minimum good data value and whether
+a variable PSF is to be used.
+.le
+.le
+.sh
+3.13 The PSF Task
+
+ The PSF task is used for obtaining the point-spread function which
+will be used in the rest of the DAOPHOT reductions. DAOPHOT uses an
+empirical point-spread function as opposed to a mathematically defined
+function. The PSF is defined from the actual brightness distribution
+of one or more stars in the frame under consideration. It is stored as
+a two-component model: (1) an analytic Gaussian profile which approximately
+matches the core of the point-spread function, and (2) a look-up table of
+residuals, which are used as additive corrections to the integrated
+analytic Gaussian function.
+
+The brightness in a hypothetical pixel at an arbitrary point within the
+point-spread function is determined in the following manner. First
+the bivariate Gaussian function is integrated over the area of the pixel,
+and then a correction is determined by double cubic interpolation
+within the lookup table, and is added to the integrated intensity.
+
+The PSF is stored as a binary data file and is in a format specific
+to DAOPHOT. The format of this file is very similar to that used by the
+VMS version of DAOPHOT but is stored in binary for compactness.
+A function is provided to take the PSF and convert it
+to a IRAF image file so that it can be manipulated by other IRAF
+tasks.
+
+PSF allows the user to perform most functions from within the interactive
+graphics part of its operation. PSF allows the user to modify the
+perspective of hist mesh plot, the contouring interval, the PSF radius
+etc. from within the PSF interactive graphics.
+
+.sh
+3.13.1 PSF Parameters
+
+ The PSF task has many parameters which specify the input and
+output files as well as specifying other information. These are
+divided in query mode parameters and hidden parameters.
+
+.ks
+.nf
+Positional or query parameters:
+
+ input_image filename
+ phot_list filename
+ psf_stars filename
+ psf_file filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ daopars pset "daophot$daopars.par"
+ verbose boolean false
+.fi
+.ke
+
+.ls 4
+.ls 16 input_image
+The name of the input image file.
+.le
+.ls phot_list
+The name of the input file containing the aperture photometry
+results for this image frame.
+.le
+.ls psf_stars
+The name of file coordinate file containing the list of stars
+to be used as PSF candidates.
+.le
+.ls psf_file
+The name of the output file for storing the PSF.
+.le
+.ls verbose
+If true then PEAK outputs more information about what it is doing.
+.le
+.ls daopars
+The name of a pset file which contains the parameters specific to the
+input image file. The parameters which PEAK uses from this pset include:
+sthe fitting radius, the maximum and minimum good data value and whether
+a variable PSF is to be used.
+.le
+.le
+.sh
+3.14 The NSTAR Task
+
+ NSTAR is one of DAOPHOT's multiple, simultaneous, profile-fitting
+photometry routine. It is similar to ALLSTAR except that NSTAR must have
+the objects grouped (using the GROUP task) and it does not dynamically
+alter the groups while running. NSTAR also does not automatically produce the
+star subtracted image file.
+
+.sh
+3.14.1 NSTAR Parameters
+
+ There are several parameters which control the function of the
+NSTAR task. These are the following:
+
+.ks
+.nf
+Positional or Query Parameters:
+
+ input_image filename
+ psf_file filename
+ group_file filename
+ output_file filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ daopars pset "daophot$daopars.par"
+ verbose boolean false
+.fi
+.ke
+
+.sh
+3.15 The SEEPSF Task
+
+ The SEEPSF task produces an IRAF image file from the given PSF
+file. This allows other IRAF tasks, especially display and plotting tasks,
+to use access the point-spread function. The user has the ability to create
+any size of image from the PSF enlargements being handled by a number of
+different interpolation schemes.
+
+.sh
+3.15.1 SEEPSF Parameters
+
+ The parameters wich control this task are limted. They basically
+control the input, output and size of the image.
+
+.ks
+.nf
+Positional or Query Parameters:
+
+ psf_file filename
+ image_name filename
+ image_size integer
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ interpolation string "nearest"
+ boundary string "constant"
+ constant real 0.0
+ daopars pset "daophot$daopars.par"
+ verbose boolean false
+.fi
+.ke
+
+.ls 4
+.ls 16 psf_file
+This specifies the input PSF file which is to be transformed into an
+IRAF image.
+.le
+.ls image_name
+The name of the output IRAF image.
+.le
+.ls image_size
+The size of the output image in pixels per side. Note that only square PSFs
+and PSF images are alllowed.
+.le
+.ls interpolation
+The type of interpolation to be used in expanding the image. The choices
+are "nearest" neighbor, "linear" bilinear, "poly3" bicubic polynomial,
+"poly5" biquintic polynomial, and "spline3" bicubic spline.
+.le
+.ls boundary
+The type of boundary extension to use for handling references to pixels
+outside the bounds of the input image. The choices are: "constant",
+"nearest" edge, "reflect" about the boundary and "wrap" to the other side
+of the image.
+.le
+.le
+.sh
+3.16 The SELECT Task
+
+ The SELECT task is used to select groups of stars with a particular
+range of sizes from a group file which has been produced by GROUP. This
+task is used when some of the groups in the group file are large than the
+maximum allowed in NSTAR, currently 60 stars.
+
+.sh
+3.16.1 SELECT Parameters
+
+ The parameters which control the SELECT task are the following:
+
+.ks
+.nf
+Positional or Query Parameters:
+
+ input_group filename
+ output_group filename
+ min_group integer
+ max_group integer
+.fi
+.ke
+
+.le 4
+.ls 16 input_group
+The input group file which is to be searched for groups within the
+limits specified by min_group and max_group.
+.le
+.ls output_group
+The output group file which will consist of groups between 'min_group'
+and 'max_group' in size.
+.le
+.ls min_group
+The minimum group size to be extracted from the input group file.
+.le
+.ls max_group
+The maximum group size to be extracted from the input group file.
+.le
+.le
+.sh
+3.17 The SKY Task
+
+.sh
+3.18 The SORT Task
+
+.sh
+3.19 The SUBSTAR Task
+
+ The SUBSTAR command takes the point-spread function for an image
+frame and a file containing the x,y coordinates and apparent magnitudes
+for a group of stars, usually an output file from one of the photometry
+routines, shifts and scales the PSF function
+according to each position and magnitude, and then subtracts it from the
+original image frame.
+
+.sh
+3.19.1 SUBSTAR Parameters
+
+ The parameters for SUBSTAR control the input and output from this
+task.
+
+.ks
+.nf
+Positional or Query Parameters:
+
+ psf_file filename
+ phot_file filename
+ input_image filename
+ output_image filename
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ verbose boolean false
+.fi
+.ke
+
+.ls 4
+.ls 16 psf_file
+The name of the file containing the PSF which is to be used as the template
+in the star subtraction.
+.le
+.ls phot_file
+The file containing the photometry results for the stars which are to be
+subtracted from the input image.
+.le
+.ls input_image
+The name of the input image file from which the stars are to be subtracted.
+.le
+.ls output_image
+The name of the output image file which will be a copy of the input frame
+except for the subtracted stars.
+.le
+.ls verbose
+If this parameter is set to true then more information about the progress
+of SUBSTAR is output.
+.le
+.le
+.sh
+4.0 Example
+
+.endhelp
diff --git a/noao/digiphot/daophot/doc/specs/daoutils.spc b/noao/digiphot/daophot/doc/specs/daoutils.spc
new file mode 100644
index 00000000..d943d63a
--- /dev/null
+++ b/noao/digiphot/daophot/doc/specs/daoutils.spc
@@ -0,0 +1,700 @@
+.help daoutils Jan89 "Utility Package for DAOPHOT"
+.sh
+1. Introduction
+
+The DAOUTILS package will provide a set of tools for working
+with the output from DAOPHOT. These tools will provide the user with
+the ability to select data upon ranges and limits for any of the
+fields in a daophot output table. The package will also provide tools
+for merging results contained in different output files.
+
+.sh
+2. Requirements
+.ls 4
+.ls (1)
+The tasks in the DAOUTILS package shall take as input the output ST Tables
+from the DAOPHOT tasks. The convert task in the daophot package shall be
+used to convert the output from apphot tasks into the proper format for use
+with the daoutils package.
+.le
+.ls (2)
+The tasks in the package which produce tabular output shall use the
+ST Tables for their output and those tasks which read output from other
+DAOUTILS tasks will be able to read ST Tables.
+.le
+.ls (3)
+The DAOUTILS package shall include tasks to inspect and edit the results
+from the photometry routines. These shall include tasks such as interactively
+rejecting particular stars from the results,
+producing plots of errors versus brightness, errors versus position etc. There
+will also be a task for merging the results contained in several different
+Tables. It shall also be possible to interactively examine the photometry
+results with various graphical and/or display tools for inspecting/editing the
+results. It shall also be possible to construct growth curves from the
+aperture photometry for the purpose of calibrating the daophot magnitudes
+to total magnitudes. There shall also be routines for calibrating the
+photometry by the use of standard stars.
+.le
+.ls (4)
+The tasks shall be able to be run in batch mode as well as interative
+mode. In batch mode use of a graphics terminal or image display shall not
+be required.
+.le
+.ls (5)
+The DAOPHOT package shall be written in the SPP language in conformance with
+the standards and conventions of IRAF. The code shall be portable and
+device independent.
+.le
+.le
+.sh
+2.1 Limitations of the Initial DAOUTILS Package
+
+The DAOUTILS package will have the following limitations:
+.ls
+.ls (1)
+The initial version of DAOUTILS will not make direct use of the interactive
+image display. It will make use of cursor readback however.
+.le
+.le
+
+.sh
+3. Specifications
+
+The DAOUTILS package will take the output from the DAOPOHT package as input
+and provide a variety of tools which will allow the use to examine, edit and
+calibrate the output from DAOPHOT. The output from DAOUTILS will consist of
+ST Tables, graphical displays and printed summaries.
+
+The CL callable part of the DAOUTILS package will consist of the following
+tasks:
+
+.ks
+.nf
+ merge -- Merge the results from different runs of daophot
+ daograph -- Graph the results of daophot stored in ST Tables
+ gtedit -- Interactive graphical data editor
+ examine -- Interactively examine the output from daophot
+ growth -- aperture growth curves <--> PSF magnitudes
+ cmd -- Color-magnitude and color-color plots
+ calibrate -- do photometric calibration
+
+.fi
+.ke
+
+In addition the ttools package provided as part of STSDAS provides for
+many generic tools for working with the ST Tables are will be usable for
+many of the data selection tasks which most users will wish to apply to
+daophot output.
+
+.sh
+3.1 The GTEDIT Task
+
+The user will be able to plot any two columns of a Table versus each other
+and with the cursor interactively delete records. The user will move the
+graphics cursor near the point on the graph which represents the record
+which he wishes to delete from the input record. The user will also be able
+to specify 'areas' of the plot for which all records pointed to by points
+in the indicated sections will be deleted. The user will also be
+able to undelete records. The records will not actually be deleted until the
+task ends. The user will also be able to interactively change which columns
+are being plotted versus each other. The user will also have the option of
+editing the table in place or to create a new output table which will contain
+the edited results of the input table.
+
+.sh
+3.1.1 GEDIT Parameters
+
+GEDIT will have input parameters which control the input and initial
+operation of the task.
+
+.ks
+.nf
+Positional or query mode parameters:
+
+ input - filename
+ xcolumn - column name (string)
+ ycolumn - column name (string)
+.fi
+.ke
+
+.ks
+.nf
+Hidden parameters:
+
+ inplace boolean "false"
+ output filename ""
+ reject filename ""
+.fi
+.ke
+
+The function and format of these parameters is decsribed in more detail
+below.
+
+.ls
+.ls 16 input
+The name of the input table which contains the output from DAOPHOT.
+.le
+.ls xcolumn
+The name of the column in the input table which will be used for the
+X axis of the plot
+.le
+.ls ycolumn
+The name of the column in the input table which will be used for the
+Y axis of the plot
+.le
+.ls inplace
+Controls whether the input table is modified in place or whether a new
+table is created.
+.le
+.ls output
+If inplace is false then the value of this parameter will be the name of
+the output table which will contain the edited output.
+.le
+.ls reject
+The name of the output file containing those objects which have been
+deleted. If this parameter is NULL then the records which have been
+deleted are not saved.
+.le
+.le
+
+.sh
+3.1.2 Interactive GEDIT Commands
+
+Once GEDIT has plotted the two columns specified as the input there are
+several commands available to the user. These allow the user to delete/undelete
+points, change which columns are plotted, view a particular record from the
+input table and exit GEDIT.
+
+.ks
+.nf
+In the interactive mode the following cursor keys are active:
+
+ x -- delete the record represented by the point nearest the cursor
+ > -- delete all records represented by Y values > than the cursor
+ < -- delete all records represented by Y values < than the cursor
+ + -- delete all records represented by X values > than the cursor
+ - -- delete all records represented by X values < than the cursor
+ b -- mark the corner of box containing records to be deleted.
+ u -- undelete the record(s) deleted by the last delete operation
+ q -- exit GEDIT
+.fi
+.ke
+
+.ks
+.nf
+In addition the following colon commands are available:
+
+ :xcol <name> Use the column <name> as the X axis
+ :ycol <name> Use the column <name> as the Y axis
+.fi
+.ke
+
+.sh
+3.1.3 GEDIT OUTPUT
+
+The output from GEDIT is a direct copy of the input table with the records
+which the user marked for deletion removed. If the parameter 'inplace' was
+set to true then the edited table replaces the original table, otherwise a
+new table is created. Is it important that no records be deleted until the
+user exits GEDIT and confirms that the update is to take place.
+
+.sh
+3.2 TGRAPH
+
+This task is will produce plots from the DAOPHOT output tables. It is similar
+to the sgraph task in STSDAS but does not have the option of plotting image
+sections. It does have the ability to plot error bars and columns of data from
+two different tables.
+
+The following is the help for sgraph:
+
+.ih
+NAME
+graph -- graph one or more lists, image sections, or tables
+.ih
+USAGE
+graph input
+.ih
+PARAMETERS
+.ls input
+List of operands to be graphed. May be STDIN, or one or more image
+sections, tables and columns, or lists. SDAS table input is specified
+by: a table name and column name, a table and two column names, or a
+pair of table and column names, separated by white space.
+.le
+.ls stack = no
+If stack = yes, plot multiple curves on separate axes (WCS) stacked
+vertically rather than on the same axes.
+.le
+.ls wx1=0., wx2=0., wy1=0., wy2=0.
+The range of user coordinates spanned by the plot. If the range of values
+in x or y = 0, the plot is automatically scaled from the minimum to
+maximum data value along the degenerate dimension.
+.le
+.ls vx1=0., vx2=0., vy1=0., vy2=0.
+NDC coordinates (0-1) of the device plotting viewport. If not set by
+the user, a suitable viewport which allows sufficient room for all labels
+is used.
+.le
+.ls pointmode = no
+If \fBpointmode\fR = yes, plot points or markers at data values, rather than
+connected lines.
+.le
+.ls marker = "box"
+Marker to be drawn if \fBpointmode\fR = yes. Markers are "point", "box",
+"cross", "plus" or "circle".
+.le
+.ls szmarker = 0.005
+The size of a marker in NDC coordinates (0 to 1 spans the screen).
+If zero and the input operand is a list, marker sizes are taken individually
+from the third column of each list element. If positive, all markers are
+of size \fBszmarker\fR. If negative and the input operand is a list,
+the size of a marker is the third column of each list element times the
+absolute value of \fBszmarker\fR.
+.le
+.ls xlabel = "", ylabel = ""
+Label for the X-axis or Y-axis.
+.le
+.ls title = "imtitle"
+Plot title. If \fBtitle\fR = "imtitle"
+and the first operand in \fBinput\fR is an image, the image title is used
+as the plot title.
+.le
+.ls box = yes
+Draw axes at the perimeter of the plotting window.
+.le
+.ls fill = yes
+Fill the output viewport regardless of the device aspect ratio?
+.le
+.ls axis = 1
+Axis along which the projection is to be computed, if an input operand is
+an image section of dimension 2 or higher. Axis 1 is X (line average),
+2 is Y (column average), and so on.
+.le
+.ls erraxis = 0
+If pointmode = no and erraxis is 1 or 2, the axis parallel to which
+error bars are plotted (1 ==> X, 2 ==> Y).
+.le
+.ls errcolumn = ""
+The column(s) in the input table to be used as the error amplitude(s).
+If one column name, then symmetrical symmetrical error bars are drawn,
+centered on the data points with the total size, in WC specified by the
+values in the column from the same table specified in parameter input.
+Two names specify two table columns for the lower and upper errors,
+respectively.
+.le
+.ls pattern = "solid"
+The line pattern for the first curve. Subsequent curves on the same
+plot cycle through the set of patterns: solid, dashed, dotted, dotdash.
+.le
+.ls crvstyle = "straight"
+The style of the plotted curve: "straight" is the usual straight
+line connection between points, "pseudohist" consists of horizontal
+segments at each data point connected by vertical segments, "fullhist"
+is a bar graph or histogram style plot.
+.le
+.ls transpose = no
+Swap the X and Y axes of the plot. If enabled, the axes are transposed
+after the optional linear transformation of the X-axis.
+.le
+.ls xflip = no, yflip = no
+Flip the axis? That is, plot and label X values increasing right to
+left instead of left to right and/or Y values top to bottom instead of
+bottom to top.
+.le
+.ls logx = no, logy = no
+Log scale the X or Y axis. Zero or negative values are indefinite and
+will not be plotted, but are tolerated.
+.le
+.ls ticklabels = yes
+Label the tick marks.
+.le
+.ls majrx=5, minrx=5, majry=5, minry=5
+Number of major tick marks on each axis; number of minor tick marks between
+major tick marks. Ignored if log scaling is in effect for an axis.
+.le
+.ls lintran = no
+Perform a linear transformation of the X-axis upon input. Used to assign
+logical coordinates to the indices of pixel data arrays (image sections).
+.le
+.ls p1=0, p2=0, q1=0, q2=1
+If \fBlintran\fR is enabled, pixel index P1 is mapped to Q1, and P2 to Q2.
+If P1 and P2 are zero, P1 is set to 1 and P2 to the number of pixels in
+the input array.
+.le
+.ls round = no
+Extend the axes up to "nice" values.
+.le
+.ls append = no
+Append to an existing plot.
+.le
+.ls device = "stdgraph"
+The output device.
+.le
+.ih
+DESCRIPTION
+\fBGraph\fR graphs one or more lists, image sections, or table columns;
+lists and image sections may be mixed in the input list at will. If the
+curves are not all the same length the plot will be scaled to the
+longest curve and all curves will be plotted left justified. If an
+image section operand has more than one dimension the projection
+(average) along a designated axis will be computed and plotted. By
+default, a unique dash pattern is used for each curve, up to a maximum
+of 4.
+
+List input may be taken from the standard input or from a file,
+and consists of a sequence of Y values, X and Y values, or X, Y,
+and marker size values, one pair of coordinates per line in the list.
+Blank lines, comment lines, and extra columns are ignored.
+The first element in the list determines whether the list is a Y list
+or and X,Y list; it is an error if an X,Y list has fewer than two
+coordinates in any element. INDEF valued elements appear as gaps
+in the plot.
+
+SDAS table input is specified by a table name and column name, a table
+and two columns, or a pair of table and column names separated by white
+space. The table name may be a file name template. Note that this is a
+single string, so that it must be quoted if entered on the command line.
+
+Error bars may be plotted for data from list or table input. Errors may
+be in X or in Y and separate upper and lower errors may be specified.
+If `pointmode' is "no" then the parameter `erraxis' specifies if the
+errors are in X or in Y if its value is 1 or 2, respectively. If
+`pointmode' is "no" and `erraxis' is zero, a polyline is plotted (see
+below). If the input data come from a list, then the third (size)
+column specifies the amplitude of symmetrical error bars. If there is a
+fourth column, the third and fourth columns specify the amplitudes of
+the lower and upper errors, respectively. If the input data are in a
+table, the parameter `errcol' specifies the source of the errors.
+If `errcol' contains a single word, it is the column in the same table
+as the input data containing the amplitudes of symmetrical errors. If
+`errcol' contains two words, they specify the columns in the same table
+containing the amplitudes of the lower and upper errors, respectively.
+If the X and Y data come from different tables, then `erraxis' specifies
+which table contains the error column or columns. Error data may not
+come from image data. The `append' parameter may be used
+to overplot several curves of different style.
+
+Different line types and curve styles may be selected. The string
+parameter `crvstyle' may take on one of the values: "none", "straight",
+"pseudohist", or "fullhist", specifying the style of connections between
+data points; the string parameter `pattern' can take on one of the
+values "solid", "dashed", "dotted", "dotdash" to indicate the style
+of the first line drawn. Subsequent lines drawn on the same graph cycle
+the available styles.
+
+If \fBappend\fR is enabled, previous values for \fBbox\fR,
+\fBfill\fR, \fBround\fR, the plotting viewport (\fBvx1\fR, \fBvx2\fR,
+\fBvy1\fR, \fBvy2\fR), and the plotting window (\fBwx1\fR, \fBwx2\fR,
+\fBwy1\fR, \fBwy2\fR) are used.
+
+By default, the plot drawn will fill the device viewport, if the viewport
+was either specified by the user or automatically calculated by
+\fIgraph\fR. Setting
+the value of \fBfill\fR to "no" means the viewport will be adjusted so
+that equal numbers of data values in x and y will occupy equal lengths
+when plotted. That is, when \fBfill = no\fR, a unity aspect ratio is
+enforced, and plots
+appear square regardless of the device aspect ratio. On devices with non
+square full device viewports (e.g., the vt640), a plot drawn by \fIgraph\fR
+appears extended in the x direction unless \fBfill\fR = no.
+
+.ih
+EXAMPLES
+Plot the output of a list processing filter:
+
+ cl> ... list_filter | graph
+
+Plot a graph entered interactively from the terminal:
+
+ cl> graph STDIN
+
+Overplot two lists:
+
+ cl> graph list1,list2
+
+Graph line 128 of image "pix":
+
+ cl> graph pix[*,128]
+
+Graph the average of columns 50 through 100:
+
+ cl> graph pix[50:100,*] axis=2
+
+Graph two columns from a table against each other:
+
+ cl> graph "table xcol ycol"
+
+Graph a list in point plot mode:
+
+ cl> graph list po+
+
+Annotate a graph:
+
+.nf
+ cl> graph pix[*,10],pix[*,20] xlabel=column\
+ >>> ylabel=intensity title="lines 10 and 20 of pix"
+.fi
+
+Direct the graph to the standard plotter device:
+
+ cl> graph list device=stdplot
+.ih
+BUGS
+Indefinites are not recognized when computing image projections.
+
+End sgraph help.
+
+.sh
+3.3 The MERGE Task
+
+This task will merge the results from a maximum of four DAOPHOT output
+files based upon positional coincidence. This task will work on files
+which could have been run images with different scales, orientations etc.
+MERGE will need to transform the coordinate systems of the input photometry
+lists to a common coordinate system. There will be two ways of inputing the
+transformations to be applied to the coordinate lists: 1) Simple X, Y shifts
+or 2) transformations as determined by the GEOMAP task. This will allow the
+most common cases to handled in a simple way without having to run the GEOMAP
+task.
+
+The user will be able to specify a match radius which will determine how
+close to each other two objects must be to be considered a coincidence.
+The user will also be able to specify the number of lists an object must
+be identified in to be included in the output file. For example, if the
+user was merging photometry results from four different output tables
+he could request that the output table would contain entries for matches
+between any two or more of the four tables. The output Table from MERGE
+will simply contain pointers to the corresponding rows of the various
+input tables and not contain a copy of the complete row from each table
+for those objects which were matched. The user will then run another task,
+MSELECT to select the fields he wants from the original photometry files.
+This will allow the user to select only the fields he wants and to do the
+selection more than once without remerging the individual files.
+
+.sh
+3.3.1 MERGE Parameters
+
+MERGE shall have parameters which control the input and functioning of the
+task.
+
+.ks
+.nf
+Positional or query parameters:
+
+ ptable1 -- Input photometry table #1
+ ptable2 -- Input photometry table #2
+ ptable3 -- Input photometry table #3
+ ptable4 -- Input photometry table #4
+ matchrad -- Matching radius for coincidence
+ nmatch -- minimum number of matches to be included in output
+ merge_table -- output table containing merge pointers
+.fi
+.ke
+
+.ks
+.nf
+Hidden Parameters:
+
+ gmfile12 -- geomap database name for transforming #1 -> #2
+ gmrec12 -- geomap database record for transforming #1 -> #2
+ gmfile13 -- geomap database name for transforming #1 -> #3
+ gmrec13 -- geomap database record for transforming #1 -> #3
+ gmfile14 -- geomap database name for transforming #1 -> #4
+ gmrec14 -- geomap database record for transforming #1 -> #4
+ dx12 -- X offset (x2 - x1)
+ dy12 -- Y offset (y2 - y1)
+ dx13 -- X offset (x3 - x1)
+ dy13 -- Y offset (y3 - y1)
+ dx14 -- X offset (x4 - x1)
+ dy14 -- Y offset (y4 - y1)
+.fi
+.ke
+
+These parameters perform the following functions:
+
+.ls 4
+.ls 16 ptable1
+The name of the first input photometry table. This should be a standard
+DAOPHOT output table or one whose column names have been modified to agree
+with the DAOPHOT standard.
+.le
+.ls ptable2
+The name of the second input photometry table.
+.le
+.ls ptable3
+The name of the third input photometry table.
+.le
+.ls ptable4
+The name of the fourth input photometry table.
+.le
+.ls matchrad
+The matching radius for determining whether two objects should be identified
+with the same object and potentially included in the output table.
+.le
+.ls nmatch
+The minumum number of matches among the input photometry files for an object
+to be included in the output Table. If there were four input files and
+\fInmatch\fR was set to two then an object would be included in the output
+if it was matched in files 1/2, 1/3, 1/4, 2/3, 2/4 or 3/4. If \fInmatch\fR
+was three then the object would have to be identified in files 1/2/3,
+2/3/4, 1/2/4 or 1/3/4
+.le
+.ls gmfile12
+The name of the \fIGEOMAP\fR database containing the record which specifies
+the transformation between photometry list 2 and photometry list 2 in the
+sense of mapping objects in list #2 into the coordinate frame of the
+list #1
+.le
+.ls gmrec12
+The name of \fIGEOMAP\fR database record within \fIgmfile12\fR which
+describes the transformation from coordinate system #2 to system #1
+.le
+.ls gmfile13
+The name of the \fIGEOMAP\fR database containing the record which specifies
+the transformation between photometry list 3 and photometry list 3 in the
+sense of mapping objects in list #3 into the coordinate frame of the
+list #1
+.le
+.ls gmrec13
+The name of \fIGEOMAP\fR database record within \fIgmfile13\fR which
+describes the transformation from coordinate system #3 to system #1
+.le
+.ls gmfile14
+The name of the \fIGEOMAP\fR database containing the record which specifies
+the transformation between photometry list 4 and photometry list 4 in the
+sense of mapping objects in list #4 into the coordinate frame of the
+list #1
+.le
+.ls gmrec14
+The name of \fIGEOMAP\fR database record within \fIgmfile14\fR which
+describes the transformation from coordinate system #4 to system #1
+.le
+.ls dx12
+The X offset between coordinate system #2 and coordinate system #1
+in the sense of (x2 - x1).
+.le
+.ls dy12
+The Y offset between coordinate system #2 and coordinate system #1
+in the sense of (y2 - y1).
+.le
+.ls dx13
+The X offset between coordinate system #3 and coordinate system #1
+in the sense of (x3 - x1).
+.le
+.ls dy13
+The Y offset between coordinate system #3 and coordinate system #1
+in the sense of (y3 - y1).
+.le
+.ls dx14
+The X offset between coordinate system #4 and coordinate system #1
+in the sense of (x4 - x1).
+.le
+.ls dy14
+The Y offset between coordinate system #4 and coordinate system #1
+in the sense of (y4 - y1).
+.le
+.le
+
+If the parameters specifying the \fIGEOMAP\fR database file name for
+a particular transformation is empty then the corresponding parameters
+describing the transformation in terms of a simple shift are queried.
+
+.sh
+3.3.2
+The Output from MERGE
+
+\fIMERGE\fR will produce an STSDAS Table as output with the table
+containing pointers to records in the input Tables which identify the
+objects which are positionally coincident. The output Table will contain
+columns with the names \fIpoint0\fR, \fIpoint1\fR, \fIpoint2\fR and
+\fIpoint3\fR. If an object is identified in a particular input photometry
+list and also meets the \fInmatch\fR criterion then the entry in the
+output Table will contain the row number in the corrsponding input Table.
+For those objects which are included in the output Table but which are not
+identified in a particular input Table the corrsponding entry will be
+INDEF.
+
+.ks
+.nf
+Sample Output Format (ASCII representation)
+
+ Point0 Point1 Point2 Point3
+
+ 1 3 INDEF 2
+ 3 2 2 4
+ 4 5 4 INDEF
+ INDEF 8 7 6
+
+ .fi
+ .ke
+
+ In the above sample the first matched object corrsponds to rows 1, 3 and
+ 2 in input Tables 0, 1 and 3 respectively. This object was not matched
+ in input Table 0.
+
+The header of the Table output by MERGE shall contain the necessary information
+for tracking the original data files, the data and time the merge was done etc.
+The MSELECT task should check that the original photometry files have not been
+modified since MERGE was run to ensure data integrity.
+
+.sh
+3.4 MSELECT
+
+This task is used to select fields from the photometry Tables which
+were used as input to the \fIMERGE\fR task. The output from \fIMERGE\fR
+is a set of pointers to the appropriate records in the input tables.
+Using \fIMSELECT\fR on an output file from \fIMERGE\fR will produce an
+output file which will contain the specified fields for each of the
+objects which have been matched. If an object has not been identified
+in a particular Table then the values for each output field are set to
+INDEF.
+
+.sh
+3.4.1 MSELECT Parameters
+
+MERGE will have parameters wich will control the input and functioning
+of the task.
+
+.ks
+.nf
+Positional Parameters:
+
+ input filename ""
+ fields string ""
+ output string ""
+.fi
+.ke
+
+.ks
+.nf
+Hidden Parameters:
+
+ tables string ""
+.fi
+.ke
+
+These parameters perform the following functions:
+
+.ls 4
+.ls 16 input
+This specifies the input Table which must be an output Table from the
+\fIMERGE\fR task. \fIMSELECT\fR will get the names of the actual
+photometry Tables from the header of the input merge table.
+.le
+.ls fields
+A list of fields to extract from the input photometry tables.
+.le
+.ls output
+The name of the output table. This table will contain entries for
+each of the selected fields of each photometry table. The values for
+each field in the output table will be the values of the selected fields
+for each of the input photometry tables. For those entries which were not
+nmatched the corresponding entries will be INDEF.
+.le
+.ls tables
+This parameter is used to select output for only a subset of the input
+photometry tables.
+.le
+
+.endhelp
diff --git a/noao/digiphot/daophot/doc/substar.hlp b/noao/digiphot/daophot/doc/substar.hlp
new file mode 100644
index 00000000..5de81b85
--- /dev/null
+++ b/noao/digiphot/daophot/doc/substar.hlp
@@ -0,0 +1,323 @@
+.help substar May00 noao.digiphot.daophot
+.ih
+NAME
+substar -- subtract photometry results from an image
+.ih
+USAGE
+substar image photfile exfile psfimage subimage
+.ih
+PARAMETERS
+.ls image
+The list of images from which to subtract the scaled and shifted PSF.
+.le
+.ls photfile
+The list of PSF fitted photometry files. There must be one photometry file
+for every input image. If photfile is "default", "dir$default", or a directory
+specification, SUBSTAR will look for a file called image.nst.? where the
+question mark stands for the highest existing version number. Photfile is
+usually the output of the NSTAR task but may also be the output of the PEAK
+and ALLSTAR tasks or even the PHOT task. Photfile may be an APPHOT/DAOPHOT text
+database or an STSDAS table.
+.le
+.ls exfile
+The list of photometry files containing the ids of stars to be excluded
+from the subtraction. Exfile must be undefined or contain one exclude file
+for every input image. If exfile is "default", "dir$default", or a directory
+specification, SUBSTAR will look for a file called image.pst.? where the ?
+mark stands for the highest existing version number. Exfile is usually the
+output of the PSTSELECT task but may also be the output of the PEAK, NSTAR and
+ALLSTAR tasks or even the PHOT task. Exfile may be an APPHOT/DAOPHOT text
+database or an STSDAS table.
+.le
+.ls psfimage
+The list of images containing the PSF models computed by the DAOPHOT PSF task.
+The number of PSF images must be equal to the number of input images. If
+psfimage is "default", "dir$default", or a directory specification,
+then PEAK will look for an image with the name image.psf.?, where
+? is the highest existing version number.
+.le
+.ls subimage
+The list of output subtracted images. There must be one output subtracted
+image for every input image. If subimage is "default", "dir$default", or a
+directory specification, then SUBSTAR will write an image called image.sub.?
+where question mark stands for the next available version number.
+.le
+.ls datapars = ""
+The name of the file containing the data dependent parameters. The parameters
+\fIscale\fR, \fIdatamin\fR, and \fIdatamax\fR are located here. If datapars
+is undefined then the default parameter set in uparm directory
+.le
+.ls daopars = ""
+The name of the file containing the daophot fitting parameters. The parameters
+\fIpsfrad\fR and \fIfitrad\fR are located here. If \fIdaopars\fR is undefined
+then the default parameter set in uparm directory is used.
+.le
+.ls wcsin = ")_.wcsin", wcsout = ")_.wcsout", wcspsf = ")_.wcspsf"
+The coordinate system of the input coordinates read from \fIphotfile\fR, of the
+psf model \fIpsfimage\fR, and of the output coordinates written to
+the standard output if \fIverbose\fR = "yes". The image header coordinate
+system is used to transform from the input coordinate system to the "logical"
+pixel coordinate system used internally, from the internal logical system to
+the PSF model system, and from the internal "logical" pixel coordinate system
+to the output coordinate system. The input coordinate system options are
+"logical", "tv", "physical", and "world". The PSF model and output coordinate
+system options are "logical", "tv", and "physical". The image cursor coordinate
+system is assumed to be the "tv" system.
+.ls logical
+Logical coordinates are pixel coordinates relative to the current image.
+The logical coordinate system is the coordinate system used by the image
+input/output routines to access the image data on disk. In the logical
+coordinate system the coordinates of the first pixel of a 2D image, e.g.
+dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300] are
+always (1,1).
+.le
+.ls tv
+Tv coordinates are the pixel coordinates used by the display servers. Tv
+coordinates include the effects of any input image section, but do not
+include the effects of previous linear transformations. If the input
+image name does not include an image section, then tv coordinates are
+identical to logical coordinates. If the input image name does include a
+section, and the input image has not been linearly transformed or copied from
+a parent image, tv coordinates are identical to physical coordinates.
+In the tv coordinate system the coordinates of the first pixel of a
+2D image, e.g. dev$ypix and a 2D image section, e.g. dev$ypix[200:300,200:300]
+are (1,1) and (200,200) respectively.
+.le
+.ls physical
+Physical coordinates are pixel coordinates invariant with respect to linear
+transformations of the physical image data. For example, if the current image
+was created by extracting a section of another image, the physical
+coordinates of an object in the current image will be equal to the physical
+coordinates of the same object in the parent image, although the logical
+coordinates will be different. In the physical coordinate system the
+coordinates of the first pixel of a 2D image, e.g. dev$ypix and a 2D
+image section, e.g. dev$ypix[200:300,200:300] are (1,1) and (200,200)
+respectively.
+.le
+.ls world
+World coordinates are image coordinates in any units which are invariant
+with respect to linear transformations of the physical image data. For
+example, the ra and dec of an object will always be the same no matter
+how the image is linearly transformed. The units of input world coordinates
+must be the same as those expected by the image header wcs, e. g.
+degrees and degrees for celestial coordinate systems.
+.le
+The wcsin, wcspsf, and wcsout parameters default to the values of the package
+parameters of the same name. The default values of the package parameters
+wcsin, wcspsf, and wcsout are "logical", "physical" and "logical" respectively.
+.le
+.ls cache = ")_.cache"
+Cache the image pixels in memory. Cache may be set to the value of the apphot
+package parameter (the default), "yes", or "no". By default caching is
+disabled.
+.le
+.ls verify = ")_.verify"
+Verify the critical SUBSTAR task parameters? Verify can be set to the DAOPHOT
+package parameter value (the default), "yes", or "no".
+.le
+.ls update = ")_update"
+Update the SUBSTAR task parameters if \fIverify\fR is "yes"? Update can be
+set to the default daophot package parameter value, "yes", or "no".
+.le
+.ls verbose = ")_.verbose"
+Print messages about the progress of the task ? Verbose can be set to the
+DAOPHOT package parameter value (the default), "yes", or "no".
+.le
+
+.ih
+DESCRIPTION
+SUBSTAR task takes an input photometry list \fIphotfile\fR containing
+the fitted coordinates and magnitudes, and an input PSF \fIpsfimage\fR, and
+for each star in the photometry list scales and shifts the PSF and subtracts
+it from the input image \fIimage\fR. The final subtracted image is saved in the
+output image \fIsubimage\fR.
+
+The input photometry list can be the output from of the PEAK, NSTAR or ALLSTAR
+tasks or even the PHOT task although most people would not want to use the PHOT
+output for this purpose.
+
+Selected stars may be omitted from the subtraction by supplying their ids in
+the file \fIexfile\fR. \fIExfile\fR is normally the output the PSTSELECT task
+and is used to tell SUBSTAR to subtract the PSF star neighbors, but not the
+PSF stars themselves.
+
+The coordinates read from \fIphotfile\fR are assumed to be in coordinate
+system defined by \fIwcsin\fR. The options are "logical", "tv", "physical",
+and "world" and the transformation from the input coordinate system to the
+internal "logical" system is defined by the image coordinate system. The
+simplest default is the "logical" pixel system. Users working on with image
+sections but importing pixel coordinate lists generated from the parent image
+must use the "tv" or "physical" input coordinate systems.
+
+The coordinate system of the PSF model is the coordinate system defined by the
+\fIwcspsf\fR parameter. Normally the PSF model was derived from the input image
+and this parameter default to "logical". However if the PSF model was derived
+from a larger image which is a "parent" of the input image, then wcspsf should
+be set to "tv" or "physical" depending on the circumstances.
+
+The coordinates written to the standard output if \fIverbose\fR = yes are in the
+coordinate system defined by \fIwcsout\fR. The options are "logical", "tv",
+and "physical". The simplest default is the "logical" system. Users wishing to
+correlate the output coordinates of objects measured in image sections or
+mosaic pieces with coordinates in the parent image must use the "tv" or
+"physical" coordinate systems.
+
+If \fIcache\fR is yes and the host machine physical memory and working set size
+are large enough the input and output image pixels are cached in memory. If
+caching is enabled and SUBSTAR is run interactively the first subtraction
+will appear to take a long time as the entire image must be read in before
+the measurement is actually made. All subsequent measurements will be very
+fast because SUBSTAR is accessing memory not disk. The point of caching is
+to speed up random image access by making the internal image i/o buffers the
+same size as the image itself. However if the input object lists are sorted
+in row order which SUBSTAR does internally and are sparse caching may
+actually worsen not improve the execution time. Also at present there is no
+point in enabling caching for images that are less than or equal to 524288
+bytes, i.e. the size of the test image dev$ypix, as the default image i/o
+buffer is exactly that size. However if the size of dev$ypix is doubled by
+converting it to a real image with the chpixtype task then the effect of
+caching in interactive is can be quite noticeable if measurements
+of objects in the top and bottom halves of the image are alternated.
+
+
+The SUBSTAR task is most commonly used to check on the quality of the PSF
+fitting produced by PEAK and NSTAR, to search for non-stellar objects and close
+binary stars, to generate an improved PSF in crowded fields, and to remove
+neighbors from bright stars which are to be used to determine aperture
+corrections.
+
+.ih
+EXAMPLES
+
+1. Subtract the NSTAR photometry results for the test image dev$ypix from the
+image dev$ypix.
+
+.nf
+ da> datapars.epadu = 14.0
+ da> datapars.readnoise = 75.0
+
+ ... set the gain and readout noise for the detector
+
+ da> daofind dev$ypix default fwhmpsf=2.5 sigma=5.0 threshold=20.0
+
+ ... answer verify prompts
+
+ ... find stars in the image
+
+ ... answer will appear in ypix.coo.1
+
+ da> phot dev$ypix default default annulus=10. dannulus=5. \
+ apertures = 3.0
+
+ ... answer verify prompts
+
+ ... do aperture photometry on the detected stars
+
+ ... answer will appear in ypix.mag.1
+
+ da> display dev$ypix 1
+
+ da> psf dev$ypix default "" default default default psfrad=11.0 \
+ fitrad=3.0 mkstars=yes display=imdr
+
+ ... verify the critical parameters
+
+ ... move the image cursor to a candidate star and hit the a key,
+ a plot of the stellar data appears
+
+ ... type ? for a listing of the graphics cursor menu
+
+ ... type a to accept the star, d to reject it
+
+ ... move to the next candidate stars and repeat the previous
+ steps
+
+ ... type l to list all the psf stars
+
+ ... type f to fit the psf
+
+ ... move cursor to first psf star and type s to see residuals,
+ repeat for all the psf stars
+
+ ... type w to save the PSF model
+
+ ... type q to quit, and q again to confirm
+
+ ... the output will appear in ypix.psf.1.imh, ypix.pst.1 and
+ ypix.psg.1
+
+ da> group dev$ypix default default default
+
+ ... verify the prompts
+
+ ... the output will appear in ypix.grp.1
+
+ da> nstar dev$ypix default default default default
+
+ ... verify the prompts
+
+ ... the results will appear in ypix.nst.1 and ypix.nrj.1
+
+ da> pdump ypix.nst.1 sharpness,chi yes | graph
+
+ ... plot chi versus sharpness, the stars should cluster around
+ sharpness = 0.0 and chi = 1.0, note that the frame does
+ not have a lot of stars
+
+ da> substar dev$ypix default "" default default
+
+ ... subtract the fitted stars
+
+ da> display ypix.sub.1 2
+
+ ... note that the psf stars subtract reasonably well but other
+ objects which are not stars don't
+.fi
+
+
+2. Rerun the previous example on a section of the test image using the group
+file and PSF model derived in example 1 for the parent image and writing the
+results in the coordinate system of the parent image.
+
+.nf
+ da> nstar dev$ypix[150:450,150:450] default default default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... answer the verify prompts
+
+ ... fit the stars
+
+ ... the results will appear in ypix.nst.2 and ypix.nst.2
+
+ da> display dev$ypix[150:450,150:450] 1
+
+ ... display the image
+
+ da> pdump ypix.nst.2 xc,yc yes | tvmark 1 STDIN col=204
+
+ ... mark the stars
+
+ da> substar dev$ypix ypix.nst.2 "" default default
+
+ ... subtract stars from parent image
+
+ ... the output images is ypix.sub.2
+
+
+ da> substar dev$ypix[150:450,150:450] ypix.nst.2 "" default default \
+ wcsin=tv wcspsf=tv wcsout=tv
+
+ ... subtract stars from the nstarinput image
+
+ ... the output images is ypix.sub.3
+
+.fi
+
+.ih
+TIME REQUIREMENTS
+.ih
+BUGS
+.ih
+SEE ALSO
+datapars,daopars,nstar,peak
+.endhelp
diff --git a/noao/digiphot/daophot/doc/userdocs/daophot.usr.tex b/noao/digiphot/daophot/doc/userdocs/daophot.usr.tex
new file mode 100644
index 00000000..ce4ed623
--- /dev/null
+++ b/noao/digiphot/daophot/doc/userdocs/daophot.usr.tex
@@ -0,0 +1,2005 @@
+%de 21 (summer solstice, midnight, la serena) (this is IT, Phil!)
+%more done on Dec 27th or so
+%typos fixed 28 Dec 1pm
+%more done on Dec 28th (1st 4-m night morning)
+%copy xfered from Chile on Jan 1, 1990
+%modifications made after the AAS meeting, Jan 15 1990:
+% end itemize problems fixed
+% buku aperture photometry stuff added Jan 15/16
+% started to make Lindsey's changes Jan 28th
+% Next set of changes made Feb. 18th when we SHOULD have been
+% off with marcia having a good time.
+% more modifications Monday Feb 19
+% march 20/21 mods made in Boulder----Lindsey's comments
+% march 20/21 mods made in Boulder---beginning of JB's comments
+% march 27 mods back in Tucson
+% may 11th, fixed the sumed/average read-noise problem!
+\documentstyle[11pt,moretext]{article}
+\begin{document}
+\title{A User's Guide to Stellar CCD Photometry with IRAF}
+\author{Philip Massey \and Lindsey E. Davis}
+\date{March 29, 1990}
+\maketitle
+\begin{abstract}
+This document is intended to guide you through the steps for obtaining
+stellar photometry from CCD data using IRAF. It deals both with the
+case that the frames are relatively uncrowded (in which case simple
+aperture photometry may suffice) and with the case that the frames
+are crowded and require more sophisticated point-spread-function
+fitting methods (i.e., {\bf daophot}). In addition we show how one
+goes about obtaining photometric solutions for the standard stars, and
+applying these transformations to instrumental magnitudes.
+\end{abstract}
+\tableofcontents
+\eject
+\section{Introduction}
+This user's guide deals with both the ``relatively simple" case of
+isolated
+stars on a CCD frame (standard stars, say, or uncrowded program stars)
+and the horrendously more complicated case of crowded field
+photometry. We describe here all the steps needed to obtain instrumental
+magnitudes and to do the transformation to the standard system. There
+are, of course, many possible paths to this goal, and IRAF provides no
+lack of options. We have chosen to illuminate a straight road, but many
+side trails are yours for the taking, and we will occasionally point
+these out (``let many flowers bloom"). This Guide is {\it not} intended
+as a reference manual; for that, you have available (a) the various
+``help pages" for the routines described herein, (b) ``A User's Guide
+to the IRAF APPHOT Package" by Lindsey Davis, and (c) ``A Reference
+Guide to the IRAF/DAOPHOT Package" by
+Lindsey Davis. (For the ``philosophy" and algorithms of DAOPHOT, see
+Stetson 1987 {\it PASP} {\bf 99}, 111.)
+What {\it this} manual is intended to be is a real
+``user's guide", in which we go through all of the steps necessary to go
+from CCD frames to publishable photometry. (N.B.: as of this writing
+the IRAF routines for determining the standard transformations and
+applying those transformations are still being written.) We outline
+a temporary kludge that will work with Peter Stetson's CCDRED VMS
+Fortran package. Hopefully the PHOTRED package currently under
+development at Cerro Tololo will be available by Spring 1990, and
+this manual will then be revised.
+
+The general steps involved are as follows: (1) fixing the header
+information to reflect accurate exposure times and airmasses,
+(2) determining and cataloging the characteristics of your data (e.g.,
+noise, seeing, etc.),
+(3) obtaining instrumental magnitudes for all the standard stars
+using aperture photometry, (4) obtaining instrumental magnitudes for
+your program stars using IRAF/daophot, (5) determining the aperture
+correction for your program stars, (6) computing the transformation
+equations for the standard star photometry, and (7) applying these
+transformations to your program photometry. We choose to illustrate
+these reductions using {\it UBV} CCD data obtained with an RCA chip on the 0.9-m
+telescope at Cerro Tololo, but the techniques are applicable to data
+taken with any detector whose noise characteristics mimic those of a
+CCD.
+
+If you are a brand-new IRAF user we strongly recommend first reading the
+document ``A User's Introduction to the IRAF
+Command Language" by Shames and Tody, which can be found in Volume 1A
+of the 4 blue binders that compose the IRAF documentation. (Actually
+if you are a brand-new IRAF user one of us recommends that you find
+some simpler task to work on before you tackle digital stellar photometry!)
+The procedures described here will work on any system supported by IRAF;
+for the purposes of discussion, however, we will assume that you are
+using the image display capabilities of a SUN. If this is true you then
+may also want to familiarize yourself with the ins and outs of using
+the SUN Imtool window; the best description is to be found in ``IRAF
+on the SUN".
+
+We assume that your data has been read onto disk, and that the basic
+instrumental signature has been removed; i.e., that you are ready
+to do some photometry. If you haven't processed your
+data this far yet, we
+refer you to ``A User's Guide to Reducing CCD Data with IRAF" by Phil
+Massey.
+
+\section{Getting Started}
+
+\subsection{Fixing your headers}
+You're going to have to this some time or another; why not now? There
+are two specific things we may need to fix at this point: (a) Add any
+missing header words if you are reducing non-NOAO data, (b) correct the
+exposure time for any shutter opening/closing time, and (c) correct the
+airmass to the effective middle of the exposure.
+
+Two things that will be useful to have in your headers are the exposure
+time and the airmass. If you are reducing NOAO data then you will
+already have the exposure time (although this may need to be corrected
+as described in the next paragraph) and enough information for the {\bf
+setairmass} task described below to compute the effective airmass of the
+observation. You can skip to the ``Correcting the exposure time"
+section below.
+If
+you are reducing non-NOAO data you should examine your header with a
+
+\centerline{ {\bf imhead} imagename{\bf l+ $|$ page} }
+
+\noindent
+and see exactly what information {\it is} there. If you are lacking the
+exposure time you can add this by doing an
+
+\centerline{ {\bf hedit} imagename{\bf ``ITIME"} value {\bf add+ up+
+ver- show+} }
+
+\noindent
+If you know the effective airmasses you can add an ``AIRMASS" keyword in
+the same manner, or if you want to compute the effective airmass
+(corrected to mid-exposure) using {\bf setairmass} as described below,
+you will need to have the celestial coordinates key words ``RA" and
+``DEC", as well as the siderial-time (``ST"),
+and preferably the coordinate ``EPOCH" and the date-of-observation
+(``DATE-OBS"), all of which should have the form shown in Fig.~\ref{header}.
+
+You may want to take this opportunity to review the filter numbers in the
+headers, and fix any that are wrong. If you are lacking filter numbers
+you may want to add them at this point.
+
+\subsubsection{Correcting the exposure time}
+The CTIO 0.9-m has an effective exposure time that is
+25-30ms longer than the requested exposure time (Massey et al. 1989 {\it
+A.J.} {\bf 97}, 107; Walker 1988 {\it NOAO Newsletter} {\bf No. 13},
+20). First see what "keyword" in your header gives the exposure time:
+
+\centerline{
+{\bf imhead} imagename{\bf.imh l+ $|$ page} }
+
+\noindent
+will produce a listing such as
+given in Figure~\ref{header}.
+\begin{figure}
+\vspace{3.2in}
+\caption{\label{header}Header information for image n602alu.imh}.
+\end{figure}
+The exposure time keyword in this header is ``ITIME". In this case
+we wish to add a new exposure time to each of the headers; we will call
+this corrected exposure time
+EXPTIME, and make it 25 ms larger than whatever value is listed as
+ITIME. To do this we use the {\bf hedit} command as follows:
+
+\centerline{
+{\bf hedit *.imh EXPTIME ``(ITIME+0.025)" ver- show+ add+}.}
+
+\noindent
+An inspection of the headers will now show a new keyword EXPTIME.
+(Walker lists a similar correction for the CTIO 1.5-m shutter, but the
+CTIO 4-m P/F shutters have a negligible correction.
+The direct CCD shutters on the Kitt Peak CCD cameras give
+an additional 3.5ms of integration on the edges but 13.0ms in the
+center [e.g., Massey 1985 {\it KPNO Newsletter} {\bf 36}, p. 6];
+if you have any 1 second exposures you had best correct these by
+10ms or so if you are interested in 1\% photometry.)
+
+\subsubsection{Computing the effective airmass}
+The task {\bf setairmass} in the {\bf astutil} package will compute
+the effective airmass of your exposure, using the header values of RA,
+DEC, ST, EPOCH, and DATE-OBS, and whatever you specify for the observatory
+latitude. An example is shown in Fig.~\ref{setairmass}.
+\begin{figure}
+\vspace{2.5in}
+\caption{\label{setairmass} The parameter file for {\bf setairmass}.}
+\end{figure}
+The default for the latitude is usually the IRAF
+variable {\bf observatory.latitude}. To by-pass this ``feature", simply
+put the correct latitude in the parameter file
+(e.g., $-30.1652$ for CTIO,
+$+31.963$ for KPNO; $+19.827$ for Mauna Kea.).
+
+\subsection{{\bf imexamine:} A Useful Tool}
+
+The {\bf proto} package task {\bf imexamine} is a powerful and versatile task
+which can be used to interactively examine image data at all stages of
+the photometric reduction process. In this section we discuss and
+illustrate those aspects of {\bf imexamine} which are most useful to
+photometrists with emphasis on three different applications of the task:
+1) examining the image, for example plotting lines and columns
+2) deriving image characteristics, for example computing the
+FWHM of the point-spread function 3) comparing the same region
+in different images.
+
+The task
+{\bf imexamine} lives within the {\bf proto} package, and you will also need
+to load {\bf images} and {\bf tv}. Then
+{\bf display} the image, and type {\bf imexamine}.
+When the task is ready to accept input the image cursor will begin blinking
+in the display window, and the user can begin executing various keystroke
+and colon commands. The most useful data examining commands are summarized
+below. The column, contour, histogram, line and surface plotting commands
+each have their own parameter sets which set the region to be plotted and
+control the various plotting parameters. All can be examined and edited
+interactively from within the {\bf imexamine} task using the
+appropriate {\bf :epar} command.
+
+\begin{description}
+ \item[c] - Plot the column nearest the image cursor
+ \item[e] - Make a contour plot of a region around the image cursor
+ \item[h] - Plot the histogram of a region around the image cursor
+ \item[l] - Plot the line nearest the image cursor
+ \item[s] - Make a surface plot of a region around the image cursor
+ \item[:c N] - Plot column N
+ \item[:l N] - Plot line N
+ \item[x] - Print the x, y, z values of the pixel nearest the image cursor
+ \item[z] - Print a 10 by 10 grid of pixels around the image cursor
+ \item[o] - Overplot
+ \item[g] - Activate the graphics cursor
+ \item[i] - Activate the image cursor
+ \item[?] - Print help
+ \item[q] - Quit {\bf imexamine}
+ \item[:epar c] - Edit the column plot parameters
+ \item[:epar e] - Edit the contour plot parameters
+ \item[:epar h] - Edit the histogram plot parameters
+ \item[:epar l] - Edit the line plot parameters
+ \item[:epar s] - Edit the surface plot parameters
+
+\end{description}
+
+
+Example 1 below shows how a user can interactively
+make and make hardcopies of image line plots using {\bf imexamine} and at the same time
+illustrates many of the general features of the task.
+
+The {\bf imexamine} task also has some elementary image analysis capability, including
+the capacity to do simple aperture photometry, compute image statistics
+and fit radial profiles. The most useful image analysis commands are
+listed below.
+
+\begin{description}
+\item[h] - Plot the histogram of a region around the cursor
+\item[r] - Plot the radial profile of a region around the cursor
+\item[m] - Plot the statistics of a region around the cursor
+\item[:epar h] - Edit the histogram parameters
+\item[:epar r] - Edit the radial profile fitting parameters
+\end{description}
+
+Example 2 shows how a photometrist might use {\bf imexamine}
+and the above commands to estimate the following image characteristics:
+1) the full width at
+half maximum (FWHM) of the point-spread function, 2) the background sky level
+3) the standard deviation of the background level 4) and the radius at which
+the light from the brightest star of interest disappears into the noise
+(this will be used to specify the size of the point-spread-function,
+e.g.,PSFRAD).
+
+Finally {\bf imexamine} can be used to compare images. Example 3
+shows how to compare regions in the original image and in the
+same image with all the fitted stars subtracted out. The example
+assumes that the target image display device supports multiple frame buffers,
+i.e. the user can load at
+least two images into the display device at once.
+
+The {\bf imexamine} task offers even more features than are discussed here and the
+user should refer to the manual page for more details.
+
+\vspace{12pt}
+{\bf Example 1:} Plot and make hardcopies of image lines within {\bf imexamine}.
+
+\begin{itemize}
+\item {\bf display} the image and then type {\bf imexamine}.
+\item move the image cursor to a star and tap {\bf l} to plot the image
+line nearest the cursor
+\item tap the {\bf g} key to activate the graphics cursor
+\item type {\bf :.snap} to make a hardcopy of the plot on your default device
+\item expand a region of interest by first moving the graphics
+cursor to the lower left corner of the region and typing {\bf E},
+and then moving the graphics cursor to the upper right corner
+of the region and typing anything
+\item type {\bf :.snap} to make a hardcopy of the new plot
+\item tap the {\bf i} key to return to the image cursor menu
+\item type {\bf :epar l} to enter the line plot parameter set, change the
+value of the logy parameter to yes and type {\bf CNTL-Z} to exit and
+save the change
+\item repeat the previous line plotting commands
+\item type {\bf q} to quit {\bf imexamine}
+\end{itemize}
+
+{\bf Example 2:} Compute some elementary image characteristics using
+{\bf imexamine}.
+
+\begin{itemize}
+\item {\bf display} the image and then type {\bf imexamine}.
+\item move to a bright star and tap the {\bf r} key
+\item examine the resulting radial profile plot and note the final
+number on the status line which is the FWHM of the best fitting
+Gaussian
+\item repeat this procedure for several stars to estimate a good
+average value for the FWHM
+\item set the parameters of the statistics box ncstat and nlstat
+from 5 and 5 to 21 and 21 with {\bf :ncstat 21} and {\bf :nlstat 21}
+commands so that the sizes of the statistics and histogram
+regions will be identical
+\item move to a region of blank sky and tap the {\bf m} key to get an
+estimate of the mean, median and standard deviation of the
+sky pixels in a region 21 by 21 pixels in size around the
+image cursor
+\item leave the cursor at the same position and tap the {\bf h} key to
+get a plot of the histogram of the pixels in the same region
+\item tap the {\bf g} key to activate the graphics cursor, move the
+cursor to the peak of the histogram and type {\bf C} to print out
+the cursor's value. The ``x" value then gives you a good estimate of
+the sky. Similarly, you can move the cursor to the
+half-power point of
+the histogram and type {\bf C} to estimate the standard deviation
+of the sky pixels. Tap the {\bf i} key to return to the
+image cursor menu
+\item compare the results of the h and m keys
+\item repeat the measurements for several blank sky regions and note
+the results
+\item move to a bright unsaturated star and turn up the zoom and
+ contrast of the display device as much as possible
+\item using the {\bf x} key mark the point on either side of the center
+where the light from the star disappears into the noise
+and estimate PSFRAD
+\item type {\bf :epar r} to edit the radial profile fitting parameters
+and set rplot to something a few pixels larger than PSFRAD
+and tap the {\bf r} key
+\item note the radius where the light levels off and compare with
+the eyeball estimate
+\item repeat for a few stars to check for consistency
+\item type {\bf q} to quit imexamine
+\end{itemize}
+
+\noindent
+{\bf Example 3:} Overplot lines from two different images.
+
+\begin{itemize}
+\item {\bf imexamine image1,image2}
+\item move the image cursor to a star and type {\bf z} to print the
+pixel values near the cursor
+\item tap the {\bf n} key to display the second image followed by {\bf z}
+to look at the values of the same pixels in the second
+image
+\item tap the {\bf p} key to return to the first image
+\item tap {\bf l} to plot a line near the center of the star and tap
+the {\bf o} key to overlay the next plot
+\item tap the {\bf p} key to return to the second image and without
+moving the image cursor tap the l key again to overplot
+the line
+\item type {\bf q} to quit imexamine
+\end{itemize}
+
+\subsection{Dealing with Parameter Files (Wheels within Wheels)}
+
+The {\bf daophot} (and {\bf apphot}) packages are unique in IRAF in that
+they obtain
+pertinent information out of separate ``parameter files" that can be
+shared between tasks. As anyone that
+has used IRAF knows, each IRAF command has its own parameter file that
+can
+be viewed by doing an {\bf lpar} {\it command} or edited by doing an
+{\bf epar} {\it command}.
+However, in {\bf daophot} and {\bf apphot} there are ``wheels within
+wheels"---some of the parameters are in fact parameter files themselves.
+For instance, the aperture photometry routine {\bf phot} does not
+explicitly
+show you the methods and details of
+the sky fitting in its parameter file.
+However, if you do an {\bf lpar phot}
+you will see a parameter
+called ``fitskypars" which
+contains, among many other things, the radii of the annulus to be used
+in determining the sky value.
+You will also find listed ``datapars" (which specifies the properties
+of your data, such as photons per ADU and read-noise), ``centerpars"
+(which
+specifies the centering algorithm to be used), and ``photpars" (which gives
+the
+size of the digital apertures and the zero-point magnitude).
+The contents of any of these parameter files can be altered either by
+{\bf epar}ing them on their own or by typing a ``:e" while on that
+line of the main parameter file. If you do the latter, a control-z
+or a ``:q" will bring you back.
+For example, to examine or edit {\bf fitskypars}, you can
+do an explicit {\bf lpar fitskypars}
+or {\bf epar fitskypars}, or you can do an {\bf epar phot}, move the
+cursor down to the ``fitskypars" line, and then type a {\bf :e} to edit
+(see Fig.~\ref{wheels}).
+\begin{figure}
+\vspace{4.2in}
+\caption{\label{wheels}Changing the Sky Annulus in {\bf fitskypars}.}
+\end{figure}
+Confusing? You bet!
+But once you are used to it, it is a convenient and powerful way to
+specify a whole bunch of things that are used by several different
+commands---i.e., you are guaranteed of using the same parameters in
+several different tasks. If there is only one thing that you want to
+change in
+a parameter file you {\it can} enter it on the command line when
+you run the command, just as if it were a ``normal" (hidden) parameter,
+i.e., {\bf phot imagename dannulus=8.} does the same as
+running {\bf epar fitskypars} and changing the ``width of sky annulus"
+{\bf dannulus} to 8.0.
+
+Mostly these things are kept out of the way (``very hidden" parameters)
+because you {\it don't} want to be changing them, once you have set them
+up for your data. There are exceptions, such as changing the PSF radius
+in making a point-spread function in a crowded field (Sec. 4.6).
+However,
+you are well protected here if you leave the {\bf verify} switch on.
+A task will then give you an opportunity to take one last look at
+anything
+that you really care about when you run the task. For instance, if we
+had simply run {\bf phot} on an image (we'll see how to do this shortly)
+it would have said ``Width of sky annulus (10.)", at which point we
+could
+either have hit [CR] to have accepted the 10., or we could have
+entered a new value.
+
+
+\section{Aperture Photometry on your Standards}
+
+Standard stars provide a good example of relatively uncrowded
+photometry,
+and in this section we will describe how to obtain instrumental
+magnitudes for your standards using {\bf phot}.
+The basic steps are
+\begin{itemize}
+ \item Decide what aperture size you wish to use for measuring your
+ standards {\bf (this should be the same for all the frames).} At the
+ same time we will pick a sky annulus.
+ \item Set up the various parameter files ({\bf datapars,
+ centerpars, fitskypars, photpars}) to have the correct values.
+ \item For each frame:
+ \begin{enumerate}
+ \item Identify the standard star(s) either
+ interactively using a cursor
+ or by using the automatic star finding algorithm
+ {\bf daofind}.
+ \item Run the aperture photometry program {\bf phot}
+ on each of your standard star frames.
+\end{enumerate}
+\end{itemize}
+Although the routines you will need to use are available both in the
+{\bf daophot} and {\bf apphot} packages, we strongly advise you to run
+them from the {\bf daophot} package: the default setup is somewhat different,
+and the two packages each have their own data parameter files.
+
+\subsection{Picking an Aperture Size}
+Unfortunately, there are not good tools available with IRAF to do this
+yet, and we will restrict our discussion here to some of the
+considerations before telling you to just go ahead and use a radius that
+is something like 4 or 5 times the FWHM of a stellar image; e.g.,
+12 or 15
+pixels as a radius, assuming you have the usual sort of ``nearly
+undersampled" FWHM$\approx3$ data.
+You might naively expect (as I did) that you wish to pick an aperture
+size
+that will ``contain all the light" from your standard stars, but in fact
+this is impossible: the wings of a star's profile extend much further
+than you imagine at a ``significant" level. King (1971 {\it Publ.
+A.S.P.} {\bf 83}, 199) and Kormendy (1973 {\it A.J.} {\bf 78}, 255)
+discuss the fact that on photographic plates the profile of a star
+extends out to {\it arcminutes} at an intensity level far exceeding the
+diffraction profile; Kormendy attributes this to scattering off of dust
+and surface irregularities on the optical surfaces.
+Massey {\it et al}.\ (1989 {\bf 97}, 107) discusses
+this in regards to CCD's and standard star solutions using the very data
+we are using here as an example (which is not exactly a coincidence).
+Although the intensity profile falls off rapidly, the increase in area
+with radius increases rapidly, and in practical terms Massey {\it et
+al.}
+found that in cases where the FWHM was typically small (2.5-3 pixels),
+increasing the digital aperture size from a diameter of 18 pixels to
+one of 20 pixels resulted in an additional 1-2\% increase in light
+for a well-exposed star, and that this increase continues
+for larger apertures until masked by the photometric errors.
+
+Given that you presumably want 1\% photometry or better, what should you
+do?
+Well, the fact that photoelectric photometery through fixed apertures
+in fact does
+work suggests that there is some radius beyond which the same fraction
+of
+light is excluded, despite variations in the seeing and guiding. You do
+not want to choose a gigantic aperture ($>$ 20 pixels, say) because the
+probability of your having a bad pixel or two goes up with the area.
+But you do not want to choose too small an aperture ($<$10 pixels, say)
+or you will find yourself at the mercy of the seeing and guiding. Most
+photoelectric photometrists will use an aperture of at least 10
+arcseconds in diameter, but remember you have one advantage over them:
+you are not sensitive to centering errors, since any digital aperture can
+be exactly centered.
+If you
+have enough standard star observations (I used about 300 obtained over a
+10 night run) you can
+compute magnitude differences between a large aperture (20 pixels),
+and a series of smaller apertures (8, 10, 12, 15, 18) for each filter,
+and then see for which radius the difference (in magnitudes) becomes
+constant. Unfortunately, there are no tools currently available within
+IRAF for taking the differences between two apertures, or for conveniently
+plotting these differences, so you are on your own. My recommendation
+would be that if you have typical data with a
+FWHM of $\leq 4$ pixels, that you use something like an aperture of 12 to 15
+pixels in radius for your standard stars. {\bf You can save yourself a lot
+of trouble if you simply adopt a single radius for all the standards
+from all the nights for all filters.}
+
+\subsection{Setting Things Up}
+
+As discussed in ``Dealing with Parameter Files" (Section 2.1) we must
+setup the parameter files from which {\bf phot} will get the details of
+what it is going to do. The easiest way to do this is to simply
+{\bf epar phot}, and on each of the four parameter lists to do a
+{\bf :e}. Mostly we will leave the defaults alone, but in fact you will
+have to change at least one thing in each of the four files.
+
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{photdatapars} Parameters for {\bf datapars}.}
+\end{figure}
+In {\bf datapars} (Fig.~\ref{photdatapars}) we need to specify both
+the FWHM
+of a star image ({\it fwhmpsf}) and the
+threshold value above sky ({\it threshold}) if we are going to use the
+automatic star-finding routine {\bf daofind}; the choices for these
+are discussed further below. In order to have
+realistic
+error estimates for our aperture photometry we need to specify
+the CCD readnoise {\it readnoise} in electrons and the
+gain (photons per ADU) for the CCD {\it epadu}.
+In order to
+correct the results for the exposure time we need the exposure time
+keyword {\it
+exposure}. Do an
+
+\centerline{{\bf imhead} {\it imagename} {\bf l+ $|$ page}}
+
+\noindent
+to see a
+listing of all the header information (Fig.~\ref{phothead}).
+\begin{figure}
+\vspace{4.0in}
+\caption{\label{phothead} Header information for std159.imh}
+\end{figure}
+By specifying the (effective) airmass and filter keywords,
+these can be carried along in the photometry file for use when we do
+the standards solution ({\it airmass} and {\it filter}). Finally we use
+{\it datamin} and {\it datamax} so we will know if we exceeded the
+linearity of the CCD in the exposure, or whether there is some anomalously
+low valued pixel on which our star is sitting.
+Since the value of the sky on our standard exposures is
+probably nearly zero, {\it datamin} should be set to a negative value
+about three times the size of the readnoise in {\it ADU's}; e.g., $-3 \times
+65. \div 2.25 \approx -90$ in this example. Note that although we will
+later argue that the shape of the PSF changes a little about 20000
+ADU's (presumably due to some sort of charge-transfer problem),
+for the purposes of simple aperture photometry we are happy
+using 32000 ADU's as the maximum good data value. (We do not really
+want to use 32767 as afterall the overscan bias was probably at a
+level of several hundred.)
+
+\begin{figure}
+\vspace{3.0in}
+\caption{\label{photcenterpars} Parameters for {\bf centerpars}.}
+\end{figure}
+In {\bf centerpars} (Fig.~\ref{photcenterpars}) we need to
+change the centering algorithm {\it calgorithm}
+from the default value of ``none" to
+``centroid". If the FWHM of your frames are unusually large ($>4$, say,
+you would also do well to up the size of {\bf cbox} to assure that the
+centering works well; make it something like twice the FWHM. In this
+case the FWHM is 3 pixels or a bit smaller, and we are content to leave
+it a the default setting of 5 pixels.
+
+\begin{figure}
+\vspace{2.7in}
+\caption{\label{photfitskypars} Parameters for {\bf fitskypars}.}
+\end{figure}
+In {\bf fitskypars} (Fig.~\ref{photfitskypars})
+the only things we must specify are the size and
+location of the annulus in which the modal value of the sky will be
+determined. If you are going to use a value of 15 for your photometry
+aperture, you probably want to start the sky around pixel 20. Keeping
+the width of the
+annulus large (5 pixels is plenty) assures you of good sampling, but
+making it too large increases the chances of getting some bad pixels in
+the sky.
+
+\begin{figure}
+\vspace{2.7in}
+\caption{\label{photphotpars} Parameters for {\bf photpars}.}
+\end{figure}
+In {\bf photpars} (Fig.~\ref{photphotpars})
+we merely need to specify the size (radius) of the
+aperture we wish to use in measuring our standards.
+
+\subsection{Doing It}
+There are basically two ways of proceeding in running photometry on the
+standard stars, depending upon how you are going to identify the
+relevant star(s) on each frame. If you have only one (or two)
+standard stars on each frame, and it is always one of the brightest
+stars present, then you can avoid a lot of the work and use the
+automatic star-finding program {\bf daofind} to find all your standards
+and the whole thing can be done fairly non-interactively. However,
+if you are one of the believers in cluster field standards, then you
+may actually want to identify the standards in each field using the
+cursor on the image display so that the numbering scheme makes sense.
+We describe below each of the two methods.
+
+\subsubsection{Automatic star finding}
+First let's put the name of each frame containing standard stars into
+a file; if you've put the standard star exposures into a separate
+directory this can be done simply by a {\bf files *.imh $>$ stands}.
+This will leave us with funny default output file
+names for a while (we advise against
+including the ``.imh" extension when we discuss crowded field photometry
+in the next section), but this will only be true for a short
+intermediate
+stage.
+
+We want to run {\bf daofind} in such a way that it finds only the
+brightest
+star or two (presumably your standard was one of the brightest stars
+in the field;
+if not, you are going to have to do this stuff as outlined below in
+the ``Photometry by eye" section). We will delve more fully into the
+nitty-gritty of {\bf daofind} in the crowded-field photometry section,
+but here we are content if we can simply find the brightest few stars.
+Thus the choice of the detection
+threshold is a critical one. If you make it too low you will find all
+sorts of junk; if you make it too high then you may not find any stars.
+You may need to run {\bf imexamine} on a few of your images: first
+{\bf display} the image, and then {\bf imexamine}, using the ``r" cursor
+key to produce a radial profile plot. Things to note are the
+typical full-width-half-maximum and the peak value. If your sky is
+really around zero for your standard exposures, then using a value
+that is, say, twenty times the readnoise (in ADU's) is nearly guaranteed to
+find only the brightest few stars; do your radial plots in {\bf
+imexamine} show this to be a reasonable value? In the example here we
+have decided to use 500 ADUs as the threshold ($20 \times 65 \div 2.25
+\approx 500$).
+
+Now {\bf epar daofind} so it resembles that of Fig.~\ref{photdaofind}.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{photdaofind} Parameter file for {\bf daofind}.}
+\end{figure}
+Go ahead and execute it (Fig. ~\ref{daoout}).
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{daoout} Screen output from a {\bf daofind} run.}
+\end{figure}
+Note that since {\it verify} is on that you
+will be given a chance to revise the FWHM and detection threshold. By
+turning verbose on you will see how many stars are detected on each
+frame.
+%Probably the best way of doing this is to write the output from
+%{\bf daofind} into a file; do a
+%
+%\centerline{ {\bf daofind @stands $|$ tee starsfound} }
+%
+%\noindent
+%to put the output into the file ``starsfound" as well as on the screen.
+Make a note of any cases where no stars were found; these you will have
+to
+go back and do with a lower threshold.
+
+The run of {\bf daofind} produced one output file named {\it
+imagename.imh.coo.1} for each input file. If you {\bf page} one of
+these you will find that it resembles that of Fig.~\ref{photcooout}.
+\begin{figure}
+\vspace{3.7in}
+\caption{\label{photcooout} Output file from {\bf daofind}.}
+\end{figure}
+The file contains many lines of header, followed by the {\it x} and {\it
+y} center values, the magnitudes above the threshold value, the ``sharpness"
+and ``roundness" values, and finally an ID number.
+In the example shown
+here in Fig.~\ref{photcooout} two stars were found: one 2.9 mags
+brighter than our detection threshold, and one about 0.4 mag brighter
+than our detection threshold.
+
+In a few cases we doubtlessly found more than one star; this is a good
+time to get rid of the uninteresting non-standards in each field.
+If things went by too fast on the screen for you to take careful notes
+while running {\bf daofind} we can find these cases now: do a
+
+\centerline{ {\bf txdump *coo* image,id,x,y yes }}
+
+
+\noindent
+to get a listing of the location and number of stars found on each image.
+If you have cases where there were lots of
+detections (a dozen, say) you may find it easier to first {\bf sort
+*.coo* mag} in order to resort the stars in each file by how bright they
+are. Of course, your standard may not be the brightest star in each
+field; you may want to keep an eye on the {\it x} and {\it y} values to
+see if it is the star you thought you were putting in the middle!
+To get rid of the spurious stars you will need to {\bf edit} each of the
+output files (e.g., {\bf edit std148.imh.coo.1} ) and simply delete the
+extras.
+
+Finally we can run aperture photometry on these frames, using the
+``.coo" files to locate the standard star in each frame. {\bf epar
+phot} until it resembles that of Fig.~\ref{photphot}.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{photphot} The parameter file for a run of {\bf phot}.}
+\end{figure}
+Note that we are specifying a {\it single} output file name
+(``standstuff" in this example); {\it all} the photometry output will be
+dumped into this single file, including things like the airmass and filter
+number. Go ahead and execute {\bf phot}.
+You should see something much like that of Fig.~\ref{photrun} on the
+screen.
+\begin{figure}
+\vspace{5.5in}
+\caption{\label{photrun} Running {\bf phot} non-interactively
+on the standard stars.}
+\end{figure}
+We will discuss the output below under ``Examining the results".
+
+\subsubsection{Photometry by Eye}
+In this section we will discuss the case of selecting stars {\it
+without}
+running the automatic star-finding program, using the image display
+window and the cursor. The first step is to {\bf epar phot} so it
+resembles that of Fig.~\ref{photeye}.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{photeye} Parameter file for {\bf phot} when stars will
+be selected interactively.}
+\end{figure}
+Note that we have replaced the {\bf coords} coordinate list with the
+null string (two adjacent double-quotes) and turned ``interactive" on.
+
+We need to display the frame we are going to work on in the imtool
+window:
+
+\centerline { {\bf display std145 1} }
+
+\noindent
+will display image {\bf std145.imh} in the first frame buffer.
+
+Now let's run {\bf phot}. We are not likely to be {\it too} accurate
+with where we place the cursor, so to be generous we will increase the
+allowable center shift to 3 pixels; otherwise we will get error messages
+saying that the ``shift was too large":
+
+\centerline{ {\bf phot std145 maxshift=3.} }
+
+\noindent
+(Note that even though {\bf maxshift} is a parameter of {\bf centerpars}
+we can change it on the command line for {\bf phot}.) Also note that we
+left off the ``{\bf .imh}" extension for a reason: we are going to take
+the default names for the output files, and they will be given names
+such as {\bf std145.mag.1} and so on. If we had included the {\bf .imh}
+extension would would now be getting {\bf std145.imh.mag.1} names.
+
+At this point I get a flashing circle in my {\bf imtool} window; I don't
+know what you get (it depends upon how your defaults are set up) but
+there should be some sort of obvious marker on top of your image.
+Put it on the first star you wish to measure and hit the space bar. The
+coordinates and magnitude should appear in the {\bf gterm} window, and
+you are ready to measure the next star on this frame. Proceed until all
+the stars on this frame are measured, and then type a ``q" followed by
+another ``q". Display the next frame, and run {\bf phot} on it.
+
+When you get done you will have kerjillions of files.
+
+\subsection{Examining the Results: the power of {\bf txdump }}
+
+Depending upon which of the two methods you selected you will either
+have a single file {\bf standstuff} containing the results of all your
+aperture photometry, or you will have a file for each frame ({\bf
+stand145.mag.1}, {\bf stand146.mag.1} \ldots)containing the stars
+on each frame. In either event the file will pretty much resemble that
+shown in Fig.~\ref{photphotout}.
+\begin{figure}
+\vspace{7.5in}
+\caption{\label{photphotout} Output file from {\bf phot}.}
+\end{figure}
+The file begins with a large header describing the parameters in
+force at the time that {\bf phot} was run. There is, however, a real
+subtlety to this statement. If you had changed a parameter in {\bf
+datapars}, say, (or any of the other parameters) between running {\bf
+daofind} and {\bf phot}, the header in {\bf phot} will reflect only the
+setting that was in force at the time that {\bf phot} was run---in other
+words, it does not take the values of what was used for the {\bf
+threshold} from the coordinate file and retain these, but instead simply
+copies what value of {\bf thresh} happens to be in {\bf datapars} at the
+time that {\bf phot} is run. To those used to the
+``self-documenting" feature of VMS DAOPHOT this is a major change!
+
+Once we get past the header information we find that there are 5 lines
+per star measured. The ``key" to these five lines of information are
+found directly above the measurement of the first star. On the first
+line we have ``general information" such as the
+image name, the beginning x and y values, the id,
+and the coordinate file. On the next line we have all the centering
+information: the computed x and y centers,
+the x and y shift, and any centering errors. On the third line of the
+file we have information about the sky. On the fourth line we have some
+information out of the image header: what was the integration time, what
+was the airmass, and what was the filter. Note
+that {\bf phot} has used that integration time in producing the
+magnitude---the exposures are now normalized to a 1.0 sec exposure.
+The fifth line gives the actual photometry, including the size of the
+measuring aperture, the total number of counts within the aperture, the
+area of the aperture, and the output magnitude, photometric error, and
+any problems encountered (such as a bad pixel within the aperture).
+
+We can extract particular fields from this file (or files) by using the
+{\bf txdump} command. For instance, are there any cases where there
+there were problems in the photometry? We can see those by saying
+
+\centerline{\bf txdump standstuff image,id,perror}
+
+\noindent
+(If you did ``Photometry by eye" you can substitute {\bf *mag*} for {\bf
+standstuff}.)
+When it queries you for the ``boolean expression" type
+
+\centerline{ {\bf perror!$=$"No\_error"} }
+
+\noindent
+The ``!$=$" construction is IRAF-ese for "not equal to"; therefore, this
+will select out anything for which there was some problem in the
+photometry.
+
+We can create a single file at this point containing just the
+interesting results from the photometry file(s): do a
+
+\centerline{ {\bf txdump standstuff
+image,id,ifilt,xair,mag,merr yes $>$ standsout} }
+
+\noindent
+to dump the image name, id-number, filter, airmass, magnitude,
+and magnitude error into a file {\bf standsout}. (Again, if you did
+``Photometry by Eye" substitute {\bf *mag*} for {\bf standstuff}).
+Unfortunately, what you do with this file is up to you right now until
+the standard reductions routines become available. In the example shown
+here we have selected the fields in the same order as used in Peter
+Stetson's VMS CCDCAL software, and at the end of this manual we will
+describe a (painful) kludge that nevertheless {\it will} let you use
+these numbers with that software.
+
+\section{Crowded Field Photometry: IRAF/daophot}
+\subsection{Historical Summary}
+
+In the beginning (roughly 1979) astronomers
+interested in obtaining photometry from stars in ``relatively" crowded fields
+would make the journey to Tucson in order to use Doug Tody's RICHFLD
+program which ran on the IPPS display system.
+RICHFLD allowed the user to define a
+point-spread-function (PSF), and then fit this PSF to the brightest star
+in a group, subtract off this star, and then proceed to the next
+brightest star, etc. This represented a giant qualitative improvement
+over the possibilities of aperture photometry, and allowed stars
+separated by a few FWHM's to be accurately measured.
+
+Beginning in 1983, a group of RICHFLD users at the DAO (including
+Ed Olszewski and Linda Stryker) began modifications to the ``poorman"
+program of Jeremy Mould. This was largely motivated by the
+implementation of the ``Kitt Peak CCD" at the prime-focus of the Tololo
+4-m, and the idea was to design a crowded-field
+photometry
+program that (a) allowed simultaneous PSF-fitting, (b) made
+use of the {\it known noise characteristics of a CCD} to do the fitting
+in a
+statistically correct manner (i.e., to make ``optimal" use of the data),
+and (c) to be largely batch oriented.
+In mid-1983 Peter Stetson arrived at the DAO, and took over
+the effort. The result was
+DAOPHOT, which did all these things and more.
+By 1986 DAOPHOT was well distributed within the astronomical community.
+The basic algorithms and philosophy can be found in Stetson 1987 (PASP
+{\bf 99}, 111).
+
+DAOPHOT (and its companion program ALLSTAR) were not part of a
+photometry
+package; they were instead stand-alone Fortran
+programs which did not deal in any way with the issue of image display
+or what to do with the instrumental magnitudes once you had them. They
+were also only supported on VMS, although several ``frozen" versions
+were translated into UNIX by interested parties around the country.
+There was therefore
+much to be gained from integrating the algorithms of daophot
+with IRAF in order to make use of
+the image display capabilities and general tools for manipulating
+images. Also, since many astronomers were now reducing their CCD data
+with IRAF, it avoided the necessity of translating the IRAF files into
+the special format needed by VMS DAOPHOT. Dennis Crabtree began this
+translation program while at the DAO; it was taken over by Lindsey Davis
+of the IRAF group in early 1989, and taken to completion in early 1990.
+Pedro Gigoux of CTIO is currently hard at work on the photometry
+reduction package, scheduled for completion sometime during the spring.
+
+\subsection{{\bf daophot}
+Overview}
+The steps involved in running daophot are certainly more involved than
+in simple aperture photometry, but they are relatively straightforward.
+The following sections will lead you through the necessary procedures.
+Alternative routes will be noted at some points, and more may be gleaned
+from reading the various "help" pages. A general outline is given here
+so that you have some overview in mind; a detailed step-by-step summary
+is provided at the end of this section.
+
+\begin{itemize}
+\item Before you reduce the first frame, {\bf imexamine} your data to
+determine FWHM's and the radius at which the brightest star you wish to
+reduce blends into the sky. Run {\bf imhead} to find the ``key-words"
+in your data headers for exposure times, filter number, and airmass.
+Enter these, along with the characteristics of your chip (read-noise,
+photons per ADU, maximum good data value)
+into the parameter sets {\bf datapars} and {\bf
+daopars}.
+\item Use {\bf daofind} and {\bf tvmark}
+to produce a list of x and y positions of most
+stars on the frame.
+\item Use {\bf phot} to perform aperture photometry on the identified
+stars. This photometry will be the basis of the zero-point of
+your frame via the PSF stars. This is also the only point where sky
+values are determined for your stars.
+\item Use {\bf psf} to define the PSF for your frame. If your PSF stars are crowded this
+will require some iteration using the routines {\bf nstar} and {\bf
+substar}.
+\item Use {\bf allstar} to do simultaneous PSF-fitting for all the stars
+found on your frame, and to produce a subtracted frame.
+\item Use {\bf
+daofind} on the subtracted frame to identify stars that had been
+previously hidden.
+\item Run {\bf phot} {\it on the original frame} to obtain aperture photometry
+and sky values for the stars on the new list.
+\item Use {\bf append} to merge the two aperture photometry lists.
+\item Run {\bf allstar} again on the merged list.
+\end{itemize}
+When you have done this for your {\it U, B,} and {\it V} frames it is
+then time to
+\begin{itemize}
+\item Use {\bf txdump}, {\bf tvmark}, and the image display
+capabilities to come up with a consistent matching between the frames.
+If there are additions or deletions then you will need to re-run
+{\bf phot} and {\bf allstar} one more time.
+\end{itemize}
+Finally you will need to
+\begin{itemize}
+\item Determine the aperture correction for each frame by subtracting
+all but the brightest few isolated stars on your frames and then running
+{\bf phot} to determine the light lost between your zero-point aperture
+and the large aperture you used on your standard stars.
+\end{itemize}
+
+\subsection{How Big Is A Star: A Few Useful Definitions}
+
+The parameter files {\bf datapars} and {\bf daopars} contain three
+``size-like" variables, and although this document is not intended as
+a reference guide, there is bound to be confusion over these three
+parameters, particularly among those new to DAOPHOT. In the hopes
+of un-muddying the waters, we present the following.
+
+\begin{description}
+\item[fwhmpsf] This is the full-width at half-maximum of a stellar object
+(point-spread function, or psf). The value for {\bf fwhmpsf} gets used
+only by the automatic star-finding algorithm {\bf daophot}, unless you
+do something very bad like setting {\bf scale} to non-unity.
+
+\item[psfrad] This is the ``radius" of the PSF. When you construct a PSF,
+the PSF will consist of an array that is
+$$(2 \times psfrad +1) \times
+(2 \times psfrad + 1)$$
+on a side. The idea here is that ``nearly all" of the light of the brightest
+star you care about will be contained within this box. If you were to construct
+a PSF with some large value of {\bf psfrad} and then run {\bf nstar} or
+{\bf allstar}
+specifying
+a smaller value of {\bf psfrad}, the smaller value would be used. Making
+the {\bf psfrad} big enough is necessary to insure that the wings of some
+nearby bright star are properly accounted for when fitting a faint star.
+
+\item[fitrad] This is how much of the psf is used in making the fit
+to a star. The ``best" photometry will be obtained (under most circumstances)
+if this radius is set to something like the value for the fwhm.
+
+\end{description}
+
+\subsection{Setting up the parameter files ``daopars" and ``datapars" }
+
+The first step in using IRAF/daophot is to determine and store the
+characteristics of your data in two parameter files called ``datapars"
+and ``daopars"; these will be used by the various daophot commands.
+In Section 1 we discussed how to deal with parameter files, and
+in Section 2 we went through setting up ``datapars" for the standard
+star solutions; at the risk of repeating ourselves, we will go through
+this again as the emphasis is now a little different.
+
+
+First inspect your headers by doing an {\bf imhead} imagename {\bf long+
+$|$ page}.
+This will produce a listing similar to that shown in Fig.~\ref{newhead}.
+\begin{figure}
+\vspace{3.0in}
+\caption{\label{newhead}Header for image n602alu.imh.}
+\end{figure}
+The things to note here are (a) what the filter keyword is (we can
+see from Fig.~\ref{newhead} that the answer is F1POS; while there is
+an F2POS also listed, the second filter bolt was not used and was always
+in position ``zero"),
+(b) what the effective exposure
+time keyword is (EXPTIME in this example), and (c) what the effective
+airmass keyword is (AIRMASS in this example).
+
+Next you need to examine some ``typical" frames in order to determine
+the FWHM ({\bf fwhmpsf}) and the radius of the brightest star for which
+you plan to do photometry ({\bf psfrad}).
+First {\bf display} an image, and use the
+middle button of the mouse (or whatever you need to do on your image
+display) to zoom on a few bright stars. On the SUN the "F6" key will
+let you see x and y values. The ``default" PSF radius is 11 pixels:
+are your stars bigger than 23 pixels($23=2 \times 11 + 1$)
+pixels from one side to the other? The FWHM is undoubtably variable
+from frame to frame, but unless these change by drastic amounts (factors
+of two, say) using a ``typical" value will doubtless suffice. You can
+use the {\bf imexamine} routine to get some idea of the FWHM; do
+{\bf imexamine} filename and then strike the ``r" key (for radial
+profile) after centering the cursor on a bright (but unsaturated) star.
+The last number on the plot is the FWHM of the best-fit Gaussian.
+
+We are now ready to do an {\bf epar datapars}. This parameter file
+contains information which is data-specific. We set {\bf fwhmpsf} to the FWHM
+determined above, and we enter the names of the keywords determined from
+the header inspection above. The ``gain" and ``read-noise" are values
+you have either determined at the telescope (using the Tololo routines)
+or which are carved in stone for your chip. Choosing the value
+for datamax, the ``Maximum good data value",
+(in ADU's, NOT electrons) is a little bit trickier. In the case of
+aperture photometry we were satisfied to take the nominal value for
+the chip, but point-spread-function fitting is a bit more demanding
+in what's ``linear". The data obtained
+here was taken with an RCA chip, and we all know that RCA chips are
+linear well past 100,000 e-. Thus, naively, we would expect that
+with a gain of 2.25 that the chip was still linear when we hit the
+digitization limit of 32,767 ADU's. Subtract off 500 for the likely
+bias, and we {\it might} think that we were safe up to 32,200. However,
+we would be wrong. Experience with PSF fitting on these data shows that
+something (presumably in those little silver VEB's) has resulted in
+these data being non-linear above 20,000 ADU's. My suggestion here is
+to start with the nominal value but be prepared to lower it if the
+residuals from PSF fitting appear to be magnitude dependent (more on this
+later). The value for
+{\bf datamin}, the
+``Minimum good
+data value", will be different for each frame (depending what the sky
+level is) and there is not much point in entering a value for that yet.
+Similarly the value we will use for threshold will change
+from frame to frame depending upon what the sky level is.
+When you are done your {\bf datapars} should resemble that of
+Fig.~\ref{datapars}.
+\begin{figure}
+\vspace{2.7in}
+\caption{\label{datapars} A sample {\bf datapars} is shown.}
+\end{figure}
+
+Next we will {\bf epar daopars}. This parameter file contains
+information specific to what you want {\bf daophot} to do. The only things here
+we might want to change at this point are the ``Radius of the psf" {\bf psfrad}
+(if your experiment above showed it should be increased somewhat), and
+you might want to change the fitting radius {\bf fitrad}. Leaving the fitting
+radius to ``something like" the FWHM results in the best SNR (you can
+work this out for yourself for a few different regimes if you like to
+do integrals). The ``standard values" are shown in Fig.~\ref{daopars}.
+\begin{figure}
+\vspace{2.7in}
+\caption{\label{daopars} A sample {\bf daopars} is shown.}
+\end{figure}.
+
+\subsection{Finding stars: {\bf daofind} and {\bf tvmark} }
+The automatic star finder {\bf daofind} convolves a Gaussian of
+width FWHM with the image, and looks for peaks greater than some
+threshold in the smoothed image. It then keeps only the ones that are
+within certain roundness and sharpness criteria in order to reject
+non-stellar objects (cosmic rays, background galaxies, bad columns,
+fingerprints). We have already entered a reasonable value for the FWHM
+into {\bf datapars}, but what should we use as a threshold? We expect
+some random fluctuations due to the photon statistics of the sky
+and to the read-noise of the chip. You can calculate this easily by
+first
+measuring the sky value on your frame by
+using {\bf imexamine} and the ``h" key to produce a histogram of
+the data ({\bf implot} and the ``s" key is another way). In the example
+shown in Fig~\ref{hist} we see that the sky value is roughly 150.
+\begin{figure}
+\vspace{3.6in}
+\caption{\label{hist} The {\bf imexamine} histogram (``h" key) indicates
+that the sky value is roughly 150.}
+\end{figure}
+In general, if $s$ is the sky value in ADU, $p$ is the number of
+photons per ADU, and $r$ is the read-noise in units of electrons,
+then the expected $1\sigma$ variance in the sky
+will be
+$$\left(\sqrt{s\times p + r^2}\right)/p$$
+in units of ADU's. For the example here we expect
+$1\sigma=\left(\sqrt{150.\times 2.25 + 65^2}\right)/2.25=30$ ADU's.
+Of course, if you have averaged N frames in producing your image,
+then you should be using
+$N\times p$ as the gain both here and in the value entered in
+{\bf datapars}; similarly the readnoise is really just $r \times \sqrt{N}$.
+If instead you summed N frames then the gain is just {\it p} and the
+readnoise is still $r\times \sqrt{N}$.
+
+In the example shown here the expected $1\sigma$ variation of the sky is
+30 ADU's; we might therefore want to set our star detection threshold to
+3.5 times that amount. That won't guarantee that every last star we
+find is real, nor will it find every last real star, but it should do
+pretty close to that!
+
+We should use this opportunity to set datamin in {\bf
+datapars} to some value like $s-3\sigma$. In this case we will set it
+to 60. This is not currently used by {\bf daofind} but will be used
+by all the photometry routines. Fig.~\ref{ndatapars} shows the data
+parameters with the appropriate values of threshold and datamin now
+entered.
+\begin{figure}
+\vspace{3.0in}
+\caption{\label{ndatapars} Datapars with {\bf threshold} and {\bf datamin}
+entered.}
+\end{figure}
+
+We now can {\bf epar daofind} so it resembles that of
+Fig.~\ref{daofind}.
+\begin{figure}
+\vspace{3.0in}
+\caption{\label{daofind} Parameters for {\bf daofind}.}
+\end{figure}
+Note that although nothing appears to be listed under {\bf datapars} the
+default name is ``datapars"; you could instead have created a separate
+data parameter file for each ``type" of data you have and have called
+them separate names (you could do this by doing an {\bf epar datapars}
+and then exiting with a ``:w newnamepar"). This might be handy if
+all your {\it U} frames were averages, say, but your {\it B} and {\it V}
+frames were
+single exposures; that way you could keep track of the separate
+effective gain and readnoise values. In that case you would enter the
+appropriate data parameter name under {\bf datapars}. As explained earlier,
+you could also do a
+``:e" on the {\bf datapars} line and essentially do the {\bf epar datapars} from
+within the {\bf epar daofind}.
+For normal star images, the
+various numerical values listed are best kept exactly the way they are;
+if you have only football shaped images, then read the help page for
+{\bf daofind} for hints how best to find footballs.
+
+We can now run {\bf daofind} by simply typing {\bf daofind}.
+As shown in Fig.~\ref{daofind} that we were asked for the FWHM and threshold
+values; this is a due to having turned ``verify" on in the parameter
+set. This safeguards to a large extent over having forgotten to set
+something correctly. A [CR] simply takes the default value listed.
+
+Running {\bf daofind} produced an output file with the (default)
+filename of {\bf n602csb.coo.1}.
+(Do {\it not} give the {\bf .imh} extension
+when specifying the image name, or the default naming
+process will get very confused!) We can page
+through that and see the x and y centers, the number of magnitudes
+brighter than the cutoff, the sharpness and roundness values, and the
+star number. However, of more immediate use is to use this file
+to mark the found stars on the image display and see how we did.
+If we have already displayed the frame in frame 1, then we can {\bf epar
+tvmark} to make it resemble Fig.~\ref{tvmark}.
+\begin{figure}
+\vspace{2.7in}
+\caption{\label{tvmark} Parameter file for {\bf tvmark}.}
+\end{figure}
+This will put red dots on top of each star found.
+
+We can see from Fig.~\ref{dots} that {\bf daofind} did a pretty nice
+\begin{figure}
+\vspace{7.0in}
+\caption{\label{dots} Stars found with {\bf daofind} and marked with
+{\bf tvmark}.}
+\end{figure}
+job. If we didn't like what we saw at this point we could rerun
+{\bf daofind} with a slightly higher or slightly lower threshold---try
+varying the threshold by half a sigma or so if you are almost right.
+As you may have guessed, subsequent runs will produce output files with
+the names n602csb.coo.2, n602csb.coo.3,...
+If you are using a very slow computer, or are exceedingly impatient,
+ you could have saved some
+time by putting a ``c" (say) under ``convolv" in your first run of
+{\bf daofind}---this would have saved the
+smoothed image as cn602csb.imh, and would drastically reduce
+the number of cpu cycles needed to rerun {\bf daofind} with
+a different threshold value.
+If you really very happy with what {\bf daofind} did but you
+just want to add one or two stars at this point, you
+can in fact do that quite readily using {\bf tvmark}. Set the
+parameters as in Fig.~\ref{tvmark}, but turn interactive on.
+Position the cursor on top of the star you wish to add and strike
+the ``a" key. Note that this will ``disturb" the format of the file,
+but we really don't care; it will still work just fine as the input to
+{\bf phot}.
+
+Note that it is fairly important that you do a good job at this stage.
+If you have used too low a threshold, and have a lot of junk marked as
+stars, these fictitious objects are likely to wander around during the
+PSF-fittings until they find something to latch onto---{\it not} a good
+idea. However, you also do not want the threshold to be so high that
+you are missing faint stars. Even if you are not planning to publish
+photometry of these faint guys, you need to have included them in the
+list of objects if they are near enough to affect the photometry of
+stars for which you do have some interest. If you find that varying the
+threshold level does not result in a good list, then something is
+wrong---probably you have badly over- or under-estimated the FWHM.
+When you are close to the ``perfect" value of the threshold,
+changing its value by as little as half a sigma will make a substantial
+difference between getting junk and real stars.
+
+\subsection{Aperture Photometry with {\bf phot} }
+The next step is to do simple aperture photometry for each of the stars
+that have been found. These values will be used as starting points in
+doing the PSF fitting, and this is the only time that sky values will be
+determined.
+
+{\bf One of the few ways of ``crash landing" in the current
+implementation of the software is to forget to reset ``datamin" in the
+datapars file before running phot on a new frame. It is the only
+critical parameter which is not queried when verify is turned on. Therefore,
+this is a good time to check to see that ``datamin" is really set to
+several sigma lower than the sky value of this particular frame.}
+
+The aperture photometry routine {\bf phot} has more parameters than all
+the others put together: there are the parameter files
+{\bf centerpars}, {\bf fitskypars}, and {\bf photpars}.
+Fortunately the ``verify"
+option frees you from having to look at these, and helps prevent you
+from making a mistake. If this is your first pass through DAOPHOT it is
+worth your while to do the following:
+
+\centerline{ {\bf unlearn centerpars} }
+
+\centerline{ {\bf unlearn fitskypars} }
+
+\centerline{ {\bf unlearn photpars} }
+
+\noindent
+If you have used {\bf phot} for measuring standard stars, then this will
+reset the defaults to reasonable values for crowded-field photometry;
+in particular, we want to make sure that the centering
+algorithm in {\bf centerpars} is set to ``none".
+Do an {\bf epar phot} and make it look like that of Fig.~\ref{phot}.
+Since we have the ``verify" switch turned on, we can be happy, not
+worry, and simply type {\bf phot}.
+{\bf phot} will then prompt you as shown in
+Fig.~\ref{phot}.
+\begin{figure}
+\vspace{7.0in}
+\caption{\label{phot} Questions and answers with {\bf phot}.}
+\end{figure}
+Note that the answers were particularly simple: we told it the name of
+the frame we wished to work with, we accepted the default for the coordinate
+list (it will take the highest ``version" of image.coo.NUMBER) and the
+default for the output photometry list (n602csb.mag.1 will be produced
+in this case.) We accepted the centers from {\bf daofind} as being
+``good enough" to not have to recenter (they are good to about one-third
+of a pixel, plenty good enough for aperture sizes of 2.5 pixels and
+bigger; when we run this routine later on the second pass we would make
+a Big Mistake by turning centering on here, so leave it off).
+The sky
+values will be taken from an annulus extending from a radius of 10
+pixels to a radius of 20 pixels, and it will determine the standard
+deviation of the sky from the actual data. Note that this is probably a
+lot closer in than you used on your standard stars; in crowded regions
+of variable background keeping this annulus relatively close in will
+help.
+Finally, we used a measuring
+aperture of 3 pixels. The number of counts within this aperture will be
+what defines the zero-point of your frame, as we will see in Section 4.9,
+and keeping this value {\it fixed} to some value like your typical FWHM
+will keep you safe.
+
+\subsection{Making the PSF with {\bf psf} }
+
+If you are used to the VMS version of DAOPHOT, you are in for a pleasant
+surprise when it comes to making a PSF within the IRAF version.
+Nevertheless, just because it's easy doesn't mean that you shouldn't be
+careful.
+
+What constitutes a good PSF star? Stetson recommends that a good PSF
+star meets the following criteria:
+\begin{enumerate}
+\item No other star at all contributes any light within one fitting
+radius of the center of the candidate star. (The fitting radius will be
+something like the FWHM.)
+\item Such stars as lie near the candidate star are significantly
+fainter. (``Near" being defined as, say, 1.5 times the radius of the
+brightest star you are going to measure.)
+\item There are no bad columns or rows near the candidate star; there
+should also be no bad pixels near the candidate star.
+\end{enumerate}
+
+
+In making a PSF, you wish to
+construct a PSF which is free from bumps and wiggles (unless those
+bumps and wiggles are really what a single isolated star would look like.)
+First off, does it matter if we get the PSF ``right"? If we had
+only isolated stars, then the answer would be no---any
+old approximation to the PSF would give you
+good relative magnitudes, and there are programs in the literature
+which do exactly this. However, if your stars are relatively isolated
+you are not going to gain anything by PSF-fitting over aperture photometry
+anyway, so why bother? If you are dealing with crowded images, then the
+PSF has to be right {\it even in the wings}, and for that reason we
+construct a PSF empirically using the brightest and least crowded stars
+in our frame.
+If you are very, very
+lucky you will find that your brightest, unsaturated star is well
+isolated, and has no neighbors about it---if that's the case, use that
+one and forget about the rest. Usually, however, you will find that
+it isn't quite that easy, and it will be necessary to construct the PSF
+interatively. The steps involved will be
+\begin{enumerate}
+ \item Select the brightest, least-crowded stars for the zeroth-order
+ PSF.
+ \item Decrease the size of the PSF radius and fit these stars
+ with their neighbors using {\bf nstar}.
+ \item Subtract off the PSF stars and their neighbors using
+ {\bf substar} to see
+ if any of the PSF stars are ``funny"; if so, go back to
+ the step 1 and start over.
+ \item Edit the {\bf nstar} results file ({\bf imagename.nst.N})
+ and delete the entries for the PSF stars. You are left
+ with a file containing the magnitudes and positions of just
+ the neighbors.
+ \item Subtract off just the neighbors using this file as input
+ to {\bf substar}. Display
+ the results, and examine the region around each PSF star.
+ Are the neighbors cleanly removed?
+ \item Increase the PSF radius back to the original value.
+ Construct an improved PSF using the new frame (the one with the
+ neighbors gone.)
+ \item Run {\bf nstar} on the PSF stars and their neighbors again, and
+ again subtract these using {\bf substar}. Examine the results.
+ If you are happy, proceed; otherwise, if the neighbors need
+ to be removed a bit more cleanly go back to step 4.
+\end{enumerate}
+
+First {\bf display} the frame, and put dots on all the stars you've found
+using {\bf tvmark} as discussed above. Next {\bf epar psf} and make sure
+it looks like that of Fig.~\ref{psfparams}.
+\begin{figure}
+\vspace{2.5in}
+\caption{\label{psfparams} Parameter file for {\bf psf}}
+\end{figure}
+We have set this up so we can choose the stars interactively from the
+display window.
+
+Next run {\bf psf}. The defaults that you will be asked to {\bf verify}
+are probably fine, but pay particular attention to {\bf psf radius}
+and {\bf fitting radius}. The {\bf psf radius} should be as large
+as you determined above (11 usually works well on ``typical" CCD
+frames whose star images have FWHM's $\approx 3$). The ``fitting radius"
+should be relatively generous here---maybe even larger than what you
+want to use on your program stars. A reasonable choice is approximately
+that of the FWHM.
+
+You will find that the cursor has turned into a circle and is sitting
+on your image in the display window. Position it on a likely looking
+PSF star, and strike the ``a" key. You will be confronted with a mesh
+plot that shows the star and it surroundings. To find out more
+about the star (such as what the peak data value is you can type
+an ``s" while looking at the mesh plot. To reject the star type an
+``x", to accept the star type an ``o". In the latter case, you will
+next see a mesh plot that
+shows you the star with a two-dimensional Gaussian fit removed from the
+star.
+Again, exit this with a ``o". If you don't find these mesh
+plots particularly useful, you can avoid them by setting {\bf showplot=no}
+in the {\bf psf} parameters (see Fig.~\ref{psfparams}).
+At this point you will be told what the star number was, what the
+magnitude was, and what the minimum and maximum data values within
+the PSF were. (If you picked a star whose peak intensity was greater
+than ``datamax" it will tell you this and not let you use this star.)
+When you are done selecting stars, type a ``w" (to write the PSF to
+disk) followed by a ``q".
+
+If in making the PSF you noticed that there were stars you could have
+used but didn't because they had faint neighbors not found in the earlier
+step of star finding, you can add these by hand by simply
+running {\bf tvmark} interactively and marking the extra stars. First
+{\bf epar tvmark} so it resembles that of Fig.~\ref{tvmark}. Then:
+
+\centerline{ {\bf display n602csb 1} }
+
+\centerline{ {\bf tvmark 1 n602csb.coo.1 interactive+} }
+
+\noindent
+
+Striking the ``l" key will mark the stars it already knows about onto
+the display (as red dots this time around); positioning the cursor on the
+first star you wish to add and type an ``a". When you are done adding
+stars exit with a ``q" and re-run {\bf phot}.
+
+Now that you have made your preliminary PSF, do a {\bf directory}. You'll
+notice that in addition to the image {\bf n602csb.psf.1.imh} that the
+{\bf psf} routine has also added a text file {\bf n602csb.psg.1}. If
+you {\bf page} this file you will see something like that of Fig.~\ref{psg}.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{psg} The ``point spread function group" file
+{\bf n602csb.psg.1}}
+\end{figure}
+This contains the aperture photometry of each PSF star plus its neighbors,
+with each set constituting a ``group". Running the psf-fitting photometry
+routine {\bf nstar} will fit PSF's to each of the stars within a group
+simultaneously.
+
+Before we run {\bf nstar}, however, we must decide what psf radius to use.
+Why not simply keep it set to the value found above (e.g., something like 11
+pixels)? The answer to this is a bit subtle, but understanding it will
+help you diagnose what is going wrong when you find a PSF going awry (and
+don't worry, you will). Let's consider the case that you construct a PSF
+from a single star with one neighbor whose center is 12 pixels away from
+the center of the PSF star, and let's have the PSF radius be 11 and the PSF
+fitting radius be 3. The PSF looks something like that of Fig.~\ref{bump}.
+\begin{figure}
+\vspace{5.0in}
+\caption{\label{bump} The zeroth order PSF of a star with a neighbor 12 pixels
+away.}
+\end{figure}
+The light from the neighbor star ``spills
+over" into the PSF.
+
+What happens when you try to fit two PSF's simultaneously? The bump from the
+PSF of the brighter star sits within the fitting radius of the fainter star,
+and it is the sum of the PSF's which are being fit to each star (that's
+what ``simultaneous" means). Thus there is an ``implicit subtraction" of
+the fainter star simply from fitting the bumpy PSF to the brighter star,
+and the brightness of the fainter star will be underestimated. The way
+to avoid this is to see that the PSF of the brighter star does not come
+within the fitting radius of the fainter star, and {\it that} we can
+accomplish easily by truncating the PSF size to something like the separation
+of the two stars minus the fitting radius. Thus in the example here
+we would want to fit the two stars using PSF's that were only ($12-3=9$)
+pixels in radius. It's true that there may still be light of the PSF
+star beyond this radius, but that will matter only if the PSF star is still
+going strong when you get within the {\it fitting radius} of the fainter
+star.
+
+Now that we understand all that, run {\bf nstar}. Specify the appropriate
+image name for ``image corresponding to photometry" and give it
+the ``.psg" file {\bf n602csb.psg.1} for the ``input group file".
+Remember to decrease
+the {\bf psf radius} when it tries to verify that number. {\bf nstar}
+will produce a photometry output file {\bf n60csb.nst.1}.
+You can
+subtract the fitted PSF's from these stars now by running {\bf substar}.
+Again, {\bf verify} the PSF radius to the smaller value. When the routine
+finishes, {\bf display} the resultant frame {\bf n60csb.sub.1.imh} and
+take a look at the PSF stars...or rather, where the PSF stars (and their
+neighbors) were. Are they subtracted cleanly? Does one of the PSF
+stars have residuals that look the reverse of the residuals of the others?
+If so, it would be best to reconstruct the PSF at this point throwing out
+that star---possibly it has a neighbor hidden underneath it, or has something
+else wrong with it. Are the variations in the cores of the subtracted image
+consistent with photon statistics? To answer this you may want to play
+around with {\bf imexamine} on both the original and subtracted images,
+but if the stars have cleanly disappeared and you can't even tell where
+they were, you are doing fine.
+
+The worst thing to find at this point
+is that there is a systematic pattern with position on the chip. This
+would indicate that the PSF is variable. There is the option for making
+a variable PSF, but the assumption is that the PSF varies smoothly in x
+and
+y; usually this is not the case. (In the case of the non-flat TI chips
+the variations are due to the potato-chip like shape.) If you {\it do}
+decide the PSF is variable, be sure to use plenty of stars in making the
+PSF. As it says in the ``help page",
+twenty-five to thirty is then not an unreasonable number. If that
+doesn't scare you off, nothing will.
+
+If the brightest stars have residuals that are systematically different than
+those of the fainter stars, maybe that chip wasn't quite as linear as you
+thought, or perhaps there are charge transfer problems. This proved to
+be the case for the RCA CCD data being reduced here. In Fig.~\ref{yuko}
+we show the residuals that result when we based our PSF on a star whose
+peak counts were 30000 ADUs.
+Empirically we found that stars with peaks of 18K ADUs (a mere 40K electrons)
+were safe to use, with the result that the dynamic range of our data
+was simply not quite as advertised. Although the PSF function broke down
+above 18K, the chip remained ``linear" in the sense that aperture photometry
+continued to give good results---the total number of counts continued to
+scale right up to the A/D limit of 32,767 ADUs (72K electrons after bias
+is allowed for). This appears to be a subtle charge transfer
+\begin{figure}
+\vspace{7.0in}
+\caption{\label{yuko} A ``before" and ``after" pair of images, where the
+PSF was constructed with a star that was too bright. Note the systematic
+residuals for the two bright stars. A ``bad" PSF star would result in a
+similar effect; however, in these data we found that there was always a
+systematic effect if the PSF stars were about 18000 ADU.}
+\end{figure}
+problem.
+
+We will assume that you have gotten the PSF to the point where
+the cores of the stars disappear cleanly, although there may be residuals
+present due to the neighbors. Our next step is to get rid of these neighbors
+so that you can make a cleaner PSF. Edit the {\bf nstar} output file
+{\bf n602csb.nst.1} and delete the lines associated with the PSF stars,
+leaving only the neighbors behind. You can recognize the PSF stars, as
+they are the first entry in each group. When you are done with this
+editing job, re-run {\bf substar}, using the edited ``.nst" file as the
+photometry file. Again in running {\bf substar} make sure you {\bf verify}
+the PSF radius to the smaller value you decided above. Examine the results
+on the image display. Now the PSF stars should be there but the neighbors
+should be cleanly subtracted. Are they? If so, you are ready to proceed.
+If not, re-read the above and keep at it until you get those neighbors
+reasonably well out of the frame.
+
+We can now run {\bf psf} on the subtracted frame---the one with only the
+neighbors gone. We have added some noise by doing the subtraction, and
+so we should reset {\bf datamin} to several sigma below the previously
+used
+value. We are going to have to do more typing this time when
+we run it, as the defaults for things will get very confused when we
+tell it that the ``Image for which to build PSF" is actually
+{\bf n60csb.sub.1}. For the ``Aperture photometry file" we can tell
+it the original photometry file {\bf n602csb.mag.1} if we want, or
+even the old ``.psg" file {\bf n602csb.psg.1} since every star that
+we are concerned about (PSF star plus neighbor) is there. Go ahead
+and give it the next `version" number for the ``Output psf image"
+{\bf n602csb.psf.2} and for the ``Output psf group file"
+{\bf n602csb.psg.2}.
+We can of course do this all on the command line:
+
+\centerline{ {\bf psf n602csb.sub.1 n602csb.mag.1 n602csb.psf.2
+n602csb.psg.2 datamin=-150.} }
+
+\noindent
+An example is shown in Fig.~\ref{psf1}.
+{\it This time make sure you take the
+large psf radius.}
+\begin{figure}
+\vspace{7.0in}
+\caption{\label{psf1} Making the first revision PSF using the frames with the
+neighbors subtracted. Compare this to Fig. 23, which shows the
+same region before the neighbors have been removed.}
+\end{figure}
+Make a new PSF using the cursor as before.
+
+How good is this revised PSF? There's only one way to find out: run
+{\bf nstar} on the original frame, this time keeping the psf radius large.
+Then do {\bf substar} and examine the frame with both the PSF stars and
+neighbors subtracted. Does this show a substantial improvement over the
+first version? Now that you have a cleaner PSF it may be necessary to repeat
+this procedure (edit the {\bf n602csb.nst.2} file, remove the PSF stars,
+run {\bf substar} using this edited file to produce a frame with the
+just the neighbors subtracted this time using a better PSF, run {\bf psf}
+on this improved subtracted frame) but probably not.
+
+\subsection{Doing the psf-fitting: {\bf allstar}.}
+The next step is to go ahead and run simultaneous PSF-fitting on all
+your stars, and produce a subtracted frame with these stars removed.
+To do both these things you need only run {\bf allstar}. The defaults
+are likely to be right: see Fig.~\ref{allstar}.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{allstar} Running {\bf allstar}.}
+\end{figure}
+As you may imagine, {\bf allstar} produces a photometry file
+{\bf n602csb.als.1}, and another subtracted image: {\bf imagename.sub.N}.
+
+Display the subtracted frame, and blink it against the original. Has
+IRAF/daophot done a nice job? If the stars are clearly gone with a few
+hidden ones now revealed, you can be proud of yourself---if the results
+are disappointing, there is only one place to look, and that is in the
+making of the PSF. Assuming that all is well, it is now time to
+add those previously hidden stars into the photometry.
+The easiest way to do this is to run {\bf daofind} on the subtracted
+image.
+Set the value of {\bf datamin} to a value several sigma lower
+than what you had used earlier in case the subtraction process generated
+some spuriously small values, and you will want to {\it increase} the
+value of threshold by 1 or 2 sigma above what you used previously.
+Why? Because the subtraction process has certainly added noise to the
+frame, and if you don't do this you will be mainly adding spurious
+detections. Use {\bf tvmark} as before to examine the results of {\bf
+daofind}; remember that the coordinate file name will be
+{\bf imagename.sub.N.coo.1} this time around. If you are really close,
+but want to add a couple of stars, re-run {\bf tvmark} on this file
+using
+{\bf interactive+}; this will allow you to add (and delete) coordinates
+from the file.
+
+Now run {\bf phot} using this new coordinate file as the input list.
+However, you do want to use the {\it original} frame for this photometry;
+otherwise the sky values for the newly found stars will be very messed
+up owing to the many subtracted images. A new aperture photometry file
+{\bf n602csb.mag.2} will have been produced. Use {\bf append} to
+concatenate these two files: {\bf append n602csb.mag.1,n602csb.mag.2
+n602csb.mag.3}. You can now re-run {\bf allstar} using this combined
+photometry file as the input.
+
+\subsection{Matching the frames}
+In the example here we have been reducing the {\it B} frame of
+a set of {\it UBV}. Once all three frames have been reduced it is often
+necessary to do a little fiddling. Have the same stars been identified
+in each group? In many cases you don't want the same stars to have been
+identified in each clump---afterall, some stars are red, some are blue
+(that's presumably why you are doing this afterall, right?), but in some
+cases you may find that a clump was identified as three objects on the
+{\it U} and the {\it V} frames and clearly should have been three on the
+{\it B} frame but instead is four or two. What to do?
+
+Using {\bf tvmark} it is relatively easy to set this right. First we
+need to use {\bf txdump} to produce a file for each frame that can be
+displayed. Do something like an
+
+\centerline{ {\bf txdump n602csu.als.2 $>$ tvu}}
+
+\noindent
+followed by an
+
+\centerline{ {\bf txdump n602csb.als.2 $>$
+tvb}}
+
+\noindent
+and a
+
+\centerline{ {\bf
+txdump n602csv.als.2 $>$ tvv}}
+
+\noindent
+In each case select {\bf xc,yc} and use
+{\bf MAG!=INDEF} as a selection criteria. Thus you will then have three text
+files that contain only the x's and y's of the stars with photometry.
+
+Next display the three frames ({\bf display n602csu 1}, {\bf display
+n602csb 2}, {\bf display n602csv 3}) and put colored dots up to denote
+the different allstar stars:
+
+\centerline{ {\bf tvmark 1 tvu color=204 inter-},}
+
+\centerline{
+{\bf tvmark 2 tvb color=205 inter-},}
+
+\noindent
+and
+
+\centerline{ {\bf tvmark 3 tvv color=206
+inter-}}
+
+\noindent
+will give pleasing results. Zoom, pan, register, and blink
+around the frames until you are convinced that you really do want to
+add or delete a star here or there. If you want to add or delete a star to the
+{\it U} frame list, do a
+
+\centerline{ {\bf tvmark 1 tvu color=203 inter+}}
+
+\noindent
+You are
+now in interactive mode, and centering the cursor on the star you want
+to add and striking the ``a" key will append the x and y value of the
+cursor the tvu list. Similarly, striking the ``u" key
+will delete a star from the list if you are using IRAF v2.9 or later.
+(For earlier versions you are just going to have to do a little
+editing by hand, good luck!) The star you add or delete will have
+a white dot appear on top of it.
+If you need to switch to a different coordinate file, simply exit the
+interactive {\bf tvmark} with a ``q" and re-execute it specifying, for
+example, {\bf tvmark 3 tvv color=203 inter+}.
+
+When you are done with adding and deleting stars, then it is time to
+redo the photometry. Do a {\bf phot n602csu coords=tvv datamin=100}
+in order to generate new aperture photometry and sky values. These
+can then be run through {\bf allstar}, and the procedure repeated for
+each
+of the frames.
+
+\subsection{Determining the Aperture Correction}
+
+The zero-point of your magnitudes have been set as follows. When you
+ran {\bf phot} using a small aperture (3 pixels in the example above)
+magnitudes were defined as -2.5 * log{(Counts above sky)/(Exposure
+time)} + Const.
+(The constant Const was hidden away in {\bf photpars} and is the
+magnitude assigned to a star that had a total of one ADU per second
+within the measuring aperture you used.) When you defined your PSF the
+magnitudes of the PSF stars determined from the aperture photometry were
+then used to set the zero-point of the PSF. However, your standard
+stars were presumably measured (if you did things right) through a much
+larger aperture, and what we must do now is measure how much brighter
+the PSF would have been had its zero-point been tied to the same size
+aperture used for the standard stars.
+
+We need to determine the aperture correction from the brightest,
+unsaturated stars (so there will still be reasonable signal above sky
+at the size of the large aperture); if you can pick out stars that are
+reasonably well isolated, so much the better. If this sounds vaguely
+familiar to you, you're right---this is basically what you did for
+selecting PSF stars, and these would be a good starting point for
+selecting stars for determining the aperture correction. Ideally you
+would like to use at least five such stars, but since when is data
+reduction ideal? Nevertheless, it is in the determination of the
+aperture correction the largest uncertainty enters in doing CCD
+photometry on crowded fields.
+
+We will first need to pick out the brightest, isolated stars and then
+to subtract off any stars that might affect their being measured through
+the large ``standard star" aperture (e.g., something like 15 pixels).
+To do this we need good photometry of any of these neighbor stars, and
+we describe two ways to do this (1) the very long complicated way, and
+(2) the very short easy way:
+
+\begin{enumerate}
+
+\item {\bf Method 1: Using the image display}
+We can also use {\bf tvmark} to mark the stars that we wish to use for
+aperture photometry. First we should remind ourselves what are multiple
+stars and what aren't: {\bf display} the image, and then use {\bf
+tvmark} to mark the stars with {\bf allstar} photometry:
+
+\centerline{ {\bf display n602csb 1} }
+
+\centerline{ {\bf txdump n602csb.als.2 xc,yc yes $>$ tvb} }
+
+\centerline{ {\bf tvmark 1 tvb color=204 interact-} }
+
+\noindent
+Now go through and mark the stars you want to use as the aperture
+correction stars {\it plus any neighbors that might contribute light
+to a large aperture centered on the bright stars:}
+
+\centerline{ {\bf tvmark 1 bapstars color=203 interact+ }}
+
+\noindent
+Use the ``a" key to generate a list ({\bf bapstars}) of the approximate
+{\it x} and {\it y} positions of these stars. Next run this list
+through {\bf phot} to generate improved centers and good sky values:
+
+\centerline{ {\bf phot n602csb bapstars bapphot calgor=``centroid" } }
+
+\noindent
+Next run the photometry output file {\bf bapphot} through {\bf group}:
+
+\centerline{ {\bf group n602csb bapphot default default crit=0.2} }
+
+\noindent
+This will have generated a ``group" file {\bf n602csb.grp.1}.
+
+\noindent
+Finally (!) run this group file through {\bf nstar}:
+
+\centerline{ {\bf nstar n602csb default default default} }
+
+\item {\bf Method 2: Using the ``.psg" files}
+If you used a goodly number ($>3-5$, say) stars in
+making the PSF, then we will simply use these stars as the aperture
+correction stars. Your last {\bf nstar} run should have produced an
+``{\bf .nst}" file that contains good photometry for the PSF stars {\it
+and} their neighbors. (If you don't remember if you did this, run {\bf
+nstar} using the ``{\bf .psg}" as the input group file.) Note that this
+method relies upon the assumption that the sum of the psf radius and psf
+fitting radius is about as large as the size of the large aperture you
+will use, so that all the important neighbors have been included in the
+point-spread-function group, but this is probably a reasonable
+assumption.
+
+\end{enumerate}
+
+Now that we are done with the preliminaries (!!),
+we now want to produce two files: one of them containing only the
+neighbors that we wish to subtract off, and another containing only the
+bright isolated stars which we want to use in computing the aperture
+correction. To do this we will use {\bf group} to divide up the ``{\bf
+.nst}" file (we could simply use the editor but that would be a lot of
+work). First we will use {\bf txdump} on the {\bf nstar} file to see the magnitude
+range covered by the PSF stars and their neighbors: hopefully there
+won't be any overlap. To do this try
+
+\centerline{ {\bf txdump n602csb.nst.3 id,group,mag yes} }
+
+\noindent
+In the example shown in Fig.~\ref{grouping} we see that the PSF stars
+\begin{figure}
+\vspace{2.0in}
+\caption{\label{grouping} The three PSF stars and their groups.}
+\end{figure}
+have magnitudes of 13.9, 15.0, and 16.5 in the three groups; all the
+neighbor stars are fainter than 17.0. Thus we can use {\bf select}
+to create a file containing the
+photometry of the faint stars:
+
+\centerline{ {\bf select n602csb.nst.3 n602csbsub} }
+
+\noindent
+and answer {\bf MAG$>$17.0} when you are queried for the ``Boolean
+expression". This will put the photometry of the stars you wish to get
+rid of into the file {\bf n602csbsub}. Next do an
+
+\centerline{ {\bf txdump n602csb.nst.3 xc,yc $>$ n602csbap} }
+
+\noindent
+and answer {\bf MAG$<$17.0} in response to ``Boolean expression". This
+will put the {\it x} and {\it y} values of the stars we wish to use for
+the aperture correction into the file
+{\bf n602csbap}. Next subtract the stars in the first file:
+
+\centerline{ {\bf substar n602csb n602csbsub} }
+
+\noindent and accept the defaults. This will result in the subtracted
+image {\bf n602csb.sub.N}. It is this file on which we wish to run
+the aperture photometry to determine the aperture correction:
+
+\centerline{
+{\bf phot n602csb.sub.N n602csbap n602csbapresults apertures=3.,15. annulus=20. dannu=5.} }
+
+\noindent
+You will see something like Fig.~\ref{apcor1} on your terminal.
+In this example we've made the assumption that the aperture size that
+set your zero-point in making the PSF was 3 pixels (i.e., what you used
+with {\bf phot} Way Back When), and that the aperture size used on your
+standard stars was 15 pixels.
+\begin{figure}
+\vspace{3.0in}
+\caption{\label{apcor1} The aperture correction run of {\bf phot}.}
+\end{figure}
+It is time to drag out your hand calculator. Using all three stars we
+find an average aperture correction of $-0.371$ with a standard
+deviation of the mean of 0.012 mag; given the large range in magnitude,
+I might have been tempted to ignore the two fainter stars and keep the
+aperture correction based only upon the brightest star (the frame is
+sparsely populated, and there isn't a whole heck of a lot else we can
+do). By an amazing coincidence, the aperture correction based just on
+the brightest star is also $-0.371$.
+
+
+\subsection{{\bf daophot} summary}
+\begin{itemize}
+\item Set up {\bf datapars} and {\bf daopars}.
+ \begin{enumerate}
+ \item Do an {\bf imhead} on some image and note the keywords for the
+ filter position, the effective exposure time, and the effective
+ airmass.
+ \item Use {\bf display} and {\bf imexamine} on a few frames to
+ determine the typical full-width-half-max
+ of stars and what would be a good
+ value to use for the radius of the psf (i.e., what radius will
+ contain the brightest star for which you wish to do photometry.)
+ \item Enter these into {\bf daopars} (psfrad) and {\bf datapars}
+ (header key words, fwhm). Also check that the correct values
+ are entered in {\bf datapars} for the gain (photons per ADU)
+ and read-noise (in electrons), as well as the ``maximum good data
+ value".
+ \end{enumerate}
+\item Find stars.
+ \begin {enumerate}
+ \item Do an {\bf implot} or {\bf imexamine} to determine the sky
+ level on your frame. Calculate the expected $1\sigma$ error.
+ \item Enter the sky value minus 3$\sigma$ as your value for
+ {\bf datamin} in {\bf datapars}.
+ \item Run {\bf daofind} using as a threshold value 3 to 5 $\sigma$.
+ \item Use {\bf tvmark} to mark the stars found ({\bf imagename.coo.1}).
+ If you need to, rerun {\bf daofind} with a larger or small
+ threshold.
+ \end {enumerate}
+\item Run aperture photometry using {\bf phot}.
+\item Generate a PSF. Run {\bf psf} and add stars using the ``a" key. Try
+ to select bright, uncrowded stars. Then:
+ \begin {enumerate}
+ \item Run {\bf nstar} using the file {\bf imagename.psg.1} as the
+ ``input photometry group" file. If there are neighbors, be sure
+ to decrease the psf radius as explained above.
+ Run {\bf substar} (also using the smaller sized psf radius)
+ and display the
+ resultant subtracted frame {\bf imagename.sub.1}. Do the residuals
+ of the PSF stars look consistent, or is one of them funny? If need
+ be, start over.
+ \item Remove any neighbor stars by editing the PSF stars out of the
+ ``.nst" file, and rerunning {\bf substar}. Run
+ {\bf psf} on the subtracted file, using the normal psf radius again.
+ You will have to over-ride the defaults for the input and output file
+ names now that you are using the subtracted image. Rerun {\bf nstar}
+ on the original frame using the normal psf radius and the revised
+ PSF. Run {\bf substar} and display the results. Are the PSF stars
+ nicely removed, and do the areas around the PSF stars look clean?
+ It may be necessary to remove neighbors again using this revised
+ PSF.
+ \end {enumerate}
+\item Run {\bf allstar}. Display the subtracted frame and see if your stars
+ have been nicely subtracted off.
+\item Run {\bf daofind} on the subtracted frame, using a value for
+ {\bf threshold} which is another $\sigma$ or two larger than before,
+ and a value for {\bf datamin} which is several $\sigma$ lower than
+ before. Use {\bf tvmark} to examine the results, and if need be
+ run {\bf tvmark} interactively so that you may add any extra stars.
+\item Run aperture photometry using {\bf phot} {\it on the original frame},
+ using the new coordinate list produced above.
+\item {\bf append} the two aperture photometry files.
+\item Run {\bf allstar} using the combine photometry file.
+\item Repeat all of the above for each frame in your ``set" (e.g., all short
+ and long exposures in each filter of a single field, say.
+\item Use {\bf txdump} to select the stars from the allstar files which
+ have magnitudes not equal to ``INDEF". Mark these stars using
+ {\bf tvmark}, and then use the capabilities of the image display
+ and {\bf tvmark} to match stars consistently from frame to frame.
+ Rerun {\bf phot} and {\bf allstar} on the final coordinate lists.
+\item Determine the aperture corrections.
+\item Transform
+ to the standard system (see the next section) and then
+ publish the results.
+\end{itemize}
+\section{Transforming to the Standard System}
+
+This section will eventually tell you how to easily and painless obtain
+the transformation equations for going from your instrumental magnitudes
+to the standard system, and how to apply these transformation equations
+to your program fields. Unfortunately, the IRAF routines for doing this
+are still under construction.
+In the meanwhile, we are providing here a kludge solution that can be
+used by initiates of Stetson's VMS CCDCAL routines. If you haven't been
+made a member of the club yet, and don't feel like waiting until the
+IRAF routines are become available before you get results, then I would
+recommend getting a hold of the good Dr. Stetson and bribing him until he
+offers to send you a copy of CCDCAL. There is an excellent manual that
+comes along with it, and we will not attempt to repeat any of that
+material here.
+
+\subsection{Standard Star Solution}
+First we will describe how to get output good enough to fool
+the CCDCAL software into believing the photometry was produced by CCDOBS
+(for the standard magnitudes), and what modifications need to be made
+to CCDSTD.FOR
+
+On the standard file do a {\bf txdump standstuff lid,ifilt,xair,mag,merr
+$>$ foolit} to dump the star number, filter number, airmass, and
+instrumental magnitudes and errors into the file {\bf foolit}.
+Unfortunately, you are now going to have to edit this file and stick in
+the star name (in what ever form you have it in creating the library of
+standard stars with CCDLIB) in place of the image name and star ID.
+(These were simply placed in the file to help guide you). While you are
+at it, line up the filter numbers, airmasses, and magnitudes into nice,
+neat columns. When you get done, stick in a line at the top that gives
+the number of instrumental magnitudes and their names, using a
+i1,13x,n(6x,a6) format. For instance, in the case shown here there
+are 3 instrumental magnitudes, U, B, and V. Finally, the filter numbers
+have to be edited so they agree with these (e.g., they must denote
+instrumental magnitude 1, 2, and 3...now aren't you sorry you didn't
+decide to wait until the IRAF routines were finished?). In
+Fig~\ref{groan} we show an example of the ``before" and ``after" file.
+\begin{figure}
+\vspace{3.5in}
+\caption{\label{groan}The output of {\bf txdump} and the final file
+ready for {\bf ccdstd}. Note the switching of the filter number ``5"
+with ``1".}
+\end{figure}
+
+CCDOBS.FOR itself now needs to be modified. Search for line statement
+``1120" (which will say JSTAR=JSTAR+1). Add a line that sets the
+integration time to 1 (tint=1.). Modify the READ statement as shown
+in Fig.~\ref{ccdobs}, and finally modify the 213 FORMAT statement
+so it actually matches your data file.
+\begin{figure}
+\vspace{2.5in}
+\caption{\label{ccdobs} Modifications to CCDOBS.FOR}
+\end{figure}
+You should now be able to compile, link, and run this modified
+version of CCDOBS and have it work on your standard star data.
+
+\subsection{Program Stars}
+The work required for faking ``CCDCAL" is actually a lot less. The data
+files are easily produced. Do a
+
+\centerline{{\bf txdump n602csu.als.2
+id,xc,yc,mag,merr,nit,chi $>$ csu} }
+
+\centerline{{\bf txdump n602csb.als.2 id,xc,yc,mag,merr,nit,chi $>$
+csb}}
+
+\centerline{{\bf txdump n602csv.als.2 id,xc,yc,mag,merr,nit,chi $>$
+csv}}
+
+\noindent
+answering {\bf MAG!=INDEF} to ``boolean expression" each time.
+These three files ({\bf csu}, {\bf csb}, {\bf csv} can be used
+with CCDCAL once a single modification is made to CCDCAL.FOR: on
+statement number 2020 change the format to ``free format", e.g.,
+2020 IF(NL(IOBS).NE.2) READ(2,*,END=2040). When CCDCAL queries
+you for an integration time, be sure to tell it 1.0, as your data have
+already been corrected for exposure times.
+
+\section{Acknowledgements}
+We are grateful to Jeannette Barnes and Carol Neese for critical
+readings of this document, although final blame for style and content
+of course rests with the authors.
+\end{document}
diff --git a/noao/digiphot/daophot/doc/userdocs/daoref.ms b/noao/digiphot/daophot/doc/userdocs/daoref.ms
new file mode 100644
index 00000000..6ef3d1f6
--- /dev/null
+++ b/noao/digiphot/daophot/doc/userdocs/daoref.ms
@@ -0,0 +1,6290 @@
+.LP
+\0
+.de XS
+.DS
+.ps -1
+.vs -1p
+.ft CB
+..
+.de XE
+.DE
+.ft R
+.ps
+.vs
+..
+.de YS
+.nf
+.ps -1
+.vs -1p
+.ft CB
+..
+.de YE
+.fi
+.ft R
+.ps
+.vs
+..
+.RP
+.TL
+A Reference Guide to the IRAF/DAOPHOT Package
+.AU
+Lindsey E. Davis
+.AI
+IRAF Programming Group
+.K2
+.ce
+.TU
+.br
+.ce
+January 1994
+.AB
+.PP
+DAOPHOT is a software package for doing stellar photometry in crowded stellar
+fields
+developed by Peter Stetson (1987) of the Dominion Astrophysical
+Observatory. IRAF/DAOPHOT uses the task structure and
+algorithms of DAOPHOT to do crowded-field stellar photometry within the
+IRAF data reduction and analysis environment.
+.PP
+This document briefly describes the principal similarities and differences
+between DAOPHOT and IRAF/DAOPHOT, the data preparation required to
+successfully use IRAF/DAOPHOT, how to examine and edit the IRAF/DAOPHOT
+algorithm parameters, how to run the IRAF/DAOPHOT package tasks interactively,
+non-interactively, or in the background, and how to examine
+and perform simple database operations on the output photometry files.
+.PP
+This document is
+intended as a reference guide to the details of using and
+interpreting the results of IRAF/DAOPHOT not a user's cookbook or a general
+guide to doing photometry in IRAF. Its goal is to take the user
+from a fully reduced image of a crowded stellar field to aperture
+corrected instrumental magnitudes using a small artificial image as a
+sample data set.
+First time IRAF/DAOPHOT users
+should consult \fIA User's Guide to Stellar Photometry With IRAF\fR, by
+Phil Massey and Lindsey Davis. Detailed descriptions of the DAOPHOT photometry
+algorithms can be found in Stetson (1987, 1990, 1992).
+.AE
+.ds CH
+.bp
+\0
+.bp
+.PP
+.na
+.LP
+\fBContents\fP
+.sp 1
+1.\h'|0.4i'\fBIntroduction\fP\l'|5.6i.'\0\01
+.sp
+2.\h'|0.4i'\fBDAOPHOT and IRAF/DAOPHOT\fP\l'|5.6i.'\0\01
+.sp
+3.\h'|0.4i'\fBPreparing Data for DAOPHOT\fP\l'|5.6i.'\0\03
+.sp
+4.\h'|0.4i'\fBSome IRAF Basics for New IRAF and DAOPHOT Users\fP\l'|5.6i.'\0\04
+.br
+.sp
+\h'|0.4i'4.1.\h'|0.9i'\fBPre-loaded Packages\fP\l'|5.6i.'\0\04
+.br
+\h'|0.9i'4.1.1.\h'|1.5i'The DATAIO Package\l'|5.6i.'\0\05
+.br
+\h'|0.9i'4.1.2.\h'|1.5i'The PLOT Package\l'|5.6i.'\0\05
+.br
+\h'|0.9i'4.1.3.\h'|1.5i'The IMAGES Package\l'|5.6i.'\0\05
+.br
+\h'|0.9i'4.1.4.\h'|1.5i'The TV Package\l'|5.6i.'\0\05
+.br
+\h'|0.4i'4.2.\h'|0.9i'\fBOther Useful Packages and Tasks\fP\l'|5.6i.'\0\05
+.br
+\h'|0.4i'4.3.\h'|0.9i'\fBImage Types, Image Directories, and Image Headers\fP\l'|5.6i.'\0\05
+.br
+\h'|0.4i'4.4.\h'|0.9i'\fBThe Image Display and Image Cursor\fP\l'|5.6i.'\0\06
+.br
+\h'|0.4i'4.5.\h'|0.9i'\fBThe Graphics Device and Graphics Cursor\fP\l'|5.6i.'\0\07
+.sp
+5.\h'|0.4i'\fBSome DAOPHOT Basics for New DAOPHOT Users\fP\l'|5.6i.'\0\08
+.br
+.sp
+\h'|0.4i'5.1.\h'|0.9i'\fBLoading the DAOPHOT Package\fP\l'|5.6i.'\0\08
+.br
+\h'|0.4i'5.2.\h'|0.9i'\fBLoading the TABLES Package\fP\l'|5.6i.'\0\08
+.br
+\h'|0.4i'5.3.\h'|0.9i'\fBRunning the Test Script\fP\l'|5.6i.'\0\08
+.br
+\h'|0.4i'5.4.\h'|0.9i'\fBOn-line Help\fP\l'|5.6i.'\0\09
+.br
+\h'|0.4i'5.5.\h'|0.9i'\fBEditing the Package Parameters\fP\l'|5.6i.'\010
+.br
+\h'|0.4i'5.6.\h'|0.9i'\fBEditing the Task Parameters\fP\l'|5.6i.'\011
+.br
+\h'|0.4i'5.7.\h'|0.9i'\fBInput and Output Image Names\fP\l'|5.6i.'\011
+.br
+\h'|0.4i'5.8.\h'|0.9i'\fBInput and Output File Names\fP\l'|5.6i.'\012
+.br
+\h'|0.4i'5.9.\h'|0.9i'\fBAlgorithm Parameter Sets\fP \l'|5.6i.'\012
+.br
+\h'|0.4i'5.10.\h'|0.9i'\fBInteractive Mode and Non-Interactive Mode\fP \l'|5.6i.'\014
+.br
+\h'|0.4i'5.11.\h'|0.9i'\fBImage and Graphics Cursor Input\fP\l'|5.6i.'\014
+.br
+\h'|0.4i'5.12.\h'|0.9i'\fBGraphics Output\fP\l'|5.6i.'\015
+.br
+\h'|0.4i'5.13.\h'|0.9i'\fBVerify, Update, and Verbose\fP\l'|5.6i.'\015
+.br
+\h'|0.4i'5.14.\h'|0.9i'\fBBackground Jobs\fP\l'|5.6i.'\015
+.br
+\h'|0.4i'5.15.\h'|0.9i'\fBTiming Tests\fP\l'|5.6i.'\016
+.sp
+6.\h'|0.4i'\fBDoing Photometry with DAOPHOT\fP\l'|5.6i.'\016
+.br
+.sp
+\h'|0.4i'6.1.\h'|0.9i'\fBThe Test Image\fP\l'|5.6i.'\016
+.br
+\h'|0.4i'6.2.\h'|0.9i'\fBTypical Analysis Sequence\fP\l'|5.6i.'\017
+.br
+\h'|0.4i'6.3.\h'|0.9i'\fBCreating and Organizing an Analysis Directory\fP\l'|5.6i.'\019
+.br
+\h'|0.4i'6.4.\h'|0.9i'\fBReading the Data\fP \l'|5.6i.'\019
+.br
+\h'|0.4i'6.5.\h'|0.9i'\fBEditing the Image Headers\fP\l'|5.6i.'\019
+.br
+\h'|0.9i'6.5.1.\h'|1.5i'The Minimum Image Header Requirements\l'|5.6i.'\019
+.br
+\h'|0.9i'6.5.2.\h'|1.5i'The Effective Gain and Readout Noise\l'|5.6i.'\019
+.br
+\h'|0.9i'6.5.3.\h'|1.5i'The Maximum Good Data Value\l'|5.6i.'\021
+.br
+\h'|0.9i'6.5.4.\h'|1.5i'The Effective Exposure Time\l'|5.6i.'\022
+.br
+\h'|0.9i'6.5.5.\h'|1.5i'The Airmass, Filter Id, and Time of Observation\l'|5.6i.'\022
+.br
+\h'|0.9i'6.5.6.\h'|1.5i'Batch Header Editing\l'|5.6i.'\024
+.br
+\h'|0.4i'6.6.\h'|0.9i'\fBEditing, Checking, and Storing the Algorithm Parameters\fP\l'|5.6i.'\024
+.br
+\h'|0.9i'6.6.1.\h'|1.5i'The Critical Algorithm Parameters\l'|5.6i.'\024
+.br
+\h'|0.9i'6.6.2.\h'|1.5i'Editing the Algorithm Parameters Interactively with Daoedit \l'|5.6i.'\024
+.br
+\h'|1.5i'6.6.2.1.\h'|2.2i'The Data Dependent Algorithm Parameters \l'|5.6i.'\025
+.br
+\h'|1.5i'6.6.2.2.\h'|2.2i'The Centering Algorithm Parameters\l'|5.6i.'\028
+.br
+\h'|1.5i'6.6.2.3.\h'|2.2i'The Sky Fitting Algorithm Parameters\l'|5.6i.'\029
+.br
+\h'|1.5i'6.6.2.4.\h'|2.2i'The Aperture Photometry Parameters\l'|5.6i.'\029
+.br
+\h'|1.5i'6.6.2.5.\h'|2.2i'The Psf Modeling and Fitting Parameters\l'|5.6i.'\030
+.br
+\h'|1.5i'6.6.2.6.\h'|2.2i'Setting the Algorithm Parameters Graphically\l'|5.6i.'\031
+.br
+\h'|0.9i'6.6.3.\h'|1.5i'Checking the Algorithm Parameters with Daoedit\l'|5.6i.'\031
+.br
+\h'|0.9i'6.6.4.\h'|1.5i'Storing the Algorithm Parameter Values with Setimpars\l'|5.6i.'\032
+.br
+\h'|0.9i'6.6.5.\h'|1.5i'Restoring the Algorithm Parameter Values with Setimpars\l'|5.6i.'\032
+.br
+\h'|0.4i'6.7.\h'|0.9i'\fBCreating a Star List\fP\l'|5.6i.'\032
+.br
+\h'|0.9i'6.7.1.\h'|1.5i'The Daofind Task\l'|5.6i.'\033
+.br
+\h'|1.5i'6.7.1.1.\h'|2.2i'The Daofind Algorithm\l'|5.6i.'\033
+.br
+\h'|1.5i'6.7.1.2.\h'|2.2i'The Daofind Algorithm Parameters\l'|5.6i.'\033
+.br
+\h'|1.5i'6.7.1.3.\h'|2.2i'Running Daofind Non-Interactively\l'|5.6i.'\034
+.br
+\h'|1.5i'6.7.1.4.\h'|2.2i'Running Daofind Interactively\l'|5.6i.'\034
+.br
+\h'|1.5i'6.7.1.5.\h'|2.2i'The Daofind Output\l'|5.6i.'\036
+.br
+\h'|1.5i'6.7.1.6.\h'|2.2i'Examining the Daofind Output\l'|5.6i.'\037
+.br
+\h'|0.9i'6.7.2.\h'|1.5i'Rgcursor and Rimcursor\l'|5.6i.'\038
+.br
+\h'|0.9i'6.7.3.\h'|1.5i'User Program\l'|5.6i.'\039
+.br
+\h'|0.9i'6.7.4.\h'|1.5i'Modifying an Existing Coordinate List\l'|5.6i.'\039
+.br
+\h'|0.4i'6.8.\h'|0.9i'\fBInitializing the Photometry with Phot\fP\l'|5.6i.'\039
+.br
+\h'|0.9i'6.8.1.\h'|1.5i'The Phot Algorithm\l'|5.6i.'\039
+.br
+\h'|0.9i'6.8.2.\h'|1.5i'The Phot Algorithm Parameters\l'|5.6i.'\040
+.br
+\h'|0.9i'6.8.3.\h'|1.5i'Running Phot Non-interactively\l'|5.6i.'\040
+.br
+\h'|0.9i'6.8.4.\h'|1.5i'Running Phot Interactively\l'|5.6i.'\042
+.br
+\h'|0.9i'6.8.5.\h'|1.5i'The Phot Output\l'|5.6i.'\043
+.br
+\h'|0.9i'6.8.6.\h'|1.5i'Examining the Results of Phot\l'|5.6i.'\044
+.br
+\h'|0.4i'6.9.\h'|0.9i'\fBCreating a Psf Star List with Pstselect\fP\l'|5.6i.'\044
+.br
+\h'|0.9i'6.9.1.\h'|1.5i'The Pstselect Algorithm\l'|5.6i.'\045
+.br
+\h'|0.9i'6.9.2.\h'|1.5i'The Pstselect Algorithm Parameters\l'|5.6i.'\045
+.br
+\h'|0.9i'6.9.3.\h'|1.5i'How Many Psf Stars Should Be Selected ?\l'|5.6i.'\046
+.br
+\h'|0.9i'6.9.4.\h'|1.5i'Running Pstselect Non-interactively\l'|5.6i.'\047
+.br
+\h'|0.9i'6.9.5.\h'|1.5i'Running Pstselect Interactively\l'|5.6i.'\047
+.br
+\h'|0.9i'6.9.6.\h'|1.5i'The Pstselect Output\l'|5.6i.'\048
+.br
+\h'|0.9i'6.9.7.\h'|1.5i'Examining and/or Editing the Results of Pstselect\l'|5.6i.'\048
+.br
+\h'|0.4i'6.10.\h'|0.9i'\fBComputing the Psf Model with Psf\fP\l'|5.6i.'\049
+.br
+\h'|0.9i'6.10.1.\h'|1.5i'The Psf Algorithm\l'|5.6i.'\049
+.br
+\h'|0.9i'6.10.2.\h'|1.5i'Choosing the Appropriate Analytic Function\l'|5.6i.'\050
+.br
+\h'|0.9i'6.10.3.\h'|1.5i'The Analytic Psf Model\l'|5.6i.'\050
+.br
+\h'|0.9i'6.10.4.\h'|1.5i'The Empirical Constant Psf Model\l'|5.6i.'\051
+.br
+\h'|0.9i'6.10.5.\h'|1.5i'The Empirical Variable Psf Model\l'|5.6i.'\051
+.br
+\h'|0.9i'6.10.6.\h'|1.5i'Rejecting Bad Data from the Psf Model\l'|5.6i.'\051
+.br
+\h'|0.9i'6.10.7.\h'|1.5i'The Model Psf Psfrad and Fitrad\l'|5.6i.'\052
+.br
+\h'|0.9i'6.10.8.\h'|1.5i'Modeling the Psf Interactively Without a Psf Star List\l'|5.6i.'\052
+.br
+\h'|0.9i'6.10.9.\h'|1.5i'Fitting the Psf Model Interactively Using an Initial Psf Star List\l'|5.6i.'\054
+.br
+\h'|0.9i'6.10.10.\h'|1.5i'Fitting the Psf Model Interactively Without an Image Display\l'|5.6i.'\055
+.br
+\h'|0.9i'6.10.11.\h'|1.5i'Fitting the Psf Model Non-interactively\l'|5.6i.'\056
+.br
+\h'|0.9i'6.10.12.\h'|1.5i'The Output of Psf\l'|5.6i.'\057
+.br
+\h'|0.9i'6.10.13.\h'|1.5i'Checking the Psf Model\l'|5.6i.'\059
+.br
+\h'|0.9i'6.10.14.\h'|1.5i'Removing Bad Stars from the Psf Model\l'|5.6i.'\062
+.br
+\h'|0.9i'6.10.15.\h'|1.5i'Adding New Stars to a Psf Star Group\l'|5.6i.'\062
+.br
+\h'|0.9i'6.10.16.\h'|1.5i'Refitting the Psf Model With the New Psf Star Groups\l'|5.6i.'\062
+.br
+\h'|0.9i'6.10.17.\h'|1.5i'Computing the Final Psf Model\l'|5.6i.'\063
+.br
+\h'|0.9i'6.10.18.\h'|1.5i'Visualizing the Psf Model with the Seepsf Task\l'|5.6i.'\063
+.br
+\h'|0.9i'6.10.19.\h'|1.5i'Problems Computing the Psf Model\l'|5.6i.'\064
+.br
+\h'|0.4i'6.11.\h'|0.9i'\fBDoing Psf Fitting Photometry with Peak, Nstar, or Allstar\fP \l'|5.6i.'\065
+.br
+\h'|0.9i'6.11.1.\h'|1.5i'Fitting Single Stars with Peak\l'|5.6i.'\065
+.br
+\h'|1.5i'6.11.1.1.\h'|2.2i'The Peak Algorithm\l'|5.6i.'\065
+.br
+\h'|1.5i'6.11.1.2.\h'|2.2i'Running Peak \l'|5.6i.'\065
+.br
+\h'|1.5i'6.11.1.3.\h'|2.2i'The Peak Output\l'|5.6i.'\066
+.br
+\h'|0.9i'6.11.2.\h'|1.5i'Fitting Stars with Group, Grpselect, Nstar and Substar\l'|5.6i.'\067
+.br
+\h'|1.5i'6.11.2.1.\h'|2.2i'The Group and Nstar Algorithms\l'|5.6i.'\067
+.br
+\h'|1.5i'6.11.2.2.\h'|2.2i'Running Group, Grpselect, and Nstar\l'|5.6i.'\068
+.br
+\h'|1.5i'6.11.2.3.\h'|2.2i'The Nstar Output\l'|5.6i.'\070
+.br
+\h'|0.9i'6.11.3.\h'|1.5i'Fitting Stars With Allstar\l'|5.6i.'\071
+.br
+\h'|1.5i'6.11.3.1.\h'|2.2i'The Allstar Algorithm\l'|5.6i.'\071
+.br
+\h'|1.5i'6.11.3.2.\h'|2.2i'Running Allstar\l'|5.6i.'\072
+.br
+\h'|1.5i'6.11.3.3.\h'|2.2i'The Allstar Output\l'|5.6i.'\073
+.br
+\h'|0.4i'6.12.\h'|0.9i'\fBExamining the Output Photometry Files\fP\l'|5.6i.'\073
+.br
+\h'|0.4i'6.13.\h'|0.9i'\fBProblems with the Photometry\fP\l'|5.6i.'\074
+.br
+\h'|0.4i'6.14.\h'|0.9i'\fBDetecting Stars Missed By Daofind\fP\l'|5.6i.'\075
+.br
+\h'|0.4i'6.15.\h'|0.9i'\fBInitializing the Missing Star Photometry with Phot\fP\l'|5.6i.'\075
+.br
+\h'|0.4i'6.16.\h'|0.9i'\fBMerging Photometry Files with Pfmerge\fP\l'|5.6i.'\076
+.br
+\h'|0.4i'6.17.\h'|0.9i'\fBRefitting the Stars with Allstar\fP\l'|5.6i.'\076
+.br
+\h'|0.4i'6.18.\h'|0.9i'\fBExamining the Subtracted Image\fP\l'|5.6i.'\076
+.br
+\h'|0.4i'6.19.\h'|0.9i'\fBComputing an Aperture Correction\fP\l'|5.6i.'\076
+.sp
+7.\h'|0.4i'\fBReferences\fP\l'|5.6i.'\077
+.sp
+8.\h'|0.4i'\fBAppendices\fP\l'|5.6i.'\077
+.br
+.sp
+\h'|0.4i'8.1.\h'|0.9i'\fBThe Instrumental Magnitude Scale\fP\l'|5.6i.'\077
+.br
+\h'|0.4i'8.2.\h'|0.9i'\fBThe Analytic Psf Models\fP\l'|5.6i.'\077
+.br
+\h'|0.4i'8.3.\h'|0.9i'\fBThe Error Model\fP\l'|5.6i.'\078
+.br
+\h'|0.4i'8.4.\h'|0.9i'\fBThe Radial Weighting Function\fP\l'|5.6i.'\078
+.br
+\h'|0.4i'8.5.\h'|0.9i'\fBTotal Weights\fP\l'|5.6i.'\078
+.br
+\h'|0.4i'8.6.\h'|0.9i'\fBBad Data Detection\fP\l'|5.6i.'\078
+.br
+\h'|0.4i'8.7.\h'|0.9i'\fBStellar Mergers\fP\l'|5.6i.'\079
+.br
+\h'|0.4i'8.8.\h'|0.9i'\fBFaint Stars\fP\l'|5.6i.'\079
+.br
+.bp
+\0
+.ds CH - % -
+.bp 1
+\0
+
+.TL
+A Reference Guide to the IRAF/DAOPHOT Package
+.AU
+Lindsey E. Davis
+.AI
+IRAF Programming Group
+.K2
+.ce
+.TU
+.br
+.ce
+January 1994
+
+.NH
+Introduction
+
+.PP
+DAOPHOT is a software package for doing stellar photometry
+in crowded fields developed by Peter Stetson of the DAO (1987, 1990, 1992).
+The IRAF/DAOPHOT package uses the task structure and algorithms of DAOPHOT
+to do crowded field photometry within the IRAF data reduction and
+analysis environment.
+.PP
+Input to IRAF/DAOPHOT consists of an IRAF image file, numerous parameters
+controlling the analysis algorithms and, optionally, graphics cursor and/or
+image display cursor input. IRAF/DAOPHOT produces output photometry files
+in either text format or STSDAS binary table format. Some IRAF/DAOPHOT tasks
+also produce image output and graphics output in the form of plot metacode
+files.
+.PP
+Separate tasks are provided for examining, editing, storing, and recalling
+the analysis parameters, creating and editing star
+lists, computing accurate centers, sky values and initial magnitudes
+for the stars in the list, computing the point-spread function,
+grouping the stars into physical associations, fitting the stars either
+singly or in groups, subtracting the fitted stars from the original image,
+and adding artificial test stars to the original image. A set of tools are
+also provided for examining and editing the output photometry files.
+
+.NH
+DAOPHOT and IRAF/DAOPHOT
+
+.PP
+The principal similarities and differences between DAOPHOT and IRAF/DAOPHOT
+are summarized below.
+.IP [1]
+The structure of IRAF/DAOPHOT is very similar to the
+structure of DAOPHOT. All the DAOPHOT photometry tasks and many of
+the utilities tasks are present in
+IRAF/DAOPHOT and in many cases the DAOPHOT task names have been preserved.
+A listing of the DAOPHOT photometry tasks and their closest IRAF/DAOPHOT
+equivalents is shown below.
+
+.TS
+l l
+l l
+l l.
+DAOPHOT\tIRAF/DAOPHOT
+TASK\tEQUIVALENT
+
+add*\taddstar
+allstar\tallstar
+attach\tN/A
+append\tpfmerge,pconcat
+find\tdaofind
+group\tgroup
+monitor\tdaophot.verbose=yes
+nomonitor\tdaophot.verbose=no
+nstar\tnstar
+offset\tpcalc
+options\tdaoedit
+peak\tpeak
+photometry\tphot
+pick\tpstselect
+psf\tpsf
+select\tgrpselect
+sort\tpsort,prenumber
+sub*\tsubstar
+.TE
+
+.IP [2]
+Some DAOPHOT utilities tasks are missing from IRAF/DAOPHOT.
+The DAOPHOT tasks \fBdump\fR, \fBexit\fR, \fBfudge\fR,
+\fBhelp\fR, \fBlist\fR, and \fBsky\fR
+have been replaced with general IRAF tasks, or with IRAF system facilities
+that perform the equivalent function. The missing DAOPHOT utilities tasks
+and their IRAF equivalents are shown below.
+
+.TS
+l l
+l l
+l l.
+DAOPHOT\tIRAF/DAOPHOT
+TASK\tEQUIVALENT
+
+dump\tlistpixels,imexamine
+exit\tbye
+fudge\timreplace,fixpix,imedit
+help\thelp daophot
+list\timheader
+sky\timstatistics,phistogram,imexamine
+.TE
+
+.IP [3]
+The IRAF/DAOPHOT default algorithms are the DAOPHOT II algorithms
+(Stetson 1992).
+.IP [4]
+Users have more choice of and control over the algorithms
+in IRAF/DAOPHOT than they do in DAOPHOT. For example the
+IRAF/DAOPHOT aperture photometry task \fBphot\fR offers several
+sky fitting algorithms besides the default "mode" algorithm,
+and full control over the sky fitting algorithm parameters.
+.IP [5]
+The algorithm parameters in IRAF/DAOPHOT are grouped by function into
+six parameter sets or psets rather than three as in DAOPHOT.
+The six IRAF/DAOPHOT parameter sets with their DAOPHOT equivalents
+in brackets are:
+1) \fBdatapars\fR, the data definition parameters (daophot.opt),
+2) \fBfindpars\fR, the detection algorithm parameters (daophot.opt),
+3) \fBcenterpars\fR, the aperture photometry centering algorithm parameters
+(no equivalent),
+4) \fBfitskypars\fR, the aperture photometry sky fitting parameters (photo.opt),
+5) \fBphotpars\fR, the aperture photometry parameters (photo.opt),
+6) \fBdaopars\fR, the IRAF/DAOPHOT psf fitting parameters (daophot.opt,
+allstar.opt).
+.IP [6]
+The IRAF/DAOPHOT algorithm parameter sets unlike the DAOPHOT parameter sets
+can be interactively examined,
+edited and saved with the \fBdaoedit\fR task using the image display
+and radial profile plots.
+.IP [7]
+The IRAF/DAOPHOT algorithm parameter sets unlike the DAOPHOT parameter sets
+can be saved and restored as a function of image using the \fBsetimpars\fR task.
+.IP [8]
+Memory allocation in IRAF/DAOPHOT is dynamic not static as in
+DAOPHOT. IRAF/DAOPHOT allocates and frees memory as required
+at run-time subject to the physical memory and swap space limitations of
+the host computer.
+.IP [9]
+The IRAF/DAOPHOT point-spread function look-up table is stored in an
+IRAF image not an ASCII table as in DAOPHOT.
+.IP [10]
+Unlike DAOPHOT, the IRAF/DAOPHOT tasks \fBdaofind\fR, \fBphot\fR,
+\fBpstselect\fR
+and \fBpsf\fR can be run interactively using the image display and graphics
+window or non-interactively. Display and graphics capabilities were
+deliberately omitted from DAOPHOT to minimize portability problems.
+.IP [11]
+The IRAF/DAOPHOT output photometry files can be written in either text
+format as in DAOPHOT or STSDAS binary table format.
+.IP [12]
+Unlike DAOPHOT, fields or columns in both IRAF/DAOPHOT text and
+STSDAS binary table photometry files are identified
+by name and have an associated units and format specifier.
+The IRAF/DAOPHOT photometry file input routines search for column
+names, for example "GROUP,ID,XCENTER,YCENTER,MAG,MSKY" as
+appropriate but are independent
+of their placement in the input file.
+.IP [13]
+Several general purpose IRAF/DAOPHOT tasks are available for performing
+operations on the final output photometry catalogs. In addition to
+\fBpcalc\fR, \fBpconcat\fR, \fBpfmerge\fR, \fBprenumber\fR,
+and \fBpsort\fR which are
+also available in DAOPHOT, there are three photometry file editing tasks which
+have no analog in DAOPHOT \fBpdump\fR, \fBpexamine\fR, and \fBpselect\fR.
+All these tasks work on IRAF/DAOPHOT output text files or STSDAS binary
+tables. An IRAF/DAOPHOT task is supplied for converting output text files to
+STSDAS binary tables so as to make use of the even more general STSDAS
+tables manipulation tools in the TABLES package.
+.IP [14]
+The IRAF/DAOPHOT output files are self-documenting.
+All the information required to comprehend the history of or decode the
+output photometry file is in the file itself, including the IRAF version
+number, host computer, date, time, and names of all the
+input and output files and the values of all the parameters.
+.PP
+For the remainder of this document IRAF/DAOPHOT will be referred to
+as DAOPHOT.
+
+.NH
+Preparing Data for DAOPHOT
+
+.IP [1]
+DAOPHOT assumes that the images to be analyzed exist on disk in IRAF
+image format. DAOPHOT can read and write old IRAF format ".imh" images
+and ST IRAF format ".hhh" images.
+When the IRAF FITS kernel becomes available DAOPHOT will be able
+to read FITS images on disk as well.
+QPOE IRAF format ".qp" images must be rasterized before they can
+be input to DAOPHOT.
+.IP [2]
+All internal DAOPHOT calculations are done in real precision.
+The pixel type of the image data on disk may be any of the following
+data types: short integer, unsigned short integer, integer, long integer,
+real or double. Users should realize that the extra precision in
+images of type double will not be used by DAOPHOT.
+.IP [3]
+The instrumental signature must be removed from the input images
+prior to running DAOPHOT. All CCD images should be overscan
+corrected, bias corrected, dark current corrected and flat-fielded.
+Users should be aware of the IRAF CCDRED package for reducing CCD data.
+.IP [4]
+DAOPHOT assumes that the input pixel data is linear.
+If the data is non-linear over a large fraction of its total dynamic range,
+the data must be linearized before running DAOPHOT.
+.IP [5]
+Saturated pixels or pixels distinguishable from good data by intensity,
+do not need to be removed from the image prior to running DAOPHOT.
+For example if the data
+is non-linear only above 25000 counts, DAOPHOT can be instructed to
+ignore pixels above 25000 counts.
+.IP [6]
+Extreme-valued pixels should be removed from the images prior to running
+DAOPHOT. Extreme-valued pixels include those with values at or near
+the floating point limits of the host machine and host machine special
+numbers produced by operations like divide by zero, floating point
+underflows and overflows, etc. The latter category of extreme-valued
+pixels should not be produced by IRAF software, but may be produced by
+user programs including imfort programs.
+Floating point operations involving such numbers will frequently cause
+arithmetic exception errors, since for efficiency and portability reasons
+the DAOPHOT package and most IRAF tasks do not test for
+their presence.
+The \fBimreplace\fR task in the PROTO package can be used to remove extreme-
+valued pixels.
+.IP [7]
+The background sky value should NOT be subtracted from the image prior
+to entering the DAOPHOT package. The DAOPHOT fitting routines use an optimal
+weighting scheme which depends on the readout noise, the gain, and the
+true counts in the pixels. If the mean sky has been subtracted
+then the counts in the image are not the true counts and the computed weights
+will be incorrect. For similar reasons users should not attempt to
+correct their magnitudes for exposure time by dividing their images
+by the exposure time.
+.IP [8]
+Cosmic ray and bad pixel removal programs should be used with caution. If the
+data and parameter values are set such that the cosmic ray and bad pixel
+detection and
+removal algorithms have difficulty distinguishing between stars and bad
+pixels or cosmic rays,
+the peaks of the stars may be clipped, altering the point-spread function
+and introducing errors into the photometry.
+.IP [9]
+DAOPHOT assumes that the local sky background is approximately flat in the
+vicinity of the object being measured. This assumption is equivalent to
+requiring that the local sky region have a unique mode. Variations
+in the sky background which occur on the same scale as the size of the
+local sky region will introduce errors into the photometry.
+.IP [10]
+The point spread function must be constant or smoothly
+varying with position over the entire image. This is the fundamental
+assumption
+underlying all of DAOPHOT. All stars in the image must be indistinguishable
+except for position and magnitude. The variable point spread function
+option is capable of handling second order variability as a function of
+position in the image.
+.IP [11]
+The input images should not have undergone any operations which fundamentally
+alter the image point spread function or the image statistics in a non-linear
+way. For example, non-linear image restoration tasks must not be run on
+the image to prior to running DAOPHOT.
+.IP [12]
+The gain, readout noise, exposure time,
+airmass, filter, and observing time should be present and correct in the
+image headers before DAOPHOT reductions are begun.
+DAOPHOT tasks can extract this information from the image headers, use it
+in the computations, and/or store
+it in the output photometry files, greatly simplifying the analysis
+and subsequent calibration procedures.
+.fi
+
+.NH
+Some IRAF Basics for New IRAF and DAOPHOT Users
+
+.NH 2
+Pre-loaded Packages
+
+.PP
+Under IRAF versions 2.10 and later the DATAIO, PLOT, IMAGES, TV and NOAO
+packages are pre-loaded so that all the tasks directly under them are
+available when
+IRAF is started. Each of these packages contains tasks which are useful
+to DAOPHOT users for various reasons, and each is discussed briefly below.
+
+.NH 3
+The DATAIO Package
+
+.PP
+DAOPHOT users should be aware of the DATAIO \fBrfits\fR and \fBwfits\fR tasks
+which are used to transport data into and out of IRAF. Any input
+and output images, including point-spread function look-up table images,
+should normally be archived with \fBwfits\fR.
+The cardimage reader and writer tasks for archiving text files,
+\fBrcardimage\fR and \fBwcardimage\fR, are also located here.
+
+.NH 3
+The PLOT Package
+
+.PP
+Various general purpose image and file plotting utilities can be found
+in the PLOT packages. DAOPHOT users should be aware of the interactive image
+row and column plotting task \fBimplot\fR, the image contour plotting task
+\fBcontour\fR, the image surface plotting task \fBsurface\fR, image
+histogram plotting task \fBphistogram\fR, the image radial profile
+plotting task \fBpradprof\fR, and the general purpose graphing tool
+\fBgraph\fR. The tasks \fBgkidir\fR and \fBgkiextract\fR are also useful
+for extracting individual plots from the plot metacode files which may
+be produced by some DAOPHOT tasks.
+
+.NH 3
+The IMAGES Package
+
+.PP
+The IMAGES package contains a set of general purpose image operators. DAOPHOT
+users
+should be aware of the image header examining tasks \fBimheader\fR and
+\fBhselect\fR, the header editing task \fBhedit\fR, the coordinate and
+pixel value dumping task \fBlistpixels\fR, and the image statistics
+task \fBimstatistics\fR.
+
+.NH 3
+The TV Package
+
+.PP
+The TV package contains tasks which interact with the image display including
+the all important \fBdisplay\fR task for displaying images, the
+interactive image examining task \fBimexamine\fR, and the \fBtvmark\fR task
+for marking objects on the image display. DAOPHOT users should become
+familiar with all three of these tasks.
+
+.NH 2
+Other Useful Packages and Tasks
+
+.PP
+The NPROTO package contains two useful tasks, \fBfindgain\fR,
+for computing the gain and readout noise of a CCD
+from a pair of biases and flats, and \fBfindthresh\fR for computing
+the standard deviation of the background in a CCD frame given the
+readout noise and gain. The ASTUTIL package contains the \fBsetairmass\fR
+task for computing and/or correcting the airmass given the appropriate
+input data.
+Users might also wish to experiment with the tasks in the artificial
+data package ARTDATA, and run the resulting images through DAOPHOT.
+
+.NH 2
+Image Types, Image Directories, and Image Headers
+
+.PP
+The IRAF image environment is controlled by several
+environment variables. The most important of these for DAOPHOT users
+are: \fBimtype\fR the disk image format, \fBimdir\fR the default pixel
+directory, and \fBmin_lenuserarea\fR the maximum length of the image header.
+The values of these environment variables can be listed
+as shown below.
+
+.YS
+cl> show imtype
+imh
+cl> show imdir
+/data/davis/pixels/
+cl> show min_lenuserarea
+24000
+.YE
+
+.PP
+\fB"imh"\fR is the default image format for most IRAF users, \fB"hhh"\fR the
+default image format for ST users, and \fB"qp"\fR the photon counting format
+used for photon counting data. DAOPHOT will work transparently on
+"imh" and "hhh" images. "qp" event lists must be rasterized prior to using
+DAOPHOT. When IRAF supports FITS images on disk, image format "fits", DAOPHOT
+will be able to work directly on FITS images as well. IRAF uses the
+image name extension, e.g. "imh" to automatically sense the image
+disk format on input. The output disk format is set by: 1) the
+extension of the output image name if present e.g. "imh", 2) the cl
+environment variable \fBimtype\fR if the output image is opened as a new
+image, e.g. the output of the \fBrfits\fR task, 3) the type of the input
+image if the output image is opened as a new copy of an existing image,
+e.g. the output of the \fBimcopy\fR task.
+.PP
+\fBimdir\fR specifies the default image pixel directory for "imh" format
+files. The image header files are written to the current directory
+and the pixel files are written to imdir. imdir can be set
+to an existing directory on a scratch disk, the current
+directory "HDR$", or the subdirectory pixels under the current
+directory "HDR$pixels/". DAOPHOT users should keep both the intrinsic
+speed of a disk and its network configuration in mind when setting
+imdir.
+.PP
+\fBmin_lenuserarea\fR is the size of the image header area reserved
+in memory when a new or existing image is opened.
+The current default value of 24000 corresponds to space for approximately
+300 keywords.
+If an image on disk has a header larger than this the image header will
+be truncated when it is read.
+For most DAOPHOT users the default value is sufficient. However users whose
+images have large headers or who are
+creating a point-spread function using more than ~70 stars should set
+min_lenuserarea to a larger value, e.g. 40000.
+.PP
+The following example shows how to change the default pixel directory to
+HDR$pixels/ and set min_lenuserarea to 40000. To avoid redefining these
+quantities for every session, users should enter the redefinitions into
+their login.cl or loginuser.cl files.
+
+
+.YS
+cl> reset imdir = "HDR$pixels/"
+cl> reset min_lenuserarea = 40000
+.YE
+
+.NH 2
+The Image Display and Image Cursor
+
+.PP
+Several DAOPHOT tasks are interactive tasks or have an interactive as well
+as a non-interactive mode. In interactive mode these tasks must be able to
+read the image cursor on a displayed image and perform various
+actions depending on the position of the image cursor and the keystroke
+command typed.
+.PP
+DAOPHOT will work with the display servers Imtool, Saoimage, and Ximtool.
+DAOPHOT users should be aware that both Imtool and Ximtool support multiple
+frame buffers while SAOimage does not. Multiple frame buffers are an
+important feature for users who wish to compare their original
+images with the DAOPHOT output images from which all the fitted
+stars have been subtracted. Users running DAOPHOT on a remote machine, e.g.
+one with lots of memory and/or disk space, but displaying on their local
+machine also need to set the \fBnode\fR environment variable to
+the name of the local machine.
+
+.YS
+cl> show node
+ERROR: No such environment variable
+ show (node)
+cl> set node = mymachine
+.YE
+
+.PP
+The maximum size of the display server frame buffer is defined by the
+environment variable \fBstdimage\fR whose value can be printed as
+shown below.
+
+.YS
+cl> show stdimage
+imt512
+.YE
+
+In the previous example the default frames buffers are 512 pixels square.
+A user whose images are 2K square will want to reset the default frame
+buffer size as shown below.
+
+.YS
+cl> reset stdimage = imt2048
+cl> show stdimage
+imt2048
+.YE
+
+.PP
+In order for image cursor read-back to function correctly the environment
+variable \fBstdimcur\fR must be set to "stdimage" as shown below.
+
+.YS
+cl> show stdimcur
+stdimage
+.YE
+
+To check that image cursor read-back is functioning correctly the user
+should display an image and try to bring up the image display cursor
+as shown below.
+
+.YS
+cl> display image 1
+cl> =imcur
+.YE
+
+The image cursor should appear on the image display reading the correct
+image pixel coordinates and ready to accept a
+keystroke command. Any keystroke will terminate the cursor read.
+
+.NH 2
+The Graphics Device and Graphics Cursor
+
+.PP
+Some interactive DAOPHOT tasks have graphics submenus which require
+them to be able to read the graphics cursor on for example a radial
+profile plot and perform various
+actions based on the position of the graphics cursor in the
+plot and the keystroke
+command issued. The default graphics device is determined by
+the \fBstdgraph\fR environment variable as shown below.
+
+.YS
+cl> show stdgraph
+xgterm
+.YE
+
+To check that graphics cursor read-back is functioning correctly the user
+should draw a plot and try to bring up the graphics cursor as
+shown below.
+
+.YS
+cl> contour image
+cl> =gcur
+.YE
+
+The graphics cursor should appear in the graphics window ready to accept a
+keystroke command. Any keystroke will terminate the cursor read.
+
+.NH
+Some DAOPHOT Basics for New DAOPHOT Users
+
+.NH 2
+Loading the DAOPHOT Package
+
+.PP
+The DAOPHOT package is located in the digital stellar photometry package
+DIGIPHOT. To load DIGIPHOT and DAOPHOT the user types the package names
+in sequence as shown below,
+
+.YS
+cl> digiphot
+di> daophot
+.YE
+
+after which the following menu of tasks appears.
+
+.YS
+addstar daotest nstar pexamine psf
+allstar datapars@ pcalc pfmerge psort
+centerpars@ findpars@ pconcat phot pstselect
+daoedit fitskypars@ pconvert photpars@ seepsf
+daofind group pdump prenumber setimpars
+daopars@ grpselect peak pselect substar
+.YE
+
+Task names with a trailing "@" are parameter set tasks.
+The remaining tasks are script and/or compiled tasks.
+After the DAOPHOT package is loaded the user can redisplay
+the package menu at any time with the command.
+
+.YS
+da> ? daophot
+.YE
+
+.NH 2
+Loading the TABLES Package
+
+.PP
+The DAOPHOT photometry tasks write their output photometry files in
+either text format (the default) or ST binary tables format. Users wishing
+to use the ST binary tables format should acquire and install
+the ST TABLES external package. Without the TABLES package the DAOPHOT
+photometry tasks will read and write ST binary tables, but DAOPHOT
+utilities like \fBpsort\fR which call TABLES package
+tasks will not run on ST binary tables.
+.PP
+When DAOPHOT is loaded, it checks to see if the TABLES package is defined,
+and if so loads it. A warning message is issued if the TABLES package is
+undefined. The TABLES package tasks can be listed at any time after DAOPHOT
+is loaded with the following command.
+
+.YS
+da> ? tables
+.YE
+
+.NH 2
+Running the Test Script
+
+.PP
+The DAOPHOT package includes a script task \fBdaotest\fR which
+executes each of the core DAOPHOT photometry tasks in turn using a test
+image stored
+in FITS format in the DAOPHOT test directory. \fBDaotest\fR is run as
+shown below.
+
+.YS
+da> daotest
+
+DAOTEST INITIALIZES THE DAOPHOT TASK PARAMETERS
+TYPE 'q' or 'Q' TO QUIT, ANY OTHER KEY TO PROCEED
+
+Name of the output test image: test
+
+INITIALIZE THE DAOPHOT PACKAGE
+
+TESTING THE DAOFIND TASK
+TESTING THE PHOT TASK
+TESTING THE PSTSELECT TASK
+TESTING THE PSF TASK
+TESTING THE PEAK TASK
+TESTING THE GROUP TASK
+TESTING THE GRPSELECT TASK
+TESTING THE NSTAR TASK
+TESTING THE ALLSTAR TASK (CACHE=YES)
+TESTING THE ALLSTAR TASK (CACHE=NO)
+TESTING THE SUBSTAR TASK
+TESTING THE ADDSTAR TASK
+
+DAOPHOT PACKAGE TESTS COMPLETED
+.YE
+
+On task completion the user will find the input image in
+test.imh, the psf image in test.psf.1.imh, the subtracted image produced
+by \fBallstar\fR in test.sub.1.imh, the input image with artificial stars
+added in test.add.1.imh, copies of all the output photometry files in
+test.log, and copies of the plots produced by the \fBpsf\fR task
+in test.plot on disk.
+.PP
+Users should be aware that the \fBdaotest\fR task will reset the DAOPHOT
+task and algorithm parameters to their default values before and after it
+is executed.
+
+.NH 2
+On-line Help
+
+.PP
+A one-line description of each DAOPHOT task can be obtained by typing
+the following command,
+
+.YS
+da> help daophot\fR
+.YE
+
+upon which the following package menu appears.
+
+.YS
+digiphot.daophot:
+ addstar - Add stars to an image using the computed psf
+ allstar - Group and fit psf to multiple stars simultaneously
+centerpars - Edit the centering algorithm parameters
+ daoedit - Review/edit algorithm parameters interactively
+ daofind - Find stars in an image using the DAO algorithm
+ daopars - Edit the daophot algorithms parameter set
+ daotest - Run basic tests on the daophot package tasks
+ datapars - Edit the image data dependent parameters
+ findpars - Edit the star detection parameters
+fitskypars - Edit the sky fitting algorithm parameters
+ group - Group stars based on position and signal/noise
+ nstar - Fit the psf to predefined groups of stars
+ peak - Fit the psf to single stars
+ phot - Compute skies and initial magnitudes for a star list
+ photpars - Edit the aperture photometry parameters
+ psf - Compute the point spread function
+ seepsf - Compute an image from the point spread function
+ setimpars - Save/restore parameter sets for a particular image
+ substar - Subtract the fitted stars from the original image
+
+ pcalc - Do arithmetic operations on list of daophot databases
+ pconcat - Concatenate a list of daophot databases
+ pconvert - Convert a text database to a tables database
+ pdump - Print selected fields from daophot databases
+ pfmerge - Merge a list of photometry databases
+ pstselect - Select candidate psf stars based on proximity
+ grpselect - Select groups from a daophot database
+ pexamine - Interactively examine and edit a daophot database
+ prenumber - Renumber stars in a daophot database
+ pselect - Select records from a daophot database
+ psort - Sort a daophot database\fR
+.YE
+
+.PP
+All the DAOPHOT tasks have on-line manual pages which can be
+listed on the terminal. The following command lists the help for the
+\fBphot\fR task on the terminal.
+
+.YS
+da> phelp phot\fR
+.YE
+
+Any section of the manual pages can be listed individually.
+For example the examples section of the \fBphot\fR manual page can be
+listed as follows.
+
+.YS
+da> phelp phot sections=examples\fR
+.YE
+
+The help page for \fBphot\fR can be piped to the local default printer as
+follows.
+
+.YS
+da> phelp phot | lprint\fR
+.YE
+
+Finally the manual pages for the whole DAOPHOT package can be printed
+by typing.
+
+.YS
+da> phelp daophot.* | lprint\fR
+.YE
+
+
+.NH 2
+Editing the Package Parameters
+
+.PP
+DAOPHOT has a package parameter set which defines the DAOPHOT
+package environment. The DAOPHOT package parameters can edited
+with epar as shown below.
+
+.YS
+da> epar daophot
+.YE
+
+.YS
+Image Reduction and Analysis Facility
+ PACKAGE = digiphot
+ TASK = daophot
+ (version = "Dec92")
+ (text = yes) Text file on output ?
+ (verify = yes) Verify critical parameters ?
+ (update = no) Update critical parameters ?
+ (verbose = yes) Print verbose output ?
+(graphics = "stdgraph") Default graphics device
+ (display = "stdimage") Default display device
+ (mode = "ql")
+.YE
+
+To edit a parameter simply move the cursor to the parameter in question,
+enter the new value, type return, and finally type \fB:wq\fR to quit and
+update the parameter set. Package parameters can also be edited on the
+command line as shown below.
+
+.YS
+da> daophot.text = yes
+.YE
+
+.PP
+The DAOPHOT package parameters control the operation of the DAOPHOT package
+as a whole. For example the \fBtext\fR parameter specifies whether the
+output photometry files will be written in text or STSDAS binary tables format,
+the parameters \fBverify\fR, \fBupdate\fR, and \fBverbose\fR determine
+the default mode of operation of the DAOPHOT package tasks, and the parameters
+\fBgraphics\fR and \fBdisplay\fR determine the default graphics and display
+devices for the entire package.
+
+.NH 2
+Editing the Task Parameters
+
+.PP
+The DAOPHOT task level parameters specify the input and output images and
+files, the algorithm parameter sets, the graphics and image display input and
+output devices, and the mode of operation of each DAOPHOT task.
+.PP
+To enter and edit the parameter set for the DAOPHOT \fBphot\fR task
+the user types the following command,
+
+.YS
+cl> epar phot
+.YE
+
+after which the parameter set for the \fBphot\fR task appears on the
+terminal ready for editing as shown below.
+
+.YS
+Image Reduction and Analysis Facility
+PACKAGE = daophot
+ TASK = phot
+
+image = Input image(s)
+coords = default Input coordinate list(s)
+output = default Output photometry file(s)
+skyfile = Input sky value file(s)
+(plotfil= ) Output plot metacode file
+(datapar= ) Data dependent parameters
+(centerp= ) Centering parameters
+(fitskyp= ) Sky fitting parameters
+(photpar= ) Photometry parameters
+(interac= no) Interactive mode ?
+(radplot= no) Plot the radial profiles?
+(verify = )_.verify) Verify critical phot parameters ?
+(update = )_.update) Update critical phot parameters ?
+(verbose= )_.verbose) Print phot messages ?
+(graphic= )_.graphics) Graphics device
+(display= )_.display) Display device
+(icomman= ) Image cursor: [x y wcs] key [cmd]
+(gcomman= ) Graphics cursor: [x y wcs] key [cmd]
+(mode = ql)
+.YE
+
+The \fBphot\fR parameters can be edited by moving
+the cursor to the line opposite the parameter name, entering the new value
+followed by a carriage return, and typing \fB:wq\fR to exit the
+\fBepar\fR task and update the parameters.
+.PP
+In the following sections the \fBphot\fR task is used to illustrate
+some general features of the DAOPHOT package.
+
+.NH 2
+Input and Output Image Names
+
+.PP
+The \fBphot\fR parameter \fIimage\fR
+defines the image to be analyzed. The
+root image name, the value of \fIimage\fR
+stripped of directory and section information,
+sets up the default input and output image naming convention for the task.
+Users should avoid appending the ".imh" or ".hhh" extension
+to their image name specification as these extensions are not required by IRAF
+image i/o and become part of the default output image names.
+.PP
+The \fBphot\fR task does not create an output image but DAOPHOT tasks
+which do, will by default create an output image name of the form
+"image.extension.?" where image is the input image name
+stripped of directory
+and section information, extension is an id appropriate
+to the task, and ? is the next available version number.
+For example the first run of the \fBsubstar\fR task on the image "image"
+will create an image called "image.sub.1", the second an image
+called "image.sub.2", and so on. The default output image naming convention
+can always be overridden by the user in any task.
+
+.NH 2
+Input and Output File Names
+
+.PP
+DAOPHOT uses a default input and output file naming convention based on the
+root image name or the input image name with the directory and
+section specification removed. Users should avoid appending the ".imh" or
+".hhh" extension to their input image name specification as these extensions
+are not required by IRAF image i/o and become part of the default input
+and output file names.
+.PP
+If a DAOPHOT task expects its input to have been written
+by another DAOPHOT task, and the input file parameter value is "default",
+the task will search for an existing
+file called "image.extension.?" where image is the root image
+name, extension identifies the task expected to have written the file,
+and version is the highest version number for that file. For example,
+if the user sets the \fBphot\fR parameters \fIimage\fR and
+\fIcoords\fR to "m92b" and "default", \fBphot\fR will search
+for a coordinate file called "m92b.coo.#" written by the
+\fBdaofind\fR task. The default input file naming convention
+can be over-ridden by the user at any point.
+.PP
+The output file naming convention works
+in an identical manner to the input file naming convention,
+although in this situation ? is the next available
+version number. For example if the user sets the \fBphot\fR task
+parameter \fIoutput\fR to "default", the output photometry file name
+will be "image.mag.?"
+where ? is 1 for the first run of \fBphot\fR, 2 for the second run, and so
+on. The default output file naming convention can be over-ridden
+by the user at any point.
+
+.NH 2
+Algorithm Parameter Sets
+
+.PP
+The DAOPHOT parameters have been grouped together into parameter sets
+or psets.
+The use of psets encourages the logical grouping of parameters, permits
+the various DAOPHOT tasks to share common parameters, and
+permits the user to optionally store the DAOPHOT algorithm parameters
+with the data rather than in the default uparm directory.
+.PP
+Six DAOPHOT psets, \fBdatapars\fR, \fBfindpars\fR, \fBcenterpars\fR,
+\fBfitskypars\fR, \fBphotpars\fR and \fBdaopars\fR
+control the DAOPHOT algorithm parameters. The \fBphot\fR task
+uses four of them, \fBdatapars\fR which specifies data dependent
+parameters like \fIfwhmpsf\fR (the full-width half-maximum of the psf),
+\fIsigma\fR (the standard deviation of
+the sky background), \fIepadu\fR and \fIreadout noise\fR
+(the gain and readout noise of the detector),
+and the \fBcenterpars\fR, \fBfitskypars\fR and \fBphotpars\fR parameter
+sets which define the centering algorithm, sky fitting algorithm
+and aperture photometry algorithm parameters respectively,
+used by phot to compute initial centers, sky values,
+and initial magnitudes for the stars to be analyzed. The \fBfindpars\fR pset
+controls the star detection algorithm parameters used by the \fBdaofind\fR
+task. The \fBdaopars\fR pset defines the psf model fitting
+and evaluation parameters including the radius of the psf, the fitting radius,
+and the grouping parameters used by all the psf fitting tasks.
+.PP
+By default the pset parameters can be examined, edited and stored
+in the user's uparm directory, in the same manner as the task level
+parameters. For example to list the current \fBdatapars\fR
+pset the user types.
+
+.YS
+da> lpar datapars
+.YE
+
+To edit the \fBdatapars\fR parameter set, the user types either
+
+.YS
+da> epar datapars
+
+or
+
+da> datapars
+.YE
+
+and edits the parameter set in the usual manner with \fBepar\fR.
+All the DAOPHOT tasks which reference this
+pset will pick up the changes from the uparm directory, assuming
+that the \fIdatapars\fR parameter is specified as "" in the calling task.
+The user can also edit the \fBdatapars\fR
+pset from within the \fBphot\fR
+task or any other task which calls it as shown below.
+
+.YS
+da> epar phot
+.YE
+
+Move the cursor to the \fBdatapars\fR parameter line and type \fB:e\fR.
+The menu for the
+\fBdatapars\fR pset will appear ready for editing. Edit the desired
+parameters and type \fB:wq\fR. \fBEpar\fR will return to the main
+\fBphot\fR parameter set after which other psets or the main task parameters
+can be edited.
+.PP
+Psets may also be stored in user files providing
+a mechanism for saving a particular pset
+with the data.
+The example below shows how to store a pset in a file in the same directory
+as the data and recall it for use by the \fBphot\fR task. The user types
+
+.YS
+da> epar phot
+.YE
+
+as before, enters the \fBdatapars\fR menu with \fB:e\fR and edits the
+parameters. The command \fB:w data1.par\fR
+writes the parameter set to a file called "data1.par" and a \fB:q\fR
+returns to the main task menu.
+A file called "data1.par" containing the new \fBdatapars\fR parameters
+is written in the current directory. At this point the user is still in the
+\fBphot\fR parameter set at the line opposite \fBdatapars\fR. He/she
+enters "data1.par" on the line opposite this parameter.
+The next time \fBphot\fR is run the parameters will
+be read from "data1.par" not from the pset in the uparm directory.
+The new parameter set can be edited in the usual way by typing
+
+.YS
+da> epar data1.par
+
+or
+
+da> epar phot
+.YE
+
+Users should be sure to append a .par extension to any pset files they
+create as IRAF needs this extension to identify the file as a pset.
+.PP
+It is possible to develop quite efficient and creative schemes for using psets.
+For example a user might choose to copy each crowded stellar field
+image to its own directory, copy the default psets \fBdatapars\fR,
+\fBfindpars\fR, \fBcenterpars\fR, \fBfitskypars\fR, \fBphotpars\fR
+and \fBdaopars\fR to the files "datapars.par", "findpars.par",
+"centerpars.par", "fitskypars.par", "photpars.par" and "daopars.par" in
+each image directory, and then edit
+the parameter sets of the top level tasks to look for psets with those names.
+Once this is done the psets in each directory can be edited at will
+without ever needing to edit the names of the psets in the top
+level tasks.
+.PP
+The individual pset parameters themselves have the same attributes as
+task level parameters. Hidden pset parameters may be altered on the
+command line in the same way as task parameters.
+The only distinction between task level parameters and pset parameters
+is that the latter may be stored in or read from a user defined file.
+
+.NH 2
+Interactive Mode and Non-Interactive Mode
+
+.PP
+The \fBphot\fR task's \fIinteractive\fR parameter
+switches the task between interactive and non-interactive mode.
+.PP
+In interactive mode user instructions in the form of single keystroke
+commands or colon commands are read from the image cursor.
+For example the \fBphot\fR task \fB'i'\fR keystroke command enters the
+interactive setup menu and the \fB'v'\fR keystroke command verifies the
+current parameters. The colon commands are used to show or set any parameter.
+For example, if the user does not like the fact that the full-width
+half-maximum of a star
+as measured with the cursor is 2.5368945 he/she can set it to 2.54 by
+typing \fB:fw 2.54\fR.
+.PP
+In non-interactive mode the input files and images are read,
+the parameters are read from the psets,
+and the output files are written,
+all, with the exception of an optional verification step, without the
+intervention of the user.
+.PP
+The DAOPHOT parameter editing task \fBdaoedit\fR and the photometry catalog
+examining task \fBpexamine\fR are interactive tasks.
+Four other DAOPHOT tasks, \fBdaofind\fR, \fBphot\fR, \fBpstselect\fR,
+and \fBpsf\fR
+have an interactive and a non-interactive mode. The default mode for
+\fBdaofind\fR, \fBphot\fR, and \fBpstselect\fR is non-interactive while
+for \fBpsf\fR
+it is interactive.
+The remaining DAOPHOT tasks are currently non-interactive tasks.
+
+.NH 2
+Image and Graphics Cursor Input
+
+.PP
+All tasks which can be run interactively accept commands from the logical image
+cursor parameter \fIicommands\fR. Logical image cursor commands can
+read from the logical image cursor, \fIicommands\fR = "" or a file,
+\fIicommands\fR = "filename". The logical image cursor is normally
+the physical image cursor and the value of the IRAF environment
+variable \fBstdimcur\fR is normally "stdimage". In cases where the image
+display device is non-existent or cursor read-back is not implemented for
+a particular device the logical image cursor may be reassigned globally to the
+the graphics cursor or the standard input
+by setting the IRAF environment variable \fBstdimcur\fR as follows.
+
+.YS
+da> set stdimcur = "stdimage" (image cursor default)
+
+da> set stdimcur = stdgraph (graphics cursor)
+
+da> set stdimcur = "text" (standard input)
+.YE
+
+If logical image cursor commands are read from the standard input or a
+file, the commands must have the following format
+
+.YS
+[x y wcs] key [cmd]\fR
+.YE
+
+where x and y stand for the x and y position of the image cursor, wcs defines
+the world coordinate system, key is
+a keystroke command, and cmd is an optional user command.
+Quantities in square brackets are optional. The necessity for their
+presence is dictated by the nature of the keystroke command. In the
+case of the \fBphot "i"\fR keystroke described above they are required, whereas
+in the case of the \fBphot "v"\fR keystroke they are not.
+.PP
+Some interactive commands require input from the logical graphics cursor
+parameter \fIgcommands\fR which may be the logical graphics cursor,
+\fIgcommands\fR = "", or a file of graphics cursor commands,
+\fIgcommands\fR = "filename".
+In DAOPHOT the logical graphics cursor must be set to the physical
+graphics cursor and the value of the IRAF environment variable
+\fBstdgcur\fR should be "stdgraph".
+
+.NH 2
+Graphics Output
+
+.PP
+The \fBphot\fR parameters \fIgraphics\fR and \fIdisplay\fR specify the
+default vector graphics and image display graphics devices.
+Vector graphics output is written to the user's
+graphics window, and image
+graphics is overlaid on the user's image display. window
+All interactive vector graphics output is written to
+the device specified by \fIgraphics\fR. An example of this type of graphics
+output is the
+radial profile plot of a star plotted by the \fBphot\fR interactive
+setup menu.
+Image graphics is written to the image display device
+specified by \fIdisplay\fR.
+Examples of this type of output are the optional crosses
+which mark the centers of the stars being measured by \fBphot\fR.
+\fBIRAF does not currently support writing interactive graphics
+to the image display device
+so the display marking features of DAOPHOT are not supported\fR.
+The single exception occurs in the situation
+where the user is running interactively
+off a contour plot as described in the \fBphot\fR help documentation.
+In this case marking will work if
+the parameter \fIdisplay\fR is set to "stdgraph".
+DAOPHOT tasks which reference \fIgraphics\fR or \fIdisplay\fR will, in
+interactive mode, issue
+a warning if they cannot open either or both of these devices,
+and continue execution.
+.PP
+Some DAOPHOT tasks permit the user to save plots of the results
+for each measured star in a plot metacode file.
+For example. if the \fBphot\fR task parameter \fIplotfile\fR is defined,
+then for each star written to \fIoutput\fR
+a radial profile plot is written to the plot metacode file \fIplotfile\fR.
+\fIPlotfile\fR is opened in append mode and succeeding executions
+of \fBphot\fR will write to the end of the same file.
+Users should be aware plotfile can become very large and
+that writing radial profile plots
+to \fIplotfile\fR will greatly slow the execution of \fBphot\fR or any
+other task.
+
+.NH 2
+Verify, Update, and Verbose
+
+.PP
+In non-interactive mode the algorithm parameter values are read from the psets,
+critical parameters are verified if the \fIverify\fR switch is on, and
+updated if both the \fIverify\fR and \fIupdate\fR switches are on.
+The \fIverify\fR and \fIupdate\fR options are also available as
+separate keystroke commands in interactive mode.
+Users must remember to turn off the
+\fIverify\fR switch if they submit a task to the background or the task
+will pause and wait indefinitely for input from the terminal.
+.PP
+In interactive or non-interactive mode a results summary and/or
+error messages are written
+to the standard output if the \fIverbose\fR switch is on.
+Users must remember to redirect
+any verbose output to a file if they submit the task to the background or
+it will be lost.
+
+.NH 2
+Background Jobs
+
+.PP
+Any DAOPHOT task can be run in background by appending an ampersand
+to the end of the command. For example the \fBphot\fR task can be run
+as a background job as shown below.
+
+.YS
+da> phot image image.coo.1 image.mag.1 verbose- verify- &
+.YE
+
+The user must be sure to turn off verbose mode
+and set the verify switch to no. VMS users may have to append a queue
+name after the trailing ampersand.
+If verbose output is desired it can be captured in a file as shown
+in the example below below. The & after the > will ensure that any error
+output is also captured.
+
+.YS
+da> phot image image.coo.1 image.mag.1 verbose+ inter- verify- \\
+ >& listing &
+.YE
+
+.NH 2
+Timing Tests
+
+.PP
+Any DAOPHOT or IRAF task can be timed by prepending a $ sign to the
+command as shown below.
+
+.YS
+da> $phot image image.coo.1 image.mag.1 inter- verify- verbose- &
+.YE
+
+At task termination the computer will print the cpu and elapsed
+time on the terminal.
+.PP
+Care must be taken in using this feature
+to make timing comparisons between hosts or even between runs on the same host,
+as factors like which queue a task is submitted to (VMS), which version of
+the OS the host is running, which version of the compiler
+two programs were compiled under,
+whether the disks are local or networked, and the number of users on the
+machine will effect the elapsed time and/or the cpu time.
+
+.NH
+Doing Photometry with DAOPHOT
+
+.NH 2
+The Test Image
+
+.PP
+Each of the DAOPHOT analysis steps summarized in the following section
+and discussed in detail in succeeding
+sections uses the artificial image stored in fits format in
+the file "daophot$test/fits3.fits" as test data. This image is small,
+51 by 51 pixels, contains 10 stars whose coordinates and magnitudes
+are listed below, has, a mean background level of ~100, poisson noise
+statistics, a gain of 1.0, and a readout noise of 0.0.
+
+.YS
+# Artificial Stars for Image Test
+
+ 41.0 4.0 17.268
+ 23.0 7.0 17.600
+ 18.0 8.0 17.596
+ 26.0 22.0 16.777
+ 36.0 22.0 16.317
+ 8.0 23.0 16.631
+ 31.0 25.0 16.990
+ 21.0 26.0 19.462
+ 29.0 34.0 17.606
+ 36.0 42.0 16.544
+.YE
+
+.PP
+Results for this test image are used to illustrate the text. It is hoped
+that users so inclined will be able to mimic the reductions on
+their host machine. The fact that the image is small, means that
+the tasks execute quickly, it is possible to display all the
+important results in the manual, and it is possible for
+the user to track and examine all the important numbers, something not
+easy with larger images. Users are encouraged to construct more
+challenging artificial images with the ARTDATA package, and to run
+them through DAOPHOT.
+.PP
+All the examples in the following text were run
+under IRAF 2.10.3 on a SPARCstation IPX. Users with different hardware
+may see minor deviations from the output shown here due to machine
+precision differences.
+
+.NH 2
+Typical Analysis Sequence
+
+.PP
+The following sequence of operations summarizes the steps required to analyze
+a crowded stellar field with DAOPHOT.
+.IP [1]
+Create a directory in which to analyze the image and make it the current
+working directory. By default all output photometry and image files
+will be written there.
+.IP [2]
+Read the reduced image into the working directory with the DATAIO package
+task \fBrfits\fR.
+.IP [3]
+Check that the correct exposure time, airmass, filter id, time of
+observation, gain, and readout noise are present and correct
+in the image header with the \fBhselect\fR task. Enter / edit them
+with the \fBhedit\fR task if they are not. Correct the exposure time for
+shutter error, the airmass to mid-exposure, and the gain
+and readout noise to the effective gain and readout noise, using the
+\fBhedit\fR and/or \fBsetairmass\fR tasks.
+.IP [4]
+Edit the DAOPHOT algorithm psets with the interactive \fBdaoedit\fR
+task. The parameters that require editing at this point are:
+1) the numerical parameters
+\fIfwhmpsf\fR (full-width at half-maximum of the point-spread function),
+\fIsigma\fR (standard deviation of the background in counts), \fIdatamin\fR
+(the minimum good data value in counts), \fIdatamax\fR (the maximum good
+data value in counts), and the image header keyword parameters
+\fIccdread\fR, \fIgain\fR, \fIexposure\fR, \fIairmass\fR, \fIfilter\fR,
+and \fIobstimes\fR in the \fBdatapars\fR parameter set,
+2) \fIcbox\fR (the centering box width) in the \fBcenterpars\fR parameter set,
+3) \fIannulus\fR (inner radius of the sky annulus) and
+\fIdannulus\fR (width of the sky annulus) in the \fBfitskypars\fR parameter set,
+4) \fIapertures\fR (radii of the photometry apertures) in the \fBphotpars\fR
+parameter set, and 5) \fIpsfrad\fR (maximum radius of the psf model)
+and \fIfitrad\fR (psf model fitting radius) in the \fBdaopars\fR parameter set.
+.IP [5]
+Create an initial star list using the \fBdaofind\fR task.
+Mark the detected stars on the image display with the \fBtvmark\fR task
+and adjust the \fBfindpars\fR parameter \fIthreshold\fR until
+a satisfactory star list is created.
+.IP [6]
+Compute sky background values and initial magnitudes for
+the detected stars using the \fBphot\fR task and the star
+list written by the \fBdaofind\fR task in step [5].
+.IP [7]
+Create a psf star list using the \fBpstselect\fR task
+and the photometry file written by \fBphot\fR in step [6]. Mark
+the coordinates of the psf stars on the image display with the
+\fBtvmark\fR task
+and edit out any non-stellar objects, stars with
+neighbors within \fIfitrad\fR pixels, or stars with obvious
+cosmetic blemishes, using the \fBpexamine\fR task.
+.IP [8]
+Compute the current psf model using the
+\fBpsf\fR task, the input photometry file written by the \fBphot\fR task
+in step [6], and the psf star list written by the \fBpstselect\fR task
+in step [7].
+.IP [9]
+Fit the current psf model to the psf stars and their neighbors
+using the \fBnstar\fR task, the psf star group photometry file
+written by the \fBpsf\fR task in step [8] or created by the user in step [11],
+and the current psf model written by the \fBpsf\fR task in steps [8] or [13].
+Subtract the fitted psf stars
+and their neighbors from the original image using the \fBsubstar\fR task,
+the photometry file written by the \fBnstar\fR task, and the current
+psf model.
+Display the subtracted image, mark the psf stars and their neighbors
+on the display with the \fBtvmark\fR task,
+and examine the \fBnstar\fR photometry
+file and the subtracted image with the \fBpexamine\fR task.
+If all the psf stars subtract out cleanly and none of them have any
+significant neighbors, skip directly to step [14]. If all the psf stars
+and their neighbors subtract out cleanly, and one or more of the psf
+stars do have significant neighbors, skip directly to step [13].
+.IP [10]
+Reexamine the subtracted image written in step [9]. Remove any psf stars
+revealed by the subtraction to be non-stellar, multiple, or to contain
+cosmetic blemishes,
+from the psf star list written by the \fBpsf\fR task in step
+[8] using the \fBpexamine\fR task.
+If any bad psf stars are detected recompute the psf model by returning to
+step [8] using the newly edited psf star list in place
+of the one written by the previous execution of the \fBpsf\fR task in step [8].
+.IP [11]
+Add any psf star neighbors too faint to be detected by the \fBdaofind\fR
+task in step [5] but bright enough to effect the computation of the
+psf model, to the original psf star group photometry file written
+by the \fBpsf\fR task in step [8],
+by estimating their positions, sky values, and magnitudes interactively
+with the \fBphot\fR task, merging the results with the original psf star group
+photometry file
+using the \fBpfmerge\fR task, and regrouping the stars with the \fBgroup\fR
+task. Refit the newly grouped psf stars and their neighbors using
+the current psf model by returning to step [9],
+replacing the original input group photometry file with the one
+including the new psf star neighbors.
+.IP [12]
+Using the subtracted image written by the \fBsubstar\fR task in step [9],
+note any systematic patterns in the psf star residuals with distance from
+the star (\fIthese indicate a poorly chosen value for the annulus,
+dannulus, function, or psfrad parameters),
+position in the image (\fIthese suggest that the psf is variable
+and that the value of the varorder parameter should be increased\fR),
+or intensity (\fIthis suggests problems with the image data itself, e.g.
+non-linearity\fR). If the problem is in the sky fitting parameters
+edit the appropriate algorithm parameters and return to step [6]. If
+the problem is in the psf modeling and fitting parameters, edit the
+appropriate algorithm parameters and return to step [7]. I the problem
+appears to be in the data or the data reduction procedures, review the
+data taking and reduction history of the image before proceeding.
+.IP [13]
+Subtract the psf star neighbors but not the psf stars from the original
+image using the \fBsubstar\fR task,
+the photometry file written by the \fBnstar\fR task
+in step [9], and the psf star list and current psf model written by
+the \fBpsf\fR task in step [8].
+Recompute the current psf model using
+the psf neighbor star subtracted image, the psf star group photometry file
+written by the \fBpsf\fR task in step [8] or created by the user in step [11],
+and the psf star list written in step [8].
+If the \fIvarorder\fR parameter was changed
+return to step [9].
+Otherwise save the psf star neighbor subtracted image as it may be
+required for computing the image
+aperture correction in step [20], and proceed to step [14].
+.IP [14]
+Fit the final psf model computed in steps [8] or [13]
+to the stars in the photometry file written in
+step [6] using the \fBallstar\fR task.
+.IP [15]
+Run \fBdaofind\fR on the subtracted image produced by \fBallstar\fR in step
+[14] in order to pick up stars missed by the first pass of \fBdaofind\fR in
+step [5].
+.IP [16]
+Run \fBphot\fR on the original image using the new star list produced by
+\fBdaofind\fR in step [15] and the \fBphot\fR algorithm parameters used
+in step [6].
+.IP [17]
+Merge the photometry file produced by \fBallstar\fR in step [14] with
+the one produced by \fBphot\fR in step [16] using the \fBpfmerge\fR
+task.
+.IP [18]
+Rerun \fBallstar\fR on the original image using the merged photometry file
+created in step [17] and the psf model created in steps [8] or [13].
+.IP [19]
+Repeat steps [15]-[18] as required, remembering to run \fBdaofind\fR
+on the subtracted image produced by \fBallstar\fR and \fBphot\fR on the
+original image.
+.IP [20]
+If the psf model is constant, compute the aperture correction for the
+image using the original image and a sample of bright well-isolated stars
+if possible, or the image with
+the psf neighbor stars subtracted if necessary, the
+\fBphot\fR task, and the PHOTCAL package \fBmkapfile\fR task.
+If the psf model is variable, compute the aperture correction by calculating
+the mean magnitude difference, for the psf stars with any
+the neighbors subtracted, between the psf model fitted magnitudes computed
+by the \fBnstar\fR task, and large aperture photometry magnitudes computed
+with the \fBphot\fR task.
+.IP [21]
+Archive the algorithm parameters for the image with the \fBsetimpars\fR task
+and proceed to the next image.
+
+
+.NH 2
+Creating and Organizing an Analysis Directory
+
+.PP
+By default DAOPHOT reads and writes data from and to the current working
+directory. To create and set a new working directory the user must
+execute the commands \fBmkdir\fR and \fBchdir\fR as shown below.
+
+.YS
+da> mkdir testim
+da> chdir testim
+.YE
+
+.PP
+DAOPHOT can in the course of reducing a single image,
+generate a large number of photometry catalogs and output images.
+Users should take a moment to consider how they wish to organize their data
+directories before beginning any DAOPHOT analysis. Some possibilities for data
+directory organization are: 1) by night of observation for standard star fields,
+2) by star field for multi-filter observations of a crowded field, or
+3) by individual image for single filter observations of several fields,
+or any combination of the above.
+
+.NH 2
+Reading the Data
+
+.PP
+DAOPHOT input images are normally read into IRAF from FITS files with
+the DATAIO package task \fBrfits\fR. The following example shows how to
+read the DAOPHOT test image stored in the FITS file "daophot$test/fits3.fits"
+into the IRAF image test.imh.
+
+.YS
+da> rfits daophot$test/fits3.fits 1 test
+File: test Artificial Starfield Size = 51 x 51
+.YE
+
+When IRAF supports FITS format images on disk this step will no longer be
+necessary, although for some images it may still be desirable for
+image i/o efficiency reasons.
+
+.NH 2
+Editing the Image Headers
+
+.NH 3
+The Minimum Image Header Requirements
+
+.PP
+Before beginning DAOPHOT reductions the user must gather
+all the data required to determine the following quantities:
+1) the effective readout noise of the detector in electrons, 2) the effective
+gain of the detector in electrons per count, 3) the maximum good data value
+of the detector in counts, 4) the effective exposure time in any units
+as long as these units are identical for all the images to be analyzed
+together,
+5) the filter id, 6) the effective airmass of the observation at mid-exposure,
+and 7) the time of the observation.
+
+.NH 3
+The Effective Gain and Readout Noise
+
+.PP
+The DAOPHOT package tasks require correct effective
+gain and readout noise values for:
+1) the computation of the magnitude errors in the \fBphot\fR (gain only
+required), \fBpeak\fR, \fBnstar\fR and \fBallstar\fR tasks,
+2) the computation of the optimal weights used by the non-linear
+least-squares fitting code in the \fBpeak\fR, \fBnstar\fR, and
+\fBallstar\fR tasks,
+3) the computation of the predicted signal-to-noise
+ratios in the \fBgroup\fR task,
+4) the computation of the sharpness and chi statistics in the \fBpeak\fR,
+\fBnstar\fR, and \fBallstar\fR tasks, and 5) the correct computation of
+the poisson noise (gain only required) in the \fBaddstar\fR task.
+.PP
+Nominal gain and readout noise values for a single image
+should be obtained from the instrument
+scientist. These values should also be determined/checked empirically with the
+PROTO package task \fBfindgain\fR using bias and flat-field frames that
+are unprocessed and uncoadded so that the noise characteristics of the
+original data are preserved.
+.PP
+If the input image is the sum or average of several frames
+the gain and readout noise values in the image headers must be edited
+from single frame to effective gain and readout noise values
+as shown below. In the following examples
+gain and effective gain are in electrons / ADU,
+readout noise and effective readout noise are in electrons, and N is the
+number of individual frames which
+have been summed, averaged, or medianed to create the input image.
+
+.nf
+ [1]. The image is the sum of N frames
+
+ effective gain = gain
+ effective readout noise = sqrt (N) * readout noise
+
+ [2]. The image is the average of N frames
+
+ effective gain = N * gain
+ effective readout noise = sqrt (N) * readout noise
+
+ [3]. The image is the median of N frames
+
+ effective gain = 2.0 * N * gain / 3
+ effective readout noise = sqrt (2 * N / 3) * readout noise
+.fi
+
+.PP
+The following example shows how to add the correct values of gain and
+readout noise, which in this very artificial example are 1.0 and 0.0
+respectively, to the header of the test image with the \fBhedit\fR task.
+
+.YS
+da> imheader test l+
+test[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=71.00896, max=535.1335
+ Line storage mode, physdim [51,51], length of user area 163 s.u.
+ Created Mon 09:59:00 17-May-93, Last modified Mon 09:59:00 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+da> hedit test gain 1.0 add+ verify-
+add test,gain = 1.
+test updated
+da> hedit test rdnoise 0.0 add+ verify-
+add test,rdnoise = 0.
+test updated
+da> imheader test l+
+test[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=71.00896, max=535.1335
+ Line storage mode, physdim [51,51], length of user area 244 s.u.
+ Created Mon 09:59:00 17-May-93, Last modified Mon 09:59:00 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+ GAIN = 1.
+ RDNOISE = 0.\fR
+.YE
+
+.PP
+The following example shows how to correct the single frame
+values of gain and readout noise, already present in the input image
+header, to account for the fact that the input image is actually the
+average of three frames (note that the frames are NOT actually independent
+in this example!).
+
+.YS
+da> imsum test,test,test testav3 option=average
+da> hedit testav3 gain "(3.0*gain)" verify-
+testav3,GAIN: 1. -> 3.
+testav3 updated
+da> hedit testav3 rdnoise "(rdnoise*sqrt(3.0))" verify-
+testav3,RDNOISE: 0. -> 0.
+testav3 updated
+da> imheader testav3 l+
+testav3.imh[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=unknown, max=unknown
+ Line storage mode, physdim [51,51], length of user area 244 s.u.
+ Created Mon 11:02:22 17-May-93, Last modified Mon 11:02:22 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/testav3.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ New copy of test
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+ GAIN = 3.
+ RDNOISE = 0.
+.YE
+
+.NH 3
+The Maximum Good Data Value
+
+.PP
+Datamax is the maximum good data value in counts. Datamax
+is the count level at which the detector saturates or the count
+level at which it becomes non-linear, whichever is lower. DAOPHOT requires
+a correct value of datamax to: 1) identify bad data in the \fBdaofind\fR,
+\fBphot\fR, \fBpsf\fR, \fBpeak\fR, \fBgroup\fR, \fBnstar\fR,
+and \fBallstar\fR tasks, and 2) identify saturated stars in the \fBphot\fR,
+\fBpsf\fR, and \fBsubstar\fR tasks.
+.PP
+Users should be sure to allow adequate leeway for the detector bias level
+in their determination of datamax. Test is an artificial image
+linear over its entire data range. However as an example assume that it was
+actually observed with a detector which is linear from 0 to 25000 counts
+at a gain setting of 1.0, and that the mean bias level that was subtracted
+from the raw data was ~400 counts.
+In that case the user should set datamax to something like 24500 not 25000
+counts.
+.PP
+Datamax may be stored in the image header with \fBhedit\fR
+as shown below. The use of the header keyword gdatamax instead of
+datamax avoids any confusion with the reserved FITS keywords
+datamin and datamax should they already be present in the image header,
+or the IRAF keywords iraf-max and iraf-min which have the same meaning.
+
+.YS
+da> hedit test gdatamax 24500 add+ verify-
+add test,gdatamax = 24500
+test updated
+.YE
+
+.NH 3
+The Effective Exposure Time
+
+.PP
+The exposure time is used by the \fBphot\fR task to normalize the computed
+initial magnitudes to an effective exposure time of one time unit. The
+magnitude scale established in \fBphot\fR is preserved
+in all the subsequent DAOPHOT analysis. Setting the correct exposure
+time in the image headers before beginning DAOPHOT reductions will
+simplify the book-keeping required in the later calibration step
+significantly.
+.PP
+Exposure times should also be corrected
+for any timing errors in the instrument shutter, although this is normally
+important only for short exposure observations of standard stars.
+.PP
+The following example shows how to add the exposure time in seconds
+to the image header, and how to correct it for a known shutter error
+of 13 milli-seconds. Note that rather than overwrite the nominal exposure time
+exptime, the user has chosen to store the corrected exposure time in
+a new keyword cexptime.
+
+.YS
+da> hedit test exptime 1.0 add+ verify-
+add test,exptime = 1.
+test updated
+da> hedit test cexptime "(exptime+.013)" add+ verify-
+add test,cexptime = 1.013
+test updated
+da> imheader test l+
+test[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=71.00896, max=535.1335
+ Line storage mode, physdim [51,51], length of user area 365 s.u.
+ Created Mon 09:59:00 17-May-93, Last modified Mon 09:59:00 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+ GAIN = 1.
+ RDNOISE = 0.
+ GDATAMAX= 24500
+ EXPTIME = 1.
+ CEXPTIME= 1.013
+.YE
+
+.NH 3
+The Airmass, Filter Id, and Time of Observation
+
+.PP
+The airmass, filter id, and time of observation are not used directly by
+any of the DAOPHOT tasks. They are read from the image header and recorded
+in the output photometry files. Correctly setting the airmass,
+filter id, and the time of observation in the image headers before running
+any DAOPHOT tasks will however significantly reduce the book-keeping
+required in the subsequent calibration step.
+.PP
+The airmass can be computed and/or corrected to mid-exposure with the
+ASTUTIL package task \fBsetairmass\fR. By default \fBsetairmass\fR requires
+that the name of the observatory, date of observation, ra and dec, epoch of
+the ra and dec, sidereal time, and exposure time be recorded
+in the image header in the appropriate units in the keywords
+observat, date-obs, ra, dec, epoch, st, and exptime. Hopefully most or
+all of this information is already in the image header but in case
+it is not, the following example shows how to edit it in and run
+\fBsetairmass\fR.
+
+.YS
+da> hedit test observat "CTIO" add+ verify- show-
+da> hedit test "date-obs" "12/10/88" add+ verify- show-
+da> hedit test ra "(str('21:51:59.0'))" add+ verify- show-
+da> hedit test dec "(str('02:33:31.0'))" add+ verify- show-
+da> hedit test epoch 1985.0 add+ verify- show-
+da> hedit test st "(str('20:47:55.0'))" add+ verify- show-
+da> setairmass test show-
+da> imheader test l+
+test[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=71.00896, max=535.1335
+ Line storage mode, physdim [51,51], length of user area 649 s.u.
+ Created Mon 09:59:00 17-May-93, Last modified Mon 09:59:00 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+ GAIN = 1.
+ RDNOISE = 0.
+ GDATAMAX= 24500
+ EXPTIME = 1.
+ CEXPTIME= 1.013
+ OBSERVAT= 'CTIO '
+ DATE-OBS= '12/10/88'
+ RA = '21:51:59.0'
+ DEC = '02:33:31.0'
+ EPOCH = 1985.
+ ST = '20:47:55.0'
+ AIRMASS = 1.238106
+.YE
+
+The tortuous syntax required to enter the ra, dec, and st keywords is
+necessary in order to avoid \fBhedit\fR turning strings like
+"21:51:59.0" into numbers,
+e.g. 21.86639. \fBSetairmass\fR permits the user to change the
+default names for the date-obs and exptime image header keywords but
+not those of observat, ra, dec, epoch or st.
+To list the observatories in the IRAF observatory database and/or to find out
+how to deal with the case of data taken at an observatory not in the
+observatory database, the user should consult the help page for the
+\fBobservatory\fR task.
+.PP
+The filter id is a string defining the filter used to take the observations.
+It can be easily edited into the image header as shown below.
+
+.YS
+da> hedit test filters V add+ verify- show-
+.YE
+
+Users should be aware that any embedded blanks will be removed from the
+filter id after it is read from the image header, but before it is
+recorded in the photometry files. For example a filter id of "V band"
+in the image header will become "Vband" in the photometry file.
+.PP
+The time of observation is a string defining the time at which the
+observation was taken. The time of observation may be ut or local
+standard time. If the time of observation is not already recorded in
+the image header it can be entered in the usual fashion as shown below.
+
+.YS
+da> hedit test ut "(str('00:07:59.0'))" add+ verify- show-
+.YE
+
+.PP
+After editing the "final" image header should look something like the
+following.
+
+.YS
+da> imheader test l+
+test[51,51][real]: Artificial Starfield with Noise
+ No bad pixels, no histogram, min=71.00896, max=535.1335
+ Line storage mode, physdim [51,51], length of user area 730 s.u.
+ Created Mon 09:59:00 17-May-93, Last modified Mon 09:59:00 17-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.pix' [ok]
+ 'KPNO-IRAF' /
+ '10-05-93' /
+ IRAF-MAX= 5.351335E2 / DATA MAX
+ IRAF-MIN= 7.100896E1 / DATA MIN
+ IRAF-BPX= 32 / DATA BITS/PIXEL
+ IRAFTYPE= 'REAL ' / PIXEL TYPE
+ GAIN = 1.
+ RDNOISE = 0.
+ GDATAMAX= 24500
+ EXPTIME = 1.
+ CEXPTIME= 1.013
+ OBSERVAT= 'CTIO '
+ DATE-OBS= '12/10/88'
+ RA = '21:51:59.0'
+ DEC = '02:33:31.0'
+ EPOCH = 1985.
+ ST = '20:47:55.0'
+ AIRMASS = 1.238106
+ FILTER = 'V '
+ UT = '00:07:59.0'\fR
+.YE
+
+
+.NH 3
+Batch Header Editing
+
+.PP
+The previous examples described in detail how to enter each of the required
+keyword and value pairs into the image header using the \fBhedit\fR task.
+Users with large number of header keywords to enter should consider using the
+more batch oriented alternative task \fBasthedit\fR.
+
+
+.NH 2
+Editing, Checking, and Storing the Algorithm Parameters
+
+.NH 3
+The Critical Algorithm Parameters
+
+.PP
+The critical DAOPHOT algorithm parameters that should be set
+before beginning any DAOPHOT analysis are:
+1) the
+full-width at half-maximum of the psf \fIfwhmpsf\fR, the standard
+deviation of the sky background in counts \fIsigma\fR, the minimum and
+maximum good data values \fIdatamin\fR and \fIdatamax\fR, and the image
+header keyword parameters
+\fIccdread\fR, \fIgain\fR, \fIexposure\fR, \fIairmass\fR, \fIfilter\fR,
+and \fIobstimes\fR in the \fBdatapars\fR parameter set,
+2) the default centering algorithm \fIcalgorithm\fR and centering box
+\fIcbox\fR parameters in the \fBcenterpars\fR parameter set, 3) the sky fitting
+algorithm \fIsalgorithm\fR, and the sky annulus \fIannulus\fR and
+\fIdannulus\fR parameters in the \fBfitskypars\fR parameter set,
+4) the \fIapertures\fR parameter in the \fBphotpars\fR parameter set,
+and 5) the psf radius \fIpsfrad\fR
+and fitting radius \fIfitrad\fR parameters in the \fBdaopars\fR parameter set.
+The reamining parameters should be left at their default values, at least
+initially.
+
+.NH 3
+Editing the Algorithm Parameters Interactively with Daoedit
+
+.PP
+The DAOPHOT algorithm parameter editing task is \fBdaoedit\fR. \fBDaoedit\fR
+permits
+the user to edit all the algorithm parameter sets at once. It offers all the
+capabilities of the IRAF parameter editing task \fBepar\fR, plus the
+ability to set parameters using the displayed image and radial
+profile plots of isolated stars.
+.PP
+To run \fBdaoedit\fR the user displays the image, types \fBdaoedit\fR, and waits
+for the image cursor to appear ready to accept user commands. The following
+example summarizes a typical \fBdaoedit\fR parameter editing session.
+
+.YS
+da> display test 1 fi+
+da> daoedit test
+.YE
+
+.IP ...
+Execute the command \fB":epar datapars"\fR and enter the correct
+values for the \fIdatamax\fR parameter, and the image header
+keyword parameters \fIccdread\fR, \fIgain\fR, \fIexposure\fR, \fIairmass\fR,
+\fIfilter\fR, and \fIobstime\fR.
+.IP ...
+Choose a bright isolated star and execute the \fBr\fR cursor
+keystroke command to plot its radial profile.
+.IP ...
+From the information in the radial plot header and the plot
+itself estimate reasonable values for the full-width at
+half-maximum of the psf, the sky level, and the standard
+deviation of the sky level in the image.
+.IP ...
+Repeat the previous step for several stars in order to
+confirm that the original estimated values are reasonable.
+.IP ...
+Execute the \fB":epar datapars"\fR command once more and enter
+the estimated values of the full-width at half-maximum of the psf and
+the standard deviation of the sky background in the \fIfwhmpsf\fR
+and \fIsigma\fR parameters respectively.
+.IP ...
+Set the \fIdatamin\fR parameter to the estimated sky background level
+minus k times the standard deviation of the sky background, where
+k is a number between 5.0 and 7.0.
+
+.IP
+then
+
+.IP ...
+Execute the command \fB":epar centerpars"\fR and set the \fIcbox\fR
+parameter to 5 pixels or ~ 2 * \fIfwhmpsf\fR whichever is
+greater.
+.IP ...
+Execute the command \fB":epar fitskypars"\fR and set the \fIannulus\fR
+parameter to ~ 4 * \fIfwhmpsf\fR and the \fIdannulus\fR parameter to a
+number between 2.5 * \fIfwhmpsf\fR and 4.0 * \fIfwhmpsf\fR.
+.IP ...
+Execute the command \fB":epar photpars"\fR and set the apertures
+parameter to ~ 1.0 * fwhmpsf or 3 pixels whichever is greater.
+.IP ...
+Execute the command \fB":epar daopars"\fR and set the \fIpsfrad\fR
+parameter to ~ 4 * \fIfwhmpsf\fR + 1 and the \fIfitrad\fR parameter to
+~ 1.0 * \fIfwhmpsf\fR or 3 pixels whichever is greater.
+
+.IP
+or alternatively
+
+.IP ...
+Move to a bright star and execute the \fBi\fR cursor keystroke
+command to enter the interactive setup menu.
+.IP ...
+Mark the \fIfwhmpsf\fR, \fIcbox\fR, \fIannulus\fR, \fIdannulus\fR,
+\fIapertures\fR, \fIpsfrad\fR, and \fIfitrad\fR parameters with the
+graphics cursor on the displayed radial profile plot, and verify and/or
+roundoff the marked values.
+.PP
+The following sections discuss in detail how to edit each of the
+parameter sets using the test image as a specific example.
+
+.NH 4
+The Data Dependent Algorithm Parameters
+
+.PP
+A subset of the datapars parameters are used to specify the
+characteristics of the detector, including the saturation or linearity
+limit (\fIdatamax\fR) and noise model (\fIccdread\fR
+and \fIgain\fR), and the parameters of the observation, including
+exposure time (\fIexposure\fR),
+airmass (\fIairmass\fR), filter (\fIfilter\fR), and time of observation
+(\fIobstime\fR).
+.PP
+To edit the \fBdatapars\fR algorithm parameter set
+from within the \fBdaoedit\fR task the user enters the command
+\fB":epar datapars"\fR to invoke the \fBepar\fR task and edits the
+parameters in the usual manner.
+Editing is terminated with the usual \fB":wq"\fR command which returns the
+user to the main \fBdaoedit\fR command loop.
+.PP
+After the appropriate \fIdatamax\fR, \fIccdread\fR, \fIgain\fR,
+\fIexposure\fR, \fIairmass\fR,
+\fIfilter\fR, and \fIobstime\fR parameter values for the
+test image are entered, the \fBdatapars\fR
+parameter should look as follows.
+
+.YS
+Image Reduction and Analysis Facility
+PACKAGE = daophot
+ TASK = datapars
+
+(scale = 1.) Image scale in units per pixel
+(fwhmpsf= 2.5) FWHM of the PSF in scale units
+(emissio= yes) Features are positive ?
+(sigma = 0.) Standard deviation of background in counts
+(datamin= INDEF) Minimum good data value
+(datamax= 24500) Maximum good data value
+(noise = poisson) Noise model
+(ccdread= rdnoise) CCD readout noise image header keyword
+(gain = gain) CCD gain image header keyword
+(readnoi= 0.) CCD readout noise in electrons
+(epadu = 1.) Gain in electrons per count
+(exposur= cexptime) Exposure time image header keyword
+(airmass= airmass) Airmass image header keyword
+(filter = filter) Filter image header keyword
+(obstime= ut) Time of observation image header keyword
+(itime = 1.) Exposure time
+(xairmas= INDEF) Airmass
+(ifilter= INDEF) Filter
+(otime = INDEF) Time of observation
+(mode = ql)
+.YE
+
+.PP
+Users should realize that the values of the parameters \fIreadnoise\fR
+and \fIepadu\fR will be used for the gain and readout noise if the image
+header keywords specified by \fIccdread\fR and \fIgain\fR are not found
+in the image header or cannot be correctly decoded. Similarly the values of
+the \fIitime\fR,
+\fIxairmass\fR, \fIifilter\fR, and \fIotime\fR parameters will be used
+for the exposure time, airmass, filter id, and time of observation if
+the image header keywords specified by \fIexposure\fR, \fIairmass\fR,
+\fIfilter\fR, and \fIobstime\fR are not found in the image header
+or cannot be correctly decoded.
+.PP
+The \fBdatapars\fR parameters \fIfwhmpsf\fR, \fIsigma\fR, and \fIdatamin\fR
+are used to: 1) determine the size of star for which the \fBdaofind\fR star
+detection algorithm is optimized (fwhmpsf), 2) define the \fBdaofind\fR
+algorithm detection threshold for faint objects (sigma),
+3) define the fwhm of the psf for the \fBphot\fR task centering algorithms
+"gauss" and "ofilter" (fwhmpsf),
+4) supply a first guess for the true fwhm of the psf to the psf
+function fitting task \fBpsf\fR (fwhmpsf), 5) determine the
+minimum good data value
+in the \fBdaofind\fR, \fBphot\fR, \fBpsf\fR, \fBpeak\fR, \fBgroup\fR,
+\fBnstar\fR, and \fBallstar\fR tasks (datamin).
+.PP
+Reasonable values for these parameters can be obtained by examining the
+radial profile plots of several isolated stars from within the
+\fBdaoedit\fR task as outlined below:
+
+.IP ...
+Move the image cursor on the displayed image to a
+reasonably bright isolated star (a good candidate is
+the star at pixel 8,23 in the test image) and execute
+the \fBr\fR keystroke command.
+A radial and integrated profile plot of the selected
+star will appear on the screen with the largest photometry aperture radius,
+inner and outer radii of the sky annulus, and median sky level in the sky
+annulus marked on the plot.
+.IP ...
+Assuming that the plot is normal, note the computed
+fwhmpsf (2.6 rounded to the nearest tenth of a pixel for
+the star at 8,23), median sky value (100 counts rounded
+to the nearest count for the star at 8,23), and standard
+deviation of the sky values (10 counts rounded to the
+nearest count for the star at 8,23) written in the plot header.
+These numbers suggest a value of ~50 for datamin (50 is ~5
+standard deviations of the background counts below the
+background count estimate)
+.IP ...
+Edit the estimated values into the datapars pset by
+typing the command \fB":epar datapars"\fR, entering the values,
+and typing \fB":wq"\fR to update the parameter set.
+
+.IP
+or
+
+.IP ...
+Enter them individually using the daoedit colon commands,
+e.g. \fB":fwhmpsf 2.5"\fR, \fB":sigma 10.0"\fR, and \fB":datamin 50.0"\fR.
+.IP ...
+Check the new values of \fIfwhmpsf\fR, \fIsigma\fR, and \fIdatamin\fR
+by doing radial profile plots of several
+other isolated stars (the stars at 36,42 and 41,4 in
+the test image are good test stars).
+.IP ...
+On the basis of the estimated \fIfwhmpsf\fR of these stars change the
+fwhmpsf parameter back to 2.5 with the command
+\fB":fwhmpsf 2.5"\fR.
+.IP ...
+Check that the observed standard deviation of the sky
+background, sigma, agrees reasonably well with the
+predicted value, psigma, based on the median sky level,
+and the effective gain and readout noise of the image.
+For the test image these numbers are related as shown below.
+
+.nf
+ psigma = sqrt (median sky / effective gain +
+ (effective rdnoise / effective gain) ** 2)
+ ~ sqrt (100.0 / 1.0 + (0. / 1.0) ** 2)
+ ~ 10.0
+ ~ sigma
+.fi
+
+.IP ...
+If psigma and sigma are significantly different check
+that the sky region is uncrowded, that the effective
+gain and readout noise values are correct, and that
+earlier reduction procedures have not altered the image
+statistics in some fundamental manner
+
+.PP
+The \fIemission\fR parameter must be left at "yes",
+since DAOPHOT assumes that stars are local maxima not local minima.
+.PP
+The \fInoise\fR parameter must be left at "poisson" since poisson noise
+statistics are assumed throughout the DAOPHOT package.
+.PP
+The \fIscale\fR parameter defines the units in which radial distances
+in the image will be measured. For example if the image scale
+is 0.25 "/pixel, users can set \fIscale\fR to 0.25 if they wish
+to define the \fIfwhmpsf\fR, \fIcbox\fR, \fIannulus\fR, \fIdannulus\fR,
+\fIapertures\fR, \fIpsfrad\fR, \fIfitrad\fR and all the other algorithm
+parameters which are defined in terms of a radial distance in arc-seconds.
+For simplicity most users choose to leave scale set to 1.0 and
+work in pixels.
+.PP
+The final version of the \fBdatapars\fR parameter set should look something
+like the following.
+
+.YS
+Image Reduction and Analysis Facility
+PACKAGE = daophot
+ TASK = datapars
+
+(scale = 1.) Image scale in units per pixel
+(fwhmpsf= 2.5) FWHM of the PSF in scale units
+(emissio= yes) Features are positive ?
+(sigma = 10.) Standard deviation of background in counts
+(datamin= 50.) Minimum good data value
+(datamax= 24500) Maximum good data value
+(noise = poisson) Noise model
+(ccdread= rdnoise) CCD readout noise image header keyword
+(gain = gain) CCD gain image header keyword
+(readnoi= 0.) CCD readout noise in electrons
+(epadu = 1.) Gain in electrons per count
+(exposur= cexptime) Exposure time image header keyword
+(airmass= airmass) Airmass image header keyword
+(filter = filter) Filter image header keyword
+(obstime= obstime) Time of observation image header keyword
+(itime = 1.0) Exposure time
+(xairmas= INDEF) Airmass
+(ifilter= INDEF) Filter
+(otime = INDEF) Time of observation
+(mode = ql)
+.YE
+
+
+.NH 4
+The Centering Algorithm Parameters
+
+.PP
+The \fBcenterpars\fR parameter set controls the centering algorithms used by
+the \fBphot\fR aperture photometry task. DAOPHOT users should concern
+themselves with only two of these parameters, \fIcalgorithm\fR and \fIcbox\fR,
+and leave the remaining \fBcenterpars\fR parameters at their default values.
+.PP
+\fICalgorithm\fR specifies the default \fBphot\fR centering algorithm. Its value
+should be "none" if the input coordinate list is the output of the
+\fBdaofind\fR task, or "centroid", "gauss", or "ofilter" if the input
+coordinate list was
+created with the image or graphics cursor list tasks \fBrimcursor\fR
+or \fBrgcursor\fR or the coordinates are
+read from the image cursor in interactive mode. The choice of centering
+algorithm is not critical since the centers are recomputed using accurate
+non-linear least-squares fitting techniques during the psf fitting
+process. The most efficient and simplest choice is "centroid", although
+more accurate results may be obtained with "gauss" which is
+very similar to the centering algorithm used in \fBdaofind\fR.
+.PP
+The \fIcbox\fR
+parameter determines the width in scale units of the data used to compute
+the center if \fIcalgorithm \fR is not "none".
+For reasonable results \fIcbox\fR should be set to the equivalent of 5 or
+~ 2 * \fIfwhmpsf\fR in pixels whichever is larger.
+.PP
+\fBCenterpars\fR can be edited from within the \fBdaoedit\fR task
+with the command \fB":epar centerpars"\fR. After editing, the \fBcenterpars\fR
+parameter set should look like the example below. Note that for the test
+image \fIfwhmpsf\fR is ~2.5 pixels so \fIcbox\fR is left at 5.0.
+
+.YS
+PACKAGE = daophot
+TASK = centerpars
+
+(calgori= none) Centering algorithm
+(cbox = 5.) Centering box width in scale units
+(cthresh= 0.) Centering threshold in sigma above background
+(minsnra= 1.) Minimum signal-to-noise ratio
+(cmaxite= 10) Maximum iterations
+(maxshif= 1.) Maximum center shift in scale units
+(clean = no) Symmetry clean before centering
+(rclean = 1.) Cleaning radius in scale units
+(rclip = 2.) Clipping radius in scale units
+(kclean = 3.) K-sigma rejection criterion in skysigma
+(mkcente= no) Mark the computed center
+(mode = ql)
+.YE
+
+.NH 4
+The Sky Fitting Algorithm Parameters
+
+.PP
+The \fBfitskypars\fR parameter set controls the sky fitting algorithm
+parameters used by the \fBphot\fR task. At this point DAOPHOT users should
+concern themselves with only three of these parameters: \fIsalgorithm\fR,
+\fIannulus\fR, and \fIdannulus\fR.
+.PP
+Users should realize that the \fBphot\fR task computes sky values
+for the individual stars, and that these values are
+used in the \fBpsf\fR task to compute the psf, averaged to form a group sky
+value in the \fBpeak\fR, \fBnstar\fR and \fBallstar\fR tasks if sky refitting
+is disabled (the default) or an initial sky value if sky refitting
+is enabled, and used
+to compute the predicted signal-to-noise ratios in the \fBgroup\fR task.
+Although the option to refit the skies at a later stage of analysis exists,
+there are difficulties associated with this choice. It is
+in the user's best interest to determine the skies as accurately as
+possible as early as possible, since sky determination will probably be
+the single most important factor in doing good photometry.
+.PP
+In cases where contamination of the sky region is mostly due
+to crowding by neighboring stars users should use the default sky fitting
+algorithm "mode"; if the variations in the background are due instead
+to nebulosity or large contaminating objects so that the sky statistics are
+confused
+"median", "centroid", or "crosscor" might be a better choice; in cases
+where the sky statistics
+are so poor that the histogram is aliased, undersampled, or sparse such
+as might be the case with
+very low sky backgrounds "mean" might be the best choice.
+When in doubt about the correct choice the user should leave \fIsalgorithm\fR
+at "mode" but examine the results carefully for accuracy at each step.
+.PP
+A good starting value for the inner radius of the sky annulus is ~ 4 *
+\fIfwhmpsf\fR
+or ~ 10 pixels for the test image. The width of the sky annulus should be
+sufficient to give a reasonable sample of sky pixels, >= 5 pixels. We have
+chosen a dannulus of ~4 * \fIfwhmpsf\fR or 10 pixels for the test image.
+.PP
+\fBFitskypars\fR can be edited from within the \fBdaoedit\fR task
+with the command \fB":epar fitskypars"\fR. After editing the \fBfitskypars\fR
+parameter set should look like the example below.
+
+.YS
+PACKAGE = daophot
+TASK = fitskypars
+
+(salgori= mode) Sky fitting algorithm
+(annulus= 10.) Inner radius of sky annulus in scale units
+(dannulu= 10.) Width of sky annulus in scale units
+(skyvalu= 0.) User sky value
+(smaxite= 10) Maximum number of sky fitting iterations
+(sloclip= 0.) Lower clipping factor in percent
+(shiclip= 0.) Upper clipping factor in percent
+(snrejec= 50) Maximum number of sky fitting rejection iteratio
+(sloreje= 3.) Lower K-sigma rejection limit in sky sigma
+(shireje= 3.) Upper K-sigma rejection limit in sky sigma
+(khist = 3.) Half width of histogram in sky sigma
+(binsize= 0.1) Binsize of histogram in sky sigma
+(smooth = no) Boxcar smooth the histogram
+(rgrow = 0.) Region growing radius in scale units
+(mksky = no) Mark sky annuli on the display
+(mode = ql)
+.YE
+
+.NH 4
+The Aperture Photometry Parameters
+
+.PP
+The \fBphotpars\fR parameter set controls the aperture photometry algorithm
+parameters used by the \fBphot\fR task. At this point DAOPHOT users should
+concern themselves with only one of these, \fIapertures\fR, the radius
+of the aperture through which the initial magnitudes will be computed.
+A good rule of thumb is to set the aperture radius to the maximum
+of 3 pixels or 1.0 * \fIfwhmpsf\fR pixels. Although magnitudes can be measured
+through more than one aperture at a time, it is the magnitude of the
+smallest aperture radius along with \fIzmag\fR and the exposure time
+which set the DAOPHOT instrumental magnitude scale, and
+the magnitudes through the other apertures contribute nothing to the
+DAOPHOT analysis until it comes time to compute accurate aperture
+corrections. Therefore it is in the user's best interest to set \fIapertures\fR
+to a single value at this point and carefully record it.
+.PP
+\fBPhotpars\fR can be edited from within the \fBdaoedit\fR task
+with the command \fB":epar photpars"\fR. After editing the \fBphotpars\fR
+parameter set should look like the example below. Note that in this example
+\fIfwhmpsf\fR is ~2.5 pixels so \fIapertures\fR is left at 3.0.
+
+.YS
+PACKAGE = daophot
+TASK = photpars
+
+(weighti= constant) Photometric weighting scheme
+(apertur= 3.0) List of aperture radii in scale units
+(zmag = 25.) Zero point of magnitude scale
+(mkapert= no) Draw apertures on the display
+(mode = ql)
+.YE
+
+.NH 4
+The Psf Modeling and Fitting Parameters
+
+.PP
+The \fBdaopars\fR parameter set controls the psf computation, star grouping,
+and psf fitting
+parameters used by the \fBpstselect\fR, \fBpsf\fR, \fBpeak\fR,
+\fBgroup\fR, \fBnstar\fR,
+\fBallstar\fR, \fBsubstar\fR, and \fBaddstar\fR tasks. At this point
+DAOPHOT users should
+concern themselves with only two of these parameters \fIpsfrad\fR, the radius
+over which the psf will be defined, and \fIfitrad\fR, the radius
+over which the psf will be fit to the individual stars. A good rule of thumb is
+to set \fIpsfrad\fR to the radius at which the radial profile of the brightest
+star of interest disappears into the noise plus 1, something like
+~ 4 * \fIfwhmpsf\fR + 1, and
+to set \fIfitrad\fR to the maximum of 3 pixels or ~ 1 * \fIfwhmpsf\fR in pixels.
+
+.PP
+\fBDaopars\fR can be edited from within the daoedit task
+with the command \fB":epar daopars"\fR. After editing the \fBdaopars\fR
+parameter set should look something like the example below for the
+test image.
+
+.YS
+PACKAGE = daophot
+TASK = daopars
+
+(functio= gauss) Analytic component of psf
+(varorde= 0) Order of psf variation
+(nclean = 0) Number of cleaning passes
+(saturat= no) Use wings of saturated stars
+(matchra= 3.) Matching radius in scale units
+(psfrad = 11.) Radius of psf in scale units
+(fitrad = 3.) Fitting radius in scale units
+(recente= yes) Recenter stars during fit
+(fitsky = no) Recompute group sky value during fit
+(sannulu= 0.) Inner radius of sky annulus in scale units
+(wsannul= 11.) Width of sky annulus in scale units
+(flaterr= 0.75) Flat field error in percent
+(proferr= 5.) Profile error in percent
+(maxiter= 50) Maximum number of iterations
+(clipexp= 6) Data clipping exponent
+(clipran= 2.5) Data clipping range in sigma
+(critove= 1.) Critical overlap group for membership
+(maxnsta= 10000) Maximum number of stars to fit
+(maxgrou= 60) Maximum number of stars to fit per group
+(mode = ql)
+.YE
+
+.NH 4
+Setting the Algorithm Parameters Graphically
+
+.PP
+Each of the radial distance dependent parameters \fIfwhmpsf\fR,
+\fIcbox\fR, \fIannulus\fR, \fIdannulus\fR, \fIapertures,\fR,
+\fIpsfrad\fR, \fIfitrad\fR can be edited
+individually and interactively by marking the current radial profile
+plot with the
+graphics cursor after executing the appropriate keystroke command.
+For example the \fBf\fR keystroke command will prompt the user to
+mark the fwhm of
+the psf on the current radial profile plot,
+verify the marked value, and update the \fIfwhmpsf\fR parameter.
+.PP
+All the radial distance dependent parameters listed above
+can be edited at once my moving the
+image cursor to a bright star, typing the \fB daoedit i\fR keystroke command
+to invoke the interactive graphics setup menu.
+The size of the radial profile plot and the sky regions
+are set by the \fIscale\fR, \fIannulus\fR, and \fIdannulus\fR parameters.
+The centering algorithm
+used is always "centroid" regardless of the value of the \fIcalgorithm\fR
+parameter, \fIcbox\fR and \fIscale\fR determine the centering box size,
+and the photometry is computed inside the largest aperture specified by
+the \fIapertures\fR parameter. After the user finishes marking all the
+parameters on the plot
+he/she is given an opportunity to verify or edit the results, e.g., change the
+value for fwhmpsf from 2.536 as read from the graphics cursor to 2.5.
+
+.NH 3
+Checking the Algorithm Parameters with Daoedit
+
+.PP
+The purpose of setting all the critical algorithm parameters to reasonable
+values before beginning any DAOPHOT analysis, is to ensure that the user
+gets off to a good start. Although setting the parameters to unreasonable
+values often results in bizarre results which are immediately obvious,
+e.g., the detection of thousands of
+noise spikes, the problems can sometimes be more subtle.
+For example, a sky annulus that is too close to the star will result in
+measured sky values which are too high and poor subtractions of
+the fitted stars which may not be discovered until the user has
+become thoroughly exasperated trying to produce good fits to the psf
+stars.
+.PP
+The current DAOPHOT algorithm parameters can be checked at any time with
+the \fBdaoedit\fR task and the \fB":lpar"\fR command. For example the
+\fBdatapars\fR parameters set can be listed with the \fBdaoedit
+":lpar datapars"\fR command. The remaining parameters sets \fBfindpars\fR,
+\fBcenterpars\fR, \fBfitskypars\fR, \fBphotpars\fR, and \fBdaopars\fR
+may be listed in the same way.
+.PP
+When listing the algorithm parameters users should check that:
+.IP [1]
+the \fBdatapars\fR image header keyword parameters \fIccdread\fR, \fIgain\fR,
+\fIexposure\fR, \fIairmass\fR, \fIfilter\fR, and \fIobstime\fR are
+properly set.
+.IP [2]
+the \fBdatapars\fR \fIfwhmpsf\fR, \fIsigma\fR, \fIdatamin\fR, and \fIdatamax\fR parameters
+are appropriate for the image. Be especially careful of datamin as the
+correct value for this parameter varies with the mean sky.
+.IP [3]
+the \fBdatapars\fR parameter \fIscale\fR is 1.0 unless the user is
+thoroughly aware of the meaning of this parameter and the consequences
+of setting it to something other than 1.0, and \fIemission\fR is "yes".
+.IP [4]
+the \fBcenterpars\fR \fIcbox\fR parameter is
+appropriate for the image and the remaining \fBcenterpars\fR parameters
+are at their default values unless the user
+really understands the consequences of altering these parameters.
+.IP [5]
+the \fBfitskypars\fR \fIannulus\fR, and \fIdannulus\fR
+parameters are appropriate for the image and the remaining \fBfitkskypars\fR
+parameters are at their default values unless the user really
+understands the consequences of altering these parameters.
+.IP [6]
+the \fBphotpars\fR \fIapertures\fR parameter is appropriate for the image
+and the remaining parameters are at their default values unless the user
+really understands the consequences of altering these parameters.
+.IP [6]
+the \fBdaopars\fR \fIpsfrad\fR and \fIfitrad\fR parameters are appropriate
+for the image and all the remaining \fBdaopars\fR parameters are at their
+default values unless the user really understands the consequences of
+altering these parameters.
+
+.NH 3
+Storing the Algorithm Parameter Values with Setimpars
+
+.PP
+The current values of all the algorithm parameters for a particular
+image may be saved in a file on disk at any
+point in the reduction sequence by executing the \fBsetimpars\fR task.
+The following command saves the current values of the parameters for
+the test image in a file called "test.pars".
+
+.YS
+da> setimpars test no yes
+.YE
+
+Repeating the previous command at any point in the reduction sequence will
+replace the stored parameter values with the current parameter values.
+
+
+.NH 3
+Restoring the Algorithm Parameter Values with Setimpars
+
+.PP
+At some point the user may wish to interrupt work on a particular image and
+begin work on a different image. This should be no problem as long as the
+user remembers to save the algorithm parameter sets with \fBsetimpars\fR
+as described in the previous section.
+.PP
+The command to restore the algorithm parameter sets for the test image is:
+
+.YS
+da> setimpars test yes no
+.YE
+
+or
+
+.YS
+da> setimpars test yes no parfile=test.pars
+.YE
+
+
+.NH 2
+Creating a Star List
+
+.PP
+The initial input to the DAOPHOT package is a star list.
+Star lists may be created with the DAOPHOT package task \fBdaofind\fR,
+interactively with the image or graphics cursor (the
+\fBrimcursor\fR and \fBrgcursor\fR tasks), by another IRAF task, or by
+any user program which writes a text file in the correct format.
+.PP
+Legal star lists are text files containing a list of stars, one star
+per line with the x and y coordinates in columns one and two.
+Blank lines, lines beginning with "#", and lines containing anything other
+than numbers in columns one and two are ignored.
+A sample DAOPHOT star list is shown below.
+
+.YS
+# Artificial Stars for Image Test
+
+ 41.0 4.0 17.268
+ 23.0 7.0 17.600
+ 18.0 8.0 17.596
+ 26.0 22.0 16.777
+ 36.0 22.0 16.317
+ 8.0 23.0 16.631
+ 31.0 25.0 16.990
+ 21.0 26.0 19.462
+ 29.0 34.0 17.606
+ 36.0 42.0 16.544
+.YE
+
+.NH 3
+The Daofind Task
+
+.PP
+The \fBdaofind\fR task, searches for point sources
+in an image whose peak intensities are above some user-defined threshold,
+computes approximate centers, magnitudes, and
+shape characteristics for all the detected objects, and writes the results
+to the output star list.
+
+.NH 4
+The Daofind Algorithm
+
+.PP
+By default the \fBdaofind\fR algorithm performs the following steps:
+.IP[1]
+reads the \fBdaofind\fR task parameters, including the input image
+and output star list names and the \fBdatapars\fR and \fBfindpars\fR
+algorithm parameters, and asks the user to verify the
+\fIfwhmpsf\fR, \fIsigma\fR,
+\fIthreshold\fR, \fIdatamin\fR, and \fIdatamax\fR parameters
+.IP[2]
+calculates the convolution kernel whose mathematical function when
+convolved with the input image is to
+compute the amplitude of the best-fitting Gaussian of
+full-width half-maximum \fIfwhmpsf\fR at each point in the input image
+.IP[3]
+convolves the input image with the convolution kernel after
+eliminating bad data with the \fIdatamin\fR and \fIdatamax\fR parameters,
+and writes the results to a temporary convolved image
+.IP[4]
+searches for local maxima in the convolved image whose amplitudes are greater
+than the detection threshold, and greater than the amplitudes of any neighbors
+within a region the size of the convolution kernel
+.IP[5]
+computes approximate centers, magnitudes, and shape
+statistics for these local maxima
+.IP[6]
+eliminates local maxima whose centers are outside the image, and whose
+sharpness and roundness statistics are outside the limits set by the user
+.IP[7]
+writes the centers, approximate magnitudes, sharpness and roundness
+statistics, and id number for the remaining local maxima, to the
+output star list
+.IP[8]
+deletes the convolved image
+
+.NH 4
+The Daofind Algorithm Parameters
+
+.PP
+The critical \fBdaofind\fR algorithm parameters are \fIfwhmpsf\fR,
+\fIdatamin\fR, \fIdatamax\fR, \fIsigma\fR, and \fIthreshold\fR.
+These parameters are verified at startup time by \fBdaofind\fR.
+.PP
+The \fIfwhmpsf\fR parameter should be close
+to the true full-width at half-maximum of the psf in order
+to optimize the detection algorithm for stellar objects. If \fIfwhmpsf\fR
+is too far from the true value, stars may be omitted from the star list
+and/or non-stellar objects added to it.
+.PP
+The \fIdatamin\fR and \fIdatamax\fR parameters are used to flag and remove
+bad data from the convolved image.
+If \fIdatamin\fR and \fIdatamax\fR are
+too far from the true value stars may be omitted from the star list
+and/or non-stellar objects added to it.
+.PP
+The \fIsigma\fR parameter should be close to the true standard deviation of
+the sky background in an uncrowded region of the frame. This parameter
+in combination with \fIthreshold\fR
+determines the detection threshold in counts for faint objects. If it is
+incorrect either too few or too many objects will be detected.
+.PP
+The \fIthreshold\fR parameter should normally be set to some small
+number between 3.0 and 5.0. If threshold is too big only
+the brightest stars will be detected. If threshold is too small too
+many noise spikes will be detected.
+
+.NH 4
+Running Daofind Non-Interactively
+
+.PP
+The following example shows how to run \fBdaofind\fR in non-interactive mode.
+
+.YS
+da> daofind test default
+
+FWHM of features in scale units (2.5) (CR or value):
+ New FWHM of features: 2.5 scale units 2.5 pixels
+Standard deviation of background in counts (10.) (CR or value):
+ New standard deviation of background: 10. counts
+Detection threshold in sigma (4.) (CR or value):
+ New detection threshold: 4. sigma 40. counts
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Image: test.imh fwhmpsf: 2.5 ratio: 1. theta: 0. nsigma: 1.5
+
+ 40.97 4.02 -1.663 0.612 0.017 1
+ 23.06 7.03 -1.214 0.636 -0.019 2
+ 18.02 7.96 -1.318 0.622 0.010 3
+ 25.99 22.01 -2.167 0.658 0.001 4
+ 35.98 22.00 -2.499 0.572 -0.039 5
+ 8.02 22.97 -2.239 0.550 0.068 6
+ 30.97 25.01 -1.934 0.711 -0.044 7
+ 28.96 33.92 -1.087 0.418 0.132 8
+ 35.98 42.03 -2.332 0.639 0.108 9
+
+threshold: 40. relerr: 1.140 0.2 <= sharp <= 1. -1. <= round <= 1.\fR
+.YE
+
+If this is the first time \fBdaofind\fR has been run the results will appear
+in the file "test.coo.1".
+.PP
+The detected objects can be marked on the image display using the
+\fBtvmark\fR task as shown below.
+
+.YS
+da> display test 1 fi+
+da> tvmark 1 test.coo.1 col=204
+.YE
+
+In this example the detected stars will be marked on the displayed image
+as red dots. If too many faints stars have been missed the user
+can rerun \fBdaofind\fR with a lower value of the \fIthreshold\fR
+parameter.
+
+.NH 4
+Running Daofind Interactively
+
+.PP
+\fBDaofind\fR may also be run in interactive mode.
+Most users will only exercise this option for small images which do not
+require long cpu/elapsed times to perform the convolution.
+.PP
+The following example shows how to run \fBdaofind\fR interactively.
+
+.YS
+da> display test 1 fi+
+
+da> daofind test default inter+
+.YE
+
+.IP ...
+Type the \fBv\fR keystroke command to verify the critical algorithm
+parameters.
+.LP
+
+.YS
+FWHM of features in scale units (2.5) (CR or value):
+ New FWHM of features: 2.5 scale units 2.5 pixels
+Standard deviation of background in counts (10.) (CR or value):
+ New standard deviation of background: 10. counts
+Detection threshold in sigma (4.) (CR or value):
+ New detection threshold: 4. sigma 40. counts
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+.YE
+
+.IP ...
+Type the \fBspacebar\fR keystroke command to detect the objects and write them
+out to the star list file.
+.LP
+
+.YS
+Image: test.imh fwhmpsf: 2.5 ratio: 1. theta: 0. nsigma: 1.5
+
+ 40.97 4.02 -1.663 0.612 0.017 1
+ 23.06 7.03 -1.214 0.636 -0.019 2
+ 18.02 7.96 -1.318 0.622 0.010 3
+ 25.99 22.01 -2.167 0.658 0.001 4
+ 35.98 22.00 -2.499 0.572 -0.039 5
+ 8.02 22.97 -2.239 0.550 0.068 6
+ 30.97 25.01 -1.934 0.711 -0.044 7
+ 28.96 33.92 -1.087 0.418 0.132 8
+ 35.98 42.03 -2.332 0.639 0.108 9
+
+threshold: 40. relerr: 1.140 0.2 <= sharp <= 1. -1. <= round <= 1.
+
+Output file: test.coo.1
+.YE
+
+.IP ...
+Change \fIthreshold\fR to 3.0 with the colon command \fB:threshold 3.0\fR.
+.IP ...
+Type the \fBspacebar\fR keystroke command to detect the objects and write
+them out to a new star list file.
+.LP
+
+.YS
+Image: test.imh fwhmpsf: 2.5 ratio: 1. theta: 0. nsigma: 1.5
+
+ 40.97 4.02 -1.975 0.577 0.017 1
+ 23.06 7.03 -1.526 0.604 -0.019 2
+ 18.02 7.96 -1.631 0.587 0.010 3
+ 25.99 22.01 -2.480 0.626 0.001 4
+ 35.98 22.00 -2.811 0.537 -0.039 5
+ 8.02 22.97 -2.551 0.515 0.068 6
+ 30.97 25.01 -2.246 0.681 -0.044 7
+ 21.27 25.94 -0.146 0.804 -0.558 8
+ 28.96 33.92 -1.400 0.379 0.132 9
+ 35.98 42.03 -2.645 0.606 0.108 10
+
+threshold: 30. relerr: 1.140 0.2 <= sharp <= 1. -1. <= round <= 1.
+
+Output file: test.coo.2
+.YE
+
+.IP ...
+Change \fIthreshold\fR to 5.0 with the colon command \fB:threshold 5.0.
+.IP ...
+Type the \fBspacebar\fR keystroke command to detect the objects and write them
+out to a new coordinate file.
+.LP
+
+.YS
+Image: test.imh fwhmpsf: 2.5 ratio: 1. theta: 0. nsigma: 1.5
+
+ 40.97 4.02 -1.420 0.577 0.017 1
+ 23.06 7.03 -0.972 0.604 -0.019 2
+ 18.02 7.96 -1.076 0.587 0.010 3
+ 25.99 22.01 -1.925 0.626 0.001 4
+ 35.98 22.00 -2.257 0.537 -0.039 5
+ 8.02 22.97 -1.997 0.515 0.068 6
+ 30.97 25.01 -1.692 0.681 -0.044 7
+ 28.96 33.92 -0.845 0.379 0.132 8
+ 35.98 42.03 -2.090 0.606 0.108 9
+
+threshold: 50. relerr: 1.140 0.2 <= sharp <= 1. -1. <= round <= 1.
+
+Output file: test.coo.3
+.YE
+
+.IP ...
+Type the \fBq\fR keystroke, first in the image display window then the
+text window to quit the task.
+.LP
+
+If this is the first run of \fBdaofind\fR,
+the three star list files for the \fIthreshold\fR values of
+4.0, 3.0, and 5.0 will be written to "test.coo.1", "test.coo.2", and
+"test.coo.3" respectively.
+.PP
+The \fBdaofind\fR results for different thresholds can be evaluated by
+marking the detected objects on the image display using the \fBtvmark\fR
+task and different
+colors for each threshold. In the following example objects detected
+at threshold=3.0 are marked in red, at threshold=4.0 in green, at threshold=
+5.0 in blue.
+
+.YS
+da> display test 1 fi+
+da> tvmark 1 test.coo.2 col=204 point=3
+da> tvmark 1 test.coo.1 col=205 point=3
+da> tvmark 1 test.coo.3 col=206 point=3
+.YE
+
+Note that the identical stars were detected at thresholds 4.0 and 5.0 but
+the faint star at 21,26 was only detected at threshold=3.0.
+.PP
+In this example the user decides that threshold = 4.0 is the
+"best" threshold, sets the \fIthreshold\fR parameter appropriately as shown
+below, and deletes the the star lists for threshold = 3.0 and threshold = 5.0.
+
+.YS
+da> findpars.threshold = 4.0
+da> delete test.coo.2,test.coo.3
+.YE
+
+.NH 4
+The Daofind Output
+
+.PP
+The quantities xcenter, ycenter, mag, sharpness, roundness, and id
+are recorded for each detected object. Each is described briefly below.
+.IP [1]
+\fIXcenter\fR and \fIycenter\fR are the coordinates of
+the detected object in fractional pixel units. They are computed by
+fitting one-dimensional Gaussian functions of full-width at half-maximum
+\fIfwhmpsf\fR to the x and y marginal pixel distributions centered on
+the star. The computed coordinates can be overlaid on the
+displayed image with the \fBtvmark\fR command.
+.IP [2]
+The estimated magnitude is measured relative to the detection threshold
+and is defined as
+
+.YS
+mag = -2.5 * log10 (density / (relerr * threshold * sigma))
+.YE
+
+where density is the peak density of the object in the convolved image,
+relerr an internally
+computed factor measuring the amount by which the standard error in one pixel
+in the input image must be multiplied to obtain the standard error
+in one pixel in the convolved image, and threshold and sigma
+are the values of the corresponding \fIthreshold\fR and \fIsigma\fR
+parameters. For stellar
+objects the computed magnitude is directly proportional to the true
+magnitude of the star. Stars with a peak density exactly equal to
+the detection threshold will have a magnitude of 0.0. The remaining
+stars will have negative magnitudes.
+.IP [3]
+The sharpness statistic is the ratio of the amplitude of the best fitting
+delta function at the position of a detected object to the amplitude of
+the best fitting gaussian at the same position as shown below.
+
+.YS
+sharpness = (data - <data>) / density
+.YE
+
+The amplitude of the best fitting gaussian is simply the density
+of the detected object in the convolved image.
+The amplitude of the best fitting delta function is defined
+as corresponding original image data value minus the average of all
+the neighboring
+pixels in the image <data>. Typical values of sharpness are of ~0.6 for
+approximately gaussian stars and \fInsigma\fR = 1.5.
+Hot pixels will have sharpness values >> 1 and cold pixels will have
+sharpness values
+of ~0, hence reasonable limits for the \fIsharphi\fR and \fIsharplo\fR
+parameters are 1.0 and 0.2 respectively.
+Increasing the size of convolution box defined by the
+\fInsigma\fR parameter from its default value of 1.5 to a larger value
+(smaller values should be avoided !) while keeping the \fIfwhmpsf\fR the
+same, will increase the average value of the sharpness statistic because
+more pixels further from the center of the star are included in the
+computation of <data>. If \fInsigma\fR is changed
+the \fBfindpars\fR parameters \fIsharphi\fR and \fIsharplo\fR
+will also need to be changed.
+.IP [4]
+The roundness statistic is computed by fitting a one-dimensional
+gaussian function of full-width at half-maximum \fIfwhmpsf\fR to the
+x and y marginal pixel distributions.
+
+.YS
+roundness = 2.0 * (hx - hy) / (hx + hy)
+.YE
+
+hx and hy are the heights of the best fitting one-dimensional
+gaussians in x and y. A totally
+round object will have a roundness of ~ 0.0. If the object is very
+elongated in x roundness will be a large negative number; a large positive
+number if it is elongated in y. The roundness statistic is
+effective at filtering out bad columns and rows of data. It is not
+effective at filtering out objects elongated at intermediate angles.
+.IP [5]
+Id is a sequence number which identifies the star.
+
+.NH 4
+Examining the Daofind Output
+
+.PP
+The easiest way to check that \fBdaofind\fR is performing correctly is to mark
+the detected stars on the image display with \fBtvmark\fR.
+.PP
+If the marked image suggests that \fBdaofind\fR is detecting too few or
+too many stars the first items to check are the the values of the
+\fIsigma\fR and \fIthreshold\fR parameters since these parameters determine the
+detection threshold. Sigma should be
+the standard deviation of the sky pixels in an uncrowded region of the image.
+Threshold should normally be some number between 3.0 and 5.0. If sigma
+and threshold are reasonable the user should compare the observed value of
+sigma with the predicted value derived from the median background level and the
+effective gain and readout noise values. If there is a significant
+mismatch in these numbers the user should check the reduction history of the
+image. The number of spurious detections goes up dramatically for
+thresholds less than ~3.0 * sigma. A plot of number
+of detections versus threshold will show a change in slope at some point below
+this threshold. Users who wish to detect faint objects while keeping
+spurious detections at a manageable minimum should
+set the detection threshold to a value just above the threshold at
+which this change in slope occurs.
+.PP
+Users should also check the values of the
+parameters \fIsharplo\fR, \fIsharphi\fR,
+\fIroundlo\fR, and \fIroundhi\fR parameters to ensure that
+detected objects are not being unfairly filtered out. In particular the values
+of \fIsharplo\fR and \fIsharphi\fR should be changed if the \fInsigma\fR
+parameter is changed.
+.PP
+Finally the user should check
+the \fIfwhmpsf\fR, \fInsigma\fR, \fIdatamin\fR and \fIdatamax\fR parameters
+for correctness since these parameters control the computation of the
+convolution kernel and the density enhancement image.
+.PP
+Histograms of the various columns in the \fBdaofind\fR output can be
+plotted using the \fBpdump\fR and \fBphistogram\fR tasks. The following
+example shows how to plot a histogram of the magnitudes.
+
+.YS
+da> pdump test.coo.1 mag yes | phistogram STDIN binwidth=.1
+.YE
+
+The various columns can also be plotted against each other.
+The following example shows how to plot magnitude error versus magnitude.
+
+.YS
+da> pdump test.coo.1 mag,merr yes | graph point+
+.YE
+
+.PP
+By setting the \fBdaofind\fR \fIstarmap\fR and \fIskymap\fR parameters the
+user can save and examine the density enhancement image and the corresponding
+background density image. The sum of these two images should yield a
+close representation of the original image except for regions of
+bad data and edge pixels. Due to the nature of the convolution kernel
+the starmap image will have a mean value of
+~0.0 in the sky regions, an rms \(~= relerr * sigma in the sky regions,
+and positive peaks of intensity surrounded by negative valleys at the positions
+of bright stars. The skymap image will have a mean value \(~= sky in
+the sky regions, an rms \(~= sqrt (sigma ** 2 / N + K * (relerr * sigma) ** 2),
+(N is the number of pixels in the gaussian kernel and K is the average power
+in the gaussian kernel), and dips in intensity surrounded by
+bright rings at the position of the stars.
+
+.NH 3
+Rgcursor and Rimcursor
+
+.PP
+The LISTS package tasks \fBrimcursor\fR and \fBrgcursor\fR can be used to
+generate coordinate lists interactively. For example a coordinate
+list can be created using the image display and the image display cursor
+as shown below.
+
+.YS
+da> display test 1 fi+
+
+da> rimcursor > test.coo
+.YE
+
+.IP ...
+Move cursor to stars of interest and tap the space bar.
+.IP ...
+Type <EOF> to terminate the list.
+
+.PP
+A coordinate list can also be created using a contour plot and the graphics
+cursor as shown below.
+
+.YS
+da> contour test
+
+da> rgcursor > test.coo
+.YE
+
+.IP ...
+Move the cursor to the stars of interest and tap the space bar.
+.IP ...
+Type <EOF> to terminate the list.
+
+.PP
+In both cases the text file "test.coo" contains the x and y coordinates of
+the marked stars in image pixel units. The output of \fBrimcursor\fR or
+\fBrgcursor\fR can
+be read directly by the DAOPHOT \fBphot\fR task.
+
+.NH 3
+User Program
+
+.PP
+Any user program which produces a text file with the stellar coordinates
+listed one per line with x and y in columns 1 and 2, can be used to produce
+DAOPHOT coordinate files which can be read by the \fBphot\fR task.
+
+.NH 3
+Modifying an Existing Coordinate List
+
+.PP
+The LISTS package routine \fBlintran\fR
+can be used to perform simple coordinate transformations on
+coordinate lists including shifts, magnifications, and rotations.
+
+.NH 2
+Initializing the Photometry with Phot
+
+.PP
+The \fBphot\fR task computes initial centers,
+sky values, and initial magnitudes for all the objects in the input
+star list. The centers and magnitudes are used as starting
+values for the non-linear
+least-squares psf computation and fitting routines in the \fBpsf\fR,
+\fBpeak\fR, \fBnstar\fR, and \fBallstar\fR tasks, and to estimate
+signal-to-noise
+values in the \fBgroup\fR task. The individual sky values
+computed by \fBphot\fR are used directly by the \fBpsf\fR task to compute
+the psf model, by the
+\fBpeak\fR, \fBnstar\fR,
+and \fBallstar\fR tasks to compute the group sky values, and by the
+\fBgroup\fR task to estimate signal-to-noise ratios.
+
+.NH 3
+The Phot Algorithm
+
+.PP
+By default the \fBphot\fR task performs the following functions:
+.IP [1]
+reads in the \fBphot\fR task parameters including the input image name,
+the input coordinate file name, the output photometry file name,
+the \fBdatapars\fR, \fBcenterpars\fR, \fBfitskypars\fR, and \fBphotpars\fR
+algorithm parameters, and determines whether the task mode of operation
+is interactive or non-interactive
+.IP [2]
+reads in the initial coordinates of a star from the coordinate list and/or
+the image cursor, and computes new coordinates for the star using the centering
+algorithm defined by the \fIcalgorithm\fR parameter (if \fIcalgorithm\fR
+is not "none") using data in a box whose size is defined by the \fIcbox\fR
+parameter
+.IP [3]
+computes the sky value for the star using the default algorithm
+specified by the \fIsalgorithm\fR parameter and the data in an annulus of
+pixels defined by the \fIannulus\fR and \fIdannulus\fR parameters
+.IP [4]
+computes the instrumental magnitude and magnitude error for each star
+inside the aperture radii
+specified by the \fIapertures\fR parameter using fractional pixel techniques,
+the computed sky value, the standard deviation of the sky pixels, and the
+gain of the CCD
+.IP [6]
+sets the instrumental magnitude scale for the image using the
+\fBphotpars\fR \fIzmag\fR parameter and the exposure time specified by
+the \fBdatapars\fR \fIexposure\fR or \fIitime\fR parameters
+.IP [7]
+sets the magnitude(s) to INDEF for stars which are saturated or contain
+bad data,
+for which the aperture is partially off the image, for which a sky
+value could not be computed, or for which the
+signal is fainter than the background
+.IP [8]
+writes the results to the output photometry file
+
+.NH 3
+The Phot Algorithm Parameters
+
+.PP
+The critical \fBphot\fR algorithm parameters are \fIcalgorithm\fR,
+\fIsalgorithm\fR,
+\fIannulus\fR, \fIdannulus\fR, \fIapertures\fR, \fIdatamin\fR and
+\fIdatamax\fR. These parameters are verified by \fBphot\fR
+at startup time.
+.PP
+The \fIcalgorithm\fR parameter tells \fBphot\fR how to compute
+centers for the objects in the coordinate list. Calgorithm should be "none"
+if the coordinate
+list was computed by \fBdaofind\fR or the coordinates are known to
+be precise; otherwise calgorithm should one of "centroid", "gauss", or
+"ofilter". "centroid" is quick and sufficiently accurate in most cases;
+"gauss" and "ofilter" take longer but are more accurate. If calgorithm is
+not "none",
+\fBphot\fR will ask the user to verify the centering box size
+\fIcbox\fR. \fIcbox\fR should be set to 5 or ~2 * \fIfwhmpsf\fR pixels wide
+whichever is greater.
+.PP
+The \fIsalgorithm\fR parameter tells \fBphot\fR how to compute the sky
+values. If the
+fluctuations in the sky background are due primarily to crowding the
+default choice
+"mode" should be used. If the fluctuations in the sky background
+are due to nebulosity or large galaxies
+and the sky statistics are confused, "median", "centroid" or
+"crosscor" might be the best choice. In cases where the
+background is very low and the sky histogram is sparse or
+undersampled "mean" might be the best choice.
+.PP
+The \fIannulus\fR and \fIdannulus\fR parameters tell \fBphot\fR the
+position of the sky annulus with respect to the star. The sky region
+must be far enough away from the star to avoid contamination from
+the star itself, but close enough
+to be representative of the intensity distribution under the star. Values of
+~ 4.0 * \fIfwhmpsf\fR for both parameters are good starting values.
+.PP
+The \fIapertures\fR parameter tells \fBphot\fR the radius of the
+photometry aperture. The photometry through this aperture sets the
+instrumental magnitude scale for all the subsequent DAOPHOT
+reductions. \fIApertures\fR should be ~ 1.0 * \fIfwhmpsf\fR.
+.PP
+The \fIdatamin\fR and \fIdatamax\fR parameters are used to detect
+bad data in the photometry and sky apertures. Bad data is removed from
+the sky pixel list before sky fitting takes place so it is important
+that datamax and datamin, but particularly datamin, be correct.
+Stars which have bad data in the photometry apertures will have their
+magnitudes set to INDEF and be flagged with an error.
+
+.NH 3
+Running Phot Non-interactively
+
+.PP
+The following example shows how to run \fBphot\fR in non-interactive
+mode using the results of \fBdaofind\fR as input.
+
+.YS
+da> phot test default default
+
+Centering algorithm (none) (CR or value):
+ New centering algorithm: none
+Sky fitting algorithm (mode) (CR or value):
+ Sky fitting algorithm: mode
+Inner radius of sky annulus in scale units (10.) (CR or value):
+ New inner radius of sky annulus: 10. scale units 10. pixels
+Width of the sky annulus in scale units (10.) (CR or value):
+ New width of the sky annulus: 10. scale units 10. pixels
+File/list of aperture radii in scale units (3.0) (CR or value): 3.0
+ Aperture radius 1: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+test 40.97 4.02 100.7955 17.218 ok
+test 23.06 7.03 100.3257 17.650 ok
+test 18.02 7.96 99.40262 17.484 ok
+test 25.99 22.01 101.3196 16.800 ok
+test 35.98 22.00 101.1601 16.373 ok
+test 8.02 22.97 98.89139 16.603 ok
+test 30.97 25.01 101.2904 17.051 ok
+test 28.96 33.92 100.6189 17.782 ok
+test 35.98 42.03 101.043 16.594 ok
+
+.YE
+
+\fBPhot\fR looks for an input star list called "test.coo.?",
+creates a file called "test.mag.?", and verifies
+the critical parameters. By default the verbose switch is set to "yes",
+so a short summary of the results for each star is printed on the
+terminal as it is computed.
+.PP
+\fBPhot\fR may also be run non-interactively from a coordinate list created
+with the image cursor list task \fBrimcursor\fR as shown below. Note
+that centering has been turned on, and the verify switch has been turned off.
+
+.YS
+da> display test 1 fi+
+
+da> rimcursor > cursor.coo
+
+da> page cursor.coo
+
+41.02 4.033 101 \040
+22.918 6.969 101 \040
+18.123 7.849 101 \040
+25.951 21.939 101 \040
+35.736 21.744 101 \040
+ 7.947 23.016 101 \040
+30.843 24.777 101 \040
+28.984 33.779 101 \040
+36.127 41.705 101 \040
+
+da> phot test cursor.coo default calg=centroid verify-
+
+test 40.92 4.04 100.8871 17.222 ok
+test 23.17 6.97 100.6163 17.666 ok
+test 18.04 7.92 99.55305 17.487 ok
+test 25.96 21.97 101.4161 16.801 ok
+test 35.94 21.98 101.2101 16.373 ok
+test 8.05 23.00 98.74371 16.601 ok
+test 30.94 25.02 101.3224 17.052 ok
+test 28.91 33.85 100.6207 17.786 ok
+test 35.96 42.08 100.9039 16.591 ok\fR
+.YE
+
+The "centroid" algorithm
+computes a new center by doing an intensity-weighted sum of the
+x and y marginals, whereas the \fBdaofind\fR algorithm
+fits a 1D gaussian to the marginal pixel distributions in x and y.
+The following example shows the results for the almost equivalent
+\fBphot\fR centering algorithm "gauss".
+
+.YS
+da> phot test cursor.coo default calg=gauss verify-
+
+test 41.00 4.03 100.8698 17.219 ok
+test 23.11 7.03 100.3567 17.653 ok
+test 18.02 7.96 99.40262 17.484 ok
+test 25.98 21.97 101.4021 16.801 ok
+test 35.96 21.99 101.2101 16.373 ok
+test 8.02 22.98 98.77907 16.601 ok
+test 30.97 25.02 101.2904 17.051 ok
+test 28.93 33.94 100.6726 17.783 ok
+test 35.97 42.02 100.976 16.593 ok\fR
+.YE
+
+The positions produced by the "gauss" algorithm are closer to
+the positions computed by the \fBdaofind\fR task,
+than those computed by the "centroid" algorithm.
+However as the positions computed by \fBphot\fR are used as initial
+positions by the DAOPHOT tasks,
+it is usually not necessary to go to the more expensive "gauss" algorithm.
+
+.NH 3
+Running Phot Interactively
+
+.PP
+\fBPhot\fR can also be configured to run interactively using the
+image display and image
+cursor for coordinate input. In this mode the user loads the image
+into the display and runs
+\fBphot\fR interactively by turning the interactive switch on as
+shown below.
+When the program is ready to accept input the cursor will begin
+blinking in the display window. The following series of steps will
+do photometry on stars selected with the image cursor.
+
+.YS
+da> display test 1 fi+
+
+da> phot test "" default interactive+ calgorithm=centroid
+.YE
+
+.IP ...
+Execute the \fBv\fR keystroke command to verify the critical parameters.
+.LP
+
+.YS
+Centering algorithm (centroid) (CR or value):
+ New centering algorithm: centroid
+Centering box width in scale units (5.) (CR or value):
+ New centering box width: 5. scale units 5. pixels
+Sky fitting algorithm (mode) (CR or value):
+ Sky fitting algorithm: mode
+Inner radius of sky annulus in scale units (10.) (CR or value):
+ New inner radius of sky annulus: 10. scale units 10. pixels
+Width of the sky annulus in scale units (10.) (CR or value):
+ New width of the sky annulus: 10. scale units 10. pixels
+File/list of aperture radii in scale units (3.) (CR or value):
+ Aperture radius 1: 3. scale units 3. pixels
+Standard deviation of background in counts (10.) (CR or value):
+ New standard deviation of background: 10. counts
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+.YE
+
+.IP ...
+Move the cursor to the stars of interest and tap the \fBspacebar\fR to do
+the photometry.
+.LP
+
+.YS
+test 40.92 4.04 100.8871 17.222 ok
+test 23.17 6.97 100.6163 17.666 ok
+test 18.04 7.92 99.55305 17.487 ok
+test 25.96 21.97 101.4161 16.801 ok
+test 35.94 21.98 101.2101 16.373 ok
+test 8.05 23.00 98.74371 16.601 ok
+test 30.94 25.02 101.3224 17.052 ok
+test 28.91 33.85 100.6207 17.786 ok
+test 35.96 42.08 100.9039 16.591 ok
+.YE
+
+.IP ...
+Type \fBq\fR to quit image, and \fBq\fR again to exit task.
+.LP
+
+The coordinate file name has been set to "" so that initial
+positions for the stars to be measured will be read from the image
+cursor, and the centering algorithm has been temporarily changed
+on the command line
+from "none" to "centroid" so that new centers will be computed.
+The user simply points the cursor to the stars to be measured and taps the
+space bar to measure the star. This option is often useful for
+picking up stars missed by \fBdaofind\fR in a previous iteration,
+or in cases where the user only wishes to measure a small group of stars.
+
+.NH 3
+The Phot Output
+
+.PP
+\fBPhot\fR produces a large output file containing many parameters,
+intermediate and final results. The principle
+quantities of interest are: 1) the position
+of the star xcenter and ycenter, 2) the sky value,
+its standard deviation, and the number of pixels used to compute
+it, msky, stdev, and nsky 3) the total
+counts inside the aperture and the effective area of the aperture,
+sum and area 4) the magnitude and magnitude error in the
+aperture, mag and merr,
+and 5) the exposure time, airmass, filter, and time of observation, itime,
+xairmass, ifilter, and otime.
+.IP [1]
+\fIXcenter\fR and \fIycenter\fR are the computed coordinates for
+the detected objects in fractional pixels. They can be overlaid on the
+displayed image with the \fBtvmark\fR command. These numbers should be compared
+with the initial coordinates xinit and yinit, to which they will be equal
+if the centering algorithm was "none", or to which they should be close
+if the centering algorithm is "centroid", "gauss", or "ofilter" assuming
+that the original x and y positions were reasonable.
+.IP [2]
+\fIMsky\fR, \fIstdev\fR and \fInsky\fR are the estimated sky value in counts,
+its standard deviation in counts, and the number of pixels used to compute it.
+Users should, check that the position of the sky annulus is reasonable
+and, check that the msky, stdev, and nsky values are reasonable
+for a few isolated stars before proceeding.
+.IP [3]
+\fISum\fR and \fIarea\fR are the total counts (star + sky) in the
+photometry aperture and area is area of the aperture in pixels squared
+and should be roughly
+equal to PI * r ** 2 where r is the radius of the photometry aperture
+in pixels.
+.IP [4]
+\fIMag\fR and \fImerr\fR are the magnitude and magnitude error respectively
+computed as follows.
+
+.YS
+ mag = zmag - 2.5 * log10(sum - area * msky) + 2.5 * log10(itime)
+
+merr = 1.0857 * sqrt((sum - area * msky) / gain + area * stdev ** 2
+ + area ** 2 * stdev ** 2 / nsky) / (sum - area * msky)
+.YE
+
+Users should check that the exposure time \fIitime\fR is correct since it
+is used to determine the instrumental magnitude scale. The correct value
+of gain is also required in order to get a correct estimate of the
+magnitude error. Stdev is the observed standard deviation
+of the sky pixels not the predicted value.
+.IP [5]
+The remaining quantities itime, \fIxairmass\fR, \fIifilter\fR, and \fIotime\fR
+should be checked for correctness, e.g., were they read correctly from the image
+header.
+
+.NH 3
+Examining the Results of Phot
+
+.PP
+The user can check the results of \fBphot\fR in several
+ways. The following command will mark all
+stars in the \fBphot\fR output file on the display in red.
+
+.YS
+da> display test 1
+da> pdump test.mag.1 xcenter,ycenter yes | tvmark 1 STDIN col=204
+.YE
+
+The following command will mark all the stars whose magnitudes are INDEF on
+the screen in green.
+
+.YS
+da> pdump test.mag.1 xcenter,ycenter "mag == INDEF" | tvmark \\
+ 1 STDIN col=205
+.YE
+
+The following command will plot magnitude error versus magnitude for all
+the stars in the photometry file.
+
+.YS
+da> pdump test.mag.1 mag,merr yes | graph STDIN point+
+.YE
+
+The following command will plot a histogram of the magnitude distribution.
+
+.YS
+da> pdump test.mag.1 mag,merr yes | phist STDIN plot_type=box
+.YE
+
+The photometry file can be examined interactively with the \fBpexamine\fR
+task as shown below.
+
+.YS
+da> pexamine test.mag.1 "" test
+.YE
+.IP ...
+A vector plot of magnitude error versus magnitude appears on the screen.
+.IP ...
+To examine individual stars in the vector plot move the graphics cursor to a
+star and type \fBo\fR to get a record listing for the star,
+followed by \fBr\fR, \fBc\fR, or \fBs\fR to see a radial profile plot,
+contour plot, or surface plot respectively, of the star.
+.IP ...
+To activate the image cursor type \fBi\fR, move the cursor to a star
+and type \fBo\fR to get a record listing
+for the star, followed by \fBr\fR, \fBc\fR or \fBs\fR to draw the desired plot.
+To reactivate the graphics cursor type \fBg\fR.
+.IP ...
+To plot magnitude error versus x coordinate for all the stars in the file, type
+\fB:xcolumn xcenter\fR and \fB:ycolumn merr\fR followed by \fBp\fR to
+redraw the plot.
+.IP ...
+To plot a histogram of the magnitudes of the objects type \fBh\fR.
+.IP ...
+Type \fBq\fR to quit.
+
+.NH 2
+Creating a Psf Star List with Pstselect
+
+.PP
+The psf model fitting routines require a list of bright isolated stars
+well distributed over the image to use as psf model templates.
+The \fBpstselect\fR
+task is used to select suitable candidate stars from the photometry file
+for input to the psf modeling task \fBpsf\fR.
+
+.NH 3
+The Pstselect Algorithm
+
+.PP
+By default the \fBpstselect\fR task performs the following functions:
+.IP[1]
+reads the task parameters including the input image name, input
+photometry file, and output psf star list, reads the \fBdatapars\fR
+and \fBdaopars\fR algorithm parameters, and determines whether the
+task will be run interactively or non-interactively
+.IP [2]
+reads the dimensions of the input image from the input image header, and
+the ids, x and y coordinates, magnitudes, and sky values of up to
+\fImaxnstar\fR stars from the input photometry file
+.IP [2]
+assigns a large negative number to the magnitudes of all stars whose
+measured magnitudes are INDEF in the input photometry file
+.IP [3]
+sorts the stars in order of increasing magnitude so that
+the saturated and brightest stars are at the beginning of the list
+.IP [4]
+selects the
+brightest \fImaxnpsf\fR stars (where maxnpsf is a number chosen by the user)
+which are, not saturated, more than \fIfitrad\fR pixels away from the edge
+of the input image, have no bad data within \fIfitrad\fR pixels,
+and have no brighter neighbor stars within
+(\fIpsfrad\fR + \fIfitrad\fR + 2) pixels
+.IP [5]
+writes the ids, x and y coordinates, magnitudes, and sky values
+of the selected stars as read from the input photometry list
+to the output psf star list
+
+.NH 3
+The Pstselect Algorithm Parameters
+
+.PP
+The critical \fBpstselect\fR algorithm parameters are \fIpsfrad\fR,
+\fIfitrad\fR, \fIdatamin\fR, and \fIdatamax\fR.
+.PP
+\fIPsfrad\fR and \fIfitrad\fR are used by \fBpstselect\fR to eliminate
+potential psf stars which have bright neighbors.
+For the test image these parameters are currently set
+to 4 * \fIfwhmpsf\fR + 1 and 1 * \fIfwhmpsf\fR or 11 and 3 pixels respectively.
+However as \fBpstselect\fR is the first task to actually use the values
+of these parameters, the user should
+check them here one more time before running \fBpstselect\fR.
+\fIFitrad\fR should be ~ 1 * \fIfwhmpsf\fR
+for optimal psf model computation and fitting so the user leaves it
+at its current value of 3.0. \fIPsfrad\fR should be set to the radius at which
+the profile of the brightest stars of interest disappear into the
+noise. Normally 4 * \fIfwhmpsf\fR + 1 pixels is a good starting value for
+this quantity.
+If \fIpsfrad\fR is too small the fitted stars will not subtract completely
+from the input image, if it is too big DAOPHOT
+will consume cpu time doing unnecessary data extractions
+and subtractions.
+One way to check the value of the \fIpsfrad\fR parameter is to
+use the \fBdaoedit\fR task to examine
+radial profiles of isolated stars in the input image as shown below.
+
+.YS
+da> display test 1 fi+
+
+da> daoedit test
+.YE
+
+.IP ...
+Move cursor to star at 36,42 and press the \fBr\fR key.
+.IP ...
+Examine the resulting radial profile and note that the stellar profile
+disappears into the noise at ~4 pixels.
+.IP ...
+Move the cursor to the star at 8,23 and press the \fBr\fR key.
+.IP ...
+Examine the radial profile and note that this stellar profile
+also disappears into the noise at ~4 pixels.
+.IP ...
+Set \fIpsfrad\fR to 5.0 pixels by typing the command \fB:psfrad 5.0\fR.
+.IP ...
+Type \fBq\fR to quit the \fBdaoedit\fR task.
+.YE
+
+.PP
+The \fBpexamine\fR task and the input photometry file can also be
+used to examine the radial profiles of isolated stars in the
+photometry file.
+
+.YS
+da> display test 1 fi+
+
+da> pexamine test.mag.1 "" test
+.YE
+
+.IP ...
+A plot of magnitude error versus magnitude appears on the screen.
+.IP ...
+Type \fBi\fR to activate the image cursor.
+.IP ...
+Move the cursor to the star at 36,42 and type \fBr\fR, adjust the
+outer radius of the plot with the command \fB:router\fR if necessary,
+e.g., \fB:router 10\fR.
+.IP ...
+Examine the radial profile and note that it disappears into the noise at a
+radius of ~4 pixels.
+.IP ...
+Move the cursor to the star at 8,23 and type \fBr\fR.
+.IP ...
+Examine the radial profile and note that that it
+also disappears into the noise at a radius of ~4 pixels.
+.IP ...
+Type \fBq\fR to quit the pexamine task.
+.LP
+
+The new value of \fIpsfrad\fR can be stored by editing the \fBdaopars\fR
+parameter set with \fBepar\fR in the usual manner or on the command
+line as shown below.
+
+.YS
+da> daopars.psfrad = 5.0
+.YE
+
+.PP
+Why is the value of 5.0 pixels for \fBpsfrad\fR so different from the
+original estimate of 11.0 ?
+There are two reasons. Firstly the stars in artificial image
+test are quite faint,
+with the brightest peaking at ~400 counts above background. Their stellar
+profiles disappear into the noise quite quickly. Secondly the artificial
+stars are gaussian in shape with a sigma \(~= 1.0 pixels.
+Unlike real stars they have almost all their light
+in the core and none in the wings. For realistic optical images
+11.0 pixels rather than 5.0 would be a more reasonable choice
+for \fIpsfrad\fR than 5.0.
+.PP
+The \fIdatamin\fR and \fIdatamax\fR parameters are used to reject
+psf stars with bad data within \fIfitrad\fR pixels.
+If \fIdatamin\fR and \fIdatamax\fR are set correctly before
+the \fBphot\fR task is run, these parameters are redundant as stars
+with bad data inside the photometry aperture will have INDEF magnitudes.
+.PP
+At this point the user should check that the current value of the
+\fImaxnstar\fR parameter is larger than the total number of stars
+in the photometry file written by the \fBphot\fR task. If \fImaxnstar\fR
+is too small, \fBpstselect\fR cannot read the entire input photometry
+file into memory and potential psf stars may be missed.
+
+.NH 3
+How Many Psf Stars Should Be Selected ?
+
+.PP
+How many stars should the user select to create the psf model ?
+An absolute minimum
+set by the mathematics is 1 star for a constant psf model,
+3 stars for a linearly variable psf model, and
+6 stars for a quadratically variable psf model. A more reasonable minimum
+suggested by Stetson (1992) is 3 stars
+per degree of freedom or,
+3 stars for a constant psf model, 9 stars for a linearly variable psf model,
+and 18 stars for a quadratically variable psf model. If a variable psf model
+is required, it is vitally important that the psf star list
+sample the region of interest in the input image completely and
+reasonably uniformly.
+As the contribution of each psf star to the psf model is weighted by
+its signal-to-noise, the psf stars may cover a range in magnitude without
+compromising the resulting psf model.
+
+.NH 3
+Running Pstselect Non-interactively
+
+.PP
+The following example shows how to run the \fBpstselect\fR task
+in non-interactive mode.
+
+.YS
+da> pstselect image default default 3
+
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Star 5 has been added to the PSF star list
+ X: 35.98 Y: 22.00 Mag: 16.372 Dmin: 82.96088 Dmax: 535.1335
+Star 9 has been added to the PSF star list
+ X: 35.98 Y: 42.03 Mag: 16.594 Dmin: 80.25255 Dmax: 489.9732
+Star 6 has been added to the PSF star list
+ X: 8.02 Y: 22.97 Mag: 16.603 Dmin: 71.00896 Dmax: 436.3393
+
+Total of 3 PSF stars selected\fR
+.YE
+
+By default \fBpstselect \fR looks for an input photometry file called
+"test.mag.?" and writes an output psf star list called
+"test.pst.?".
+
+.NH 3
+Running Pstselect Interactively
+
+.PP
+\fBPstselect\fR may also be run interactively. In this mode of operation
+the stars selected
+by \fBpstselect\fR are examined by the user and accepted or rejected on
+the basis of the appearance of their mesh, contour or radial profile plots
+until a total of \fImaxnpsf\fR psf stars is reached.
+Stars from the input photometry file which do not meet the
+\fBpstselect\fR task selection criteria,
+can be added to the psf star list by the user with the image cursor
+until a total of \fImaxnpsf\fR psf stars have been selected.
+.PP
+The following example shows how to run \fBpstselect\fR in interactive
+mode.
+
+.YS
+da> pstselect image default default 3 inter+ plottype=radial
+
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+.YE
+
+.IP ...
+The image cursor appears on the screen ready to accept user input.
+.IP ...
+Type \fBn\fR to display the first potential psf star found by
+\fBpstselect\fR, \fBa\fR to select the star, or \fBd\fR to delete it.
+.IP ...
+Repeat the previous step for 2 more stars.
+.IP ...
+Type \fBl\fR to list the selected psf stars.
+.IP ...
+Type \fBq\fR to quit the task.
+
+.PP
+By default \fBpstselect \fR looks for an input photometry file called
+"test.mag.?" and writes an output psf star list called
+"test.pst.?" as before.
+
+.NH 3
+The Pstselect Output
+
+.PP
+The output psf star list consists of the ids, x and y coordinates,
+magnitudes, and sky values of the selected psf stars copied from the
+input photometry file without change.
+
+.NH 3
+Examining and/or Editing the Results of Pstselect
+
+.PP
+The \fBpdump\fR and \fBtvmark\fR commands can be used to mark
+and label the selected psf stars on the image display as shown in the
+following example.
+
+.YS
+da> display test 1 fi+
+da> pdump test.pst.1 xcenter,ycenter,id yes | tvmark 1 STDIN \\
+ col=204 label+\fR
+.YE
+
+Bad stars can be removed from the psf star list using the displayed and
+labeled image and
+the text editor, the \fBpselect\fR task, or
+the \fBpexamine\fR task.
+.PP
+The following command shows how to create a new psf star list
+without the psf star whose id is "5" using the \fBpselect\fR task.
+
+.YS
+da> pselect test.pst.1 test.pst.2 "id != 5"\fR
+.YE
+
+.PP
+The same operation can be accomplished using the \fBpexamine\fR task
+as shown below.
+
+.YS
+da> pexamine test.pst.1 test.pst.2 test
+.YE
+
+.IP ...
+A message appears on the screen to the affect that
+pexamine cannot plot x versus y since the default y
+column merr is not in the input file.
+.IP ...
+The user types \fBh\fR to plot a histogram of the magnitudes
+and notes that there are three stars in the histogram.
+.IP ...
+The user decides that the star with id number 5 marked on the
+display should be deleted because it is too crowded.
+.IP ...
+The user types the \fBi\fR key to bring up the image cursor, moves
+it to star number 5, types the \fBd\fR key to delete the star, and
+the \fBp\fR key to replot the data.
+.IP ...
+The user types the \fBf\fR key to make the deletions permanent and the \fBe\fR
+key to exit the task, and update the output catalog.
+.LP
+
+Finally the user marks the new list on the display image using a
+different marking color.
+
+.YS
+da> pdump test.pst.2 xcenter,ycenter,id yes | tvmark 1 STDIN \\
+ col=205 label+
+.YE
+.LP
+
+.NH 2
+Computing the Psf Model with Psf
+
+.PP
+The \fBpsf\fR task computes the psf model used by the
+\fBpeak\fR, \fBnstar\fR, and \fBallstar\fR tasks to do psf fitting
+photometry, by the \fBgroup\fR task to estimate magnitudes for stars
+whose initial magnitudes are INDEF, and by the \fBaddstar\fR and
+\fBsubstar\fR tasks to add stars to and subtract stars from an image.
+
+.NH 3
+The Psf Algorithm
+
+.PP
+By default the \fBpsf\fR task performs the following functions:
+.IP [1]
+reads the \fBpsf\fR task parameters including, the input image name,
+the input photometry file name, the input psf star list name,
+the output psf image name,
+the output psf star list name, the output psf star group file name, and
+the \fBdatapars\fR and \fBdaopars\fR algorithm parameters
+.IP [2]
+reads the ids, x and y coordinates, magnitudes, and sky values
+of the first \fImaxnstar\fR stars in the input photometry file
+.IP [3]
+reads the ids, x and y coordinates, magnitudes, and sky values
+of the candidate psf stars from the input psf star list and/or
+the image cursor, rejecting stars
+which are not in the input photometry file, are within \fIfitrad\fR pixels
+of the edge of the image, are saturated (if
+the parameter \fIsaturated\fR is "no"),
+or have bad data within \fIfitrad\fR pixels
+.IP [4]
+computes the analytic component of the psf model
+specified by the parameter \fIfunction\fR using, data within \fIfitrad\fR
+pixels of each psf star, weights proportional to the signal-to-noise
+ratio in each psf star, and non-linear least-squares fitting techniques
+.IP [5]
+computes the residuals of each psf star from the best fit analytic function
+within a radius of \fIpsfrad\fR + 2 pixels
+.IP [6]
+scales the residuals for each psf star to match the intensity of the first
+psf star, subsamples the scaled residuals in x and y by a factor of 2,
+weights the residuals by the signal-to-noise ratio of the psf star,
+and combines the scaled, subsampled, and weighted residuals
+to create 0, 1, 3, or 6, depending on the \fIvarorder\fR parameter,
+psf model look-up tables
+.IP [7]
+repeats steps [5] and [6] \fInclean\fR times, down-weighting the contributions
+to the psf model look-up table(s) of pixels with particularly large
+residuals each time through the loop
+.IP [8]
+estimates magnitudes for the saturated psf stars (if any exist and
+if the parameter \fIsaturated\fR is "yes"),
+by fitting the current psf model to the wings of the saturated stars
+using the \fBpeak\fR task fitting algorithm,
+.IP [9]
+computes the residuals of each saturated psf star (if any exist and they
+were successfully fit) from the best fit
+analytic function within a radius of \fIpsfrad\fR + 2 pixels, weights
+the residuals by a factor of 0.5, and adds
+the contribution of the scaled, subsampled, and weighted residuals
+to the psf model look-up table(s)
+.IP [10]
+writes the computed analytic function parameters and
+look-up tables to the output psf image
+.IP [11]
+identifies all stars within (psfrad + 2 * fitrad + 1) pixels of
+a psf star as psf star neighbors, and stars within (2 * fitrad) pixels of
+the psf star neighbors as friends of the neighbors
+.IP [12]
+writes the ids, x and y coordinates, magnitudes, and sky values of
+the final list of psf stars to the output psf star list, and the group
+and star ids,
+x and y coordinates, magnitudes, and sky values of the psf stars,
+psf star neighbors, and friends of the psf star neighbors
+to the output psf star group file
+
+.NH 3
+Choosing the Appropriate Analytic Function
+
+.PP
+DAOPHOT offers several choices for the functional form of the analytic
+component of the psf model (see Appendix 8.2 for details).
+To achieve the best fits and to minimize interpolation errors in
+the psf model look-up tables,
+users should choose the analytic function that most closely
+approximates the stellar psf. The options are:
+.IP [1]
+\fBgauss\fR (2 parameters),
+a 2D elliptical gaussian function aligned along the x and y axes of the image.
+Gauss is generally the best choice for well-sampled, fwhmpsf >= 2.5 pixels,
+ground-based images because the interpolation errors are small
+and evaluation is efficient as the function is separable in x and y.
+.IP [2]
+\fBmoffat25\fR and \fBmoffat15\fR (3 parameters),
+elliptical Moffat functions of beta 2.5 and 1.5 respectively which can
+be aligned along an arbitrary position angle. The Moffat functions
+are good choices for under-sampled ground-based data.
+.IP [3]
+\fBlorentz\fR (3 parameters),
+an elliptical Lorentz function which can be aligned along an arbitrary position
+angle. The Lorenz function is a good choice for old ST data since it has
+extended wings.
+.IP [4]
+\fBpenny1\fR (4 parameters),
+a two component model consisting of an elliptical gaussian core
+which can be aligned along an arbitrary position angle and
+lorentzian wings aligned along the x and y axes of the image.
+The Penny1 function is a good choice for a purely analytic psf model.
+.IP [5]
+\fBpenny2\fR (5 parameters),
+a two component model consisting of an elliptical gaussian core
+aligned along an arbitrary position angle and lorentzian wings aligned
+along an arbitrary position angle which may be different from that of the
+core. The Penny2 function is a good choice for a purely analytic psf model.
+.IP [6]
+\fBauto\fR (2, 3, 4 or 5 parameters),
+try each of the 6 analytic psf functions in turn and select the one which
+yields the smallest scatter in the fit. Users should use
+this option with caution
+since the greater number of free parameters in some models may
+artificially produce a fit with less scatter without significantly
+improving the resulting photometry.
+.IP [7]
+\fBlist\fR (2, 3, 4 or 5 parameters),
+check only those functions in a user specified list, e.g.
+"gauss,moffat25,lorentz" and select the one that gives the smallest
+scatter.
+.PP
+Users uncertain of which analytic function to choose should leave
+\fIfunction\fR set to "gauss"
+and only if the results prove unsatisfactory experiment with one of the
+more complicated analytic functions.
+
+.NH 3
+The Analytic Psf Model
+
+.PP
+A purely analytic psf model may be computed
+by setting the \fBdaopars\fR parameter \fIvarorder\fR = -1.
+Analytic psf models are
+constant, i.e. they have the same shape everywhere in the
+image.
+In the majority
+of cases this is NOT the best modeling option,
+as a better representation of the true psf is almost always obtained by
+computing an empirical psf model composed of an
+analytic function plus one look-up table.
+.PP
+An analytic psf model may be required to model severely undersampled
+data because interpolation errors can produce large uncertainties
+in the computed look-up tables and the resulting fits.
+.PP
+Fields which are so crowded that
+isolated psf stars are non-existent, may also require psf modeling and
+psf star neighbor subtraction with an analytic psf model,
+before a more accurate higher order model free of ghosts produced
+by the psf star neighbors can be computed.
+This step is particularly important if the field is very crowded AND the
+psf is known to be variable.
+
+.NH 3
+The Empirical Constant Psf Model
+
+.PP
+Most users with typical ground-based optical
+data choose to compute an empirical constant psf
+model composed of an analytic component and a single look-up table,
+by setting the \fBdaopars\fR parameter \fIvarorder\fR = 0.
+This type of model is constant, i.e. the psf model has
+the same shape everywhere in the image.
+.PP
+Because of interpolation errors, severely undersampled data may be better
+fit with a purely analytic psf model as described in the previous section.
+.PP
+Fields which are so crowded that
+isolated psf stars are non-existent may require psf modeling and
+psf neighbor star subtraction with an analytic psf model,
+before an accurate look-up table free of ghosts caused by the bright
+psf star neighbors can be computed.
+
+.NH 3
+The Empirical Variable Psf Model
+
+.PP
+Psf models which vary linearly or quadratically
+with position in the image can be computed by setting
+the \fIvarorder\fR parameter to 1 or 2 respectively.
+In the first case a total of 3 look-up tables will be computed;
+in the second case 6 look-up tables will be computed.
+Users should always begin their analysis with \fIvarorder\fR = -1 or
+0 if their data is from a telescope/instrument combination that
+is unfamiliar to them. Only if the patterns of the residuals around stars
+fit and subtracted with a constant psf model show systematic variations
+with position
+in the image, should the user proceed to experiment with the variable
+psf models.
+.PP
+In very crowded regions it may be necessary to compute a good
+variable psf model iteratively, starting with \fIvarorder\fR = -1
+and proceeding to \fIvarorder\fR = 2 by, computing the psf model,
+fitting the psf model to the psf stars and their neighbors, subtracting
+the psf star neighbors but not the psf stars from the original image,
+increasing \fIvarorder\fR by 1, and recomputing the
+psf model using the subtracted image, until all the psf stars and their
+neighbors subtract out cleanly.
+
+.NH 3
+Rejecting Bad Data from the Psf Model
+
+.PP
+The \fBpsf\fR task uses the \fBdatapars\fR parameters \fIdatamin\fR
+and \fIdatamax\fR to flag bad data.
+If the \fBdaopars\fR parameter \fIsaturated\fR is "no", a prospective
+psf star
+will be rejected outright if it has high or low bad data inside the fitting
+radius; if \fIsaturated\fR is "yes" a star with low bad data will
+be rejected outright but one with high bad data will be flagged
+as saturated and accepted. Except in rare cases (see below) users should leave
+\fIsaturated\fR set to "no". Stars with bad data outside the fitting radius
+but inside the psf radius are flagged, and the user warned, but are still
+accepted as psf stars.
+.PP
+All data within one fitting radius of the unsaturated psf stars is weighted by
+the signal-to-noise ratio of the psf star and used to compute the
+analytic component of the psf model.
+Pixels which deviate strongly from the current best fit
+analytic function are down-weighted during the course of the fit.
+.PP
+After the analytic function is fit, the residuals of the psf star data
+from the best fit analytic function are computed, scaled to the magnitude
+of the first psf star, weighted by the signal-to-noise in the psf star,
+subsampled for a factor
+of 2 in x and y, and added into the look-up table(s).
+If there are too few psf stars with
+good data to compute a particular element of the look-up table(s),
+\fBpsf\fR will quit with an error. If the \fBdaopars\fR parameter
+\fInclean\fR > 0, deviant pixels contributing to the psf model look-up tables
+are down-weighted and the look-up table(s) are recomputed \fInclean\fR
+times.
+.PP
+For images where all the bright candidate psf stars are saturated and all the
+remaining
+candidate psf stars are faint, it may be necessary to use the faint stars to
+compute the analytic component of the psf model and bright saturated stars
+to compute the look-up tables(s).
+In this circumstance the user must set the parameter \fIsaturated\fR
+to "yes" and include several saturated stars in the psf star list.
+After the analytic function and an initial set of look-up tables(s)
+is computed without using the saturated psf stars, the \fBpeak\fR task
+fitting algorithm is used to compute accurate magnitudes for the
+saturated psf stars by fitting the wings of the saturated stars to
+the current psf model. New look-up table(s) are computed
+which include the contributions weighted by 0.5 of the saturated psf stars.
+
+.NH 3
+The Model Psf Psfrad and Fitrad
+
+.PP
+The \fBdaopars\fR parameter \fIpsfrad\fR defines the region over which
+the psf model is defined. This radius should equal the radius at which the
+radial profile of the brightest star of interest disappears into the noise,
+e.g. \(~= 5 pixels for the test image as determined
+in the section describing the
+\fBpstselect\fR task. The fitting radius defines the region of data around
+each psf star used to compute the analytic component of the psf model
+and should be the larger of the numbers 3 and 1 * \fIfwhmpsf\fR pixels.
+
+.NH 3
+Modeling the Psf Interactively Without a Psf Star List
+
+.PP
+The psf can be modeled interactively without an initial list of candidate
+psf stars by displaying the image and selecting candidate psf stars
+with the image
+cursor. Good candidate psf stars must be in the input photometry file,
+have no neighbors within \fIfitrad\fR
+pixels, and be free of cosmetic blemishes.
+.PP
+The following example shows how to model the psf interactively without
+using an initial psf star list.
+
+.YS
+da> display test 1 fi+
+
+da> psf test default "" default default default
+
+Analytic psf function(s) (gauss):
+ Analytic psf function(s): gauss
+Order of variable psf (0):
+ Order of variable psf: 0
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Warning: Graphics overlay not available for display device.
+
+Computing PSF for image: test
+9 stars read from test.mag.1
+.YE
+
+.IP ...
+A message appears on the screen telling the user how
+many stars have been read from the photometry file
+(users should make sure that this is the entire star list)
+and the image cursor begins blinking.
+.IP ...
+The user types the \fBa\fR keystroke at pixel 36,42
+followed by another \fBa\fR keystroke after the default
+plot appears,
+to add star 9 psf star list. Star 6 at pixel 8,23 is added
+to the psf star list in the identical manner.
+.LP
+
+.YS
+Star 9 has been added to the PSF star list
+ X: 35.98 Y: 42.03 Mag: 16.594 Dmin: 80.25255 Dmax: 489.9732
+Star 6 has been added to the PSF star list
+ X: 8.02 Y: 22.97 Mag: 16.603 Dmin: 71.00896 Dmax: 436.3393
+.YE
+
+.IP ...
+The user types the \fBl\fR keystroke command to list the selected psf stars.
+.LP
+
+.YS
+Current PSF star list
+ Star: 9 X: 35.98 Y: 42.03 Mag: 16.59 Sky: 101.0
+ Star: 6 X: 8.02 Y: 22.97 Mag: 16.60 Sky: 98.9
+.YE
+.LP
+
+.IP ...
+The user types the \fBf\fR keystroke command to compute the psf model.
+.LP
+
+.YS
+Fitting function gauss norm scatter: 0.03422394
+
+Analytic PSF fit
+ Function: gauss X: 25. Y: 25. Height: 523.8066 Psfmag: 16.594
+ Par1: 1.082032 Par2: 1.162063
+
+Computed 1 lookup table(s)
+.YE
+
+.IP ...
+The user reviews the model fit with the \fBr\fR keystroke command and
+decides to keep both psf stars.
+.LP
+
+.YS
+PSF star 9 saved by user
+PSF star 6 saved by user
+.YE
+
+.IP ...
+The user types the \fBf\fR keystroke command to remodel the psf.
+.LP
+
+.YS
+Fitting function gauss norm scatter: 0.03422394
+
+Analytic PSF fit
+ Function: gauss X: 25. Y: 25. Height: 523.8066 Psfmag: 16.594
+ Par1: 1.082032 Par2: 1.162063
+
+Computed 1 lookup table(s)
+.YE
+
+.IP ...
+The user types the \fBw\fR keystroke command to save the psf model
+followed by the \fBq\fR keystroke command, executed twice, to quit the task.
+.LP
+
+.YS
+Writing PSF image test.psf.1.imh
+Writing output PSF star list test.pst.1
+Writing output PSF star group file test.psg.1
+.YE
+
+.PP
+At this point the user has created an initial psf model in the image
+test.psf.1, a list of the psf stars in test.pst.1, and a list of the
+psf stars and their neighbors in the file
+test.psg.1 respectively.
+.PP
+Users may occasionally see "Star not found" messages when
+selecting psf stars with the image cursor. This may mean: 1) that the star
+is truly not in the input photometry file (this can be checked
+with the \fBtvmark\fR task), 2) that the image cursor
+is more than \fImatchrad\fR pixels from the position of the star
+in the input photometry file (either position the image cursor more
+carefully by hand or increase the value of the \fImatchrad\fR parameter), or,
+3) that the input photometry file contains
+more than \fImaxnstar\fR stars (increase the value of the parameter
+\fImaxnstar\fR so that it is greater than the number of stars in
+the photometry file).
+
+.NH 3
+Fitting the Psf Model Interactively Using an Initial Psf Star List
+
+.PP
+The \fBpsf\fR task can also be run interactively using an initial list of
+psf stars chosen by the user with the \fBpstselect\fR task.
+If the \fBpsf\fR task parameter \fIshowpsf\fR is "yes" (the default),
+the psf stars are read from the psf star list one at a time,
+a mesh, contour, or radial profile plot is displayed in the graphics window,
+and the user can accept or delete the star with the \fBa\fR or \fBd\fR
+keystroke commands. If
+\fIshowplots\fR is "no", the psf star list is read without intervention
+by the user. In both cases new stars can be added to the end of the psf
+star list with the image cursor in the usual manner.
+.PP
+A sample run is shown below.
+
+.YS
+da> display test 1 fi+
+
+da> pdump test.pst.1 xcenter,ycenter,id yes | tvmark 1 STDIN \\
+ col=205 label+
+.YE
+
+.IP ...
+The user marks and labels the initial list of psf stars on the image display.
+.LP
+
+.YS
+da> psf test default test.pst.1 default default default
+
+Analytic psf function(s) (gauss):
+ Analytic psf function(s): gauss
+Order of variable psf (0):
+ Order of variable psf: 0
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Warning: Graphics overlay not available for display device.
+
+Computing PSF for image: test
+9 stars read from test.mag.1
+.YE
+
+.IP ...
+The user rejects or accepts the stars in the .pst file by typing the
+\fBd\fR or \fBa\fR keystroke commands respectively after the
+default plot appears.
+.LP
+
+.YS
+Star 5 rejected by user
+Star 9 has been added to the PSF star list
+ X: 35.98 Y: 42.03 Mag: 16.594 Dmin: 80.25255 Dmax: 489.9732
+Star 6 has been added to the PSF star list
+ X: 8.02 Y: 22.97 Mag: 16.603 Dmin: 71.00896 Dmax: 436.3393
+
+2 PSF stars read from test.pst.1
+.YE
+
+.IP ...
+The user types the \fBl\fR keystroke command to view the psf star
+list one more time.
+.LP
+
+.YS
+Current PSF star list
+ Star: 9 X: 35.98 Y: 42.03 Mag: 16.59 Sky: 101.0
+ Star: 6 X: 8.02 Y: 22.97 Mag: 16.60 Sky: 98.9
+.YE
+
+.IP ...
+The user computes the psf model with the \fBf\fR keystroke command.
+.LP
+
+.YS
+Fitting function gauss norm scatter: 0.03422394
+
+Analytic PSF fit
+ Function: gauss X: 25. Y: 25. Height: 523.8066 Psfmag: 16.594
+ Par1: 1.082032 Par2: 1.162063
+
+Computed 1 lookup table(s)
+.YE
+
+.IP ...
+The user saves the psf model with the \fBw\fR keystroke command.
+.LP
+
+.YS
+Writing PSF image test.psf.1.imh
+Writing output PSF star list test.pst.2
+Writing output PSF star group file test.psg.1
+.YE
+
+.IP ...
+The user types the \fBq\fR keystroke command to quit the task.
+.LP
+
+The user notes that the output psf star list is given a version number
+of 2 in this example, since version 1 was written by the \fBpstselect\fR task.
+
+.NH 3
+Fitting the Psf Model Interactively Without an Image Display
+
+.PP
+Users without access to an image display, may still run \fBpsf\fR
+interactively by redirecting
+the image cursor commands to the terminal as shown below.
+
+.YS
+da> set stdimcur = text
+
+da> psf test default test.pst.1 default default default
+
+Analytic psf function(s) (gauss):
+ Analytic psf function(s): gauss
+Order of variable psf (0):
+ Order of variable psf: 0
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Warning: Graphics overlay not available for display device.
+
+Computing PSF for image: test
+9 stars read from test.mag.1
+.YE
+
+.IP ...
+The user rejects or accepts the stars in the .pst file by typing
+the \fBd\fR or \fBa\fR keystroke commands respectively at the prompt.
+.LP
+
+.YS
+Star 5 rejected by user
+Star 9 has been added to the PSF star list
+ X: 35.98 Y: 42.03 Mag: 16.594 Dmin: 80.25255 Dmax: 489.9732
+Star 6 has been added to the PSF star list
+ X: 8.02 Y: 22.97 Mag: 16.603 Dmin: 71.00896 Dmax: 436.3393
+
+2 PSF stars read from test.pst.1
+.YE
+
+.IP ...
+The user types the \fBl\fR keystroke command at the prompt to
+view the psf star list one more time.
+.LP
+
+.YS
+Current PSF star list
+ Star: 9 X: 35.98 Y: 42.03 Mag: 16.59 Sky: 101.0
+ Star: 6 X: 8.02 Y: 22.97 Mag: 16.60 Sky: 98.9
+.YE
+
+.IP ...
+The user computes the psf model by typing the \fBf\fR keystroke
+command at the prompt.
+.LP
+
+.YS
+Fitting function gauss norm scatter: 0.03422394
+
+Analytic PSF fit
+ Function: gauss X: 25. Y: 25. Height: 523.8066 Psfmag: 16.594
+ Par1: 1.082032 Par2: 1.162063
+
+Computed 1 lookup table(s)
+.YE
+
+.IP ...
+The user saves the psf model by typing the \fBw\fR keystroke command
+at the prompt.
+.LP
+
+.YS
+Writing PSF image test.psf.1.imh
+Writing PSF output star list test.pst.2
+Writing PSF output star group file test.psg.1
+.YE
+
+.IP ...
+The user types the \fBq\fR keystroke command at the prompt to quit the task.
+.LP
+
+Additional stars can be added to the psf star list by commands of
+the form \fB":a id#"\fR or \fB"100.2 305.6 1 a"\fR typed in at the
+terminal prompt.
+The user should remember to reset the image cursor to the logical
+image cursor with the command \fB"reset stdimcur = stdimage"\fR
+after running the \fBpsf\fR task in "no image display" mode.
+
+.NH 3
+Fitting the Psf Model Non-interactively
+
+.PP
+Finally the psf model can be fit non-interactively by setting the
+\fIinteractive\fR parameter to "no", and using the list of psf stars produced by
+the \fBpstselect\fR task as input. This is the preferred method for computing
+the psf model when the number of psf stars is large (e.g. the psf
+model to be computed is variable).
+
+.YS
+da> psf test default test.pst.1 default default default inter-
+.YE
+
+.NH 3
+The Output of Psf
+
+.PP
+\fBPsf\fR writes an output psf star list test.pst.# containing the ids, x and
+y coordinates, magnitudes, and sky values, copied from the
+input photometry file,
+of the psf stars actually used to compute the final psf model.
+Because of the ability
+to add and subtract stars within \fBpsf\fR itself, this list may be different
+from the input psf star list if any. A sample output psf star list is
+shown below.
+
+.YS
+#K IRAF = NOAO/IRAFV2.10EXPORT version %-23s
+#K USER = davis name %-23s
+#K HOST = tucana computer %-23s
+#K DATE = 05-28-93 mm-dd-yr %-23s
+#K TIME = 14:34:31 hh:mm:ss %-23s
+#K PACKAGE = daophot name %-23s
+#K TASK = psf name %-23s
+#K IMAGE = test imagename %-23s
+#K PHOTFILE = test.mag.1 filename %-23s
+#K PSTFILE = test.pst.1 filename %-23s
+#K PSFIMAGE = test.psf.1 imagename %-23s
+#K GRPSFILE = test.psg.1 filename %-23s
+#K OPSTFILE = test.pst.2 filename %-23s
+#K SCALE = 1. units/pix %-23.7g
+#K OTIME = 00:07:59.0 timeunit %-23s
+#K IFILTER = V filter %-23s
+#K XAIRMASS = 1.238106 number %-23.7g
+#K PSFRAD = 5. scaleunit %-23.7g
+#K FITRAD = 3. scaleunit %-23.7g
+#
+#N ID XCENTER YCENTER MAG MSKY \\
+#U ## pixels pixels magnitudes counts \\
+#F %-9d %-10.3f %-10.3f %-12.3f %-12.3f
+#
+9 35.980 42.029 16.594 101.043
+6 8.022 22.970 16.603 98.891
+.YE
+
+.PP
+\fBPsf\fR also writes an output psf star group photometry file
+test.psg.? containing the group ids, and the star ids,
+x and y coordinates, magnitudes, and sky values
+copied from the input photometry file,
+for the psf stars and their
+neighbors. A sample psf star group file is shown below.
+
+.YS
+#K IRAF = NOAO/IRAFV2.10EXPORT version %-23s
+#K USER = davis name %-23s
+#K HOST = tucana computer %-23s
+#K DATE = 05-26-93 mm-dd-yr %-23s
+#K TIME = 16:10:48 hh:mm:ss %-23s
+#K PACKAGE = daophot name %-23s
+#K TASK = psf name %-23s
+#K IMAGE = test imagename %-23s
+#K PHOTFILE = test.mag.2 filename %-23s
+#K PSTFILE = test.pst.2 filename %-23s
+#K PSFIMAGE = test.psf.2 imagename %-23s
+#K GRPSFILE = test.psg.2 filename %-23s
+#K SCALE = 1. units/pix %-23.7g
+#K OTIME = 00:07:59.0 timeunit %-23s
+#K IFILTER = V filter %-23s
+#K XAIRMASS = 1.238106 number %-23.7g
+#K PSFRAD = 5. scaleunit %-23.7g
+#K FITRAD = 3. scaleunit %-23.7g
+#
+#N ID GROUP XCENTER YCENTER MAG MSKY \\
+#U ## ## pixels pixels magnitudes counts \\
+#F %-9d %-6d %-10.3f %-10.3f %-12.3f %-14.3f
+#
+9 1 35.980 42.029 16.594 101.043
+8 1 28.958 33.924 17.781 100.619
+6 2 8.022 22.970 16.603 98.891
+.YE
+
+There are two stellar groups, one group per psf star,
+in this file. The first psf star
+has a single neighbor so there are two stars in the first group.
+The first star in a group is always the psf star. The header parameters
+record the input and output image and file names, the name of the
+computed psf model, and the values
+of the parameters
+\fIpsfrad\fR and \fIfitrad\fR used to define the psf star groups.
+.PP
+The psf image contains, in the image header, the values of the
+parameters that were used
+to compute the psf model, the best fit values of the parameters of
+the chosen analytic function, and a record of all the
+psf stars used to compute the psf, and in the image pixels, the best fit
+look-up table(s) of the residuals from the analytic function
+subsampled by a factor of 2.
+The psf image look-up table(s) can be plotted and examined just like any
+other IRAF image.
+.PP
+A sample psf image header is shown below.
+
+.YS
+test.psf.2[23,23][real]: PSF for image: test
+ No bad pixels, no histogram, min=unknown, max=unknown
+ Line storage mode, physdim [23,23], length of user area 1540 s.u.
+ Created Wed 16:10:47 26-May-93, Last modified Wed 16:10:47 26-May-93
+ Pixel file 'tucana!/d0/iraf/davis/test.psf.2.pix' [ok]
+ IRAF = 'NOAO/IRAFV2.10EXPORT'
+ HOST = 'tucana '
+ USER = 'davis '
+ DATE = '05-26-93'
+ TIME = '16:10:48'
+ PACKAGE = 'daophot '
+ TASK = 'psf '
+ IMAGE = 'test '
+ PHOTFILE= 'test.mag.2'
+ PSTFILE = 'test.pst.2'
+ PSFIMAGE= 'test.psf.2'
+ GRPSFILE= 'test.psg.2'
+ SCALE = 1.
+ PSFRAD = 5.
+ FITRAD = 3.
+ DATAMIN = 50.
+ DATAMAX = 24500.
+ NCLEAN = 0
+ USESAT = F
+ FUNCTION= 'gauss '
+ PSFX = 25.
+ PSFY = 25.
+ PSFHEIGH= 523.8066
+ PSFMAG = 16.594
+ NPARS = 2
+ PAR1 = 1.082032
+ PAR2 = 1.162063
+ VARORDER= 0
+ FEXPAND = F
+ NPSFSTAR= 2
+ ID1 = 9
+ X1 = 35.98
+ Y1 = 42.029
+ MAG1 = 16.594
+ ID2 = 6
+ X2 = 8.022
+ Y2 = 22.97
+ MAG2 = 16.603
+.YE
+
+This psf image header records that: the psf model
+was computed with a gaussian
+analytic function (function = gauss), the analytic
+function has two parameters (npars=2)
+whose values are 1.08 and 1.16 (par1 and par2 are the fwhm of the function
+in x and y respectively in this case), the psf is constant but there is
+1 look-up
+table (varorder = 0), no saturated stars were used to compute the psf
+(usesat=no), and no cleaning of bad pixels was done to compute the
+lookup table (nclean=0). The number of psf stars and their positions
+and magnitudes
+are also listed. The psf model is defined over a radius of 5
+pixels (psfrad = 5.0), resulting in a square look-up table with dimensions
+of 2 * (nint (2 * psfrad) + 1) + 1 pixels in x and y, and a fitting radius
+of 3 (fitrad = 3.0) was used to compute the analytic portion of the psf
+model.
+.PP
+The height of the best fit gaussian psfheigh is 523.81 counts.
+The psf model has been assigned a magnitude of 16.594 which is the
+magnitude of the first psf star in the input photometry file.
+All fits to the psf model are scaled with respect to this
+magnitude. Therefore a star which is twice as bright as the psf model will
+have a fitted magnitude of ~15.841.
+.PP
+Psfx and psfy define the distance from the center of the input image to the
+center of the edge pixels in x and y respectively, e.g psfx =
+(ncols - 1.0) / 2.0 and psfy = (nlines - 1) / 2.0. These numbers are used to
+evaluate the psf model only if the model is variable, \fIvarorder\fR > 0.
+.PP
+If the value of \fIvarorder\fR in this example had been 1 or 2 the
+psf model image would have been 3-dimensional with 3 and 6 23 by 23
+pixel look-up
+tables in planes 1-3 and 1-6 of the image respectively.
+In both cases planes 1-3 would contain the 0th, 1st order in x,
+and 1st order in y Taylor expansion coefficients around the analytic function.
+In the latter case planes 4-6 would contain the
+2nd order in x, 2nd order in xy, and 2nd order in y Taylor expansion
+coefficients. If the value of \fIvarorder\fR
+had been -1 no look-up tables would have been computed and the
+psf model image would consist of an image header but no pixel file.
+
+.NH 3
+Checking the Psf Model
+
+.PP
+To check the accuracy of the psf model, the user must fit each psf
+star and its neighbors and friends
+as a group using the \fBnstar\fR task, and the psf model and psf star group
+photometry file
+produced by \fBpsf\fR as shown below. In the following example
+the user has chosen to set the rejections
+file to "", so that all stars, even those too faint to be properly
+fit, will be placed in the same output file.
+
+.YS
+da> nstar test test.psg.1 default default ""
+
+Recenter the stars (yes):
+ Recenter the stars: yes
+Refit the sky (no):
+ Refit the sky: no
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Maximum group size in number of stars (60):
+ New maximum group size: 60 stars
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Group: 1 contains 2 stars
+ ID: 9 XCEN: 35.98 YCEN: 42.01 MAG: 16.60
+ ID: 8 XCEN: 28.96 YCEN: 33.91 MAG: 17.73
+Group: 2 contains 1 stars
+ ID: 6 XCEN: 8.02 YCEN: 22.97 MAG: 16.63
+.YE
+
+The results of the fits will appear in test.nst.? as shown below.
+
+.YS
+da> page test.nst.1
+
+#K IRAF = NOAO/IRAFV2.10EXPORT version %-23s
+#K USER = davis name %-23s
+#K HOST = tucana computer %-23s
+#K DATE = 05-28-93 mm-dd-yy %-23s
+#K TIME = 14:46:13 hh:mm:ss %-23s
+#K PACKAGE = daophot name %-23s
+#K TASK = nstar name %-23s
+#K IMAGE = test imagename %-23s
+#K GRPFILE = test.psg.1 filename %-23s
+#K PSFIMAGE = test.psf.1 imagename %-23s
+#K NSTARFILE = test.nst.1 filename %-23s
+#K REJFILE = "" filename %-23s
+#K SCALE = 1. units/pix %-23.7g
+#K DATAMIN = 50. counts %-23.7g
+#K DATAMAX = 24500. counts %-23.7g
+#K GAIN = 1. number %-23.7g
+#K READNOISE = 0. electrons %-23.7g
+#K OTIME = 00:07:59.0 timeunit %-23s
+#K XAIRMASS = 1.238106 number %-23.7g
+#K IFILTER = V filter %-23s
+#K RECENTER = yes switch %-23b
+#K FITSKY = no switch %-23b
+#K PSFMAG = 16.594 magnitude %-23.7g
+#K PSFRAD = 5. scaleunit %-23.7g
+#K FITRAD = 3. scaleunit %-23.7g
+#K MAXITER = 50 number %-23d
+#K MAXGROUP = 60 number %-23d
+#K FLATERROR = 0.75 percentage %-23.7g
+#K PROFERROR = 5. percentage %-23.7g
+#K CLIPEXP = 6 number %-23d
+#K CLIPRANGE = 2.5 sigma %-23.7g
+#
+#N ID GROUP XCENTER YCENTER MAG MERR MSKY \\
+#U ## ## pixels pixels magnitudes magnitudes counts \\
+#F %-9d %-6d %-10.3f %-10.3f %-12.3f %-14.3f %-12.3f
+#
+#N NITER SHARPNESS CHI PIER PERROR \\
+#U ## ## ## ## perrors \\
+#F %-17d %-12.3f %-12.3f %-6d %-13s
+#
+9 1 35.982 42.006 16.601 0.019 101.043 \\
+ 4 -0.019 0.512 0 No_error
+8 1 28.962 33.912 17.730 0.074 100.619 \\
+ 4 0.026 1.093 0 No_error
+6 2 8.017 22.968 16.628 0.021 98.891 \\
+ 3 0.022 0.558 0 No_error
+.YE
+
+In this example the chi values computed by \fBnstar\fR for the two
+psf stars are lower than expected, ~ 0.5 instead of ~ 1.0, meaning that the
+observed errors are less than the predicted errors.
+This occurs because there are only 2 psf stars,
+and therefore the model psf and the fitted psf stars are not totally
+independent.
+For example, if only one psf star is used to compute
+the psf model, the chi
+computed by \fBnstar\fR for that star would be ~ 0.0 and for any others
+such as its neighbors ~ 1.0.
+.PP
+After checking that the chi values look reasonable, the user subtracts the
+fitted psf stars and their neighbors from the input image
+with the \fBsubstar\fR task, and examines the residuals
+of the fit around the psf stars as shown below. After \fBsubstar\fR is
+run the subtracted
+image is displayed and the psf stars are marked in green and the
+psf neighbor stars are marked in red.
+
+.YS
+da> substar test default "" default default
+
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+SUBTRACTING - Star: 6 X = 8.02 Y = 22.97 Mag = 16.63
+SUBTRACTING - Star: 8 X = 28.96 Y = 33.91 Mag = 17.73
+SUBTRACTING - Star: 9 X = 35.98 Y = 42.01 Mag = 16.60
+
+A total of 3 stars were subtracted out of a possible 3
+
+da> display test.sub.1 1 fi+
+da> pdump test.nst.1 xc,yc,id yes | tvmark 1 STDIN col=204 label+
+da> pdump test.pst.1 xc,yc,id yes | tvmark 1 STDIN col=205 label+
+.YE
+
+.PP
+The psf stars and their neighbors should subtract out cleanly
+with no systematic patterns in the residuals as a function of distance
+from the star (note this may not be the case if the psf is purely analytic
+or so severely undersampled that the interpolation errors near the
+center are very large), with magnitude, or with position in the image.
+There should be no hidden
+underlying neighbors revealed after the subtraction (these psf stars
+should be rejected) or neighbors
+that are not in the photometry file (this can be fixed up later).
+The amplitudes of the fit residuals
+should be consistent with the noise if sufficient stars are
+used to determine the psf model.
+.PP
+The displayed and marked subtracted image and the output of \fBnstar\fR can
+be examined in more detail with the \fBpexamine\fR task as shown below.
+
+.YS
+da> pexamine test.nst.1 "" test.sub.1
+.YE
+.IP ...
+A plot of magnitude versus magnitude error for the psf stars and their
+neighbors will appear.
+.IP ...
+Change the default plot to mag versus chi with the command \fB:ycolumn chi\fR
+followed by the \fBp\fR keystroke command.
+.IP ...
+Activate the image cursor with the \fBi\fR keystroke command.
+.IP ...
+Move to psf star number 9 and type \fBr\fR to examine the radial profile
+of the subtracted star, followed by \fBo\fR to get a listing of its position,
+magnitude, magnitude error, sky value, etc.
+.IP ...
+Examine the radial profiles of the other subtracted psf stars and their
+neighbors.
+.IP ...
+Type \fBq\fR to quit the task.
+
+.PP
+For the test image "test", examination of the radial profiles of the
+subtracted stars shows that the residuals are
+consistent with the noise in the image and have no unusual features
+leading to the conclusion that the current psf model is a good representation
+of the true psf.
+
+.NH 3
+Removing Bad Stars from the Psf Model
+
+.PP
+Bad psf stars detected after the psf star and neighbor subtraction,
+for example those with
+a cosmetic blemish, a close double, or an underlying neighbor star,
+should be removed altogether from
+the psf star list. This can be done by editing the psf star list written
+by \fBpsf\fR with the text editor, with the \fBpselect\fR task and an
+expression, e.g. "id != 5", specifying the star to be deleted, or
+with the interactive \fBpexamine\fR task using the delete and update keys,
+and rerunning \fBpsf\fR with the new psf star list.
+.PP
+This step is not required for the test image as both psf stars and their
+neighbors subtracted cleanly from the image.
+
+.NH 3
+Adding New Stars to a Psf Star Group
+
+.PP
+Occasionally stars that are too faint to be included
+in initial star list produced by \fBdaofind\fR and measured with \fBphot\fR, are
+nevertheless sufficiently bright and close to a psf star
+to affect the computation of the psf model.
+Ideally the psf stars should have no such companions and/or the look-up
+table cleaning option in the \fBpsf\fR task should minimize the problem of
+undetected neighbors. However in some cases it is necessary for
+the user to intervene and add faint stars to the photometry list.
+.PP
+The easiest way to accomplish this
+is to run \fBphot\fR interactively, selecting the
+missing neighbor stars with the image cursor and appending the results
+for the new neighbor stars to the photometry file produced by the first
+run of \fBnstar\fR.
+
+.YS
+da> phot test "" psf.mag inter+ calgorithm=centroid
+.YE
+
+.IP ...
+Point cursor to undetected psf star neighbors and hit spacebar.
+.IP ...
+Type \fBq\fR to quit.
+.LP
+
+.YS
+da> prenumber psf.mag idoffset=5000
+.YE
+
+.IP ...
+Renumber the stars in the new file starting with a number greater
+than the number of stars in the original photometry file in order
+to insure that all the stars have unique ids.
+.LP
+
+.YS
+da> pfmerge test.psg.1,psf.mag test.psf.psg
+.YE
+
+.IP ...
+Combine the psf star group photometry file produced by the \fBpsf\fR task
+with the photometry file for the new psf star neighbors produced by
+the \fBphot\fR task.
+.LP
+
+Users should note that there is no input coordinate list to \fBphot\fR in
+this case. Therefore the coordinate list is set to "", interactive mode
+is on, and centering is turned on.
+The remaining photometry parameters should be set exactly as they were in the
+first run of \fBphot\fR.
+.PP
+This step is not required for the test image as all the significant
+psf star neighbors were detected by the first run of the \fBdaofind\fR task.
+
+.NH 3
+Refitting the Psf Model With the New Psf Star Groups
+
+.PP
+After the \fBpsf \fR and \fBphot\fR results have been merged, the
+user must regroup the psf stars and their neighbors with
+the \fBgroup\fR task, and refit the
+new groups with the \fBnstar\fR task.
+
+.YS
+da> group test test.psf.psg default test.grp critov=.2
+.YE
+
+.IP ...
+Regroup the stars using a very small value for the critical overlap
+parameter.
+.LP
+
+.YS
+da> nstar test test.grp default default ""
+.YE
+
+.IP ...
+Rerun nstar on the new psf star groups.
+.LP
+
+.YS
+da> substar test test.nst.2 "" default default
+.YE
+
+.IP ...
+Check that the new psf star groups subtract cleanly from the original
+image.
+.PP
+This step is not required for the test image as all the significant
+psf star neighbors were detected by the first run of the \fBdaofind\fR task.
+
+
+.NH 3
+Computing the Final Psf Model
+
+.PP
+Once the psf star and psf star neighbors subtract out cleanly
+from the input image with the current psf model,
+a final psf model should be computed using an image from which all
+the psf star neighbors but not the psf stars have been subtracted.
+To do this the user runs the \fBsubstar\fR task, setting the input photometry
+file to the final output of \fBnstar\fR, and the exclude file to the final
+psf star list written by the \fBpsf\fR task, and reruns \fBpsf\fR.
+An example of this procedure is shown below.
+
+.YS
+da> substar test test.nst.2 test.pst.2 default default
+da> psf test.sub.3 test.grp test.pst.2 test.psf.2 test.pst.3 \\
+ test.psg.3 inter-
+.YE
+
+After this step the user should have a good psf model and can proceed to do
+psf fitting photometry.
+.PP
+This step is not required for the test image as the single psf star
+neighbor is sufficiently far from the psf star to have a negligible
+effect on the computation of the psf model.
+
+.NH 3
+Visualizing the Psf Model with the Seepsf Task
+
+.PP
+The psf analytic function parameters are stored in the psf image header
+and the look-up table(s) in the psf image pixels. The look-up table(s) are
+subsampled by a factor of 2 with respect to the image, and cannot
+be used directly to visualize what the psf model looks like
+at the scale of the image. The task \fBseepsf\fR can be used to
+do this conversion as shown below.
+
+.YS
+da> seepsf test.psf.3 psf3
+.YE
+
+The output image will contain a picture of what an ideal star of magnitude
+equal to the magnitude of the psf (see the psfmag keyword in the psf
+image header) should look like at the center of the image.
+.PP
+In the case of a variable psf the appearance of the psf model can be examined at
+various
+places in the image by specifying a position at which to compute the psf
+model.
+
+.YS
+da> seepsf test.psf.3 psf.13.8 xpsf=13 ypsf=8
+.YE
+
+.PP
+The total power in a variable psf should be constant
+as a function of position in the image even though its shape is
+different. The variable psf fitting code
+in DAOPHOT does perform flux conservation. Users can check this by using
+the \fBimstatistics\fR task to check that there is no net power in the
+look-up tables 2-3 or
+2-6 if the psf order is 1 or 2. Similarly they can use \fBseepsf\fR to compute
+the psf at various positions in the input image and \fBimstat\fR to check
+that the net power in the psf is constant over the image
+even though the shape of the
+psf is variable.
+
+.NH 3
+Problems Computing the Psf Model
+
+.PP
+Computing the psf model is the most crucial step in DAOPHOT.
+The \fBdaofind\fR and \fBphot\fR
+steps are usually straight-forward, and the principal fitting task
+\fBallstar\fR runs entirely in batch once started. However computing
+a good psf model requires user input.
+.PP
+This section suggests a few
+things to check if the computed psf model is not doing a good
+job of fitting and subtracting the psf or program stars. The user
+should check:
+.IP [1]
+that the sky annulus chosen in the \fBphot\fR step is neither too
+close or too far from the stars. If the sky annulus is too close
+the computed skies will tend to be too high and the psf model
+will have too small an amplitude,
+producing false halos around the fitted and subtracted stars. If the sky annulus
+is too far away the computed sky value will not represent the sky under the
+psf star well, adding scatter to the photometry.
+.IP [2]
+the psf radius.
+If the stars appear to be well fit in the cores but have residual halos with a
+sharp inner edge around
+them then the psf radius may be too small. The psf radius needs to
+be big enough to give good subtractions for the brightest stars of interest.
+.IP [3]
+that the analytic component of the psf function is appropriate for
+the data.
+If the data is somewhat undersampled, fwhmpsf < 2.5 pixels,
+one of the Moffat functions may give a better fit to the data than
+the Gauss function. If that data is extremely undersampled an analytic
+function may do better than one involving look-up tables.
+.IP [4]
+the psf stars.
+One or more of the psf stars may not be stars, may be doubles, or contain
+bad data. Although psf does try to detect and down-weight bad data it may
+not be completely successful. Users need to examine the subtracted image
+for objects with bad residuals and for stars with large fitted chi values
+and eliminate them.
+.IP [5]
+for psf variability with position in the image. The true psf may be variable
+and inadequately fit by a constant psf model. The user should examine the
+residuals around the subtracted psf stars to see if there are patterns
+with position in the image and
+increase the order of the psf model if these are detected.
+Large fitted chi values may also be an indication of a poor psf model.
+.IP [6]
+the distribution of the psf stars.
+If the psf is variable the user must ensure that the psf stars adequately
+cover the region of interest in the image. For example if there are no
+psf stars in a certain portion of the image the psf may not
+be well represented there.
+.IP [7]
+the data. If the psf is a higher order than quadratic \fBpsf\fR may
+not be able to model it adequately. The user should check the image data
+reduction history, and investigate any image combining, bad pixel and cosmic
+ray removal
+operations, etc., that may have fundamentally altered the data.
+The data should also be checked for linearity.
+.IP [8]
+the noise model. If the chi values for the fitted psf stars are unusually
+large or small, the effective readout noise and gain for the image
+may not be correct. The user should check that these values are
+being read from the image header correctly and that they are appropriate
+for the data.
+
+
+.NH 2
+Doing Psf Fitting Photometry with Peak, Nstar, or Allstar
+
+.PP
+There are three psf fitting
+photometry tasks in DAOPHOT. The \fBpeak\fR task fits the current psf
+model to stars individually; the \fBnstar\fR task fits the psf model to
+stars in fixed stellar groups simultaneously; the \fBallstar\fR task
+groups and fits the psf model to stellar groups dynamically
+and subtracts the fitted stars from the input image.
+\fBAllstar\fR is the
+task of choice for the majority of users, but all three options are
+discussed in the following sections.
+
+.NH 3
+Fitting Single Stars with Peak
+
+.PP
+\fBPeak\fR is the simplest psf fitting task.
+\fBPeak\fR fits the psf model to the stars in the
+input photometry list individually. Because \fBpeak\fR cannot fit stars in
+groups as the \fBnstar\fR and \fBallstar\fR tasks do, and in
+uncrowded frames aperture photometry is often simpler and just as accurate,
+\fBpeak\fR has few unique functions.
+However \fBpeak\fR can be useful in cases where the user wishes to: 1) improve
+the signal to noise of faint stars by taking advantage of
+\fBpeak's\fR optimal weighting scheme, 2) do astrometry of single
+stars, 3) fit and remove single stars from the frame in order to
+examine the underlying light distribution.
+
+.NH 4
+The Peak Algorithm
+
+.PP
+By default the \fBpeak\fR task performs the following functions:
+.IP [1]
+reads the task parameters, including the name of
+the input image, the input photometry file, the psf model, the
+output photometry and rejections files, and the
+\fBdatapars\fR and \fBdaopars\fR algorithm parameter sets
+.IP [2]
+reads the id, x and y coordinates, magnitude, and sky value
+of a star from the input photometry file
+.IP [3]
+rejects the star if it has an undefined sky value, too
+few good data pixels to obtain a fit, or is too faint
+.IP [4]
+extracts the image data within one fitting radius of each star and
+performs an optimally weighted non-linear least-squares fit of the psf model
+to the extracted data
+.IP [5]
+rejects the star if its signal-to-noise ratio is too low
+or a unique solution cannot be found
+.IP [6]
+computes the best fit x, y, and magnitude for the star
+.IP [7]
+writes the id, new x and y coordinates, sky value, new magnitude, magnitude
+error, number of iterations required to fit the star, chi statistic,
+and sharpness
+statistic for the fitted star to the
+output photometry file, and the id, last computed x and y position,
+and sky value of the rejected star, to
+the rejections file
+.IP [8]
+repeats steps [2]-[7] for each star in the input photometry list
+
+.NH 4
+Running Peak
+
+.PP
+A sample run of the \fBpeak\fR task is shown below. The user is prompted
+for all the input and output file names and asked to verify the
+critical parameters \fIrecenter\fR, \fIfitsky\fR, \fIpsfrad\fR, \fIfitrad\fR,
+\fIdatamin\fR, and \fIdatamax\fR.
+
+.YS
+da> peak test default default default default
+
+Recenter the stars (yes):
+ Recenter the stars: yes
+Refit the sky (no):
+ Refit the sky: no
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Star: 1 X: 40.97 Y: 4.01 Mag: 17.22 Sky: 100.74
+ FIT: Star: 1 X: 41.01 Y: 4.03 Mag: 17.22 Sky = 100.74
+Star: 2 X: 23.06 Y: 7.03 Mag: 17.65 Sky: 100.33
+ FIT: Star: 2 X: 23.02 Y: 7.05 Mag: 17.75 Sky = 100.33
+Star: 3 X: 18.02 Y: 7.96 Mag: 17.48 Sky: 99.40
+ FIT: Star: 3 X: 17.98 Y: 8.00 Mag: 17.57 Sky = 99.40
+Star: 4 X: 25.99 Y: 22.01 Mag: 16.80 Sky: 101.34
+ FIT: Star: 4 X: 25.99 Y: 22.01 Mag: 16.81 Sky = 101.34
+Star: 5 X: 35.98 Y: 22.00 Mag: 16.37 Sky: 101.12
+ FIT: Star: 5 X: 35.97 Y: 22.02 Mag: 16.39 Sky = 101.12
+Star: 6 X: 8.02 Y: 22.97 Mag: 16.60 Sky: 98.89
+ FIT: Star: 6 X: 8.02 Y: 22.97 Mag: 16.63 Sky = 98.89
+Star: 7 X: 30.97 Y: 25.01 Mag: 17.05 Sky: 101.29
+ FIT: Star: 7 X: 30.96 Y: 25.04 Mag: 17.05 Sky = 101.29
+Star: 8 X: 28.96 Y: 33.92 Mag: 17.78 Sky: 100.62
+ FIT: Star: 8 X: 28.96 Y: 33.93 Mag: 17.74 Sky = 100.62
+Star: 9 X: 35.98 Y: 42.03 Mag: 16.59 Sky: 101.04
+ FIT: Star: 9 X: 35.98 Y: 42.01 Mag: 16.60 Sky = 101.04\fR
+.YE
+
+In this example the user chose to recenter the stars (almost always
+the best choice), and not to refit the sky (usually the best choice).
+Recentering should only be turned off if the initial centers in the input
+photometry file are known to be very accurate, e.g. they
+are derived from a better seeing
+image or one that has gone through some image restoration program.
+Users who elect to refit the sky,
+should realize that they will almost certainly need to increase
+the fitting radius to
+obtain a reasonable fitted sky value. Increasing the fitting radius
+however may also increase the scatter caused by neighboring stars.
+.PP
+The fitted stars can be subtracted from the input image with the \fBsubstar\fR
+task as shown below.
+
+.YS
+da> substar test test.pk.1 "" default default\fR
+.YE
+
+.PP
+
+.NH 4
+The Peak Output
+
+.PP
+Peak writes the quantities: id, xcenter, ycenter, mag, merr, msky,
+niter, chi, sharp, pier, and perror to the output photometry file and the
+rejections file.
+.IP [1]
+Id is the id number of the star as read from the input photometry file.
+.IP [2]
+Xcenter and ycenter are the best fit position of the star.
+If the star was rejected xcenter and ycenter will be the computed
+values of x and
+y at the time it was rejected. If \fIrecenter\fR is "no", xcenter and ycenter
+will be the position of the star in the input photometry file.
+.IP [3]
+Mag and merr are the best fit magnitude and magnitude error respectively.
+The instrumental magnitude is computed relative to the
+magnitude assigned to the
+psf model.
+Mag and merr are set to INDEF if the star cannot be fit to the psf model.
+.IP [4]
+Msky is the sky value in the input photometry file if fitsky = "no",
+otherwise it is the
+fitted sky value. If the star is not fit for some reason,
+msky is the computed sky value
+at the time the star was rejected.
+.IP [5]
+Niter is the number of iterations it took to fit the star. If this
+number if equal to the \fBdaopars\fR parameter \fImaxiter\fR the user should be
+suspicious of the computed positions, magnitudes, and sky values.
+However as the convergence criteria are
+conservative the star may still be reasonably well fit.
+Niter is set to 0 if the star cannot be fit to the psf model.
+.IP [6]
+Chi and sharp are measures of the goodness of fit and the shape
+of the star respectively. Chi should be ~ 1.0. If it is not then,
+either the object is not a single star, the noise model including
+one or more of the gain, readout noise, flat-fielding error, and
+interpolation error parameters for the image are incorrect, the
+psf model is a poor representation of the true psf, or the input
+image does not conform to the requirements of the DAOPHOT package.
+Sharp is a measure of the difference between the observed width
+of the object and the width of the psf model. Stars should have a sharpness
+value ~ 0.0, resolved objects a sharpness of > 0.0, and cosmic rays and similar
+blemishes a sharpness of < 0. Chi and sharp are set to INDEF if the star
+cannot be fit to the psf model.
+.IP [7]
+Pier and perror are an integer error code and error string respectively.
+If no error was encountered during the fit pier is 0 and perror is
+"No_error". Stars are rejected by the \fBpeak\fR task if 1) the sky value of
+the star is INDEF 2) there are too few good data pixels to fit the star
+3) the fitting matrix is singular meaning a unique solution could not
+be found 4) the star is too faint, i.e. its signal / noise < 2.0. A fifth
+condition, the solution did not converge by \fImaxiter\fR iterations, is not
+used to reject the star, although users should be suspicious of a star
+for which niter = \fImaxiter\fR.
+
+
+.NH 3
+Fitting Stars with Group, Grpselect, Nstar and Substar
+
+.PP
+Stars can be fit simultaneously in fixed groups using the
+\fBnstar\fR task.
+This psf fitting technique requires grouping the stars
+into physically meaningful
+associations with the \fBgroup\fR and/or the \fBgrpselect\fR tasks,
+fitting the stars in each group simultaneously with the \fBnstar\fR task,
+and subtracting
+the fitted stars from the image with the \fBsubstar\fR task.
+\fBNstar\fR is the task of choice when the user wishes to explicitly
+control the grouping process or fit stars in a small number of
+widely separated groups efficiently.
+\fBNstar\fR is most commonly used to fit the psf model to the psf stars and
+their neighbors.
+
+.NH 4
+The Group and Nstar Algorithms
+
+.PP
+By default the \fBgroup\fR task performs the following steps:
+
+.IP [1]
+reads the task parameters, including the name of the input image, the input
+photometry file, the psf model, the output photometry
+file, and the \fBdatapars\fR and \fBdaopars\fR
+algorithm parameter sets
+.IP [2]
+reads the ids, x and y coordinates, magnitudes, and sky values
+of up to \fImaxnstar\fR stars in the input photometry file, computes an
+approximate magnitude for the stars with INDEF magnitudes, and sorts
+the stars in increasing order of y
+.IP [3]
+finds all the stars which are within \fIpsfrad\fR + \fIfitrad\fR + 1 pixels
+of a given star, evaluates the psf of the brighter star at a distance
+of \fIfitrad\fR pixels from
+the fainter, and if this value is larger than \fIcritovlap\fR
+times the expected
+error per pixel, or the two stars are within \fIfitrad\fR + 1 pixels of
+each other, adds the star to the group
+.IP [4]
+writes the group and star ids, x and y coordinates, magnitudes and sky values
+for all the groups, to the output group photometry file.
+
+.PP
+By default the \fBnstar\fR task performs the following steps:
+
+.IP [1]
+reads the task parameters including the name of
+the input image, the input group file, the psf image, the
+output group photometry and rejections files and the \fBdatapars\fR and
+\fBdaopars\fR algorithm parameter sets
+.IP [2]
+reads the group and star ids, x and y coordinates, magnitudes, and
+sky values for all the stars in a group from the input group photometry
+file
+.IP [3]
+extracts the data within psfrad + fitrad pixels
+around the group and
+performs a weighted least-squares fit of the psf model to the extracted
+data
+.IP [4]
+rejects stars which have an undefined sky value, which are too faint (more
+than 12.5 magnitudes fainter than the psf), which are
+too noisy (faintest star in the group less than a 1.0, 1.5, or 2.0
+sigma detection after 5, 10, and 15 iterations or convergence respectively),
+for which there are too few good
+pixels to compute a fit, for which a unique solution cannot
+be found, which have merged with another star (fainter star < 0.37 *
+fwhmpsf from a brighter star in the group), which are both too
+noisy and too
+close to a brighter star (a star is between .37 and 1.0 fwhm of
+a brighter star and is a 1.0, 1.5, or 2.0 sigma detection before
+iterations 5, 10, and 15 respectively), or which are in a group
+too large (> than the value of the \fImaxgroup\fR parameter) to be reduced.
+.IP [5]
+estimates new x and y coordinates and magnitudes for each star in
+the group
+.IP [6]
+iterates until all the stars in the group satisfy the convergence criteria
+backing up the iteration counter by 1 each time a star is rejected from
+the group to allow the remaining stars time to settle into a new fit
+.IP [7]
+writes the star and group ids, new x and y coordinates, sky values,
+new magnitudes and magnitude errors, chi and sharpness statistics
+for the fitted stars to the
+output group photometry and rejections files
+.IP [8]
+repeats steps [2]-[7] for each group in the input group photometry file.
+
+.NH 4
+Running Group, Grpselect, and Nstar
+
+.PP
+Before \fBnstar\fR can be run the stars must be grouped with the
+\fBgroup\fR task as shown below.
+
+.YS
+da> group test default default default
+
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Critical overlap in stdevs per pixel (1.): .2
+ New critical overlap: 0.2 stdevs per pixel
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Size of Number of
+group groups
+
+1 4
+2 1
+3 1
+
+Total of 9 stars in 6 groups\fR
+.YE
+
+The critical overlap parameter \fIcritovlap\fR determines the degree
+to which crowding and/or random photometric errors are expected/allowed
+to influence the photometry. If the default value of 1 is required to group
+all the stars into associations of <= the current value of
+\fImaxgroup\fR stars, then unavoidable random photometric errors and
+crowding errors will affect the photometry about equally.
+If a critical
+overlap much greater than 1 is required, then crowding errors will
+dominate the random photometric errors. If a critical overlap
+much less than 1 does the
+job then
+unavoidable random photometric errors will dominate, and crowding errors
+are relatively insignificant.
+In
+the previous example the user chose to set \fIcritovlap\fR to a value
+much smaller
+than 1 to test whether random photometric rather than crowding errors will
+dominate the photometry.
+.PP
+If the first run of \fBgroup\fR separates all the stars into groups of less than
+60 all is well and the user can proceed to the \fBnstar\fR task. Otherwise
+the \fBgrpselect\fR task must be used to select out the larger groups
+and subdivide them as shown in the following example.
+
+.YS
+da> grpselect test.grp.1 small.grp 1 60
+.YE
+
+.IP ...
+First separate out the small groups.
+.LP
+
+.YS
+da> grpselect test.grp.1 big.grp.1 61 10000
+.YE
+
+.IP ...
+Next separate out the large groups.
+.LP
+
+.YS
+da> group test big.grp.1 default big.grp.2 critovlap=1.0
+.YE
+
+.IP ...
+Rerun the group task on the large group file with a bigger value
+of critovlap.
+.LP
+
+.YS
+da> pconcat small.grp,big.grp.2 all.grp
+.YE
+
+.IP ...
+Finally concatenate all the new group files together.
+.LP
+This step is not required for the test image since there are only a
+few stars and the field is not very crowded.
+
+.PP
+Run \fBnstar\fR on the grouped photometry file and \fBsubstar\fR on the
+fitted photometry file.
+
+.YS
+da> nstar test default default default default
+
+Recenter the stars (yes):
+ Recenter the stars: yes
+Refit the sky (no):
+ Refit the sky: no
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Maximum group size in number of stars (60):
+ New maximum group size: 60 stars
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+Group: 1 contains 1 stars
+ ID: 1 XCEN: 41.01 YCEN: 4.03 MAG: 17.22
+Group: 2 contains 2 stars
+ ID: 2 XCEN: 23.04 YCEN: 7.07 MAG: 17.75
+ ID: 3 XCEN: 17.99 YCEN: 8.00 MAG: 17.57
+Group: 3 contains 3 stars
+ ID: 5 XCEN: 35.98 YCEN: 22.01 MAG: 16.39
+ ID: 7 XCEN: 30.99 YCEN: 25.04 MAG: 17.04
+ ID: 4 XCEN: 26.00 YCEN: 22.01 MAG: 16.80
+Group: 4 contains 1 stars
+ ID: 6 XCEN: 8.02 YCEN: 22.97 MAG: 16.63
+Group: 5 contains 1 stars
+ ID: 8 XCEN: 28.96 YCEN: 33.93 MAG: 17.74
+Group: 6 contains 1 stars
+ ID: 9 XCEN: 35.98 YCEN: 42.01 MAG: 16.60
+
+da> substar test default "" default default
+.YE
+
+The parameter \fImaxgroup\fR specifies the
+maximum number of stars that \fBnstar\fR will
+fit simultaneously. The default value of 60
+is a conservative number based
+on the observed numerical behavior of the matrix inversion routines.
+.PP
+For most crowded field photometry applications it is simpler and easier
+to use the automated \fBallstar\fR task.
+
+.NH 4
+The Nstar Output
+
+.PP
+By default \fBnstar\fR writes the quantities: id, group, xcenter, ycenter,
+mag, merr, msky, niter, chi, sharp, pier, and perror to the output
+photometry and rejections files.
+.IP [1]
+Id and group are the star and group id numbers in the input group
+photometry file.
+.IP [2]
+Xcenter and ycenter are the best fit coordinates of the star.
+If the star was rejected xcenter and ycenter will be the best fit
+values of x and y at the time it was rejected. If \fIrecenter\fR is "no"
+xcenter and ycenter will be the position of the star in the input
+group photometry file.
+.IP [3]
+Mag and merr are the best fit magnitude and magnitude error respectively.
+The instrumental magnitude is computed relative to the magnitude
+of the psf model.
+Mag and merr are set to INDEF if the star cannot be fit to the
+psf model.
+.IP [4]
+Msky is always the individual sky for the star in the input photometry
+file regardless of whether fitsky is "no" or "yes". In the former
+case the actual value of the sky used in \fBnstar\fR is
+the mean of all the sky values for all the stars in the group. In the
+latter case it is a fitted parameter.
+.IP [5]
+Niter is the number of iterations it took to fit the star. If \fBniter\fR
+is equal to the parameter \fImaxiter\fR the user should be
+suspicious of the result. However since the convergence criteria are
+quite tightly constrained the result may still be reasonable.
+Niter is set to 0 if the star cannot be fit to the psf model.
+.IP [6]
+Chi and sharp are measures of the goodness of fit and the star's shape
+respectively. Chi should be ~ 1.0. If it is not then
+either the object is not a single star,
+the noise model including the ccd gain and readout noise, the flat
+fielding error and the interpolation error parameters assumed for the image are
+not correct, the
+psf model is a poor representation of the true psf, or the input
+image does not conform to the requirements of the DAOPHOT package.
+Sharp is a measure of the difference between the observed width
+of the object and the width of the psf model. Stars should have sharpness
+values \(~= 0.0, resolved objects sharpness values > 0.0, and cosmic rays
+and similar blemishes sharpnesses values < 0.0. Chi and sharp are set to INDEF
+if the star cannot be fit to the psf model.
+.IP [7]
+Pier and perror are an integer error code and error string respectively.
+If no error was encountered during the fit, pier is 0 and perror is
+"No_error".
+
+.NH 3
+Fitting Stars With Allstar
+
+.PP
+\fBAllstar\fR groups, fits
+and subtracts the fitted stars from the input image without intervention
+by the user.
+Because the grouping process is dynamic and the best
+fit stars are fit and subtracted first, fewer weak stars
+and noise spikes migrate to the position of stronger stars in \fBallstar\fR
+than is the case with \fBnstar\fR. \fBAllstar\fR replaces the functionality
+of the tasks \fBgroup\fR, \fBgrpselect\fR, \fBnstar\fR, and \fBallstar\fR.
+\fBAllstar\fR is the task of choice for doing crowded
+field photometry with DAOPHOT.
+
+.NH 4
+The Allstar Algorithm
+
+.PP
+By default the \fBallstar\fR task performs the following steps:
+.IP [1]
+reads the task parameters including the name of the input image, the input
+photometry file, the psf
+model, the output photometry and rejections files, the output
+subtracted image, and the \fBdatapars\fR and \fBdaopars\fR algorithm
+parameter sets
+sets
+.IP [2]
+reads the ids, x and y coordinates, magnitudes, and sky values for
+the first \fImaxnstars\fR stars in the input photometry file, rejecting
+at the start stars which have undefined sky values or which
+are too close to another star
+.IP [3]
+reads the original image into a working array and initializes
+two scratch arrays containing 1) the noise model and 2) the residuals from
+the current best fit for all the stars
+.IP [4]
+at the beginning of each iteration:
+1) groups the stars into physical associations that contain fewer
+than \fImaxgroup\fR
+stars, regrouping as necessary until all the groups are less than
+\fImaxgroup\fR or until the group is too dense to reduce, 2)
+subtracts the current best fit for all the stars that are still unfit from
+the working copy of the image and stores the results in the residuals
+array 3) initializes the weight array for all the unfitted stars
+.IP [5]
+during each iteration: 1) extracts the data within fitrad pixels
+around each star in each group from the residuals image, 2)
+performs a weighted non-linear least-squares fit of the psf model to
+the extracted
+data, ignoring bad pixels and down-weighting pixels that deviate too
+far from the psf model, and 3) computes new x and y coordinates and
+magnitudes for each star in each group
+.IP [6]
+after the fourth iteration 1) writes the id, new x and y coordinates,
+sky value, new magnitude and magnitude error, number of iterations
+required to fit the star, and the chi and sharpness statistic of stars
+which meet the convergence criteria, to
+the output photometry file, 2) subtracts the fitted star permanently from
+the working copy of the image, 3) updates the
+noise model in the weight array, 4) and eliminates the star from
+the active star list
+.IP [7]
+after the fourth iteration rejects stars which: 1) are too faint
+(more than 12.5 magnitudes fainter
+than the psf model), 2) have too low a signal-to-
+noise ratio (1.0, 1.5 and 2.0 sigma detection after 5, 10, and 15 iterations
+respectively), 3) have too few good
+pixels to compute a fit, 4) do not permit a unique solution,
+5) have merged with another star (star is
+< 0.37 * fwhmpsf from a brighter star), 6) are both too noisy
+and too close to a neighbor star (star is between 0.37 and 1.0 * fwhmpsf from
+a brighter star in the group and is a 1.0, 1.5, or 2.0 sigma
+detection before iterations 5, 10, and 15 respectively),
+or 7) are part of a group too dense to be reduced.
+.IP [8]
+writes out the final version of the work array into the output subtracted
+image
+
+.NH 4
+Running Allstar
+
+.PP
+\fBAllstar\fR is run as shown below.
+
+.YS
+da> allstar test default default default default default
+
+Recenter the stars (yes):
+ Recenter the stars: yes
+Refit the sky (no):
+ Refit the sky: no
+Psf radius in scale units (5.):
+ New psf radius: 5. scale units 5. pixels
+Fitting radius in scale units (3.):
+ New fitting radius: 3. scale units 3. pixels
+Maximum group size in number of stars (60):
+ New maximum group size: 60 stars
+Minimum good data value (50.) (CR or value):
+ New minimum good data value: 50. counts
+Maximum good data value (24500.) (CR or value):
+ New maximum good data value: 24500. counts
+
+NITER = 1
+NITER = 2
+NITER = 3
+NITER = 4
+FITTING: ID: 1 XCEN: 41.01 YCEN: 4.03 MAG: 17.22
+FITTING: ID: 4 XCEN: 26.00 YCEN: 22.01 MAG: 16.80
+FITTING: ID: 7 XCEN: 30.99 YCEN: 25.04 MAG: 17.04
+FITTING: ID: 6 XCEN: 8.02 YCEN: 22.97 MAG: 16.63
+FITTING: ID: 8 XCEN: 28.96 YCEN: 33.93 MAG: 17.74
+FITTING: ID: 9 XCEN: 35.98 YCEN: 42.01 MAG: 16.60
+NITER = 5
+FITTING: ID: 2 XCEN: 23.04 YCEN: 7.05 MAG: 17.75
+FITTING: ID: 3 XCEN: 18.00 YCEN: 7.99 MAG: 17.56
+FITTING: ID: 5 XCEN: 35.98 YCEN: 22.01 MAG: 16.39
+.YE
+
+.PP
+Users can easily run \fBallstar\fR as a background job as shown below.
+
+.YS
+da> allstar test default default default default default verify- \\
+ >& allstar.out &
+.YE
+
+.NH 4
+The Allstar Output
+
+.PP
+\fBAllstar\fR writes the following
+quantities: id, xcenter, ycenter, mag, merr, msky, niter, chi, sharp,
+pier, and perror to the output photometry and
+rejections files.
+.IP [1]
+Id is the id number of the star as read from the input photometry file.
+.IP [2]
+Xcenter and ycenter are the best fit position of the star.
+If the star was rejected xcenter and ycenter will be the computed
+values of x and
+y at the time it was rejected. If \fIrecenter\fR is "no", xcenter and ycenter
+will be the position of the star in the input photometry file.
+.IP [3]
+Mag and merr are the best fit magnitude and magnitude error respectively.
+The instrumental magnitude is computed relative to the magnitude of the
+psf model.
+Mag and merr are set to INDEF if the star cannot be fit to the psf model.
+.IP [4]
+Msky is the sky value in the input photometry file if \fIfitsky\fR = "no",
+otherwise it is the
+recomputed sky value. If \fIfitsky\fR is "yes" the sky is recomputed
+every third iteration after the current best fit for the star is
+subtracted from the image data. The new sky value is set to the
+average of 40% of the sky pixels, centered on the median sky value,
+which are inside the sky
+annulus defined by the parameters \fIsannulus\fR and
+\fIwsannulus\fR. The sky value is not recomputed
+if there are fewer than 100 sky pixels in the specified sky annulus
+even if \fIfitsky\fR is "yes".
+If the star is not fit for some reason,
+msky is the sky value at the time the star was rejected.
+.IP [5]
+Niter is the number of iterations it took to fit the star. If this
+number is equal to \fImaxiter\fR the user should be
+suspicious of the result. However as the convergence criteria are
+conservative the star may still be reasonably well fit.
+Niter is set to 0 if the star cannot be fit to the psf model.
+.IP [6]
+Chi and sharp are measures of the goodness of fit and the shape
+respectively. Chi should be ~ 1.0. If it is not, then
+either the object is not a single star, the noise model including
+one or more of the gain, readout noise, flat-fielding error, and
+interpolation error parameters for the image are incorrect, the
+psf model is a poor representation of the true psf, or the input
+image does not conform to the requirements of the DAOPHOT package.
+Sharpness is a measure of the difference between the observed width
+of the object and the width of the psf model. Stars should have a sharpness
+value ~ 0.0, resolved objects a sharpness of > 0.0, and cosmic rays and similar
+blemishes a sharpness of < 0. Chi and sharp are set to INDEF if the star
+cannot be fit for some reason.
+.IP [7]
+Pier and perror are an integer error code and error string respectively.
+If no error was encountered during the fit, pier is 0 and perror is
+"No_error".
+
+.NH 2
+Examining the Output Photometry Files
+
+.PP
+The identical tools can be used to examine the output of the \fBpeak\fR,
+\fBnstar\fR, and \fBallstar\fR tasks. Some examples using the output of
+\fBallstar\fR are shown below.
+.PP
+The following command produces a plot of magnitude error versus magnitude.
+
+.YS
+da> pdump test.als.1 mag,merr yes | graph point+
+.YE
+
+The following command produces a plot of chi versus magnitude.
+
+.YS
+da> pdump test.als.1 mag,chi yes | graph STDIN point+
+.YE
+
+The following command produces a plot of chi versus sharpness.
+
+.YS
+da> pdump test.als.1 sharp,chi yes | graph STDIN point+
+.YE
+
+The output photometry file can also be examined interactively
+with the \fBpexamine\fR task and the displayed subtracted image.
+Note that the fitted stars are marked in green and the rejected stars
+are marked in red on the display.
+
+.YS
+da> display test.sub.1 1 fi+
+
+da> pdump test.als.1 xcenter,ycenter yes | tvmark 1 STDIN col=205
+
+da> pdump test.arj.1 xcenter,ycenter yes | tvmark 1 STDIN col=204
+
+da> pexamine test.als.1 "" test.sub.1
+.YE
+
+.IP ...
+A plot of magnitude error versus magnitude appears on the screen.
+.IP ...
+The user moves to a discrepant point in the graph and types o to get a
+listing of the results for the star, r to get a radial profile plot
+around the subtracted star, and concludes on the basis of the plots
+that the bad chi value is due to the star being a close double.
+.IP ...
+The user types i to switch to image cursor mode,
+moves to several other stars with poor subtractions and types
+s to see a surface plot of the residuals.
+.IP ...
+The user types q to quit.
+
+.NH 2
+Problems with the Photometry
+
+.PP
+Bad chi values in, and poor
+subtractions of, \fBpeak\fR, \fBnstar\fR or \fBallstar\fR
+photometry can usually be traced to: 1) a psf model which was
+poorly determined in the first place, e.g. poor choice of
+parameters, bad choice of
+psf stars or too few stars used for determining a good variable psf model,
+2) data reduction problems e.g. the mean sky value was subtracted from the
+image, the image statistics have been altered, or cosmic ray removal
+clipped the tops of the stars, to give a few of many examples,
+or 3) the properties of the image, e.g. non-linearity, a psf which has
+very high order variability or very undersampled data, make computation
+of a good psf model difficult or impossible.
+.PP
+Bad chi values can also be caused by incorrect
+values of gain and readout noise or by a data reduction operation
+which has significantly affected the image statistics.
+.PP
+Poor sky fitting can also cause scatter
+in the photometry. Users should carefully check the position of the
+sky annulus used in \fBphot\fR if they are seeing poor subtractions.
+If the images have a rapidly varying
+background due, due for example to nebulosity, it might be useful to
+check out the alternate sky fitting routines, median or centroid, in the
+\fBphot\fR task. The refit sky option in \fBpeak\fR and \fBnstar\fR
+should be exercised with caution
+since a larger fitting radius is often required
+to get a reasonable sky fit, than is required to get good positions
+and magnitudes, and this in turn can cause more scatter
+in the photometry due to the influence of neighbors. On the other
+hand the refit sky option in \fBallstar\fR can often significantly
+reduce scatter in very crowded regions since it can use data closer to
+or even underneath (!) the star to improve the sky estimate.
+Users who use this option must remember to set the inner
+radius of the \fBallstar\fR sky annulus to avoid the inner stellar
+core region where there is a lot of noise in the subtraction.
+.PP
+After running \fBsubstar\fR on a file produced by the \fBpeak\fR
+task, users will sometimes see large holes in the data at the
+position of some subtracted
+stars. This is usually caused by fainter stars (which are fit individually)
+migrating to the position of a brighter nearby star and then being
+subtracted out twice by \fBsubstar\fR. Keeping the fitting radius small
+will help minimize this problem, but if it is frequent and the frame
+is somewhat crowded, the user should run \fBnstar\fR or \fBallstar\fR
+instead of \fBpeak\fR.
+.PP
+A similar problem can be caused by users running \fBdaofind\fR
+with a very low threshold and detecting a lot of noise spikes, which
+then migrate to the positions of brighter stars
+and cause scatter and holes in the subtracted \fBpeak\fR photometry,
+or attach themselves to noise spikes in the stellar profiles and cause
+scatter and holes in the subtracted \fBnstar\fR photometry.
+Similar problems can affect \fBallstar\fR photometry but to a much
+lesser degree since the
+stars are grouped dynamically and subtracted from the input data as
+they are fit. For all three photometry tasks spurious detections
+can consume a lot of excess computer time because the stellar groups
+become much larger.
+
+.NH 2
+Detecting Stars Missed By Daofind
+
+.PP
+In very crowded fields many new stars, missed by the first run of \fBdaofind\fR,
+will be detected after
+the first run of \fBpeak\fR+\fBsubstar\fR, \fBnstar\fR+\fBsubstar\fR,
+or \fBallstar\fR. If there
+are many "missed" stars
+\fBdaofind\fR should be run on the subtracted image after increasing the
+\fIthreshold\fR parameter to avoid detecting the residuals
+of previously subtracted stars. If there
+are only a few such stars they can be "detected" by creating a coordinate
+file using the subtracted image and \fBtvmark\fR in interactive mode.
+Examples of both techniques are shown below.
+
+.YS
+da> daofind test.sub.1 newstars.coo threshold=5.0
+.YE
+
+or
+
+.YS
+da> display test.sub.1 1 fi+
+
+da> pdump test.als.1 xcen,ycen yes | tvmark 1 STDIN col=204
+
+da> tvmark 1 newstars.coo inter+
+.YE
+
+.IP ...
+Move cursor to missing stars and tap the \fBa\fR key to append them to the
+output coordinate file.
+
+.NH 2
+Initializing the Missing Star Photometry with Phot
+
+.PP
+The next step is to get initial photometry for the "missing"
+stars. The simplest way is
+to run \fBphot\fR on the original image using the coordinate list created
+by \fBdaofind\fR or \fBtvmark\fR, and the same algorithm parameters as
+were used
+in the first run of \fBphot\fR. It is also possible to use \fBphot\fR directly
+in interactive mode to create a photometry file of missed stars. Both
+options are shown below.
+
+.YS
+da> phot test newstars.coo newstars.mag
+.YE
+
+or
+
+.YS
+da> display test.sub.1 1 fi+
+
+da> pdump test.als.1 xcen,ycen yes | tvmark 1 STDIN col=204
+
+da> phot test "" newstars.mag centroid=calgorithm inter+
+.YE
+
+.IP ...
+Point the cursor to the missing stars and tap \fBspacebar\fR.
+.LP
+
+Note that if the stars are or were marked with the cursor, the user must
+turn centroiding on in order to center them correctly.
+
+.NH 2
+Merging Photometry Files with Pfmerge
+
+.PP
+The photometry file containing the aperture photometry for the new stars
+can be combined with the best psf fitting photometry already computed
+by the \fBnstar\fR or \fBallstar\fR tasks
+for the original star list, using the task \fBpfmerge\fR as shown below.
+The \fBprenumber\fR task ensures that the new stars all have unique ids.
+
+.YS
+da> pfmerge test.als.1,newstars.mag newstars.als.1
+da> prenumber newstars.als.1\fR
+.YE
+
+
+.NH 2
+Refitting the Stars with Allstar
+
+.PP
+After the photometry files have been merged a final run of \fBallstar\fR or
+\fBgroup\fR+\fBnstar\fR+\fBsubstar\fR on the combined file in order
+to compute accurate magnitudes for the new stars should be made
+as shown below.
+
+.YS
+da> allstar test newstars.als.1 default default default default
+.YE
+
+.NH 2
+Examining the Subtracted Image
+
+.PP
+The user should search the subtracted image for any remaining unfit
+stars and perform another iteration of \fBdaofind\fR, \fBphot\fR,
+\fBpfmerge\fR and \fBallstar\fR to computed fitted magnitudes for
+the new objects.
+
+.NH 2
+Computing an Aperture Correction
+
+.PP
+The aperture correction is the number which must be added to the
+fitted instrumental magnitudes computed by the \fBpeak\fR,
+\fBnstar\fR, or \fBallstar\fR tasks to produce the total instrumental
+magnitude.
+.PP
+In order to compute aperture corrections for an image with a constant psf model
+the user must:
+.IP [1]
+identify several bright isolated stars in the input image or subtract
+all the neighbors from around several bright stars such as the
+psf stars using the current psf model and the \fBsubstar\fR task
+.IP [2]
+using a minimum aperture radius equal to the one used in \fBphot\fR to compute
+initial aperture photometry for all the crowded field stars,
+and a maximum aperture radius equal to the one through which
+the instrumental magnitudes of the standard stars were or will be measured,
+use the \fBphot\fR task to
+do multi-aperture photometry of the stars identified in [1] through at
+least five apertures
+.IP [3]
+run the \fBmkapfile\fR task in the PHOTCAL package on the aperture
+photometry file produced in 2, to determine the aperture
+correction for the image as shown below
+.LP
+
+.YS
+da> phot test "" test.apmags calg=centroid aperture="3,3.5,4.0,4.5 5.0"
+.YE
+
+.IP ...
+Do multi-aperture photometry of the selected stars.
+.LP
+
+.YS
+da> mkapfile test.apmags 5 test.apcors
+.YE
+
+.IP ...
+Compute the aperture correction between apertures 1 and 5.
+
+.PP
+To compute compute aperture corrections for an image with a variable psf model
+the user must:
+.IP [1]
+identify several bright isolated stars in the input image or subtract
+all the neighbors from around several bright stars such as the
+psf stars using the current psf model and the \fBsubstar\fR task
+.IP [2]
+using a photometry aperture equal to the one through which
+the magnitudes of the standard stars were or will be measured,
+use the \fBphot\fR task to
+do aperture photometry of the stars identified in [1]
+.IP [3]
+extract the fitted magnitudes for these stars from existing \fBnstar\fR
+or \fBallstar\fR photometry or recompute them using the
+\fBnstar\fR or \fBallstar\fR tasks and the current psf model
+.IP [4]
+set the aperture correction to the mean difference between the fitted
+magnitudes computed in [3] and the aperture photometry magnitudes
+computed through the large aperture in [2]
+
+.NH
+References
+
+.LP
+.nf
+Stetson, P. B. 1987 Pub .A.S.P., \fB99\fR, 191
+Stetson, P. B., Davis, L.E. and Crabtree, D.B. 1989, in
+ \fICCDs in Astronomy\fR, G.H. Jacoby, San Francisco: Astronomical
+ Society of the Pacific, 289
+Stetson, P. B. 19 Pub .A.S.P., \fB102\fR, 932
+Stetson, P.B, 1992, \fIUser's Manual for DAOPHOT II\fR
+Stetson, P. B. 1992 in \fIAstronomical Data Analysis Software and Systems I\fR,
+ D.M. Worall, C. Biemesderfer, and J. Barnes, San Francisco: Astronomical
+ Society of the Pacific, 297
+.fi
+
+.NH
+Appendices
+
+.NH 2
+The Instrumental Magnitude Scale
+
+.PP
+The instrumental magnitude scale is set by the magnitude assigned
+to the psf model, the quantity \fIpsfmag\fR stored in the psf image header.
+Psfmag is the magnitude of the first psf star in the input photometry
+file, usually but not always the file written by the \fBphot\fR task.
+If magnitudes were measured through more than one aperture
+in \fBphot\fR, the magnitude used will be the
+magnitude through the smallest aperture.
+
+.NH 2
+The Analytic Psf Models
+
+.PP
+The functional forms of the currently supported analytic psf models
+are listed below.
+The quantity A is a normalization factor. The Pn are
+the parameters which are fit during the psf modeling process.
+
+.nf
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2
+ gauss = A * exp (-0.5 * z)
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p3
+ moffat15 = A / (1 + z) ** 1.5
+ moffat25 = A / (1 + z) ** 2.5
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p3
+ lorentz = A / (1.0 + z)
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2
+ e = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p4
+ penny1 = A * ((1 - p3) / (1.0 + z) + p3 * exp (-0.693*e))
+
+ z = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + p5 * x * y
+ e = x ** 2 / p1 ** 2 + y ** 2 / p2 ** 2 + x * y * p4
+ penny2 = A * ((1 - p3) / (1.0 + z) + p3 * exp (-0.693*e))
+.fi
+
+.NH 2
+The Error Model
+
+.PP
+The predicted errors in the the DAOPHOT photometry are computed per
+pixel as shown below, where terms 1, 2, 3, and 4 represent the readout
+noise, the poisson noise, the flat-fielding error, and the
+interpolation error respectively. The quantities readnoise, epadu,
+I, M, p1, and p2 are the effective readout noise in electrons, the
+effective gain in
+electrons per ADU, the pixel intensity in ADU, the PSF model
+intensity in ADU, the FWHM in x in pixels, and the FWHM in y in pixels.
+
+.nf
+ error = sqrt (term1 + term2 + term3 + term4) (ADU)
+ term1 = (readnoise / epadu) ** 2
+ term2 = I / epadu
+ term3 = (.01 * flaterr * I) ** 2
+ term4 = (.01 * proferr * M / p1 / p2) ** 2
+.fi
+
+
+.NH 2
+The Radial Weighting Function
+
+.PP
+The radial weighting function employed by all the psf fitting tasks
+is shown below, where dx and dy are the distance of the pixel
+in question from the centroid of the star being fit.
+
+.nf
+ wtr = 5.0 / (5.0 + rsq / (1.0 - rsq))
+ rsq = (dx ** 2 + dy ** 2) / fitrad ** 2
+.fi
+
+.NH 2
+Total Weights
+
+.PP
+The total weight assigned each pixel in the fit is the
+following.
+
+.nf
+ wtp = wtr / error ** 2
+.fi
+
+.NH 2
+Bad Data Detection
+
+.PP
+Pixels less than the good data minimum \fIdatamax\fR or greater than
+the good data maximum \fIdatamax\fR are rejected immediately from the
+fit.
+.PP
+After a few iterations and if clipexp > 0, a clipping scheme to
+reject bad data is enabled. The weights of the pixels are
+recomputed as follows. Pixels having a residual of cliprange sigma
+will have their weight reduced by half.
+
+.nf
+ wt = wtp / (1.0 + (residual / error / chiold /
+ cliprange) ** clipexp)
+.fi
+
+.NH 2
+Stellar Mergers
+
+.PP
+In order for two stars to merge during the course of the psf fitting
+process either their separation must be < 0.37 * FWHM of the psf model,
+or their separation must be > 0.37 * FWHM but < 1.0 * FWHM of the
+psf model and the signal-to-noise ratio of the fainter is less than 1.0, 1.5,
+or 2.0 after iterations 4, 9, and 14 respectively.
+
+.NH 2
+Faint Stars
+
+.PP
+Stars are considered to be too faint if they are more than 12.5
+magnitudes fainter than the psf, or if after a certain number of iterations,
+they have a signal-to-noise ratio less than 2.0.
diff --git a/noao/digiphot/daophot/findpars.par b/noao/digiphot/daophot/findpars.par
new file mode 100644
index 00000000..f42b3e89
--- /dev/null
+++ b/noao/digiphot/daophot/findpars.par
@@ -0,0 +1,12 @@
+# FINDPARS
+
+threshold,r,h,4.0,,,Threshold in sigma for feature detection
+nsigma,r,h,1.5,,,Width of convolution kernel in sigma
+ratio,r,h,1.0,0.0,1.0,Ratio of minor to major axis of Gaussian kernel
+theta,r,h,0.0,0.0,180.0,Position angle of major axis of Gaussian kernel
+sharplo,r,h,.2,,,Lower bound on sharpness for feature detection
+sharphi,r,h,1.0,,,Upper bound on sharpness for feature detection
+roundlo,r,h,-1.0,,,Lower bound on roundness for feature detection
+roundhi,r,h,1.0,,,Upper bound on roundness for feature detection
+mkdetections,b,h,no,,,Mark detections on the image display?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/fitskypars.par b/noao/digiphot/daophot/fitskypars.par
new file mode 100644
index 00000000..bbb17dd1
--- /dev/null
+++ b/noao/digiphot/daophot/fitskypars.par
@@ -0,0 +1,17 @@
+# SKY FITTING PARAMETERS
+
+salgorithm,s,h,"mode","|median|mode|centroid|gauss|crosscor|ofilter|histplot|radplot|constant|file|mean|",,Sky fitting algorithm
+annulus,r,h,10.0,,,Inner radius of sky annulus in scale units
+dannulus,r,h,10.0,,,Width of sky annulus in scale units
+skyvalue,r,h,0.0,,,User sky value
+smaxiter,i,h,10,,,Maximum number of sky fitting iterations
+sloclip,r,h,0.0,,,Lower clipping factor in percent
+shiclip,r,h,0.0,,,Upper clipping factor in percent
+snreject,i,h,50,,,Maximum number of sky fitting rejection iterations
+sloreject,r,h,3.0,,,Lower K-sigma rejection limit in sky sigma
+shireject,r,h,3.0,,,Upper K-sigma rejection limit in sky sigma
+khist,r,h,3.0,,,Half width of histogram in sky sigma
+binsize,r,h,0.10,,,Binsize of histogram in sky sigma
+smooth,b,h,no,,,Boxcar smooth the histogram
+rgrow,r,h,0.0,,,Region growing radius in scale units
+mksky,b,h,no,,,Mark sky annuli on the display
diff --git a/noao/digiphot/daophot/group.par b/noao/digiphot/daophot/group.par
new file mode 100644
index 00000000..6deeedd3
--- /dev/null
+++ b/noao/digiphot/daophot/group.par
@@ -0,0 +1,16 @@
+# Parameters for the GROUP task
+
+image,f,a,,,,"Image corresponding to the photometry file"
+photfile,f,a,default,,,"Photometry file (default: image.mag.?)"
+psfimage,f,a,default,,,"PSF image (default: image.psf.?)"
+groupfile,f,a,"default",,,"Output group file (default: image.grp.?)"
+datapars,pset,h,"",,,Data dependent parameters
+daopars,pset,h,"",,,Psf fitting parameters
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,Verify critical group parameters?
+update,b,h,)_.update,,,Update critical group parameters?
+verbose,b,h,)_.verbose,,,Print group messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/group/dpgconfirm.x b/noao/digiphot/daophot/group/dpgconfirm.x
new file mode 100644
index 00000000..4dcb3003
--- /dev/null
+++ b/noao/digiphot/daophot/group/dpgconfirm.x
@@ -0,0 +1,24 @@
+# DP_GCONFIRM -- Confirm the critical GROUP task parameters.
+
+procedure dp_gconfirm (dao)
+
+pointer dao # pointer to the group structure
+
+begin
+ call printf ("\n")
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the critical signal-to-noise ratio.
+ call dp_vcritsnratio (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/group/dpmkgroup.x b/noao/digiphot/daophot/group/dpmkgroup.x
new file mode 100644
index 00000000..741fc8b0
--- /dev/null
+++ b/noao/digiphot/daophot/group/dpmkgroup.x
@@ -0,0 +1,484 @@
+include <mach.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define EPS_OVERLAP (1.0e-10)
+
+# DP_MKGROUP -- Arrange the photometry results into natural groupings
+# based on physical proximity and the signal-to-noise ratio.
+
+procedure dp_mkgroup (dao, im, grp)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to input image
+int grp # the output file descriptor
+
+bool overlap
+int i, maxgroup, curr_star, first_unknown, first_ingrp, nin_currgrp
+int curr_point, crit_point, ier
+pointer psffit, apsel, index, group_size, number
+real fradius, critovlap, bright_mag, read_noise, fitradsq, critsep
+real critsep_sq, xcurr, ycurr, dxcurr_frompsf, dycurr_frompsf, magcurr
+real skycurr, magcrit, skycrit, dxcrit_frompsf, dycrit_frompsf
+real deltax, deltay, radsq, rel_bright, radius, ratio, stand_err, dvdx, dvdy
+
+bool dp_gchkstar()
+real dp_usepsf()
+
+begin
+ # Get the daophot pointers.
+ psffit = DP_PSFFIT(dao)
+ apsel = DP_APSEL(dao)
+
+ # Return if the photometry file is empty.
+ if (DP_APNUM(apsel) <= 0)
+ return
+
+ # Store the original fitting radius.
+ fradius = DP_FITRAD(dao)
+ DP_FITRAD(dao) = min (DP_FITRAD(dao), DP_PSFRAD(dao))
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+
+ # Get some working memory.
+ call malloc (index, DP_APNUM(apsel), TY_INT)
+ call malloc (group_size, DP_APNUM(apsel), TY_INT)
+ call malloc (number, DP_APNUM(apsel), TY_INT)
+
+ # Initialize the group information.
+ call aclri (Memi[index], DP_APNUM(apsel))
+ call aclri (Memi[group_size], DP_APNUM(apsel))
+ call aclri (Memi[number], DP_APNUM(apsel))
+
+ # Check for INDEF results and fix them up..
+ call dp_gpfix (dao, im, bright_mag)
+
+ # Sort the stars into order of increasing y value. The star ID's, X,
+ # MAG and SKY values are still in the order in which they were read
+ # in. INDEX points to the proper value, i.e. Y (i) and X (index(i)).
+
+ call quick (Memr[DP_APYCEN(apsel)], DP_APNUM(apsel), Memi[index], ier)
+
+ # Bright_mag is the apparent magnitude of the brightest star
+ # in the input file. If this is INDEF then set to the PSFMAG.
+
+ if (! IS_INDEFR(bright_mag))
+ bright_mag = DAO_RELBRIGHT (psffit, bright_mag)
+ else
+ bright_mag = 1.0
+
+ # Smooth the PSF.
+ if ((DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)) > 0)
+ call dp_smpsf (dao)
+
+ # Define some important constants in terms of the daophot parameters.
+
+ critovlap = DP_CRITSNRATIO(dao) * DP_CRITSNRATIO(dao)
+ read_noise = (DP_READNOISE (dao) / DP_PHOTADU(dao)) ** 2
+ fitradsq = (DP_FITRAD(dao) + 1) * (DP_FITRAD(dao) + 1)
+
+ ## Note that the definition of firadsq has been changed in this
+ ## version of group. This has been done so that the grouping
+ ## algorithm defaults to the one used by ALLSTAR in the case that
+ ## the critoverlap parameter is very large.
+ ## fitradsq = (2.0 * DP_FITRAD(dao)) * (2.0 * DP_FITRAD(dao))
+
+ # Define the critical separation.
+ critsep = DP_PSFRAD(dao) + DP_FITRAD(dao) + 1.0
+ critsep_sq = critsep * critsep
+
+ # Now we search the list for stars lying within one critical
+ # separation of each other. The stars are currently in a stack
+ # DP_APNUM(apsel) stars long. FIRST_INGRP points to the first star
+ # in the current group and starts out, of course, with the
+ # value CURR_STAR. CURR_STAR will point to the position in the stack
+ # occupied by the star which is currently the center of a circle
+ # of radius equal to the critical radius, within which we are
+ # looking for other stars. CURR_STAR starts out with a value of
+ # 1. FIRST_UNKNOWN points to the top position in the stack of the
+ # stars which have not yet been assigned to groups. FIRST_UNKNOWN
+ # starts out with the value 2. Each time through, the program goes
+ # down through the stack from FIRST_UNKNOWN to DP_APNUM(apsel) and
+ # looks for stars within the critical distance from the star at stack
+ # position CURR_STAR. When such a star is found, it changes places
+ # in the stack with the star at FIRST_UNKNOWN and FIRST_UNKNOWN is
+ # incremented by one. When the search has gotten to the last
+ # position in the stack (DP_APNUM(apsel)), the pointer CURR_STAR is
+ # incremented by one, and the search proceeds again from the new
+ # value of FIRST_UNKNOWN to DP_APNUM(apsel). If the pointer CURR_STAR
+ # catches up with the pointer FIRST_UNKNOWN, that means that the
+ # group currently being built up is complete. The number of stars in
+ # the newly-created group (the first star of which is at stack
+ # position FIRST_INGRP) is stored in array element GROUP_SIZE[FIRST_
+ # INGRP]. Then a new group is started beginning with the star at the
+ # current position CURR_STAR, ( = FIRST_UNKNOWN for the moment),
+ # FIRST_UNKNOWN is incremented by 1, and the next group is built up
+ # as before.
+
+ # Initialize.
+ maxgroup = 0
+ curr_star = 1
+ first_unknown = 1
+
+ # Loop through the list of stars.
+ while (curr_star <= DP_APNUM(apsel)) {
+
+ # Initialize for the next group.
+ first_ingrp = curr_star
+ nin_currgrp = 1
+ first_unknown = first_unknown + 1
+
+ # Begin defining a group.
+ while (curr_star < first_unknown) {
+
+ # Get the parameters of the current star.
+ curr_point = Memi[index+curr_star-1]
+ xcurr = Memr[DP_APXCEN(apsel)+curr_point-1]
+ ycurr = Memr[DP_APYCEN(apsel)+curr_star-1]
+ call dp_wpsf (dao, im, xcurr, ycurr, dxcurr_frompsf,
+ dycurr_frompsf, 1)
+ dxcurr_frompsf = (dxcurr_frompsf - 1.0) / DP_PSFX(psffit) - 1.0
+ dycurr_frompsf = (dycurr_frompsf - 1.0) / DP_PSFY(psffit) - 1.0
+ magcurr = Memr[DP_APMAG(apsel)+curr_point-1]
+ skycurr = Memr[DP_APMSKY(apsel)+curr_point-1]
+ if (IS_INDEFR(magcurr))
+ magcurr = bright_mag
+ else if (abs (DAO_MAGCHECK(psffit, magcurr)) > (MAX_EXPONENTR -
+ 1))
+ magcurr = bright_mag
+ else
+ magcurr = DAO_RELBRIGHT (psffit, magcurr)
+
+ # Go through the list of unassigned stars looking for stars
+ # within one critical distance of the current star.
+
+ do i = first_unknown, DP_APNUM(apsel) {
+
+ # Is this star within one critical separation of the
+ # current star ?
+
+ overlap = dp_gchkstar (Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memi[index], i, xcurr, ycurr,
+ critsep_sq, deltax, deltay, radsq)
+
+ # Break from the do loop if we are beyond the the critical
+ # separation.
+
+ if (deltay > critsep)
+ break
+ if (! overlap)
+ next
+
+ # Define the characteristics of the unknown star.
+
+ crit_point = Memi[index+i-1]
+ magcrit = Memr[DP_APMAG(apsel)+crit_point-1]
+ skycrit = Memr[DP_APMSKY(apsel)+crit_point-1]
+ call dp_wpsf (dao, im, Memr[DP_APXCEN(apsel)+crit_point-1],
+ Memr[DP_APYCEN(apsel)+i-1], dxcrit_frompsf,
+ dycrit_frompsf, 1)
+ dxcrit_frompsf = (dxcrit_frompsf - 1.0) / DP_PSFX(psffit) -
+ 1.0
+ dycrit_frompsf = (dycrit_frompsf - 1.0) / DP_PSFY(psffit) -
+ 1.0
+
+ # Check to see if stars overlap critically.
+
+ if ((critovlap > EPS_OVERLAP) && (radsq > fitradsq)) {
+
+ overlap = false
+
+ # Rel_bright is the brightness of the star currently
+ # being tested relative to the star in the center.
+
+ if (IS_INDEFR(magcrit))
+ rel_bright = bright_mag
+ else if (abs (DAO_MAGCHECK (psffit, magcrit)) >
+ (MAX_EXPONENTR - 1))
+ rel_bright = bright_mag
+ else
+ rel_bright = DAO_RELBRIGHT(psffit, magcrit)
+
+ # Determine the point at which to evaluate the PSF.
+
+ radius = sqrt (radsq)
+ ratio = (radius - (DP_FITRAD(dao) + 1)) / radius
+ deltax = ratio * deltax
+ deltay = ratio * deltay
+
+ # Determine which star is brighter.
+
+ if (magcurr > rel_bright) {
+ rel_bright = magcurr *
+ dp_usepsf (DP_PSFUNCTION(psffit), deltax,
+ deltay, DP_PSFHEIGHT(psffit),
+ Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ dxcurr_frompsf, dycurr_frompsf, dvdx, dvdy)
+ } else {
+ rel_bright = rel_bright *
+ dp_usepsf (DP_PSFUNCTION(psffit), -deltax,
+ -deltay, DP_PSFHEIGHT(psffit),
+ Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ dxcrit_frompsf, dycrit_frompsf, dvdx, dvdy)
+ }
+
+ # Do the stars overlap ?
+
+ if (! IS_INDEFR(skycurr) && ! IS_INDEFR(skycrit)) {
+ stand_err = read_noise + 0.5 * (skycurr +
+ skycrit) / DP_PHOTADU(dao)
+ if ((rel_bright * rel_bright) >= (stand_err *
+ critovlap))
+ overlap = true
+ }
+ }
+
+ # The two stars do overlap. Increment the pointers
+ # and move this star to the top of the stack.
+
+ if (overlap) {
+ nin_currgrp = nin_currgrp + 1
+ call dp_gswap2 (i, first_unknown, Memi[index],
+ Memr[DP_APYCEN(apsel)])
+ first_unknown = first_unknown + 1
+ }
+ }
+
+ curr_star = curr_star + 1
+ }
+
+ # Check for maximum group size.
+ if (nin_currgrp > maxgroup)
+ maxgroup = nin_currgrp
+
+ # Increment the number of groups versus size counter. Stars
+ # with undefined centers are always in a group with a membrship
+ # of 1 and are skipped.
+
+ if (! IS_INDEFR(xcurr) && ! IS_INDEFR(ycurr))
+ Memi[number+nin_currgrp-1] = Memi[number+nin_currgrp-1] + 1
+
+ # Define the group size.
+ Memi[group_size+first_ingrp-1] = nin_currgrp
+ }
+
+ # Write out all the groups to the output file.
+ call dp_wrtgroup (dao, im, grp, Memi[number], Memi[index],
+ Memi[group_size], maxgroup)
+
+ call mfree (number, TY_INT)
+ call mfree (index, TY_INT)
+ call mfree (group_size, TY_INT)
+
+ # Restore the original fitting radius.
+ DP_FITRAD(dao) = fradius
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+end
+
+
+# DP_GSWAP2 -- Interchange two stars in the photometry list and then shift
+# the list.
+
+procedure dp_gswap2 (star1, star2, index, y)
+
+int star1, star2 # the two star numbers to interchange
+int index[ARB] # the index array
+real y[ARB] # array of y positions
+
+int j, k, l, ihold
+real yhold
+
+begin
+ yhold = y[star1]
+ ihold = index[star1]
+
+ l = star1 + star2
+ do j = star2, star1 - 1 {
+ k = l - j
+ y[k] = y[k-1]
+ index[k] = index [k-1]
+ }
+
+ y[star2] = yhold
+ index[star2] = ihold
+end
+
+
+# DP_GCHKSTR -- Check to see if the unknown stars star is within one critical
+# separation of the current star.
+
+bool procedure dp_gchkstar (x, y, index, i, xcurr, ycurr, crit, deltax,
+ deltay, radsq)
+
+real x[ARB] # array of x positions
+real y[ARB] # array of y positions
+int index[ARB] # index array from the quick sort
+int i # position of test star in stack
+real xcurr # x position of current star
+real ycurr # y position of current star
+real crit # critical radius squared
+real deltax # output difference in x
+real deltay # output difference in y
+real radsq # separation squared
+
+begin
+ # Initialize the deltas.
+ deltax = MAX_REAL
+ deltay = MAX_REAL
+
+ # Check to see if star is within a critical radius. Reject the
+ # star if any of the positions are INDEF.
+ if (IS_INDEFR(xcurr) || IS_INDEFR(ycurr)) {
+ return (false)
+ } else if (IS_INDEFR(y[i]) || IS_INDEFR(x[index[i]])) {
+ return (false)
+ } else {
+ deltay = y[i] - ycurr
+ deltax = x[index[i]] - xcurr
+ radsq = deltax * deltax + deltay * deltay
+ if (radsq <= crit)
+ return (true)
+ else
+ return (false)
+ }
+end
+
+
+# DP_GPFIX -- Check for INDEF photometry and get estimate of magnitude.
+
+procedure dp_gpfix (dao, im, bright_mag)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real bright_mag # apparent magnitude of the brightest star
+
+int i, lowx, lowy, nxpix, nypix
+pointer apsel, subim
+real fitrad, fitradsq, mingdata, maxgdata, x, y, sky, mag
+
+bool fp_equalr()
+pointer dp_gsubrast()
+real dp_gaccum()
+
+begin
+ # Get pointers to the daophot structures.
+ apsel = DP_APSEL (dao)
+
+ # Initialize.
+ fitrad = DP_FITRAD(dao)
+ fitradsq = fitrad * fitrad
+ if (IS_INDEFR (DP_MINGDATA(dao)))
+ mingdata = -MAX_REAL
+ else
+ mingdata = DP_MINGDATA(dao)
+ if (IS_INDEFR (DP_MAXGDATA(dao)))
+ maxgdata = MAX_REAL
+ else
+ maxgdata = DP_MAXGDATA(dao)
+ bright_mag = MAX_REAL
+
+ # Get a magnitude estimate for stars with INDEF magnitudes by summing
+ # all of the pixels within one fitting radius and scaling with respect
+ # to the PSFMAG.
+
+ do i = 1, DP_APNUM(apsel) {
+
+ # Check for undefined centers.
+ x = Memr[DP_APXCEN(apsel)+i-1]
+ y = Memr[DP_APYCEN(apsel)+i-1]
+ if (IS_INDEFR(x) || IS_INDEFR(y))
+ next
+
+ # Check for an undefined sky.
+ sky = Memr[DP_APMSKY(apsel)+i-1]
+ if (IS_INDEFR(sky))
+ next
+
+ # Correct the magnitudes.
+ mag = Memr[DP_APMAG(apsel)+i-1]
+ if (IS_INDEFR(mag)) {
+
+ # Get subraster around star position. If the subraster
+ # cannot be extracted leave the magnitude as INDEF.
+ subim = dp_gsubrast (im, x, y, fitrad, lowx, lowy, nxpix,
+ nypix)
+ if (subim == NULL)
+ next
+
+ # Estimate the value of the PSF.
+ mag = dp_gaccum (dao, Memr[subim], nxpix, nypix, lowx, lowy,
+ x, y, sky, fitradsq, mingdata, maxgdata)
+
+ if (! IS_INDEFR(mag))
+ Memr[DP_APMAG(apsel)+i-1] = mag
+
+
+ } else if (mag < bright_mag)
+ bright_mag = mag
+ }
+
+ if (fp_equalr (bright_mag, MAX_REAL))
+ bright_mag = INDEFR
+end
+
+
+# DP_GACCUM -- Accumulate the model counts.
+
+real procedure dp_gaccum (dao, subim, nxpix, nypix, lowx, lowy, x, y, sky,
+ fitradsq, mingdata, maxgdata)
+
+pointer dao # pointer to the daophot structure
+real subim[nxpix,nypix] # the input data subraster
+int nxpix, nypix # the dimensions of the data subraster
+int lowx, lowy # the lower left corner of the subraster
+real x, y # the coordinates of the star
+real sky # the sky value of the star
+real fitradsq # the fitting radius of the star
+real mingdata, maxgdata # the minimum and maximum good data values
+
+int k, j
+pointer psffit
+real mag, dxfrom_psf, dyfrom_psf, numer, denom, dx, dy, radsq, dvdx, dvdy
+real weight, value
+real dp_usepsf()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ # Compute the distance from the psf star.
+ dxfrom_psf = (x - 1.0) / DP_PSFX(psffit) - 1.0
+ dyfrom_psf = (y - 1.0) / DP_PSFY(psffit) - 1.0
+
+ denom = 0.
+ numer = 0.
+ mag = INDEFR
+ do k = 1, nypix {
+ do j = 1, nxpix {
+
+ dx = real (lowx + j - 1) - x
+ dy = real (lowy + k - 1) - y
+ radsq = dx * dx + dy * dy
+ if ((radsq >= fitradsq) || (subim[j,k] < mingdata) ||
+ (subim[j,k] > maxgdata))
+ next
+
+ value = dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ dxfrom_psf, dyfrom_psf, dvdx, dvdy)
+ radsq = radsq / fitradsq
+ weight = 5. / (5. + radsq / (1.0 - radsq))
+ numer = numer + weight * value * (subim[j,k] - sky)
+ denom = denom + weight * value * value
+ }
+ }
+
+ if (denom > 0.0 && numer > 0.0)
+ mag = DP_PSFMAG(psffit) - 2.5 * log10 (numer / denom)
+
+ return (mag)
+end
diff --git a/noao/digiphot/daophot/group/dpsmpsf.x b/noao/digiphot/daophot/group/dpsmpsf.x
new file mode 100644
index 00000000..96cdb324
--- /dev/null
+++ b/noao/digiphot/daophot/group/dpsmpsf.x
@@ -0,0 +1,199 @@
+include <mach.h>
+include "../lib/daophotdef.h"
+
+define NSEC 4
+define IRMIN 4
+
+# DP_SMPSF -- Smooth the psf before grouping.
+
+procedure dp_smpsf (dao)
+
+pointer dao # pointer to the daophot strucuture
+
+int k, icenter, irmax, nexpand
+pointer psffit, sum, high, low, n
+real rmax
+
+begin
+ # Get some pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Get some constants.
+ icenter = (DP_PSFSIZE(psffit) + 1) / 2
+ rmax = .7071068 * real (DP_PSFSIZE(psffit) - 1)
+ irmax = int (rmax + 1.0e-5)
+ nexpand = DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)
+
+ # Allocate working memory.
+ call malloc (sum, NSEC * irmax, TY_REAL)
+ call malloc (high, NSEC * irmax, TY_REAL)
+ call malloc (low, NSEC * irmax, TY_REAL)
+ call malloc (n, NSEC * irmax, TY_INT)
+
+ # Do the smoothing.
+ do k = 1, nexpand {
+
+ # Initialize.
+ call aclrr (Memr[sum], NSEC * irmax)
+ call amovkr (-MAX_REAL, Memr[high], NSEC * irmax)
+ call amovkr (MAX_REAL, Memr[low], NSEC * irmax)
+ call aclri (Memi[n], NSEC * irmax)
+
+ # Acumulate.
+ call dp_smaccum (Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_PSFSIZE(psffit), Memr[sum], Memr[low], Memr[high], Memi[n],
+ NSEC, IRMIN, icenter, rmax, k)
+
+ # Normalize.
+ call dp_smnorm (Memr[sum], Memr[low], Memr[high], Memi[n], NSEC,
+ IRMIN, irmax)
+
+ # Smooth.
+ call dp_smo (Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_PSFSIZE(psffit), Memr[sum], NSEC, IRMIN, icenter, rmax, k)
+ }
+
+ call mfree (sum, TY_REAL)
+ call mfree (low, TY_REAL)
+ call mfree (high, TY_REAL)
+ call mfree (n, TY_INT)
+end
+
+
+# DP_SMACCUM -- Accumulate the sums and limits
+
+procedure dp_smaccum (psflut, nxpsf, nypsf, sum, low, high, n, nsec, irmin,
+ icenter, rmax, k)
+
+real psflut[nxpsf,nypsf,ARB] # the psf lookup table
+int nxpsf, nypsf # size of the psf lookup table
+real sum[nsec,ARB] # array of sums
+real low[nsec,ARB] # array of low values
+real high[nsec,ARB] # array of high values
+int n[nsec,ARB] # array of number of points
+int nsec # dimension of sum arrays
+int irmin # number of sums
+int icenter # center of the array
+real rmax # max radius
+int k # third dimension array index
+
+int i, j, idx, idy, is, ir
+real dxsq, dysq, r
+int dp_isctr()
+
+begin
+ do j = 1, nypsf {
+ idy = j - icenter
+ dysq = idy ** 2
+ do i = 1, nxpsf {
+ idx = i - icenter
+ dxsq = idx ** 2
+ r = sqrt (dxsq + dysq)
+ if (r > rmax)
+ next
+ ir = int (r + 1.0e-5)
+ if (ir < irmin)
+ next
+ is = dp_isctr (idx, idy)
+ sum[is,ir] = sum[is,ir] + psflut[i,j,k]
+ if (psflut[i,j,k] > high[is,ir])
+ high[is,ir] = psflut[i,j,k]
+ if (psflut[i,j,k] < low[is,ir])
+ low[is,ir] = psflut[i,j,k]
+ n[is,ir] = n[is,ir] + 1
+ }
+ }
+end
+
+
+# DP_SMNORM -- Normalize the sum
+
+procedure dp_smnorm (sum, low, high, n, nsec, irmin, irmax)
+
+real sum[nsec,ARB] # array of sums
+real low[nsec,ARB] # array of low values
+real high[nsec,ARB] # array of high values
+int n[nsec,ARB] # array of counter
+int nsec # array dimension
+int irmin # radius index
+int irmax # maximum radius index
+
+int ir, is
+
+begin
+ do ir = irmin, irmax {
+ do is = 1, nsec {
+ if (n[is,ir] > 2)
+ sum[is,ir] = (sum[is,ir] - high[is,ir] - low[is,ir]) /
+ (n[is,ir] - 2)
+ }
+ }
+end
+
+
+# DP_SMO -- Do the actual smoothing.
+
+procedure dp_smo (psflut, nxpsf, nypsf, sum, nrec, irmin, icenter, rmax, k)
+
+real psflut[nxpsf,nypsf,ARB] # the lookup table
+int nxpsf, nypsf # size of the psf lookup table
+real sum[nrec,ARB] # array of sums
+int nrec # dimension of sum array
+int irmin # min radius index
+int icenter # index of center
+real rmax # maximum radius
+int k # index of third dimension
+
+int i, j, idx, idy, ir, is
+real dysq, r
+int dp_isctr()
+
+begin
+ do j = 1, nypsf {
+ idy = j - icenter
+ dysq = idy ** 2
+ do i = 1, nxpsf {
+ idx = i - icenter
+ r = sqrt (real (idx ** 2) + dysq)
+ if (r > rmax)
+ next
+ ir = int (r + 1.0e-5)
+ if (ir < irmin)
+ next
+ is = dp_isctr (idx, idy)
+ psflut[i,j,k] = sum[is,ir]
+ }
+ }
+end
+
+
+# DP_ISCTR -- Convert an index pair into a numbered sector from 1 to 4.
+
+int procedure dp_isctr (i, j)
+
+int i # first index
+int j # second index
+
+int isctr
+
+begin
+ if (i > 0) {
+ isctr = 1
+ } else if (i < 0) {
+ isctr = 3
+ } else {
+ if (j <= 0)
+ isctr = 1
+ else
+ isctr = 3
+ }
+
+ if (j > 0) {
+ isctr = isctr + 1
+ } else if (j == 0) {
+ if (i > 0)
+ isctr = 2
+ }
+
+ return (isctr)
+end
diff --git a/noao/digiphot/daophot/group/dpwrtgroup.x b/noao/digiphot/daophot/group/dpwrtgroup.x
new file mode 100644
index 00000000..97b9a714
--- /dev/null
+++ b/noao/digiphot/daophot/group/dpwrtgroup.x
@@ -0,0 +1,448 @@
+include <mach.h>
+include <time.h>
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define NCOLUMN 6
+
+# DP_TGNEWGRP -- Create a new GROUP output ST table.
+
+procedure dp_tgnewgrp (tp, colpoint)
+
+pointer tp # pointer to outpu ST table
+pointer colpoint[ARB] # array of pointers to columns
+
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for table definition.
+ call smark (sp)
+ call salloc (colnames, NCOLUMN * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, NCOLUMN * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, NCOLUMN * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, NCOLUMN, TY_INT)
+ call salloc (col_len, NCOLUMN, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (GROUP, Memc[colnames], SZ_COLNAME)
+ call strcpy (ID, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+5*SZ_COLNAME+5], SZ_COLNAME)
+
+ # Set up the format definitions.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+ call strcpy ("%15.7g", Memc[colformat+5*SZ_COLFMT+5], SZ_COLFMT)
+
+ # Set up the unit definitions.
+ call strcpy ("##", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("##", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+ call strcpy ("ADC", Memc[colunits+5*SZ_COLUNITS+5], SZ_COLUNITS)
+
+ # Set up the data type definitions.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_INT
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+ Memi[col_dtype+4] = TY_REAL
+ Memi[col_dtype+5] = TY_REAL
+
+ # Define the column lengths.
+ Memi[col_len] = 1
+ Memi[col_len+1] = 1
+ Memi[col_len+2] = 1
+ Memi[col_len+3] = 1
+ Memi[col_len+4] = 1
+ Memi[col_len+5] = 1
+
+ # Define and create the table.
+ call tbcdef (tp, colpoint, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], NCOLUMN)
+ call tbtcre (tp)
+
+ call sfree (sp)
+end
+
+
+# DP_XGGRPPARS -- Write out the parameters to the header of the GROUP text
+# output file.
+
+procedure dp_xggrppars (dao, tp)
+
+pointer dao # pointer to the DAOPHOT structure
+int tp # the output file descriptor
+
+pointer sp, outstr, date, time, psffit
+int envfind()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ psffit = DP_PSFFIT(dao)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IRAF", Memc[outstr], "version", "")
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call dp_sparam (tp, "USER", Memc[outstr], "name", "")
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "HOST", Memc[outstr], "computer", "")
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (tp, "DATE", Memc[date], "yyyy-mm-dd", "")
+ call dp_sparam (tp, "TIME", Memc[time], "hh:mm:ss", "")
+ call dp_sparam (tp, "PACKAGE", "daophot", "name", "")
+ call dp_sparam (tp, "TASK", "group", "name", "")
+
+ # Write the file name parameters.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PHOTFILE", Memc[outstr], "filename", "")
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSFIMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "GRPFILE", Memc[outstr], "filename", "")
+
+ # Write out relevant data parameters.
+ call dp_rparam (tp, "SCALE", DP_SCALE(dao), "units/pix", "")
+ call dp_rparam (tp, "DATAMIN", DP_MINGDATA(dao), "counts", "")
+ call dp_rparam (tp, "DATAMAX", DP_MAXGDATA(dao), "counts", "")
+ call dp_rparam (tp, "GAIN", DP_PHOTADU(dao), "number", "")
+ call dp_rparam (tp, "READNOISE", DP_READNOISE(dao), "electrons", "")
+
+ # Write out the observing parameters.
+ call dp_sparam (tp, "OTIME", DP_OTIME(dao), "timeunit", "")
+ call dp_rparam (tp, "XAIRMASS", DP_XAIRMASS(dao), "number", "")
+ call dp_sparam (tp, "IFILTER", DP_IFILTER(dao), "filter", "")
+
+ # Write out the daophot parameters.
+ call dp_rparam (tp, "PSFRAD", DP_SPSFRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "FITRAD", DP_SFITRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "PSFMAG", DP_PSFMAG(psffit), "magnitude", "")
+ call dp_rparam (tp, "CRITSNRATIO", DP_CRITSNRATIO(dao), "sigma", "")
+ call dp_iparam (tp, "MAXGROUP", DP_MAXGROUP(dao), "number", "")
+ #call dp_iparam (tp, "MAXNSTAR", DP_MAXNSTAR(dao), "number", "")
+
+ # Write out the group size parameters.
+ # call dp_iparam (tp, "MINSZGROUP", 1, "number", "")
+ # call dp_iparam (tp, "MAXSZGROUP", MAX_INT, "number", "")
+
+ call sfree(sp)
+end
+
+
+# DP_TGGRPPARS -- Write out the parameters to the header of the GROUP output
+# ST table file.
+
+procedure dp_tggrppars (dao, tp)
+
+pointer dao # pointer to the DAOPHOT structure
+pointer tp # pointer to the output table
+
+pointer sp, outstr, date, time, psffit
+int envfind()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ psffit = DP_PSFFIT(dao)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IRAF", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call tbhadt (tp, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (tp, "DATE", Memc[date])
+ call tbhadt (tp, "TIME", Memc[time])
+ call tbhadt (tp, "PACKAGE", "daophot")
+ call tbhadt (tp, "TASK", "group")
+
+ # Write the file name parameters.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PHOTFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSFIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "GRPFILE", Memc[outstr])
+
+ # Write out relevant data parameters.
+ call tbhadr (tp, "SCALE", DP_SCALE(dao))
+ call tbhadr (tp, "DATAMIN", DP_MINGDATA(dao))
+ call tbhadr (tp, "DATAMAX", DP_MAXGDATA(dao))
+ call tbhadr (tp, "GAIN", DP_PHOTADU(dao))
+ call tbhadr (tp, "READNOISE", DP_READNOISE(dao))
+
+ # Write out the observing parameters.
+ call tbhadt (tp, "OTIME", DP_OTIME(dao))
+ call tbhadr (tp, "XAIRMASS", DP_XAIRMASS(dao))
+ call tbhadt (tp, "IFILTER", DP_IFILTER(dao))
+
+ # Write out the daophot parameters.
+ call tbhadr (tp, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (tp, "FITRAD", DP_SFITRAD(dao))
+ call tbhadr (tp, "PSFMAG", DP_PSFMAG(psffit))
+ call tbhadr (tp, "CRITSNRATIO", DP_CRITSNRATIO(dao))
+ call tbhadi (tp, "MAXGROUP", DP_MAXGROUP(dao))
+ #call tbhadi (tp, "MAXNSTAR", DP_MAXNSTAR(dao))
+
+ # call tbhadi (tp, "MINSZGROUP", 1)
+ # call tbhadi (tp, "MAXSZGROUP", MAX_INT)
+
+ call sfree(sp)
+end
+
+
+# DP_WRTGROUP -- Write out each group into a text file or an ST table.
+
+procedure dp_wrtgroup (dao, im, grp, number, index, group_size, maxgroup)
+
+pointer dao # pointer to daophot structure
+pointer im # the input image descriptor
+int grp # the output file descriptor
+int number[ARB] # number in group of each size
+int index[ARB] # index to results
+int group_size[ARB] # size of groups
+int maxgroup # maximum group size
+
+begin
+ if (DP_TEXT(dao) == YES)
+ call dp_xwrtgroup (dao, im, grp, number, index, group_size,
+ maxgroup)
+ else
+ call dp_twrtgroup (dao, im, grp, number, index, group_size,
+ maxgroup)
+end
+
+
+define GR_NAMESTR "#N%4tGROUP%10tID%16tXCENTER%26tYCENTER%36tMAG%48tMSKY\
+%80t\\\n"
+define GR_UNITSTR "#U%4t##%10t##%16tpixels%26tpixels%36tmagnitudes%48tcounts\
+%80t\\\n"
+define GR_FORMATSTR "#F%4t%%-9d%10t%%-6d%16t%%-10.3f%26t%%-10.3f%36t%%-12.3f\
+%48t%%-15.7g%80t \n"
+define GR_DATASTR "%-9d%10t%-6d%16t%-10.3f%26t%-10.3f%36t%-12.3f%48t%-15.7g\
+%80t \n"
+
+
+# DP_XWRTGROUP -- Write each group into the GROUP output ST table.
+
+procedure dp_xwrtgroup (dao, im, grp, number, index, group_size, maxgroup)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int grp # the output file descriptor
+int number[ARB] # number in group of each size
+int index[ARB] # index to results
+int group_size[ARB] # size of groups
+int maxgroup # maximum group size
+
+int i, j, k, id, ngroup, nstars, first_ingrp
+pointer apsel
+real x, y, mag, sky
+
+begin
+ # Get the daophot pointer.
+ apsel = DP_APSEL(dao)
+
+ # Print results to the standard output.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (" Size of Number of\n")
+ call printf (" group groups\n\n")
+ do i = 1, maxgroup {
+ if (number[i] <= 0)
+ next
+ call printf ("%8d %9d\n")
+ call pargi (i)
+ call pargi (number[i])
+ }
+ }
+
+ # Add header parameters to the table.
+ call dp_xggrppars (dao, grp)
+
+ # Write out the banner.
+ call fprintf (grp, "#\n")
+ call fprintf (grp, GR_NAMESTR)
+ call fprintf (grp, GR_UNITSTR)
+ call fprintf (grp, GR_FORMATSTR)
+ call fprintf (grp, "#\n")
+
+ # Write out each group.
+ ngroup = 1
+ first_ingrp = 1
+ while (first_ingrp <= DP_APNUM(apsel)) {
+
+ do j = first_ingrp, first_ingrp + group_size[first_ingrp] - 1 {
+
+ # Test the center.
+ k = index[j]
+ x = Memr[DP_APXCEN(apsel)+k-1]
+ y = Memr[DP_APYCEN(apsel)+j-1]
+ if (IS_INDEFR(x) || IS_INDEFR(y))
+ break
+ call dp_wout (dao, im, x, y, x, y, 1)
+
+ # Get the rest of the numbers.
+ id = Memi[DP_APID(apsel)+k-1]
+ mag = Memr[DP_APMAG(apsel)+k-1]
+ sky = Memr[DP_APMSKY(apsel)+k-1]
+
+ # Write the results.
+ call fprintf (grp, GR_DATASTR)
+ call pargi (ngroup)
+ call pargi (id)
+ call pargr (x)
+ call pargr (y)
+ call pargr (mag)
+ call pargr (sky)
+ }
+
+ ngroup = ngroup + 1
+ first_ingrp = first_ingrp + group_size[first_ingrp]
+ }
+
+ # Compute the number of groups and the number of stars.
+ ngroup = 0
+ nstars = 0
+ do i = 1, maxgroup {
+ if (number[i] <= 0)
+ next
+ nstars = nstars + i * number[i]
+ ngroup = ngroup + number[i]
+ }
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nTotal of %d stars in %d groups\n")
+ call pargi (nstars)
+ call pargi (ngroup)
+ }
+end
+
+
+# DP_TWRTGROUP -- Write each group into the GROUP output text file.
+
+procedure dp_twrtgroup (dao, im, grp, number, index, group_size, maxgroup)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+pointer grp # pointer to group output file
+int number[ARB] # number in group of each size
+int index[ARB] # index to results
+int group_size[ARB] # size of groups
+int maxgroup # maximum group size
+
+int row, first_ingrp, ngroup, nstars, i, j, k, id
+pointer apsel, sp, colpoint
+real x, y, mag, sky
+
+begin
+ # Get the daophot pointer.
+ apsel = DP_APSEL(dao)
+
+ # Allocate space for the column pointers.
+ call smark( sp)
+ call salloc (colpoint, NCOLUMN, TY_INT)
+
+ # Get the necessary info to create the ST table.
+ call dp_tgnewgrp (grp, Memi[colpoint])
+
+ # Add header parameters to the ST table.
+ call dp_tggrppars (dao, grp)
+
+ # Optionally print results to the standard output.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (" Size of Number of\n")
+ call printf (" group groups\n\n")
+ do i = 1, maxgroup {
+ if (number[i] <= 0)
+ next
+ call printf (" %d %d\n")
+ call pargi (i)
+ call pargi (number[i])
+ }
+ }
+
+ # Initialize for writing.
+ ngroup = 1
+ row = 0
+
+ # Initialize for reading.
+ first_ingrp = 1
+
+ # Write out the data for all the groups.
+ while (first_ingrp <= DP_APNUM(apsel)) {
+
+ do j = first_ingrp, first_ingrp + group_size[first_ingrp] - 1 {
+
+ # Test the center.
+ k = index[j]
+ x = Memr[DP_APXCEN(apsel)+k-1]
+ y = Memr[DP_APYCEN(apsel)+j-1]
+ if (IS_INDEFR(x) || IS_INDEFR(y))
+ break
+ call dp_wout (dao, im, x, y, x, y, 1)
+
+ # Get the rest of the values.
+ id = Memi[DP_APID(apsel)+k-1]
+ mag = Memr[DP_APMAG(apsel)+k-1]
+ sky = Memr[DP_APMSKY(apsel)+k-1]
+
+ # Copy the values to the correct table row.
+ row = row + 1
+ call tbrpti (grp, Memi[colpoint], ngroup, 1, row)
+ call tbrpti (grp, Memi[colpoint+1], id, 1, row)
+ call tbrptr (grp, Memi[colpoint+2], x, 1, row)
+ call tbrptr (grp, Memi[colpoint+3], y, 1, row)
+ call tbrptr (grp, Memi[colpoint+4], mag, 1, row)
+ call tbrptr (grp, Memi[colpoint+5], sky, 1, row)
+ }
+
+ ngroup = ngroup + 1
+ first_ingrp = first_ingrp + group_size[first_ingrp]
+ }
+
+ # Compute the number of groups and the number of stars.
+ ngroup = 0
+ nstars = 0
+ do i = 1, maxgroup {
+ if (number[i] <= 0)
+ next
+ nstars = nstars + i * number[i]
+ ngroup = ngroup + number[i]
+ }
+
+ # Optionally print out a summary of the results.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nTotal of %d stars in %d groups\n")
+ call pargi (nstars)
+ call pargi (ngroup)
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/group/mkpkg b/noao/digiphot/daophot/group/mkpkg
new file mode 100644
index 00000000..35173772
--- /dev/null
+++ b/noao/digiphot/daophot/group/mkpkg
@@ -0,0 +1,18 @@
+# GROUP task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpmkgroup.x <mach.h> ../lib/apseldef.h \
+ ../lib/daophotdef.h
+ dpsmpsf.x <mach.h> ../lib/daophotdef.h
+ dpgconfirm.x
+ dpwrtgroup.x <mach.h> <time.h> \
+ <tbset.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h
+ t_group.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/group/t_group.x b/noao/digiphot/daophot/group/t_group.x
new file mode 100644
index 00000000..5596c0b3
--- /dev/null
+++ b/noao/digiphot/daophot/group/t_group.x
@@ -0,0 +1,246 @@
+include <fset.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# T_GROUP -- Procedure to divide the stars in a photometry table into
+# natural groups based on the magnitude level at which they overlap.
+
+procedure t_group ()
+
+pointer image # name of the image
+pointer apfile # aperture photometry file
+pointer psfimage # name of the output PSF
+pointer groupfile # output group table
+
+pointer sp, im, dao, outfname, str
+int apd, root, cache, verbose, verify, update, grp, tp, wcs
+int imlist, limlist, alist, lalist, pimlist, lpimlist, olist, lolist
+int req_size, old_size, buf_size, memstat
+bool ap_text
+
+pointer immap(), tbtopn()
+int access(), fnldir(), strlen(), strncmp(), fstati(), btoi()
+int imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb(), fntgfnb()
+int open(), clgwrd(), sizeof(), dp_memstat()
+bool clgetb(), itob()
+
+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 (image, SZ_FNAME, TY_CHAR)
+ call salloc (apfile, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (groupfile, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[apfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("groupfile", Memc[groupfile], SZ_FNAME)
+ verbose = btoi (clgetb ("verbose"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb ("cache"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[apfile], NO)
+ lalist = fntlenb (alist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ olist = fntopnb (Memc[groupfile], NO)
+ lolist = fntlenb (olist)
+
+ # Test that the lengths of the photometry file, psf image, and output
+ # file lists are the same as the length of the input image list.
+
+ if ((limlist != lalist) && (strncmp (Memc[apfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and photometry file list lengths")
+ }
+
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and psf file list lengths")
+ }
+
+ if ((limlist != lolist) && (strncmp (Memc[groupfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and group file list lengths")
+ }
+
+ # Initialize the daophot structure and get the pset parameters.
+ call dp_gppars (dao)
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Optionally verify and update the parameters.
+ if (verify == YES) {
+ call dp_gconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+ # Open the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Open the photometry list structure.
+ call dp_apselsetup (dao)
+
+ # Loop over the image list.
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open input image and grab some header parameters.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ # Open input photometry list and read in the photometry.
+ if (fntgfnb (alist, Memc[apfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[apfile], SZ_FNAME)
+ root = fnldir (Memc[apfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[apfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[apfile]))
+ call dp_inname (Memc[image], Memc[outfname], "mag",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[apfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ apd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ apd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_wgetapert (dao, im, apd, DP_MAXNSTAR(dao), ap_text)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Read the PSF.
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage]))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ tp = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_readpsf (dao, tp)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+
+ # Open output GROUP file. If the output is "default", dir$default
+ # or a directory specification then the extension "grp" is added to
+ # the image name and a suitable version number is appended to the
+ # output name.
+
+ if (fntgfnb (olist, Memc[groupfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[groupfile], SZ_FNAME)
+ root = fnldir (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[groupfile + root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[groupfile]))
+ call dp_outname (Memc[image], Memc[outfname], "grp",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ grp = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ grp = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ # Now go and group the stars.
+ call dp_mkgroup (dao, im, grp)
+
+ # Close up the input image.
+ call imunmap (im)
+
+ # Close up the photometry file.
+ if (ap_text)
+ call close (apd)
+ else
+ call tbtclo (apd)
+
+ # Close up the PSF image.
+ call imunmap (tp)
+
+ # Close up the group table.
+ if (DP_TEXT(dao) == YES)
+ call close (grp)
+ else
+ call tbtclo (grp)
+
+ # Uncache memory.
+ call fixmem (old_size)
+
+ }
+
+ # Close the image/file lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+
+ # Free the photometry structure
+ call dp_apclose (dao)
+
+ # Free the PSF structure.
+ call dp_fitclose (dao)
+
+ # Free the daophot structure.
+ call dp_free (dao)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/grpselect.par b/noao/digiphot/daophot/grpselect.par
new file mode 100644
index 00000000..4129ef54
--- /dev/null
+++ b/noao/digiphot/daophot/grpselect.par
@@ -0,0 +1,8 @@
+# GRPSELECT Parameters
+
+ingroupfile,s,a,,,,Input group file
+outgroupfile,s,a,,,,Output group file
+min_group,i,a,,,,Minimum group size to select
+max_group,i,a,,,,Maximum group size to select
+verbose,b,h,)_.verbose,,,Print grpselect messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/lib/allstardef.h b/noao/digiphot/daophot/lib/allstardef.h
new file mode 100644
index 00000000..3f71aa28
--- /dev/null
+++ b/noao/digiphot/daophot/lib/allstardef.h
@@ -0,0 +1,116 @@
+# ALLSTAR Structure
+
+define LEN_ALLSTARSTRUCT (80)
+
+define DP_ISCACHE Memi[$1] # is data cached (default no)
+define DP_ALLCACHE Memi[$1+2] # is all the data cached ? (yes)
+define DP_CACHE Memi[$1+3+$2-1] # which data is cached ?
+define DP_SZCACHE Memi[$1+6] # current working set size
+define DP_SZOLDCACHE Memi[$1+7] # old working set size
+define DP_DATA Memi[$1+8] # pointer to data
+define DP_SUBT Memi[$1+9] # pointer to subt
+define DP_WEIGHTS Memi[$1+10] # pointer to weights
+
+define DP_SBUF Memi[$1+13] # local subt buffer
+define DP_SNX Memi[$1+14] # subt x dimension
+define DP_SNY Memi[$1+15] # subt y dimension
+define DP_SLX Memi[$1+16] # subt lower left x coord
+define DP_SMX Memi[$1+17] # subt lower right x coord
+define DP_SLY Memi[$1+18] # subt lower left y coord
+define DP_SMY Memi[$1+19] # subt lower right y coord
+define DP_SXOFF Memi[$1+20] # subt lower left x offset
+define DP_SYOFF Memi[$1+21] # subt lower left y offset
+
+define DP_WBUF Memi[$1+23] # local weight buffer
+define DP_WNX Memi[$1+24] # weight x dimension
+define DP_WNY Memi[$1+25] # weight y dimension
+define DP_WLX Memi[$1+26] # weight lower left x coord
+define DP_WMX Memi[$1+27] # weight lower right x coord
+define DP_WLY Memi[$1+28] # weight lower left y coord
+define DP_WMY Memi[$1+29] # weight lower right y coord
+define DP_WXOFF Memi[$1+30] # weight lower left x offset
+define DP_WYOFF Memi[$1+31] # weight lower left y offset
+
+define DP_DBUF Memi[$1+33] # local weight buffer
+define DP_DNX Memi[$1+34] # weight x dimension
+define DP_DNY Memi[$1+35] # weight y dimension
+define DP_DLX Memi[$1+36] # weight lower left x coord
+define DP_DMX Memi[$1+37] # weight lower right x coord
+define DP_DLY Memi[$1+38] # weight lower left y coord
+define DP_DMY Memi[$1+39] # weight lower right y coord
+define DP_DXOFF Memi[$1+40] # weight lower left x offset
+define DP_DYOFF Memi[$1+41] # weight lower left y offset
+
+define DP_ANUMER Memi[$1+55] # pointer to the anumer1 directory
+define DP_ADENOM Memi[$1+57] # pointer to the adenom1 directory
+define DP_ARPIXSQ Memi[$1+59] # pointer to the rpixsq directory
+define DP_ASUMWT Memi[$1+60] # pointer to the sumwt directory
+define DP_ASKIP Memi[$1+61] # pointer to the skip directory
+define DP_ALAST Memi[$1+62] # pointer to the last directory
+define DP_AXOLD Memi[$1+63] # pointer to the xold array
+define DP_AYOLD Memi[$1+64] # pointer to the yold array
+define DP_AXCLAMP Memi[$1+65] # pointer to the xclamp array
+define DP_AYCLAMP Memi[$1+66] # pointer to the yclamp array
+define DP_AX Memi[$1+67] # pointer to the x array
+define DP_AV Memi[$1+68] # pointer to the v array
+define DP_AC Memi[$1+69] # pointer to the c array
+define DP_ANPIX Memi[$1+70] # pointer to the npix array
+define DP_AIER Memi[$1+71] # pointer to the error array
+
+define A_SUBT 1
+define A_WEIGHT 2
+define A_DCOPY 3
+
+# Separation criterion
+
+define FRACTION_MINSEP 0.14
+define CLAMP_FRACTION 0.25
+
+# Limit on N/S ** 2 for two stars to merge.
+
+define WCRIT0 0.0
+define WCRIT5 1.0
+define WCRIT10 1.5
+define WCRIT15 2.0
+
+# Minimum and maximum sharpness limits.
+
+define MIN_SHARP -99.99
+define MAX_SHARP 99.99
+
+# Number of output files columns
+
+define ALL_NOUTCOLUMN 11
+
+# Define the fitting contstants and constraints
+
+define RADIUS_FRACTION 0.95 # % decrease in radius for regrouping
+define DENSE_RADIUS1 1.2 # 1st limiting radius for regrouping
+define DENSE_RADIUS2 0.8 # 2nd limiting radius for regrouping
+define MIN_ITER 4 # minimum number of iterations
+define MAX_RELERR 100.0 # maximum relative error
+define MAX_RSQ 0.999999 # maximum values of ratio of radii ** 2
+define MAX_RHOSQ 36.0 # limit on core radius ** 2 for sharp
+define CHI_NORM 1.2533141 # sqrt (PI / 2.0)
+define MIN_SUMWT 3.0 # min value for radial weight sum
+define MIN_NPIX 4 # min pixels per star for a fit
+define MIN_XYCLAMP 0.001 # min value of x-y clamp
+define MIN_XYCLAMP_FRACTION 0.5 # min change in value of x-y clamp
+define MAX_XYCLAMP_FRACTION 1.2 # max change in value of x-y clamp
+define MAX_DELTA_FAINTER 0.84 # max permitted brightness decrease
+define MAX_DELTA_BRIGHTER 5.25 # max permitted brightness increase
+define MAX_NEW_ERRMAG 0.10 # 1st convergence check on mag error
+define MAX_NEW_RELBRIGHT2 0.0005 # 2nd convergenge check on mag
+define MAX_PIXERR2 4.0e-6 # 2nd convergence check on x/y
+define MIN_REL_BRIGHT 1.0e-5 # min relative brightness
+
+# List of ALLSTAR error codes
+
+define ALLERR_OK 0
+define ALLERR_BIGGROUP 1
+define ALLERR_INDEFSKY 2
+define ALLERR_NOPIX 3
+define ALLERR_SINGULAR 4
+define ALLERR_FAINT 5
+define ALLERR_MERGE 6
+define ALLERR_OFFIMAGE 7
diff --git a/noao/digiphot/daophot/lib/apseldef.h b/noao/digiphot/daophot/lib/apseldef.h
new file mode 100644
index 00000000..ddf3c7d2
--- /dev/null
+++ b/noao/digiphot/daophot/lib/apseldef.h
@@ -0,0 +1,57 @@
+# the photometry structure definition
+
+
+# input photometry list parameters (# 101 - 200)
+
+define APNUM 101
+
+# parameters for reading photometry results
+
+define DP_PAPID 1 # star id number
+define DP_PAPXCEN 2 # x center
+define DP_PAPYCEN 3 # y center
+define DP_PAPSKY 4 # sky value
+define DP_PAPMAG1 5 # aperture 1 magnitude
+define DP_PAPMERR1 6 # aperture 1 magnitude error
+define DP_PAPGROUP 7 # group number
+define DP_PAPNITER 8 # number of iterations
+define DP_PAPCHI 9 # chi squared of fit
+define DP_PAPSHARP 10 # sharpness characteristic
+
+# some useful definitions
+
+define NAPRESULT 5
+define NAPGROUP 6
+define NAPPAR 10
+
+# define the column names for reading and writing photometry files
+
+define ID "ID"
+define GROUP "GROUP"
+define XCENTER "XCENTER"
+define YCENTER "YCENTER"
+define APMAG "MAG[1]"
+define MAG "MAG"
+define APMAGERR "MERR[1]"
+define MAGERR "MERR"
+define SKY "MSKY"
+define NITER "NITER"
+define CHI "CHI"
+define SHARP "SHARPNESS"
+define PIER "PIER"
+define PERROR "PERROR"
+
+define LEN_DPAPSTRUCT (15)
+
+define DP_APNUM Memi[$1] # number of stars in list
+define DP_APRESULT Memi[$1+1] # pointer to fields needed
+define DP_APID Memi[$1+2] # pointer to star ids
+define DP_APXCEN Memi[$1+3] # pointer to stellar x centers
+define DP_APYCEN Memi[$1+4] # pointer to stellar y centers
+define DP_APMAG Memi[$1+5] # pointer to magnitudes
+define DP_APERR Memi[$1+6] # pointer to magnitude errors
+define DP_APMSKY Memi[$1+7] # pointer to sky values
+define DP_APGROUP Memi[$1+8] # pointer to group numbers
+define DP_APNITER Memi[$1+9] # pointer to number of iterations
+define DP_APCHI Memi[$1+10] # pointer to output chi values
+define DP_APSHARP Memi[$1+11] # pointer to output sharp values
diff --git a/noao/digiphot/daophot/lib/daophotdef.h b/noao/digiphot/daophot/lib/daophotdef.h
new file mode 100644
index 00000000..043e7f1b
--- /dev/null
+++ b/noao/digiphot/daophot/lib/daophotdef.h
@@ -0,0 +1,257 @@
+# DAOPHOT header file
+
+# DAOPHOT PSF function types
+
+define FCTN_FTYPES "|gauss|lorentz|moffat15|moffat25|penny1|penny2|auto|"
+define FCTN_GAUSS 1
+define FCTN_LORENTZ 2
+define FCTN_MOFFAT15 3
+define FCTN_MOFFAT25 4
+define FCTN_PENNY1 5
+define FCTN_PENNY2 6
+define FCTN_AUTO 7
+
+define FCTN_NFTYPES 6
+
+# WCS types
+
+define WCS_LOGICAL 1
+define WCS_TV 2
+define WCS_PHYSICAL 3
+define WCS_WORLD 4
+
+define WCSINSTR "|logical|tv|physical|world|"
+define WCSOUTSTR "|logical|tv|physical|"
+define WCSPSFSTR "|logical|tv|physical|"
+
+# DAOPHOT parameters (# 1 - 100)
+
+# wcs parameters
+
+define MW 1 # mwcs pointer
+define WCSIN 2 # input wcs type
+define WCSOUT 3 # output wcs type
+define WCSPSF 4 # psf wcs type
+define CTIN 5 # input transform
+define CTOUT 6 # output transform
+define CTPSF 7 # psf transform
+
+# data dependent parameters
+
+define SFWHMPSF 8 # full-width at half-max of the psf (scale)
+define FWHMPSF 9 # full-width at half-max of the psf (pixels)
+define MAXGDATA 10 # maximum good data value (ADU)
+define MINGDATA 11 # minimum good data value (ADU)
+define PHOTADU 12 # gain (e- / ADU)
+define READNOISE 13 # readout noise (e-)
+define SCALE 14 # scale of the imge
+
+# keyword parameters
+
+define CCDGAIN 15 # gain image header keyword
+define CCDREAD 16 # readnoise image header keyword
+define EXPTIME 17 # exposure time image header keyword
+define FILTER 18 # filter image header keyword
+define OBSTIME 19 # observing time image header keyword
+define AIRMASS 20 # airmass image header keyword
+
+# observing parameters
+
+define XAIRMASS 21 # value of the airmass
+define IFILTER 22 # filter id
+define ITIME 23 # integration time
+define OTIME 24 # time of observation
+
+# psf fitting parameters
+
+define FUNCTION 25 # psf function analytic function
+define VARORDER 26 # order of psf variability (0, 1, or 2)
+define FEXPAND 27 # fraction pixel interpolation (yes or no)
+define SATURATED 28 # use saturated psf stars ?
+define NCLEAN 29 # the number of psf clean passes
+define FUNCLIST 30 # user function list
+define RPSFRAD 31 # requested psf radius (scale)
+define SPSFRAD 32 # psf radius (scale)
+define PSFRAD 33 # psf radius (pixels)
+define SMATCHRAD 34 # matching radius (scale)
+define MATCHRAD 35 # matching radius (pixels)
+
+# star fitting parameters
+
+define SFITRAD 36 # fitting radius (scale)
+define FITRAD 37 # fitting radius (pixels)
+define SANNULUS 38 # inner sky radius (scale)
+define ANNULUS 39 # inner sky radius (pixels)
+define SDANNULUS 40 # width of sky annulus (scale)
+define DANNULUS 41 # width of sky annulus (pixels)
+define SMERGERAD 42 # merging radius (scale)
+define MERGERAD 43 # merging radius (pixels)
+
+define CRITSNRATIO 44 # critical S/N overlap
+define MAXNSTAR 45 # maximum number of stars to fit
+define MAXGROUP 46 # maximum number of stars in group
+define MAXITER 47 # maximum number of iterations
+define RECENTER 48 # recenter ?
+define FITSKY 49 # refit the group sky ?
+define GROUPSKY 50 # use group or individual sky values
+define FLATERR 51 # the flat field error
+define PROFERR 52 # the profile or interpolation error
+define CLIPRANGE 53 # clipping range
+define CLIPEXP 54 # clipping exponent
+
+
+# file/image name and input/output parameters
+
+define TEXT 55 # text file
+define VERBOSE 56 # verbose mode
+define INIMAGE 57 # input image name
+define INPHOTFILE 58 # input photometry file
+define PSFIMAGE 59 # psf image name
+define COORDS 60 # input coordinate file
+define OUTPHOTFILE 61 # output photometry file
+define OUTIMAGE 62 # output image name
+define OUTREJFILE 63 # output rejected photometry file
+
+define MEMFUDGE 1.05
+
+# DAOPHOT structure definitions
+
+define LEN_DPSTRUCT (70 + 17 * SZ_FNAME + 17)
+
+# sub-structure pointers
+
+define DP_VERSION Memi[$1] # package version number
+define DP_ADDSTAR Memi[$1+1] # pointer to addstar structure
+define DP_ALLSTAR Memi[$1+2] # pointer to allstar structure (used)
+define DP_APSEL Memi[$1+3] # pointer to phot structure (used)
+define DP_GROUP Memi[$1+4] # pointer to group structure
+define DP_NSTAR Memi[$1+5] # pointer to nstar structure (used)
+define DP_PEAK Memi[$1+6] # pointer to the peak structure
+define DP_PSF Memi[$1+7] # pointer to psf structure (used)
+define DP_PSFFIT Memi[$1+8] # pointer to psffit structure (used)
+define DP_SUBSTAR Memi[$1+9] # pointer to substar structure
+
+# the wcs parameters
+
+define DP_WCSIN Memi[$1+10] # the input wcs
+define DP_WCSOUT Memi[$1+11] # the output wcs
+define DP_WCSPSF Memi[$1+12] # the psf wcs
+define DP_MW Memi[$1+13] # pointer to mwcs structure
+define DP_CTIN Memi[$1+14] # the input transformation pointer
+define DP_CTOUT Memi[$1+15] # the output transformation pointer
+define DP_CTPSF Memi[$1+16] # the psf transformation pointer
+
+# parameters
+
+define DP_VARORDER Memi[$1+17] # order of psf variability
+define DP_FEXPAND Memi[$1+18] # expand the analytic function ?
+define DP_SATURATED Memi[$1+19] # use saturated psf stars ?
+define DP_NCLEAN Memi[$1+20] # number of psf cleaning passes
+define DP_MAXNSTAR Memi[$1+21] # maximum number of stars
+define DP_MAXGROUP Memi[$1+22] # maximum group size
+define DP_MAXITER Memi[$1+23] # maximum number of iterations
+define DP_RECENTER Memi[$1+24] # recenter ?
+define DP_FITSKY Memi[$1+25] # fit the sky ?
+define DP_GROUPSKY Memi[$1+26] # use the group sky value ?
+define DP_CLIPEXP Memi[$1+27] # clip exponent
+define DP_TEXT Memi[$1+28] # text file or table input/output ?
+define DP_VERBOSE Memi[$1+29] # verbose mode ?
+
+define DP_SCALE Memr[P2R($1+30)] # image scale in units/pixel
+define DP_SFWHMPSF Memr[P2R($1+31)] # fwhm of the psf (scale)
+define DP_FWHMPSF Memr[P2R($1+32)] # fwhm of the psf (pixels)
+define DP_MAXGDATA Memr[P2R($1+33)] # maximum good data value (ADU)
+define DP_MINGDATA Memr[P2R($1+34)] # minimum good data value (ADU)
+define DP_PHOTADU Memr[P2R($1+35)] # gain in electrons/ADU
+define DP_READNOISE Memr[P2R($1+36)] # readout noise (electrons)
+define DP_XAIRMASS Memr[P2R($1+37)] # value of the airmass
+define DP_ITIME Memr[P2R($1+38)] # value of the exposure time
+define DP_SMATCHRAD Memr[P2R($1+39)] # matching radius (scale)
+define DP_MATCHRAD Memr[P2R($1+40)] # matching radius (pixels)
+define DP_RPSFRAD Memr[P2R($1+41)] # requested psf radius (scale)
+define DP_SPSFRAD Memr[P2R($1+42)] # actual psf radius (scale)
+define DP_PSFRAD Memr[P2R($1+43)] # actual psf radius (pixels)
+define DP_SFITRAD Memr[P2R($1+44)] # fitting radius (scale)
+define DP_FITRAD Memr[P2R($1+45)] # fitting radius (pixels)
+define DP_SANNULUS Memr[P2R($1+46)] # inner sky radius (scale)
+define DP_ANNULUS Memr[P2R($1+47)] # inner sky radius (pixels)
+define DP_SDANNULUS Memr[P2R($1+48)] # width of sky annulus (scale)
+define DP_DANNULUS Memr[P2R($1+49)] # width of sky annulus (pixels)
+define DP_CRITSNRATIO Memr[P2R($1+50)] # critical S/N overlap
+define DP_FLATERR Memr[P2R($1+51)] # percent flat field error
+define DP_PROFERR Memr[P2R($1+52)] # percent profile error
+define DP_CLIPRANGE Memr[P2R($1+53)] # clipping range
+define DP_SMERGERAD Memr[P2R($1+54)] # merging radius (scale)
+define DP_MERGERAD Memr[P2R($1+55)] # merging radius (pixels)
+
+# temporary variables, not yet used
+
+#define DP_FITRADSQ Memr[P2R($1+56)] # fit radius squared (pixels)
+#define DP_PSFRADSQ Memr[P2R($1+57)] # psf radius squared (pixels)
+#define DP_RNOISESQ Memr[P2R($1+58)] # read noise squared (ADU)
+#define DP_PERR Memr[P2R($1+59)] # percentage error
+#define DP_PKERR Memr[P2R($1+60)] # peak error
+#define DP_TMAXGDATA Memr[P2R($1+61)] # true data max
+#define DP_TMINGDATA Memr[P2R($1+62)] # true data min
+
+# file / image names
+
+define DP_INIMAGE Memc[P2C($1+64)] # input image name
+define DP_PSFIMAGE Memc[P2C($1+64+SZ_FNAME+1)] # psf image name
+define DP_INPHOTFILE Memc[P2C($1+64+2*SZ_FNAME+2)] # input photometry file
+define DP_COORDS Memc[P2C($1+64+3*SZ_FNAME+3)] # input coordinate file
+define DP_OUTIMAGE Memc[P2C($1+64+4*SZ_FNAME+4)] # output image name
+define DP_OUTPHOTFILE Memc[P2C($1+64+5*SZ_FNAME+5)] # output photometry file
+define DP_OUTREJFILE Memc[P2C($1+64+6*SZ_FNAME+6)] # output photometry file
+
+# keyword / parameter names
+
+define DP_IFILTER Memc[P2C($1+64+7*SZ_FNAME+7)] # filter id
+define DP_OTIME Memc[P2C($1+64+8*SZ_FNAME+8)] # time of observation
+define DP_CCDGAIN Memc[P2C($1+64+9*SZ_FNAME+9)] # gain keyword
+define DP_CCDREAD Memc[P2C($1+64+10*SZ_FNAME+10)] # readnoise keyword
+define DP_EXPTIME Memc[P2C($1+64+11*SZ_FNAME+11)] # exposure keyword
+define DP_FILTER Memc[P2C($1+64+12*SZ_FNAME+12)] # filter keyword
+define DP_OBSTIME Memc[P2C($1+64+13*SZ_FNAME+13)] # obstime keyword
+define DP_AIRMASS Memc[P2C($1+64+14*SZ_FNAME+14)] # airmass keyword
+define DP_FUNCTION Memc[P2C($1+64+15*SZ_FNAME+15)] # analytic psf function
+define DP_FUNCLIST Memc[P2C($1+64+16*SZ_FNAME+16)] # psf function list
+
+# PSF Fit Parameters
+
+define LEN_PSFFIT (20)
+
+define DP_PSFUNCTION Memi[$1] # PSF type
+define DP_PSFNPARS Memi[$1+1] # number of psf parameters
+define DP_PSFSIZE Memi[$1+2] # size of PSF lut
+define DP_PSFPARS Memi[$1+3] # pointer to the PSF parameters
+define DP_PSFLUT Memi[$1+4] # pointer to the PSF lookup table
+define DP_NVLTABLE Memi[$1+5] # number of variability luts
+define DP_NFEXTABLE Memi[$1+6] # number of PSF expansion luts
+define DP_PSFHEIGHT Memr[P2R($1+7)] # brightness of psf
+define DP_PSFMAG Memr[P2R($1+8)] # magnitude of the PSF
+define DP_PSFX Memr[P2R($1+9)] # x position of the PSF
+define DP_PSFY Memr[P2R($1+10)]# y position of the PSF
+
+define MAX_NFCTNPARS (6) # max number of pars in psf function
+define MAX_NEXPTERMS (11) # max number of expansion terms
+
+# default daophot parameter values
+
+define DEF_SCALE 1.0
+define DEF_FWHMPSF 2.5
+define DEF_PSFRAD 11.0
+define DEF_FITRAD 2.5
+define DEF_ANNULUS 10.0
+define DEF_DANNULUS 10.0
+define DEF_MAXNSTAR 5000
+define DEF_MAXGROUP 60
+define DEF_MAXITER 50
+define DEF_DEFNAME "default"
+define DEF_LENDEFNAME 7
+
+# some useful macros
+
+define DAO_GOODDATA ($2>DP_MINGDATA($1)&&$2<DP_MAXGDATA($1))
+define DAO_RELBRIGHT (10.0**(0.4*(DP_PSFMAG($1) - $2)))
+define DAO_MAGCHECK (0.4*(DP_PSFMAG($1) - $2))
diff --git a/noao/digiphot/daophot/lib/nstardef.h b/noao/digiphot/daophot/lib/nstardef.h
new file mode 100644
index 00000000..460f8031
--- /dev/null
+++ b/noao/digiphot/daophot/lib/nstardef.h
@@ -0,0 +1,63 @@
+# NSTAR Structure
+
+define LEN_NSTARSTRUCT (20)
+
+define DP_NGNUM Memi[$1] # current group number
+define DP_NNUM Memi[$1+1] # number of stars in current group
+define DP_NSTARCOLS Memi[$1+2] # pointer to NSTAR table columns
+define DP_NNPIX Memi[$1+3] # pointer to number of pixels
+define DP_NNUMER Memi[$1+4] # pointer to NUMER in curr group
+define DP_NDENOM Memi[$1+5] # pointer to DENOM stat in curr group
+define DP_NSKIP Memi[$1+6] # pointer to SKIP in curr group
+define DP_NXCLAMP Memi[$1+7] # pointer to CLAMP stat in curr group
+define DP_NXOLD Memi[$1+8] # pointer to XOLD stat in curr group
+define DP_NX Memi[$1+9] # pointer to X array in curr group
+define DP_NV Memi[$1+10] # pointer to V array in curr group
+define DP_NSUMWT Memi[$1+11] # pointer to SUMWT array in curr group
+define DP_NC Memi[$1+12] # pointer to C array in curr group
+define DP_NRPIXSQ Memi[$1+13] # pointer to RPIXSQ array in curr group
+define DP_NIER Memi[$1+14] # pointer to NSTAR error codes
+
+# Definitions controlling the input / output format
+
+define NST_NOUTCOL 12
+
+# NSTAR fitting constants
+
+define CUT_FACTOR 0.999998 # the pixel cutoff radius in fitrad ** 2
+define FRACTION_MINSEP 0.14 # min sep in fwhmpsf for merging
+define NITER_MAX 15 # iteration limit for difficult stars
+define NITER_MED 10 # iteration limit for moderate stars
+define NITER_MIN 5 # iteration limit for easy stars
+define WCRIT_MAX 0.5 # max N/S for difficult stars
+define WCRIT_MED 0.66667 # max N/S for moderate stars
+define WCRIT_MIN 1.0 # max N/S for easy stars
+define NCORE_SIGMASQ 36.0 # max number of hwidths for sharpness
+define MIN_NPIX 4 # min pixels per star for fit
+define CHI_NORM 1.2533141 # sqrt (PI / 2.0)
+define MIN_SUMWT 3.0 # min value for radial weight sum
+define MAX_DELTA_FAINTER 0.84 # max permitted brightness decrease
+define MAX_DELTA_BRIGHTER 5.25 # max permitted brightness increase
+define MAX_NEW_ERRMAG 0.1 # 1st convergence check on mag error
+define MAX_NEW_RELBRIGHT1 0.005 # 1st convergence check on magnitude
+define MAX_NEW_RELBRIGHT2 0.0005 # 2nd convergence check on magnitude
+define MAX_PIXERR1 4.0e-4 # 1st convergence check on x/y positions
+define MAX_PIXERR2 4.0e-6 # 2nd convergence check on x/y positions
+define MAX_DELTA_PIX 0.4 # max +/- change in x/y positions
+define MAX_PIX_INCREMENT 0.001 # test for nearness to edge of image
+define MIN_REL_BRIGHT 1.0e-5 # minimum relative brightness
+define MIN_FAINT 0.5 # min N/S
+define MIN_ITER 4 # min number of iterations
+define MIN_SHARP -99.9 # min sharpness value
+define MAX_SHARP 99.9 # max sharpness value
+
+# List of NSTAR error codes
+
+define NSTERR_OK 0
+define NSTERR_BIGGROUP 1
+define NSTERR_INDEFSKY 2
+define NSTERR_NOPIX 3
+define NSTERR_SINGULAR 4
+define NSTERR_FAINT 5
+define NSTERR_MERGE 6
+define NSTERR_OFFIMAGE 7
diff --git a/noao/digiphot/daophot/lib/peakdef.h b/noao/digiphot/daophot/lib/peakdef.h
new file mode 100644
index 00000000..badc6246
--- /dev/null
+++ b/noao/digiphot/daophot/lib/peakdef.h
@@ -0,0 +1,55 @@
+# The PEAK task definitions files
+
+# The fitting algorithm error codes
+
+define PKERR_OK 0
+define PKERR_INDEFSKY 1
+define PKERR_NOPIX 2
+define PKERR_SINGULAR 3
+define PKERR_FAINT 4
+#define PKERR_NOCONVERGE 5
+
+# The PEAK fitting structure
+
+define LEN_PKSTRUCT 10
+
+define DP_PKNTERM Memi[$1] # the number of terms to be fit
+define DP_PKCLAMP Memi[$1+1] # pointer to the clamp array
+define DP_PKNORMAL Memi[$1+2] # pointer to the norm array
+define DP_PKRESID Memi[$1+3] # pointer to the residuals vector
+define DP_PKDERIV Memi[$1+4] # pointer to the derivative array
+define DP_PKRESULT Memi[$1+5] # pointer to the results vector
+define DP_PKOLDRESULT Memi[$1+6] # pointer to the old results vector
+
+# Definitions controlling input / output variables
+
+define DELTA_MAG 5.0 # mag difference assigned to input INDEF stars
+define PK_NOUTCOL 11 # the number of columns in the output table
+
+# Various PEAK fitting constants
+
+#define SIGN_CHECK -1.2e-38 # check for change of sign
+define MAX_DELTA_BRIGHTER 5.25 # max permitted brightness increase
+define MAX_DELTA_FAINTER 0.84 # max permitted brightness decrease
+define MAX_DELTA_PIX 0.4 # max +/- change in x/y positions
+define MAX_NEW_ERRMAG 0.05 # convergenge check on magnitude error
+define MIN_REL_BRIGHT 1.0e-5 # minimum relative brightness
+define MAX_NEW_RELBRIGHT1 0.0001 # convergence check on brightness
+define MAX_NEW_RELBRIGHT2 0.002 # convergence check on brightness
+define MAX_PIXERR1 0.001 # convergence check on x/y positions
+define MAX_PIXERR2 0.02 # convergence check on x/y positions
+define MAX_CLAMPFACTOR 0.25 # maximum clamping factor
+define MIN_SHARP -99.99 # min sharpness value
+define MAX_SHARP 99.99 # max sharpness value
+define PEAK_EPSILONR 2.0e-6 # test for inclusion inside fitrad
+define NCORE_SIGMASQ 36.0 # max gsigma-sq for sharpness value
+define CHI_NORM 1.2533141 # sqrt (PI / 2.0)
+define MIN_SUMWT 3.0 # min value of the radial weight sum
+define MIN_NPIX 4 # min number of pixels for fit
+
+define WCRIT_MAX 0.5 # max noise / signal ratio
+define WCRIT_MED 0.6667 # median noise / signal ratio
+define WCRIT_MIN 1.0 # min noise / signal ratio
+define WCRIT_NMAX 15 # max number of iterations
+define WCRIT_NMED 10 # median number of iterations
+define WCRIT_NMIN 5 # minimum number of iterations
diff --git a/noao/digiphot/daophot/lib/psfdef.h b/noao/digiphot/daophot/lib/psfdef.h
new file mode 100644
index 00000000..2a40b590
--- /dev/null
+++ b/noao/digiphot/daophot/lib/psfdef.h
@@ -0,0 +1,111 @@
+# PSF fitting task definitions
+
+# PSF fitting parameters (# 201 - 300)
+
+define PNUM 201 # number of PSF stars
+define CUR_PSF 202 # index of current PSF star
+define CUR_PSFID 203 # id of current PSF star
+define CUR_PSFX 204 # x coordinate of current PSF star
+define CUR_PSFY 205 # y coordinate of current PSF star
+define CUR_PSFSKY 206 # sky value of current PSF star
+define CUR_PSFMAG 207 # magnitude of current PSF star
+define CUR_PSFMIN 208 # min data value of current PSF star
+define CUR_PSFMAX 209 # max data value of current PSF star
+define CUR_PSFGMAX 210 # max good data value of current PSF star
+define PLOTTYPE 211 # the plot type
+define LENUSERAREA 212 # PSF image user area length
+
+# PSF task plot types
+
+define PSF_PLOTS "|mesh|contour|radial|" # list of plot types
+define PSF_MESHPLOT 1 # mesh plot
+define PSF_CONTOURPLOT 2 # contour plot
+define PSF_RADIALPLOT 3 # radial profile plot
+
+# miscellaneous definitions
+
+define MIN_LENUSERAREA 50000 # minimum length of the user area
+define PSF_NINCOLS 4 # number of columns in input psf star list
+define PSF_NOUTCOLS 6 # number of columns in output group table
+define MAX_NPSFITER 300 # max number of analytic fit iterations
+
+# PSF fitting colon commands
+
+define PSF_CMDS "|psfimage|groupfile|function|varorder|fexpand|psfrad|\
+fitrad|nclean|saturated|matchrad|scale|fwhmpsf|datamin|datamax|"
+
+define PSFCMD_PSFIMAGE 1
+define PSFCMD_GROUPFILE 2
+define PSFCMD_FUNCTION 3
+define PSFCMD_VARORDER 4
+define PSFCMD_FEXPAND 5
+define PSFCMD_PSFRAD 6
+define PSFCMD_FITRAD 7
+define PSFCMD_NCLEAN 8
+define PSFCMD_SATURATED 9
+define PSFCMD_MATCHRAD 10
+define PSFCMD_SCALE 11
+define PSFCMD_FWHMPSF 12
+define PSFCMD_DATAMIN 13
+define PSFCMD_DATAMAX 14
+
+# the PSF task fitting structure
+
+define LEN_PSFSTRUCT (50)
+
+# arrays required for fitting analytic psf and the look-up table
+
+define DP_LENUSERAREA Memi[$1] # size of the output psf user area
+define DP_PC Memi[$1+1] # pointer to fitting matrix
+define DP_PV Memi[$1+3] # pointer to fitting vector
+define DP_PTMP Memi[$1+4] # pointer to temporary vector
+define DP_PZ Memi[$1+5] # pointer to parameter changes
+define DP_PCLAMP Memi[$1+6] # pointer to clamp vector
+define DP_POLD Memi[$1+7] # pointer to previous parameter changes
+define DP_PSIGANA Memr[P2R($1+8)] # normalized sigma for analytic fit
+define DP_PSUMANA Memr[P2R($1+9)] # number of points in analytic fit
+
+# dimensions and arrays required for psf star list
+
+define DP_PNUM Memi[$1+10] # number of stars in PSF
+define DP_PSAT Memi[$1+11] # pointer to PSF star saturation indices
+define DP_PXCEN Memi[$1+12] # pointer to the PSF star x coords
+define DP_PYCEN Memi[$1+13] # pointer to the PSF star y coords
+define DP_PMAG Memi[$1+14] # pointer to the PSF star list mags
+define DP_PH Memi[$1+15] # pointer to the PSF star heights
+define DP_PWEIGHT Memi[$1+16] # pointer to the PSF star weights
+define DP_PXCLAMP Memi[$1+17] # pointer to the PSF star x clamps
+define DP_PYCLAMP Memi[$1+18] # pointer to the PSF star y clamps
+define DP_PXOLD Memi[$1+19] # pointer to the old PSF star x values
+define DP_PYOLD Memi[$1+20] # pointer to the old PSF star y values
+
+# additional arrays required for fitting the look-up table
+
+define DP_PSUMN Memi[$1+21] # pointer to the number of points
+define DP_PSUMW Memi[$1+22] # pointer to the weights corrections
+define DP_PSUMSQ Memi[$1+23] # pointer to the resdiduals
+define DP_PSIGMA Memi[$1+24] # pointer to the standard deviations
+define DP_PCONST Memi[$1+25] # pointer to the const part of psf
+define DP_POLDLUT Memi[$1+26] # pointer to the old lookup table
+
+# description of current psf star
+
+define DP_CUR_PSF Memi[$1+27] # position of current PSF star in file
+define DP_CUR_PSFID Memi[$1+28] # id of current PSF star
+define DP_CUR_PSFX Memr[P2R($1+29)]# x position of current PSF star
+define DP_CUR_PSFY Memr[P2R($1+30)]# y position of current PSF star
+define DP_CUR_PSFSKY Memr[P2R($1+31)]# sky for current PSF star
+define DP_CUR_PSFMAG Memr[P2R($1+32)]# magnitude for current PSF star
+define DP_CUR_PSFMIN Memr[P2R($1+33)]# minimum data value in PSF subrast
+define DP_CUR_PSFMAX Memr[P2R($1+34)]# maximum data value in PSF subrast
+define DP_CUR_PSFGMAX Memr[P2R($1+35)]# maximum good data value in fitrad
+
+# the psf plotting parameters
+
+define DP_PLOTTYPE Memi[$1+36] # type of PSF plot
+define DP_MANGV Memr[P2R($1+37)]# vertical angle for surface plot
+define DP_MANGH Memr[P2R($1+38)]# horizontal angle for surface plot
+define DP_MFLOOR Memr[P2R($1+39)]# floor value for surface plot
+define DP_MCEILING Memr[P2R($1+40)]# ceiling for surface plot
+define DP_CFLOOR Memr[P2R($1+41)]# floor for contour
+define DP_CCEILING Memr[P2R($1+42)]# ceiling for contour
diff --git a/noao/digiphot/daophot/lib/warning.dat b/noao/digiphot/daophot/lib/warning.dat
new file mode 100644
index 00000000..ee8d55c1
--- /dev/null
+++ b/noao/digiphot/daophot/lib/warning.dat
@@ -0,0 +1,14 @@
+
+
+ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+ WARNING FROM THE DAOPHOT PACKAGE LOADER
+ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+ The SDAS external package TABLES optionally used by some of the
+ DAOPHOT tasks is not available. The tasks PAPPEND, PDUMP,
+ PRENUMBER, PSELECT and PSORT will run only on DAOPHOT output
+ files written in text database format (the default) but will not
+ run on files written in ST tables format. Check the value of the
+ DAOPHOT package parameter "text" before beginning reductions.
+
+
diff --git a/noao/digiphot/daophot/mkpkg b/noao/digiphot/daophot/mkpkg
new file mode 100644
index 00000000..84fab316
--- /dev/null
+++ b/noao/digiphot/daophot/mkpkg
@@ -0,0 +1,44 @@
+# DAOPHOT libraries
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $omake x_daophot.x
+ !mkpkg -p noao trelink XF="$(XFLAGS)" LF="$(LFLAGS)"
+ ;
+
+linkonly:
+ !mkpkg -p noao trelink XF="$(XFLAGS)" LF="$(LFLAGS)"
+ ;
+
+install:
+ $move xx_daophot.e noaobin$x_daophot.e
+ ;
+
+trelink:
+ $set LIBS = "-lncar -lgks -ltbtables -lxtools -lds"
+ $set XFLAGS = "$(XFLAGS) $(XF)"
+ $set LFLAGS = "$(LFLAGS) $(LF)"
+ $update libpkg.a
+ $link x_daophot.o libpkg.a ../lib/libpttables.a $(LIBS) -o xx_daophot.e
+ ;
+
+libpkg.a:
+ @addstar
+ @allstar
+ @daoedit
+ @daolib
+ @group
+ @nstar
+ @peak
+ @psf
+ @seepsf
+ @select
+ @substar
+ ;
diff --git a/noao/digiphot/daophot/nstar.par b/noao/digiphot/daophot/nstar.par
new file mode 100644
index 00000000..28589e90
--- /dev/null
+++ b/noao/digiphot/daophot/nstar.par
@@ -0,0 +1,17 @@
+# Parameters for the NSTAR task
+
+image,f,a,,,,"Image corresponding to photometry"
+groupfile,f,a,default,,,"Input group file (image.grp.?)"
+psfimage,f,a,default,,,"PSF image (default: image.psf.?)"
+nstarfile,f,a,default,,,"Output photometry file (default: image.nst.?)"
+rejfile,f,a,default,,,"Output rejections file (default: image.nrj.?)"
+datapars,pset,h,"",,,Data parameters
+daopars,pset,h,"",,,Psf fitting parameters
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,Verify critical nstar parameters?
+update,b,h,)_.update,,,Update critical nstar parameters?
+verbose,b,h,)_.verbose,,,Print nstar messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/nstar/dpggroup.x b/noao/digiphot/daophot/nstar/dpggroup.x
new file mode 100644
index 00000000..fa180c17
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpggroup.x
@@ -0,0 +1,386 @@
+include "../../lib/ptkeysdef.h"
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+# DP_GNSTPSF -- Procedure to initialize for reading the group file fields from
+# a photometry text file . The group file fields are ID, GROUP, X, Y, MAG, ERR,
+# and SKY.
+
+procedure dp_gnstpsf (fields, sel_fields, max_nfields)
+
+int fields[ARB] # array of selected fields
+char sel_fields[ARB] # names of selected containing fields
+int max_nfields # maximum number of fields selected
+
+int i
+int strlen()
+
+begin
+ # Initialize the fields string.
+ sel_fields[1] = EOS
+
+ # Encode the fields.
+ do i = 1, max_nfields {
+ switch (fields[i]) {
+ case DP_PAPID:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (ID)
+ case DP_PAPXCEN:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (XCENTER)
+ case DP_PAPYCEN:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (YCENTER)
+ case DP_PAPSKY:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (SKY)
+ case DP_PAPMAG1:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (MAG)
+ case DP_PAPGROUP:
+ call sprintf (sel_fields[strlen(sel_fields)+1], SZ_LINE, "%s ")
+ call pargstr (GROUP)
+ }
+ }
+
+ # Backspace over the terminating blank character.
+ if (sel_fields[1] != EOS)
+ sel_fields[strlen(sel_fields)] = EOS
+end
+
+
+# DP_TNSTINIT -- Procedure to initialize for reading the group file fields from
+# a photometry table. The group file fields are ID, GROUP, X, Y, MAG, ERR,
+# and SKY.
+
+procedure dp_tnstinit (tp, colpoint)
+
+pointer tp # the table descriptor
+pointer colpoint[ARB] # the column descriptor
+
+begin
+ # Get the id.
+ # First the ID
+ call tbcfnd (tp, ID, colpoint[1], 1)
+ if (colpoint[1] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (ID)
+ }
+
+ # Get the x position.
+ call tbcfnd (tp, XCENTER, colpoint[2], 1)
+ if (colpoint[2] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (XCENTER)
+ }
+
+ # Get the y position.
+ call tbcfnd (tp, YCENTER, colpoint[3], 1)
+ if (colpoint[3] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (YCENTER)
+ }
+
+ # Get the magnitude.
+ call tbcfnd (tp, MAG, colpoint[4], 1)
+ if (colpoint[4] == NULL) # No column
+ call tbcfnd (tp, APMAG, colpoint[4], 1)
+ if (colpoint[4] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (APMAG)
+ }
+
+ # Get the sky.
+ call tbcfnd (tp, SKY, colpoint[5], 1)
+ if (colpoint[5] == NULL)
+ call tbcfnd (tp, SKY, colpoint[5], 1)
+ if (colpoint[5] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (SKY)
+ }
+
+ # Get the group number.
+ call tbcfnd (tp, GROUP, colpoint[6], 1)
+ if (colpoint[6] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (GROUP)
+ }
+end
+
+
+# DP_GGROUP -- Read in a single group.
+
+int procedure dp_ggroup (dao, tp, key, fields, indices, colpoint, max_row,
+ max_group, in_record, curr_group)
+
+pointer dao # pointer to daophot structure
+int tp # input file/table descriptor
+pointer key # pointer to text database structure
+char fields[ARB] # nstar fields to be read
+int indices[ARB] # array of text file field pointers
+int colpoint[ARB] # array of column pointers
+int max_row # number of rows in table
+int max_group # maximum group size
+int in_record # pointer to current input record
+int curr_group # current group number
+
+bool nullflag
+int istar, group, buf_size
+pointer apsel
+int dp_nstsel()
+
+begin
+ # If the current input record is set to zero we are at EOF. In_record
+ # is initialized to one on entry to this routine.
+
+ if (in_record == 0)
+ return (0)
+
+ # Get the next group number. Note that the last star read on the
+ # previous call is the first star in the new group.
+
+ apsel = DP_APSEL(dao)
+ if (in_record == 1) {
+ buf_size = max_group
+ group = 0
+ istar = 0
+ } else {
+ Memi[DP_APID(apsel)] = Memi[DP_APID(apsel)+istar-1]
+ Memr[DP_APXCEN(apsel)] = Memr[DP_APXCEN(apsel)+istar-1]
+ Memr[DP_APYCEN(apsel)] = Memr[DP_APYCEN(apsel)+istar-1]
+ Memr[DP_APMAG(apsel)] = Memr[DP_APMAG(apsel)+istar-1]
+ Memr[DP_APMSKY(apsel)] = Memr[DP_APMSKY(apsel)+istar-1]
+ istar = 1
+ }
+
+ # Loop over the stars in a single group.
+ repeat {
+
+ # Set the current group.
+ curr_group = group
+
+ # Read in the photometry for a single star.
+
+ # In this case we have a text database file.
+ if (key != NULL) {
+
+ if (dp_nstsel (key, tp, fields, indices, Memi[DP_APID(apsel)+
+ istar], group, Memr[DP_APXCEN(apsel)+istar],
+ Memr[DP_APYCEN(apsel)+istar], Memr[DP_APMSKY(apsel)+
+ istar], Memr[DP_APMAG(apsel)+ istar]) == EOF) {
+ in_record = 0
+ break
+ }
+
+ # In this case we have a table.
+ } else {
+
+ if (in_record > max_row) {
+ in_record = 0
+ break
+ } else {
+ call tbrgti (tp, colpoint[1], Memi[DP_APID(apsel)+istar],
+ nullflag, 1, in_record)
+ call tbrgtr (tp, colpoint[2], Memr[DP_APXCEN(apsel)+istar],
+ nullflag, 1, in_record)
+ call tbrgtr (tp, colpoint[3], Memr[DP_APYCEN(apsel)+istar],
+ nullflag, 1, in_record)
+ call tbrgtr (tp, colpoint[4], Memr[DP_APMAG(apsel)+istar],
+ nullflag, 1, in_record)
+ call tbrgtr (tp, colpoint[5], Memr[DP_APMSKY(apsel)+istar],
+ nullflag, 1, in_record)
+ call tbrgti (tp, colpoint[6], group, nullflag, 1, in_record)
+ }
+ }
+
+ # Increment the record and star counters.
+ in_record = in_record + 1
+ istar = istar + 1
+
+ # Allocate more memory as needed.
+ if (istar == buf_size) {
+ buf_size = buf_size + max_group
+ call dp_rmemapsel (dao, indices, NAPPAR, buf_size + 1)
+ }
+
+ } until ((group != curr_group) && (curr_group != 0))
+
+ # Return the number of stars in the group.
+ if (in_record == 0) {
+ if (curr_group == 0)
+ curr_group = group
+ return (istar)
+ } else
+ return (istar - 1)
+end
+
+
+# DP_NSTSEL -- Read in the required photometry records from a text file.
+
+int procedure dp_nstsel (key, fd, fields, indices, id, group, x, y, sky, mag)
+
+pointer key # pointer to key structure
+int fd # text file descriptor
+char fields[ARB] # fields to be output
+int indices[ARB] # indices array
+int id # star id number
+int group # group number
+real x # x center
+real y # y center
+real sky # sky value
+real mag # magnitude
+
+int nchars, nunique, uunique, funique, ncontinue, recptr
+int first_rec, nselect, record
+pointer line
+int getline(), strncmp(), pt_choose()
+data first_rec /YES/
+
+begin
+ # Initialize the file read.
+ if (first_rec == YES) {
+ nunique = 0
+ uunique = 0
+ funique = 0
+ nselect = 0
+ record = 0
+ call malloc (line, SZ_LINE, TY_CHAR)
+ }
+
+ # Initialize the record read.
+ ncontinue = 0
+ recptr = 1
+
+ # Loop over the text file records.
+ repeat {
+
+ # Read in a line of the text file.
+ 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 text file 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 (nselect <= 0) {
+ nselect = pt_choose (key, fields)
+ if (nselect < NAPGROUP) {
+ call eprintf (
+ "The group file does not have the correct format\n")
+ break
+ }
+ }
+
+ # Construct the output record by moving the selected fields
+ # into the data structures.
+
+ call dp_gnst (key, indices, id, group, x, y, sky, mag)
+ record = record + 1
+ first_rec = NO
+
+ # Record is complete so exit the loop.
+ break
+ }
+ }
+
+ }
+
+ # Return EOF or the record number.
+ if (nchars == EOF || (nselect < NAPGROUP)) {
+ first_rec = YES
+ nunique = 0
+ uunique = 0
+ funique = 0
+ nselect = 0
+ call mfree (line, TY_CHAR)
+ return (EOF)
+ } else
+ return (record)
+end
+
+
+# DP_GNST -- Decode the standard GROUP text file fields into the appropriate
+# arrays.
+
+procedure dp_gnst (key, fields, id, group, x, y, sky, mag)
+
+pointer key # pointer to keys strucuture
+int fields[ARB] # fields array
+int id # star id
+int group # group id
+real x # x position
+real y # y position
+real sky # sky value
+real mag # magnitude
+
+int i, index, elem, maxch, kip, ip
+int ctoi(), ctor()
+char buffer[SZ_LINE]
+
+begin
+ 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
+ call amovc (Memc[kip], buffer, maxch)
+ buffer[maxch+1] = EOS
+
+ # Decode the output value.
+ ip = 1
+ switch (fields[i]) {
+ case DP_PAPID:
+ if (ctoi (buffer, ip, id) <= 0)
+ call error (0, "ERROR: Error reading ID field.")
+ case DP_PAPGROUP:
+ if (ctoi (buffer, ip, group) <= 0)
+ call error (0, "ERROR: Error reading GROUP field.")
+ case DP_PAPXCEN:
+ if (ctor (buffer, ip, x) <= 0)
+ call error (0, "ERROR: Error reading XCENTER field.")
+ case DP_PAPYCEN:
+ if (ctor (buffer, ip, y) <= 0)
+ call error (0, "ERROR: Error reading YCENTER field.")
+ case DP_PAPSKY:
+ if (ctor (buffer, ip, sky) <= 0)
+ call error (0, "ERROR: Error reading MSKY field.")
+ case DP_PAPMAG1:
+ if (ctor (buffer, ip, mag) <= 0)
+ call error (0, "ERROR: Error reading MAG field.")
+ default:
+ call printf ("Error reading the photometry file.\n")
+ }
+
+ }
+end
diff --git a/noao/digiphot/daophot/nstar/dpmemnstar.x b/noao/digiphot/daophot/nstar/dpmemnstar.x
new file mode 100644
index 00000000..04bd25f4
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpmemnstar.x
@@ -0,0 +1,158 @@
+include "../lib/daophotdef.h"
+include "../lib/nstardef.h"
+
+# DP_NSTARSETUP -- Procedure to set up the NSTAR parameters.
+
+procedure dp_nstarsetup (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer nstar
+
+begin
+ # Allocate Memory
+ call malloc (DP_NSTAR(dp), LEN_NSTARSTRUCT, TY_STRUCT)
+ nstar = DP_NSTAR(dp)
+
+ DP_NNPIX(nstar) = NULL
+ DP_NNUMER(nstar) = NULL
+ DP_NDENOM(nstar) = NULL
+ DP_NRPIXSQ(nstar) = NULL
+ DP_NSKIP(nstar) = NULL
+ DP_NXCLAMP(nstar) = NULL
+ DP_NXOLD(nstar) = NULL
+ DP_NX(nstar) = NULL
+ DP_NV(nstar) = NULL
+ DP_NSUMWT(nstar) = NULL
+ DP_NC(nstar) = NULL
+ DP_NIER(nstar) = NULL
+end
+
+
+# DP_MEMNSTAR -- Procedure to allocate sufficient memory for NSTAR.
+
+procedure dp_memnstar (dao, max_star)
+
+pointer dao # pointer to daophot structure
+int max_star # maximum number of stars
+
+pointer nstar
+
+begin
+ nstar = DP_NSTAR(dao)
+
+ if (DP_NNPIX (nstar) != NULL)
+ call mfree (DP_NNPIX (nstar), TY_INT)
+ call malloc (DP_NNPIX (nstar), max_star + 1, TY_INT)
+
+ if (DP_NNUMER (nstar) != NULL)
+ call mfree (DP_NNUMER (nstar), TY_REAL)
+ call malloc (DP_NNUMER (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NDENOM (nstar) != NULL)
+ call mfree (DP_NDENOM (nstar), TY_REAL)
+ call malloc (DP_NDENOM (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NRPIXSQ (nstar) != NULL)
+ call mfree (DP_NRPIXSQ (nstar), TY_REAL)
+ call malloc (DP_NRPIXSQ (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NSKIP (nstar) != NULL)
+ call mfree (DP_NSKIP (nstar), TY_INT)
+ call malloc (DP_NSKIP (nstar), max_star + 1, TY_INT)
+
+ if (DP_NIER (nstar) != NULL)
+ call mfree (DP_NIER (nstar), TY_INT)
+ call malloc (DP_NIER(nstar), max_star + 1, TY_INT)
+
+ if (DP_NSUMWT (nstar) != NULL)
+ call mfree (DP_NSUMWT (nstar), TY_REAL)
+ call malloc (DP_NSUMWT (nstar), max_star + 1, TY_REAL)
+
+ if (DP_RECENTER(dao) == YES) {
+
+ if (DP_NXCLAMP (nstar) != NULL)
+ call mfree (DP_NXCLAMP (nstar), TY_REAL)
+ call malloc (DP_NXCLAMP (nstar), 3 * max_star + 1, TY_REAL)
+
+ if (DP_NXOLD (nstar) != NULL)
+ call mfree (DP_NXOLD (nstar), TY_REAL)
+ call malloc (DP_NXOLD (nstar), 3 * max_star + 1, TY_REAL)
+
+ if (DP_NX (nstar) != NULL)
+ call mfree (DP_NX (nstar), TY_REAL)
+ call malloc (DP_NX (nstar), 3 * max_star + 1, TY_REAL)
+
+ if (DP_NC (nstar) != NULL)
+ call mfree (DP_NC (nstar), TY_REAL)
+ call malloc (DP_NC (nstar), (3 * max_star + 1) * (3 * max_star + 1),
+ TY_REAL)
+
+ if (DP_NV (nstar) != NULL)
+ call mfree (DP_NV (nstar), TY_REAL)
+ call malloc (DP_NV (nstar), 3 * max_star + 1, TY_REAL)
+
+ } else {
+
+ if (DP_NXCLAMP (nstar) != NULL)
+ call mfree (DP_NXCLAMP (nstar), TY_REAL)
+ call malloc (DP_NXCLAMP (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NXOLD (nstar) != NULL)
+ call mfree (DP_NXOLD (nstar), TY_REAL)
+ call malloc (DP_NXOLD (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NX (nstar) != NULL)
+ call mfree (DP_NX (nstar), TY_REAL)
+ call malloc (DP_NX (nstar), max_star + 1, TY_REAL)
+
+ if (DP_NC (nstar) != NULL)
+ call mfree (DP_NC (nstar), TY_REAL)
+ call malloc (DP_NC (nstar), (max_star + 1) * (max_star + 1),
+ TY_REAL)
+
+ if (DP_NV (nstar) != NULL)
+ call mfree (DP_NV (nstar), TY_REAL)
+ call malloc (DP_NV (nstar), max_star + 1, TY_REAL)
+ }
+end
+
+
+# DP_NSCLOSE -- Procedure to close up the NSTAR parameters.
+
+procedure dp_nsclose (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer nstar
+
+begin
+ nstar = DP_NSTAR(dp)
+
+ if (DP_NNPIX (nstar) != NULL)
+ call mfree (DP_NNPIX (nstar), TY_INT)
+ if (DP_NNUMER (nstar) != NULL)
+ call mfree (DP_NNUMER (nstar), TY_REAL)
+ if (DP_NDENOM (nstar) != NULL)
+ call mfree (DP_NDENOM (nstar), TY_REAL)
+ if (DP_NRPIXSQ (nstar) != NULL)
+ call mfree (DP_NRPIXSQ (nstar), TY_REAL)
+ if (DP_NSKIP (nstar) != NULL)
+ call mfree (DP_NSKIP (nstar), TY_INT)
+ if (DP_NXCLAMP (nstar) != NULL)
+ call mfree (DP_NXCLAMP (nstar), TY_REAL)
+ if (DP_NXOLD (nstar) != NULL)
+ call mfree (DP_NXOLD (nstar), TY_REAL)
+ if (DP_NX (nstar) != NULL)
+ call mfree (DP_NX (nstar), TY_REAL)
+ if (DP_NV (nstar) != NULL)
+ call mfree (DP_NV (nstar), TY_REAL)
+ if (DP_NSUMWT (nstar) != NULL)
+ call mfree (DP_NSUMWT (nstar), TY_REAL)
+ if (DP_NC (nstar) != NULL)
+ call mfree (DP_NC (nstar), TY_REAL)
+ if (DP_NIER (nstar) != NULL)
+ call mfree (DP_NIER (nstar), TY_INT)
+
+ call mfree (nstar, TY_STRUCT)
+end
diff --git a/noao/digiphot/daophot/nstar/dpnconfirm.x b/noao/digiphot/daophot/nstar/dpnconfirm.x
new file mode 100644
index 00000000..ecbd3056
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpnconfirm.x
@@ -0,0 +1,34 @@
+include "../lib/daophotdef.h"
+
+# DP_NCONFIRM -- Procedure to confirm the critical nstar parameters.
+
+procedure dp_nconfirm (dao)
+
+pointer dao # pointer to the group structure
+
+int dp_stati()
+
+begin
+ call printf ("\n")
+
+ # Confirm recentering and sky fitting.
+ call dp_vrecenter (dao)
+ call dp_vfitsky (dao)
+ if (dp_stati (dao, FITSKY) == NO)
+ call dp_vgroupsky (dao)
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the maximum group size.
+ call dp_vmaxgroup (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/nstar/dpnstar.x b/noao/digiphot/daophot/nstar/dpnstar.x
new file mode 100644
index 00000000..66ba10a4
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpnstar.x
@@ -0,0 +1,355 @@
+include <imhdr.h>
+include <tbset.h>
+include <mach.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/nstardef.h"
+
+
+# DP_NPHOT -- Read in the groups and fit all the stars in each group
+# simultaneously.
+
+procedure dp_nphot (dao, im, grp, nst, rej, ap_text)
+
+pointer dao # pointer to the daophot structure
+pointer im # input image descriptor
+int grp # input group file descriptor
+int nst # output photometry file descriptor
+int rej # rejections file descriptor
+bool ap_text # photometry text file
+
+bool converge
+int out_record, rout_record, in_record, nrow_in_table, old_size, niter
+int cdimen, stat
+pointer sp, indices, fields, icolpoint, ocolpoint, key, nstar, apsel
+real radius, mean_sky
+
+int dp_ggroup(), tbpsta(), dp_nstarfit(), dp_nxycheck()
+real dp_nmsky()
+
+begin
+ # Store the original value of the fitting radius.
+ radius = DP_FITRAD(dao)
+ DP_FITRAD(dao) = min (DP_FITRAD(dao), DP_PSFRAD(dao))
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+
+ # Allocate working memory.
+ call smark (sp)
+ call salloc (icolpoint, NAPGROUP, TY_INT)
+ call salloc (indices, NAPPAR, TY_INT)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (ocolpoint, NST_NOUTCOL, TY_INT)
+
+ # Get some daophot pointers.
+ apsel = DP_APSEL(dao)
+ nstar = DP_NSTAR (dao)
+
+ # Allocate space for and define the output table.
+ if (DP_TEXT(dao) == YES) {
+ call dp_xpnewnstar (dao, nst)
+ if (rej != NULL)
+ call dp_xpnewnstar (dao, rej)
+ } else {
+ call dp_tpnewnstar (dao, nst, Memi[ocolpoint])
+ if (rej != NULL)
+ call dp_tpnewnstar (dao, rej, Memi[ocolpoint])
+ }
+
+ # Set up the input file.
+ call dp_gnindices (Memi[indices])
+ if (ap_text) {
+ call pt_kyinit (key)
+ call dp_gnstpsf (Memi[indices], Memc[fields], NAPGROUP)
+ nrow_in_table = 0
+ } else {
+ key = NULL
+ call dp_tnstinit (grp, Memi[icolpoint])
+ nrow_in_table = tbpsta (grp, TBL_NROWS)
+ }
+
+ # Allocate some memory for fitting.
+ call dp_memapsel (dao, Memi[indices], NAPPAR, DP_MAXGROUP(dao) + 1)
+ call dp_memnstar (dao, DP_MAXGROUP(dao) + 1)
+
+ # Initialize the input/output files for reading/writing.
+ in_record = 1
+ out_record = 0
+ rout_record = 0
+
+ repeat {
+
+ # Read in the next group of stars.
+ old_size = dp_ggroup (dao, grp, key, Memc[fields], Memi[indices],
+ Memi[icolpoint], nrow_in_table, DP_MAXGROUP(dao), in_record,
+ DP_NGNUM(nstar))
+ if (old_size <= 0)
+ break
+ DP_NNUM(nstar) = old_size
+
+ # Convert coordinates if necessary.
+ call dp_win (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], DP_NNUM(nstar))
+
+ # Print out the group number and number of stars.
+ if (DP_VERBOSE (dao) == YES) {
+ call printf ("Group: %4d contains %2d stars\n")
+ call pargi (DP_NGNUM (nstar))
+ call pargi (DP_NNUM (nstar))
+ }
+
+ # If the group center is undefined or off image skip to next
+ # group.
+ if (dp_nxycheck (im, Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ DP_NNUM(nstar), DP_FITRAD(dao), stat) <= 0) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ if (stat < 0)
+ call printf (
+ "\tGroup %d center is undefined: skipping\n")
+ else if (stat == 0)
+ call printf ("\tGroup %d is off the image: skipping\n")
+ call pargi (DP_NGNUM(nstar))
+ }
+ next
+
+ # If too many stars skip to the next group.
+ } else if (DP_NNUM (nstar) > DP_MAXGROUP(dao)) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\tGroup %d larger than %d stars: skipping\n")
+ call pargi (DP_NGNUM(nstar))
+ call pargi (DP_MAXGROUP(dao))
+ }
+ niter = 0
+ call realloc (DP_NIER(nstar), DP_NNUM(nstar), TY_INT)
+ call dp_nstindef (dao, DP_NNUM(nstar), NSTERR_BIGGROUP)
+
+ # If the mean sky value of group is undefined skip to next group.
+ } else if (IS_INDEFR (dp_nmsky (Memr[DP_APMSKY(apsel)],
+ DP_NNUM(nstar), mean_sky))) {
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "\tGroup %d sky value is undefined: skipping\n")
+ call pargi (DP_NGNUM(nstar))
+ }
+ niter = 0
+ call dp_nstindef (dao, DP_NNUM(nstar), NSTERR_INDEFSKY)
+
+ # Do the fit.
+ } else {
+
+ # Estimate values of INDEF magnitudes.
+ call dp_nmaginit (dao, Memr[DP_APMAG(apsel)],
+ Memr[DP_APERR(apsel)], DP_NNUM(nstar))
+
+ # Set up for the fit.
+ if (DP_RECENTER(dao) == YES)
+ cdimen = 3 * DP_NNUM(nstar) + 1
+ else
+ cdimen = DP_NNUM(nstar) + 1
+
+ # Iterate.
+ for (niter = 1; niter <= DP_MAXITER(dao); niter = niter + 1) {
+ DP_NNUM(nstar) = dp_nstarfit (dao, im, DP_NNUM(nstar),
+ mean_sky, cdimen, niter, converge)
+ if (DP_NNUM(nstar) <= 0)
+ break
+ if (converge)
+ break
+ }
+
+ # Solution did not converge.
+ niter = min (niter, DP_MAXITER(dao))
+ }
+
+ # Now write out the results.
+ if (DP_TEXT(dao) == YES)
+ call dp_xntwrite (dao, im, nst, rej, niter, old_size)
+ else
+ call dp_tntwrite (dao, im, nst, rej, niter, old_size,
+ out_record, rout_record, Memi[ocolpoint])
+ }
+
+ if (ap_text)
+ call pt_kyfree (key)
+
+ call sfree (sp)
+
+ # Restore the original value of the fitting radius.
+ DP_FITRAD(dao) = radius
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+end
+
+
+# DP_NSTINDEF -- Set magnitudes and fitting parameters of unfit stars to indef.
+
+procedure dp_nstindef (dao, max_nstars, pier)
+
+pointer dao # pointer to the daophot structure
+int max_nstars # number of stars
+int pier # the photometry error code
+
+int i
+pointer apsel, nstar
+
+begin
+ apsel = DP_APSEL(dao)
+ nstar = DP_NSTAR(dao)
+ do i = 1, max_nstars {
+ Memr[DP_APMAG(apsel)+i-1] = INDEFR
+ Memr[DP_APERR(apsel)+i-1] = INDEFR
+ Memr[DP_APCHI(apsel)+i-1] = INDEFR
+ Memr[DP_APSHARP(apsel)+i-1] = INDEFR
+ Memi[DP_NIER(nstar)+i-1] = pier
+ }
+end
+
+
+# DP_GNINDICES -- Get the memory allocation fields.
+
+procedure dp_gnindices (indices)
+
+int indices[ARB] # index array
+
+begin
+ indices[1] = DP_PAPID
+ indices[2] = DP_PAPXCEN
+ indices[3] = DP_PAPYCEN
+ indices[4] = DP_PAPMAG1
+ indices[5] = DP_PAPSKY
+ indices[6] = DP_PAPGROUP
+ indices[7] = DP_PAPMERR1
+ indices[8] = DP_PAPNITER
+ indices[9] = DP_PAPSHARP
+ indices[10] = DP_PAPCHI
+end
+
+
+define GRP_CTRINDEF -1
+define GRP_CTROFFIMAGE 0
+define GRP_CTROK 1
+
+# DP_NXYCHECK -- Check that the center of the group is defined. -1 is
+# returned if the center of the group is undefined, 0, is returned if the
+# group is entirely off the image, 1 is returned if the group is at least
+# partially on the input image.
+
+int procedure dp_nxycheck (im, x, y, group_size, radius, stat)
+
+pointer im # pointer to the input image
+real x[ARB] # array of x values
+real y[ARB] # array of y values
+int group_size # the size of the group
+real radius # the fitting radius
+int stat # the return status
+
+int i, nxy
+real xmin, xmax, ymin, ymax, xx, yy
+
+begin
+ # Initialize.
+ stat = GRP_CTRINDEF
+ xmin = MAX_REAL
+ xmax = -MAX_REAL
+ ymin = MAX_REAL
+ ymax = -MAX_REAL
+
+ # Compute the minimum and maximum x and y values.
+ nxy = 0
+ do i = 1, group_size {
+ xx = x[i]
+ yy = y[i]
+ if (IS_INDEFR(xx) || IS_INDEFR(yy))
+ next
+ nxy = nxy + 1
+ if (xx < xmin)
+ xmin = xx
+ if (xx > xmax)
+ xmax = xx
+ if (yy < ymin)
+ ymin = yy
+ if (yy > ymax)
+ ymax = yy
+ }
+ if (nxy <= 0)
+ return (stat)
+
+ # Test the min and max values.
+ stat = GRP_CTROFFIMAGE
+ if ((int (xmin - radius) + 1) > IM_LEN(im,1))
+ return (stat)
+ if (int (xmax + radius) < 1)
+ return (stat)
+ if ((int (ymin - radius) + 1) > IM_LEN(im,2))
+ return (stat)
+ if (int (ymax + radius) < 1)
+ return (stat)
+
+ # The group is on the image.
+ stat = GRP_CTROK
+ return (stat)
+end
+
+
+# DP_NMSKY -- Compute the mean sky value for the group of stars.
+
+real procedure dp_nmsky (sky, group_size, msky)
+
+real sky[ARB] # the array of sky values
+int group_size # the size of the group of stars
+real msky # the mean sky value
+
+int i, nsky
+real sky_sum
+
+begin
+ sky_sum = 0.0
+ nsky = 0
+
+ do i = 1, group_size {
+ if (IS_INDEFR(sky[i]))
+ next
+ sky_sum = sky_sum + sky[i]
+ nsky = nsky + 1
+ }
+
+ if (nsky <= 0)
+ msky = INDEFR
+ else
+ msky = sky_sum / nsky
+
+ return (msky)
+end
+
+
+define MIN_REL_BRIGHT 1.0E-04 # minimum relative brightness
+define INIT_REL_BRIGHT 0.01 # initial relative brightness
+
+# DP_NMAGINIT -- Initialize the magnitude and magnitude error arrays before
+# fitting the group.
+
+procedure dp_nmaginit (dao, mag, magerr, group_size)
+
+pointer dao # pointer to the daophot strucuture
+real mag[ARB] # the magnitude array
+real magerr[ARB] # the magnitude error array
+int group_size # size of the group
+
+int i
+pointer psffit
+
+begin
+ psffit = DP_PSFFIT (dao)
+ do i = 1, group_size {
+ if (IS_INDEFR(mag[i]))
+ mag[i] = INIT_REL_BRIGHT
+ else {
+ mag[i] = DAO_RELBRIGHT (psffit, mag[i])
+ if (mag[i] <= MIN_REL_BRIGHT)
+ mag[i] = INIT_REL_BRIGHT
+ }
+ magerr[i] = 0.0
+ }
+end
diff --git a/noao/digiphot/daophot/nstar/dpnstarfit.x b/noao/digiphot/daophot/nstar/dpnstarfit.x
new file mode 100644
index 00000000..8b864c86
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpnstarfit.x
@@ -0,0 +1,1383 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/nstardef.h"
+
+
+# DP_NSTARFIT -- Fit the stellar group.
+
+int procedure dp_nstarfit (dao, im, nin_group, mean_sky, cdimen, iter,
+ converge)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int nin_group # original group size
+real mean_sky # the mean sky for the group
+int cdimen # dimensions of the coefficient matrix
+int iter # the current iteration
+bool converge # did the fit converge ?
+
+bool clip, refit
+int i, j, k, xpix, ypix, group_size, nterm, ncols, mindex, ifaint, tifaint
+int ntmin, ixmin, ixmax, iymin, iymax, ifxmin, ifxmax, ifymin, ifymax, flag
+pointer apsel, psffit, nstar, subim, ypixel, pixel
+real fitradsq, cutoff, psfradsq, sepcrit, sepmin, perr, peakerr, sky_value
+real read_noise, mingdata, maxgdata, chigrp, wcrit, xmin, xmax, ymin, ymax
+real datum, sumres, grpwt, xtemp, ytemp, weight, ds, pred_pixval, sigmasq
+real relerr, dswt, faint, tfaint, noise
+
+bool dp_nstmerge(), dp_ntomit(), dp_ntmin(), dp_ncheckc()
+pointer imgs2r()
+real dp_ntskyval(), dp_ntsubtract()
+
+begin
+ # Define the daophot pointers.
+ psffit = DP_PSFFIT (dao)
+ apsel = DP_APSEL(dao)
+ nstar = DP_NSTAR (dao)
+
+ # Set up some daophot constants. At some point these will be computed
+ # when the NSTAR task is started up instead of at the beginning of
+ # each group fit. For the moment it is convenient and not too
+ # costly to compute them here. Also initialize the fit.
+
+ if (iter == 1) {
+
+ # Compute the fitting and psf radii.
+ fitradsq = DP_FITRAD (dao) ** 2
+ psfradsq = DP_PSFRAD(dao) ** 2
+ cutoff = CUT_FACTOR * fitradsq
+
+ # Compute the merging parameters.
+ if (IS_INDEFR(DP_MERGERAD(dao))) {
+ sepcrit = 2.0 * (Memr[DP_PSFPARS(psffit)] ** 2 +
+ Memr[DP_PSFPARS(psffit)+1] ** 2)
+ sepmin = min (1.0, FRACTION_MINSEP * sepcrit)
+ } else {
+ sepcrit = DP_MERGERAD(dao) ** 2
+ sepmin = min (1.0, FRACTION_MINSEP * sepcrit)
+ }
+
+ # Compute the noise parameters.
+ read_noise = (DP_READNOISE(dao) / DP_PHOTADU(dao)) ** 2
+ perr = 0.01 * DP_FLATERR(dao)
+ peakerr = 0.01 * DP_PROFERR(dao) / (Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1])
+
+ # Compute the minimum and maximum good pixel values.
+ if (IS_INDEFR(DP_MINGDATA(dao)))
+ mingdata = -MAX_REAL
+ else
+ mingdata = DP_MINGDATA(dao)
+ if (IS_INDEFR(DP_MAXGDATA(dao)))
+ maxgdata = MAX_REAL
+ else
+ maxgdata = DP_MAXGDATA(dao)
+
+ # Initialize the fit.
+ chigrp = 1.0
+ clip = false
+ if (DP_RECENTER(dao) == YES) {
+ nterm = 3 * nin_group
+ ntmin = 3
+ } else {
+ nterm = nin_group
+ ntmin = 1
+ }
+ if (DP_FITSKY(dao) == YES) {
+ nterm = nterm + 1
+ ntmin = ntmin + 1
+ }
+ call aclrr (Memr[DP_NXOLD(nstar)], nterm)
+ call amovkr (1.0, Memr[DP_NXCLAMP(nstar)], nterm)
+ }
+
+ # Start a new iteration.
+ group_size = nin_group
+ if (DP_RECENTER(dao) == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (DP_FITSKY(dao) == YES)
+ nterm = nterm + 1
+
+ # Begin fitting the current group of stars.
+ repeat {
+
+ # Initialize the convergence criteria.
+ converge = false
+
+ # Check that there is at least 1 star in the group.
+ if (group_size < 1)
+ return (group_size)
+
+ # Set up the critical error for star rejection.
+ if (iter >= NITER_MAX)
+ wcrit = WCRIT_MAX
+ else if (iter >= NITER_MED)
+ wcrit = WCRIT_MED
+ else if (iter >= NITER_MIN)
+ wcrit = WCRIT_MIN
+ else
+ wcrit = MAX_REAL
+
+ # Set the sky fitting derivative.
+ if (DP_FITSKY(dao) == YES)
+ Memr[DP_NX(nstar)+nterm-1] = -1.0
+
+ # Initialize arrays.
+ call aclrr (Memr[DP_APCHI(apsel)], group_size)
+ call aclrr (Memr[DP_NSUMWT(nstar)], group_size)
+ call aclrr (Memr[DP_NNUMER(nstar)], group_size)
+ call aclrr (Memr[DP_NDENOM(nstar)], group_size)
+ call amovki (NSTERR_OK, Memi[DP_NIER(nstar)], group_size)
+
+ # Compute the minimum and maximum x and y values.
+ call alimr (Memr[DP_APXCEN(apsel)], group_size, xmin, xmax)
+ call alimr (Memr[DP_APYCEN(apsel)], group_size, ymin, ymax)
+
+ # Check to see whether any two stars are within the critical
+ # difference from each other.
+
+ if ((group_size > 1) && dp_nstmerge (Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APERR(apsel)], group_size, sepcrit, sepmin, wcrit,
+ i, j, k)) {
+
+ # Compute the new centroid and brightness.
+ call dp_nstcen (Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], i, j, k)
+
+ # Print out verbose comments.
+ if (DP_VERBOSE (dao) == YES) {
+ call printf ("\tStar %-5d has merged with star %-5d\n")
+ call pargi (Memi[DP_APID(apsel)+k-1])
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ }
+
+ # Recompute the mean sky.
+ if ((DP_FITSKY(dao) == NO) && (DP_GROUPSKY(dao) == YES))
+ mean_sky = (mean_sky * group_size -
+ Memr[DP_APMSKY(apsel)+k-1]) / (group_size - 1)
+
+ # Now remove the k-th star from the group.
+ call dp_remove (k, group_size, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)],
+ Memi[DP_NIER(nstar)], NSTERR_MERGE)
+
+ # After deleting a star, resize the matrix, release all of
+ # the clamps and back up the iteration counter.
+
+ if (DP_RECENTER(dao) == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (DP_FITSKY(dao) == YES)
+ nterm = nterm + 1
+ clip = false
+ call aclrr (Memr[DP_NXOLD(nstar)], nterm)
+ call amovkr (1.0, Memr[DP_NXCLAMP(nstar)], nterm)
+ iter = max (1, iter - 1)
+ next
+ }
+
+ # Now we can proceed with the iteration. If this is the first
+ # iteration read in the subraster. Determine the size of the
+ # subraster we need to extract from the image for this group.
+
+ if (iter == 1) {
+ ixmin = max (1, int (xmin - DP_PSFRAD(dao) -
+ DP_FITRAD(dao)) + 1)
+ iymin = max (1, int (ymin - DP_PSFRAD(dao) -
+ DP_FITRAD(dao)) + 1)
+ ixmax = min (IM_LEN(im,1), int (xmax + DP_PSFRAD(dao) +
+ DP_FITRAD(dao)))
+ iymax = min (IM_LEN(im,2), int (ymax + DP_PSFRAD(dao) +
+ DP_FITRAD(dao)))
+ subim = imgs2r (im, ixmin, ixmax, iymin, iymax)
+ ncols = ixmax - ixmin + 1
+ }
+
+ # Compute the area on the subraster that is off interest to
+ # the current iteration.
+
+ ifxmin = max (ixmin, int (xmin - DP_FITRAD(dao)) + 1)
+ ifymin = max (iymin, int (ymin - DP_FITRAD(dao)) + 1)
+ ifxmax = min (ixmax, int (xmax + DP_FITRAD(dao)))
+ ifymax = min (iymax, int (ymax + DP_FITRAD(dao)))
+
+ # Zero the normal matrix and the vector of residuals.
+
+ call aclrr (Memr[DP_NV(nstar)], nterm)
+ call aclrr (Memr[DP_NC(nstar)], cdimen * cdimen)
+ call aclri (Memi[DP_NNPIX(nstar)], group_size)
+
+ sumres = 0.0
+ grpwt = 0.0
+
+ # Loop over the pixels in the subraster.
+
+ ypixel = subim + (ifymin - iymin) * ncols + ifxmin - ixmin - 1
+ do ypix = ifymin, ifymax {
+
+ ytemp = ypix
+ pixel = ypixel
+
+ do xpix = ifxmin, ifxmax {
+
+ xtemp = xpix
+ pixel = pixel + 1
+ datum = Memr[pixel]
+
+ # Reject pixel if not in good data range.
+ if ((datum < mingdata) || (datum > maxgdata))
+ next
+
+ # If this pixel is within one fitting radius of at
+ # least one star then include it in the solution.
+ # While figuring this out, compute the squared distance
+ # of this pixel from the centroid of each star in the
+ # group, and sum its contribution to the number
+ # of pixels within one fitting radius of each star.
+
+ if (dp_ntomit (Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_NRPIXSQ(nstar)],
+ Memi[DP_NSKIP(nstar)], group_size, xtemp, ytemp,
+ cutoff))
+ next
+
+ if ((DP_FITSKY(dao) == NO) && (DP_GROUPSKY(dao) == NO)) {
+ sky_value = dp_ntskyval (Memr[DP_APMSKY(apsel)],
+ Memi[DP_NSKIP(nstar)], group_size)
+ if (IS_INDEFR(sky_value))
+ sky_value = mean_sky
+ } else
+ sky_value = mean_sky
+
+ # Subtract the mean sky from the pixel.
+ #ds = datum - mean_sky
+ ds = datum - sky_value
+
+ # Now loop over the stars and subtract from this pixel
+ # the light contribution from each star within one psf
+ # radius.
+ #
+ # The condition equation for pixel[xpix,ypix] is
+ #
+ # residual = data[xpix,ypix] - sky - sum (scale *
+ # psf[xpix-xc,ypix-yc])
+ #
+ # The scale, xc, and yc are iterated until
+ #
+ # sum (weight * residual ** 2)
+ #
+ # is minimized. Weight will be a function of 1) the
+ # distance of the pixel from the center of the nearest
+ # star, 2) the model-predicted brightness of the pixel
+ # (taking into consideration the readout noise, the
+ # photons/ADU, and the interpolating error of the PSF,
+ # and, 3) the size of the residual itself. One is
+ # necessary to prevent the non-linear least squares
+ # solution from oscillating: oftimes it will come
+ # to pass that if you include a pixel in the solution
+ # then the predicted shift of the centroid will cause
+ # that pixel to be excluded in the next iteration, and the
+ # new predicted shift of the centroid will cause that
+ # pixel to be included again. This could go on ad
+ # infinitum. The cure is to have the weight of the pixel
+ # go asymptotically to zero as its distance from the
+ # stellar centroid approaches the fitting radius. In
+ # the case like that just described, the solution can
+ # then find a real minimum of the sum of the weighted
+ # squared residuals with that pixel at some low-weight
+ # position just inside the fitting radius. Two is
+ # just sensible weighting. Three is a crude attempt
+ # at making the solution more robust against bad pixels.
+
+ weight = dp_ntsubtract (dao, im, Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_NRPIXSQ(nstar)],
+ Memr[DP_APMAG(apsel)], Memi[DP_NSKIP(nstar)],
+ Memr[DP_NX(nstar)], group_size, xtemp, ytemp, ds,
+ psfradsq, fitradsq, DP_RECENTER(dao))
+
+ # At this point the vector X contains the first
+ # derivative of the condition equation, for the pixel
+ # under consideration, with respect to each of the
+ # fitting parameters for all of these stars. We now need
+ # to add these values into the normal matrix and the vector
+ # of residuals.
+
+ # The expected random error in the pixel is the quadratic
+ # sum of the Poisson statistics, plus the readout noise,
+ # plus an estimated error of 0.75% of the total brightness
+ # of the total brightness for the difficulty of flat-
+ # fielding and bias subtraction, plus an estimated error
+ # of the same fraction of the fourth derivative at the
+ # peak of the profile, to account for the difficulty
+ # of accurately interpolating within the point-spread
+ # function. The fourth derivative of the PSF is
+ # proportional to H / sigma ** 4 (sigma is the Gaussian
+ # width parameter for the stellar core); using the geometric
+ # mean of sigma(x) and sigma(y), this becomes H / [sigma(x)
+ # * sigma(y)] ** 2. The ratio of the fitting error to this
+ # quantity is estimated to be approximately 0.027 from a
+ # good-seeing CTIO frame. (This is probably a function of
+ # seeing, sampling etc.)
+
+ # Get the residual from the PSF fit and the pixel
+ # intensity as predicted by the fit. Pred_pixval = raw data
+ # minus residual = model predicted value of the intensity at
+ # this point.
+
+ pred_pixval = max (0.0, datum - ds)
+ if ((pred_pixval > maxgdata) && (iter >= 4))
+ next
+
+ #sigmasq = pred_pixval / DP_PHOTADU (dao) + read_noise +
+ #(perr * pred_pixval) ** 2 + (peakerr *
+ #(pred_pixval - mean_sky)) ** 2
+ sigmasq = pred_pixval / DP_PHOTADU (dao) + read_noise +
+ (perr * pred_pixval) ** 2 + (peakerr *
+ (pred_pixval - sky_value)) ** 2
+ if (sigmasq <= 0.0)
+ next
+ relerr = abs (ds) / sqrt (sigmasq)
+
+ # Add this residual into the weighted sum of the
+ # absolute relative residuals.
+
+ sumres = sumres + relerr * weight
+ grpwt = grpwt + weight
+
+ # Add into the accumulating sums of the weighted
+ # absolute relative residuals and of the image sharpness
+ # parameter for each of the stars. Include in the
+ # sharpness index only those pixels within NCORE_SIGMA
+ # sigma of the centroid of the object. This saves time
+ # and floating underflows by excluding pixels
+ # which contribute less than about one part in a
+ # million to the index.
+
+ call dp_acsharp (Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memi[DP_NSKIP(nstar)],
+ Memi[DP_NNPIX(nstar)], Memr[DP_NNUMER(nstar)],
+ Memr[DP_NDENOM(nstar)], Memr[DP_NSUMWT(nstar)],
+ Memr[DP_APCHI(apsel)], group_size, xtemp, ytemp,
+ Memr[DP_PSFPARS(psffit)], Memr[DP_PSFPARS(psffit)+1],
+ ds, sigmasq, relerr, weight)
+
+ # If clipping is in effect, reduce the weight of a bad
+ # pixel. A pixel having a residual of 2.5 sigma gets
+ # reduced to half weight and one with a rersidual of 5
+ # sigma gets weight of 1 / 257.
+
+ weight = weight / sigmasq
+ if (clip)
+ weight = weight / (1.0 + (relerr / (DP_CLIPRANGE(dao) *
+ chigrp)) ** DP_CLIPEXP(dao))
+ dswt = ds * weight
+
+ # Work this pixel into the normal matrix.
+ call dp_mataccum (Memr[DP_NX(nstar)], Memi[DP_NSKIP(nstar)],
+ group_size, Memr[DP_NC(nstar)], Memr[DP_NV(nstar)],
+ cdimen, nterm, weight, dswt, DP_RECENTER(dao),
+ DP_FITSKY(dao))
+
+ }
+
+ ypixel = ypixel + ncols
+ }
+
+ # Make sure that every star in the group has at least MIN_FIT_PIXEL
+ # pixels within one fitting radius.
+
+ refit = dp_ntmin (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_NNPIX(nstar)],
+ Memi[DP_NIER(nstar)], group_size, nterm, DP_RECENTER(dao),
+ DP_FITSKY(dao), DP_GROUPSKY(dao), mean_sky, DP_VERBOSE(dao))
+ if (group_size < 1)
+ return (group_size)
+ if (refit)
+ next
+
+ # Reflect the normal matrix across the diagonal.
+ call dp_mreflect (Memr[DP_NC(nstar)], cdimen, nterm)
+
+ # Compute the robust estimate of the standard deviation of the
+ # residuals for the group as a whole, and for each star. This
+ # estimate is sqrt (PI/2) * weighted mean absolute relative
+ # residual. Do you like that "absolute relative" stuff? (PBS)
+ # NO! (LED)
+ #
+ # CHI = CHI_NORM * SUM (weight * resid) / (# of pixels)
+ #
+ # This gets corrected for bias by being multiplied by
+ #
+ # SQRT (# of pixels) / (# of pixels - 3)
+
+ # Then the value is driven towards unity, depending on
+ # exactly how many pixels were involved: if CHIOLD is based
+ # on a total weight of 3, then it is extremely poorly determined
+ # and we just want to keep CHIOLD = 1. The larger GRPWT is, the
+ # better determined CHIOLD is, and the less we want to force it
+ # toward unity. So, just take the weighted average of CHIOLD and
+ # unity, with weights GRPWT - 3 and 1, respectively.
+
+ if (grpwt > ntmin) {
+ chigrp = CHI_NORM * sumres * sqrt (1.0 / (grpwt * (grpwt -
+ ntmin)))
+ chigrp = ((grpwt - ntmin) * chigrp + ntmin) / grpwt
+ }
+
+ # CHIOLD has been pulled toward its expected value of unity to
+ # keep the statistics of a small number of pixels from completely
+ # dominating the error analysis. Similarly, the photometric
+ # errors for the individual stars will be pulled toward unity
+ # now. Later on, if the number of stars in the group is
+ # greated than one, CHI will be nudged toward the group average.
+ # In order to work optimally, of course, this requires that
+ # the # of photons / ADU, the READNOISE and the other noise
+ # contributors are properly specified.
+
+ call dp_ntchi (Memr[DP_NSUMWT(nstar)], Memr[DP_APCHI(apsel)],
+ group_size, ntmin, chigrp, grpwt)
+
+ # Invert the matrix.
+ call invers (Memr[DP_NC(nstar)], cdimen, nterm, flag)
+
+ # Check for a singular matrix.
+ refit = dp_ncheckc (Memr[DP_NC(nstar)], cdimen, nterm,
+ Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_NIER(nstar)], group_size,
+ DP_RECENTER(dao), DP_FITSKY(dao), DP_GROUPSKY(dao), mean_sky,
+ DP_VERBOSE(dao))
+ if (group_size < 1)
+ return (group_size)
+ if (refit)
+ next
+
+ # Solve for position and scale factor increments.
+ call mvmul (Memr[DP_NC(nstar)], cdimen, nterm, Memr[DP_NV(nstar)],
+ Memr[DP_NX(nstar)])
+
+ if (iter <= 1)
+ refit = true
+ else
+ refit = false
+
+ # Fit the sky.
+ if (DP_FITSKY(dao) == YES) {
+ noise = sqrt (abs (mean_sky / DP_PHOTADU(dao)) + read_noise)
+ mean_sky = mean_sky - max (-3.0 * noise,
+ min (Memr[DP_NX(nstar)+nterm-1], 3.0 * noise))
+ if (abs (Memr[DP_NX(nstar)+nterm-1]) > (1.0e-4 * mean_sky))
+ refit = true
+ }
+
+ # In the beginning, the brightness of each star will be permitted
+ # to change by no more than 2 magnitudes per iteration, and the x,y
+ # coordinates of each centroid will be permitted to change by
+ # no more than 0.4 pixels per iteration. Any time that the
+ # parameter correction changes sign from one iteration to the
+ # next, the maximum permissible change will be reduced by a factor
+ # of two. These clamps are released any time a star disappears.
+
+ call dp_ntclamp (Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ Memr[DP_NSUMWT(nstar)], group_size, Memr[DP_NC(nstar)], cdimen,
+ Memr[DP_NX(nstar)], Memr[DP_NXOLD(nstar)],
+ Memr[DP_NXCLAMP(nstar)], DP_RECENTER(dao), clip, refit)
+
+ # Check whether the estimated centroid of the any star has
+ # moved so far out of the limits of the picture that it has fewer
+ # than 4 or 5 pixels within one fitting radius.
+
+ call dp_ntcentroid (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_NIER(nstar)], group_size,
+ ixmin, ixmax, iymin, iymax, fitradsq, DP_FITSKY(dao),
+ DP_GROUPSKY(dao), mean_sky, refit, DP_VERBOSE(dao))
+
+ if (group_size < 1)
+ return (group_size)
+
+ # Update matrix dimensions.
+ if (DP_RECENTER(dao) == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (DP_FITSKY(dao) == YES)
+ nterm = nterm + 1
+
+ # Now check whether any of the stars is too faint (more than 12.5
+ # magnitudes fainter than the PSF star). If several stars are too
+ # faint, delete the faintest one, and set the brightness of the
+ # other faint ones to 12.5 magnitudes below the PSF star. That way
+ # on the next iteration we will see whether these stars want to
+ # grow or to disappear.
+
+ faint = 0.0
+ ifaint = 0
+ call dp_ntfmag (Memr[DP_APMAG(apsel)], group_size, tfaint, tifaint)
+
+ # If at least one star is more than 12.5 magnitudes fainter
+ # than the PSF then ifaint is the relative index of the faintest
+ # of them, and faint is the relative brightness of the
+ # faintest of them.
+
+ # No very faint star was detected.
+ if (tifaint <= 0) {
+
+ # If the solution has not converged and if the number of
+ # iterations is less than MIN_ITER, perform another iteration
+ # with no questions asked.
+
+ if ((refit) && (iter < MIN_ITER))
+ return (group_size)
+
+ # If the solution doesn't think it has converged, after the
+ # fourth iteration delete the least certain star if it is less
+ # less than a one-sigma detection; after the eighth iteration
+ # delete the least certain star if it is less than a 1.5 sigma
+ # detection; after the twelfth iteration OR if the solution
+ # thinks it has converged, delete the least certain star if it
+ # is less than a two-sigma detection.
+
+ call dp_fsnoise (Memr[DP_APMAG(apsel)], Memr[DP_APERR(apsel)],
+ group_size, faint, ifaint)
+
+ if ((refit) && (iter < DP_MAXITER (dao)) && (faint < wcrit))
+ return (group_size)
+ }
+
+ # Reject the appropriate star.
+ if ((tifaint > 0) || (faint >= MIN_FAINT)) {
+
+ # Either (a) the solution thinks it has not converged
+ # and the faintest star is more uncertain than sqrt(wcrit)
+ # or (b) the solution thinks it has converged and the
+ # faintest star is more uncertain than two-sigma.
+
+ if (DP_VERBOSE (dao) == YES) {
+ mindex = max (tifaint, ifaint)
+ call printf (
+ "\tStar %-5d has been deleted because it is too faint\n")
+ call pargi (Memi[DP_APID(apsel)+mindex-1])
+ }
+
+ if ((DP_FITSKY(dao) == NO) && (DP_GROUPSKY(dao) == YES) &&
+ (group_size > 1))
+ mean_sky = (mean_sky * group_size -
+ Memr[DP_APMSKY(apsel)+max(tifaint,ifaint)-1]) /
+ (group_size - 1)
+
+ call dp_remove (max (tifaint, ifaint), group_size,
+ Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_NIER(nstar)],
+ NSTERR_FAINT)
+
+ if (group_size < 1)
+ return (group_size)
+
+ if (DP_RECENTER(dao) == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (DP_FITSKY(dao) == YES)
+ nterm = nterm + 1
+ call aclrr (Memr[DP_NXOLD(nstar)], nterm)
+ call amovkr (1.0, Memr[DP_NXCLAMP(nstar)], nterm)
+ clip = false
+ iter = max (1, iter - 1)
+ next
+ }
+
+ # Solution has either converged or gone to the maximum number
+ # of iterations.
+
+ if ((iter < DP_MAXITER(dao)) && (! clip)) {
+
+ # The first convergence milestone has been reached. Turn on the
+ # clipper, loosen the clamps and keep on going.
+
+ if (DP_CLIPEXP(dao) > 0)
+ clip = true
+ converge = false
+ call aclrr (Memr[DP_NXOLD(nstar)], nterm)
+ call amaxkr (Memr[DP_NXCLAMP(nstar)], 0.25,
+ Memr[DP_NXCLAMP(nstar)], nterm)
+ return (group_size)
+ }
+
+ converge = true
+
+ } until (converge)
+
+ return (group_size)
+end
+
+
+# DP_NSTMERGE -- Decide whether two stars in a group should merge.
+
+bool procedure dp_nstmerge (xcen, ycen, mag, magerr, group_size, sepcrit,
+ sepmin, wcrit, i, j, k)
+
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+real magerr[ARB] # array of magnitude errors
+int group_size # group size
+real sepcrit # the critical separation squared
+real sepmin # the minimum separation
+real wcrit # critical error for rejection
+int i, j, k # output indices
+
+real separation
+
+begin
+ do i = 1, group_size {
+ do j = 1, i - 1 {
+
+ # Compute the separation.
+ separation = (xcen[j] - xcen[i]) ** 2 +
+ (ycen[j] - ycen[i]) ** 2
+ if (separation > sepcrit)
+ next
+
+ # Find the fainter of the two stars.
+ k = j
+ if (mag[i] < mag[j])
+ k = i
+ if ((separation < sepmin) || ((magerr[k] / mag[k]) > wcrit))
+ return (true)
+ }
+ }
+
+ return (false)
+end
+
+
+# DP_NSTCEN -- Recompute the centroid and brightness of the i-th star.
+
+procedure dp_nstcen (xcen, ycen, mag, i, j, k)
+
+real xcen[ARB] # the x centers
+real ycen[ARB] # the y centers
+real mag[ARB] # the magnitudes
+int i, j, k # array indices
+
+begin
+ # Now eliminate the fainter of the two stars. The k-th
+ # star is now the fainter of the two, the i-th the
+ # brighter.
+
+ if (mag[i] < mag[j])
+ i = j
+
+ # Now replace the centroid of the i-th star with the
+ # weighted mean of the most recent estimates of the
+ # centroids of the i-th and the k-th stars, and the
+ # brightness of i-th with the sum of the brightnesses.
+
+ xcen[i] = xcen[i] * mag[i] + xcen[k] * mag[k]
+ ycen[i] = ycen[i] * mag[i] + ycen[k] * mag[k]
+ mag[i] = mag[i] + mag[k]
+ xcen[i] = xcen[i] / mag[i]
+ ycen[i] = ycen[i] / mag[i]
+end
+
+
+# DP_NTOMIT -- Check whether a pixel is within one fitting radius of another
+# star.
+
+bool procedure dp_ntomit (xcen, ycen, rpixsq, skip, group_size, fx, fy, cutoff)
+
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real rpixsq[ARB] # array of distances squared
+int skip[ARB] # array of skip values
+int group_size # the group size
+real fx, fy # pixel position in image
+real cutoff # radius cuttoff for pixel inclusion
+
+bool omit
+int i
+
+begin
+ omit = true
+ do i = 1, group_size {
+ skip[i] = YES
+ rpixsq[i] = (fx - xcen[i]) ** 2 + (fy - ycen[i]) ** 2
+ if (rpixsq[i] > cutoff)
+ next
+ skip[i] = NO
+ omit = false
+ }
+
+ return (omit)
+end
+
+
+# DP_NTSKYVAL -- Compute the average sky value to use for a particular
+# pixel by averaging the sky values of all stars for which the
+# pixel is within one fitting radius.
+
+real procedure dp_ntskyval (sky, skip, nstar)
+
+real sky[ARB] # array of sky values
+int skip[ARB] # array of skip values
+int nstar # the number of stars
+
+int i, npts
+real sum
+
+begin
+ sum = 0.0
+ npts = 0
+ do i = 1, nstar {
+ if (skip[i] == YES)
+ next
+ sum = sum + sky[i]
+ npts = npts + 1
+ }
+ if (npts <= 0)
+ return (INDEFR)
+ else
+ return (sum / npts)
+end
+
+
+# DP_NTSUBTRACT -- Procedure to subtract the contribution of a particular
+# pixel from a particular star.
+
+real procedure dp_ntsubtract (dao, im, xcen, ycen, rpixsq, mag, skip, x,
+ group_size, fx, fy, ds, psfradsq, fitradsq, recenter)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real rpixsq[ARB] # array of distances squared
+real mag[ARB] # array of magnitudes
+int skip[ARB] # array of skip values
+real x[ARB] # x accumulation vector array
+int group_size # size of the group
+real fx, fy # center of pixel in image
+real ds # pixel value
+real psfradsq # psf radius squared
+real fitradsq # fit radius squared
+int recenter # recenter the coordinates
+
+int i, i3, k
+pointer psffit
+real weight, dx, dy, deltax, deltay, val, dvdx, dvdy, rsq
+real dp_usepsf()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ weight = 0.0
+ do i = 1, group_size {
+ if (rpixsq[i] >= psfradsq)
+ next
+ dx = fx - xcen[i]
+ dy = fy - ycen[i]
+ call dp_wpsf (dao, im, xcen[i], ycen[i], deltax, deltay, 1)
+ deltax = (deltax - 1.0) / DP_PSFX(psffit) - 1.0
+ deltay = (deltay - 1.0) / DP_PSFY(psffit) - 1.0
+ val = dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), deltax, deltay,
+ dvdx, dvdy)
+ ds = ds - mag[i] * val
+ if (skip[i] == YES)
+ next
+ rsq = rpixsq[i] / fitradsq
+ weight = max (weight, 5.0 / (5.0 + rsq / (1.0 - rsq)))
+ if (recenter == YES) {
+ i3 = 3 * i
+ k = i3 - 2
+ x[k] = -val
+ k = i3 - 1
+ x[k] = -mag[i] * dvdx
+ x[i3] = -mag[i] * dvdy
+ } else
+ x[i] = -val
+ }
+
+ return (weight)
+end
+
+
+# DP_ACSHARP -- Procedure to accumulate sums of the weighted absolute
+# relative residuals and the image sharpness parameter for each of the
+# stars.
+
+procedure dp_acsharp (xcen, ycen, skip, npix, numer, denom, sumwt, chi,
+ group_size, fx, fy, fwhmx, fwhmy, ds, sigmasq, relerr, weight)
+
+real xcen[ARB] # array of object x centers
+real ycen[ARB] # array of object y centers
+int skip[ARB] # array of skip values
+int npix[ARB] # array of numbers of pixels
+real numer[ARB] # numerator array
+real denom[ARB] # denominator array
+real sumwt[ARB] # array of summed weights
+real chi[ARB] # array of chis
+int group_size # group size paramter.
+real fx, fy # position of data in image
+real fwhmx, fwhmy # gaussian core widths in x and y
+real ds # the data residual
+real sigmasq # the sigma squared
+real relerr # the relative error
+real weight # the weight
+
+int i
+real rhosq, dfdsig
+
+begin
+ do i = 1, group_size {
+
+ if (skip[i] == YES)
+ next
+
+ # Accumulate the number of pixels, chi and sum of the weights.
+ npix[i] = npix[i] + 1
+ chi[i] = chi[i] + relerr * weight
+ sumwt[i] = sumwt[i] + weight
+
+ # Include in the sharpness index only those pixels
+ # within NCORE_SIGMASQ of the centroid of the
+ # object. (This saves time and floating underflows
+ # by excluding pixels which contribute very little
+ # to the index.
+
+ rhosq = ((xcen[i] - fx) / fwhmx) ** 2 + ((ycen[i] - fy) /
+ fwhmy) ** 2
+ if (rhosq > NCORE_SIGMASQ)
+ next
+ rhosq = 0.6931472 * rhosq
+ dfdsig = exp (-rhosq) * (rhosq - 1.0)
+ numer[i] = numer[i] + dfdsig * ds / sigmasq
+ denom[i] = denom[i] + (dfdsig ** 2) / sigmasq
+ }
+end
+
+
+# DP_MATACCUM -- Procedure to accumulate the data into the matrices.
+
+procedure dp_mataccum (x, skip, group_size, c, v, cdimen, nterm, weight, dswt,
+ recenter, fitsky)
+
+real x[ARB] # x array
+int skip[ARB] # skip vector
+int group_size # size of the group
+real c[cdimen,ARB] # coefficient matrix
+real v[ARB] # vector array
+int cdimen # dimensions of the coefficient matrix
+int nterm # the number of terms
+real weight # weight
+real dswt # data weight
+int recenter # recenter the coordinates
+int fitsky # fit the sky value
+
+int i, i3, i3m2, k, j, l
+
+begin
+ if (fitsky == YES) {
+ c[nterm,nterm] = c[nterm,nterm] + weight
+ v[nterm] = v[nterm] - dswt
+ }
+
+ do i = 1, group_size {
+ if (skip[i] == YES)
+ next
+ if (recenter == YES) {
+ i3 = i * 3
+ i3m2 = i3 - 2
+ do k = i3m2, i3 {
+ if (fitsky == YES)
+ c[nterm,k] = c[nterm,k] - x[k] * weight
+ v[k] = v[k] + x[k] * dswt
+ }
+ do j = 1, i {
+ if (skip[j] == YES)
+ next
+ do k = i3m2, i3 {
+ do l = 3 * j - 2, min (k, 3 * j)
+ c[k,l] = c[k,l] + x[k] * x[l] * weight
+ }
+ }
+ } else {
+ v[i] = v[i] + x[i] * dswt
+ if (fitsky == YES)
+ c[nterm,i] = c[nterm,i] - x[i] * weight
+ do j = 1, i {
+ if (skip[j] == YES)
+ next
+ c[i,j] = c[i,j] + x[i] * x[j] * weight
+ }
+ }
+ }
+end
+
+
+# DP_NTMIN -- Make sure that every star in the group has at least
+# MIN_NPIX pixels within one fitting radius.
+
+bool procedure dp_ntmin (ids, xcen, ycen, mag, sky, npix, nier, group_size,
+ nterm, recenter, fitsky, groupsky, mean_sky, verbose)
+
+int ids[ARB] # array of ids
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+int npix[ARB] # array of pixel numbers
+int nier[ARB] # array of error codes
+int group_size # size of the group
+int nterm # number of terms
+int recenter # recenter the objects
+int fitsky # fit the sky value
+int groupsky # use group sky value
+real mean_sky # the current mean sky value
+int verbose # verbose flag
+
+bool redo
+int i
+
+begin
+ redo = false
+ do i = 1, group_size {
+ if (npix[i] >= MIN_NPIX)
+ next
+ redo = true
+ if (verbose == YES) {
+ call printf (
+ "\tStar %-5d has been deleted: too few good pixels\n")
+ call pargi (ids[i])
+ }
+ if ((fitsky == NO) && (groupsky == YES) && (group_size > 1))
+ mean_sky = (mean_sky * group_size - sky[i]) / (group_size - 1)
+ call dp_remove (i, group_size, ids, xcen, ycen, mag, sky,
+ nier, NSTERR_NOPIX)
+ if (group_size <= 0)
+ return (redo)
+ if (recenter == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (fitsky == YES)
+ nterm = nterm + 1
+ }
+
+ return (redo)
+end
+
+
+# DP_MREFLECT -- Reflect the normal matrix around the diagonal.
+
+procedure dp_mreflect (c, cdimen, nterm)
+
+real c[cdimen,ARB] # coefficient matrix
+int cdimen # dimension of the c matrix
+int nterm # number of terms
+
+int l, k
+
+begin
+ # Reflect the normal matrix across the diagonal.
+ do l = 2, nterm {
+ do k = 1, l - 1
+ c[k,l] = c[l,k]
+ }
+end
+
+
+# DP_NTCHI -- Compute the chi value for each star.
+
+procedure dp_ntchi (sumwt, chi, group_size, ntmin, chigrp, grpwt)
+
+real sumwt[ARB] # sum of the weights
+real chi[ARB] # the chis:wq
+int group_size # size of the group
+int ntmin # minimum number of points
+real chigrp # the group chi
+real grpwt # the group weight
+
+int i
+
+begin
+ do i = 1, group_size {
+ if (sumwt[i] > ntmin) {
+ chi[i] = CHI_NORM * chi[i] / sqrt ((sumwt[i] - ntmin) *
+ sumwt[i])
+ sumwt[i] = ((sumwt[i] - ntmin) * chi[i] + MIN_SUMWT) /
+ sumwt[i]
+ } else {
+ chi[i] = chigrp
+ sumwt[i] = grpwt
+ }
+ }
+end
+
+
+# DP_NCHECKC -- Check the inverted matrix for singularity.
+
+bool procedure dp_ncheckc (c, cdimen, nterm, ids, xcen, ycen, mag, sky,
+ nier, group_size, recenter, fitsky, groupsky, mean_sky, verbose)
+
+real c[cdimen,ARB] # coefficient matrix
+int cdimen # dimension of the c matrix
+int nterm # number of terms
+int ids[ARB] # array of ids
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+int nier[ARB] # array of error codes
+int group_size # size of the group
+int recenter # recenter the objects
+int fitsky # fit the sky value
+int groupsky # use group sky value
+real mean_sky # the current mean sky value
+int verbose # verbose flag
+
+bool redo
+int j, starno, i
+
+begin
+ redo = false
+ do j = 1, nterm {
+ if (c[j,j] > 0.0)
+ next
+ redo = true
+ if ((j == nterm) && (fitsky == YES))
+ starno = 0
+ else if (recenter == YES)
+ starno = (j + 2) / 3
+ else
+ starno = j
+ if (starno == 0) {
+ if (verbose == YES) {
+ do i = 1, group_size {
+ call printf (
+ "\tStar %-5d has been deleted: singular matrix\n")
+ call pargi (ids[i])
+ }
+ }
+ call amovki (NSTERR_SINGULAR, nier, group_size)
+ group_size = 0
+ } else {
+ if (verbose == YES) {
+ call printf (
+ "\tStar %-5d has been deleted: singular matrix\n")
+ call pargi (ids[starno])
+ }
+ if ((fitsky == NO) && (groupsky == YES) && (group_size > 1))
+ mean_sky = (mean_sky * group_size - sky[starno]) /
+ (group_size - 1)
+ call dp_remove (starno, group_size, ids, xcen, ycen, mag,
+ sky, nier, NSTERR_SINGULAR)
+ }
+ if (group_size <= 0)
+ return (redo)
+ if (recenter == YES)
+ nterm = 3 * group_size
+ else
+ nterm = group_size
+ if (fitsky == YES)
+ nterm = nterm + 1
+ }
+
+ return (redo)
+end
+
+
+# DP_NTCLAMP -- Restrict the amount the solution can vary on each iteration.
+
+procedure dp_ntclamp (xcen, ycen, mag, magerr, sumwt, group_size, c, cdimen,
+ x, xold, clamp, recenter, clip, redo)
+
+real xcen[ARB] # x centers array
+real ycen[ARB] # y centers array
+real mag[ARB] # magnitude array
+real magerr[ARB] # magnitude errors array
+real sumwt[ARB] # array of weight sums
+int group_size # size of the group
+real c[cdimen, ARB] # coefficient matrix
+int cdimen # dimensions of c
+real x[ARB] # x vector
+real xold[ARB] # old x vector
+real clamp[ARB] # clamp on solution matrix
+int recenter # recenter the objects
+bool clip # clip the matrix
+bool redo # redo the solution
+
+int i, l, j, k
+real df
+
+begin
+ do i = 1, group_size {
+
+
+ # If any correction has changed sign since the last
+ # iteration, reduce the maximum permissible change by
+ # a factor of two.
+
+ # Note that the sign of the correction is such that it
+ # must be SUBTRACTED from the current value of the
+ # parameter to get the improved parameter value. This being
+ # the case, if the correction to the brightness is
+ # negative (the least-squares thinks that the star should
+ # be brighter) a change of 1 magnitude is a change of a
+ # factor of 2.5; if the brightness correction is positive
+ # (the star should be fainter) a change of 1 magnitude
+ # is a change of 60%.
+
+ if (recenter == YES) {
+
+ l = 3 * i
+ k = l - 1
+ j = l - 2
+
+ if ((xold[j] * x[j]) < 0.0)
+ clamp[j] = 0.5 * clamp[j]
+ mag[i] = mag[i] - x[j] / (1.0 + max (x[j] /
+ (MAX_DELTA_FAINTER * mag[i]), -x[j] / (MAX_DELTA_BRIGHTER *
+ mag[i])) / clamp[j])
+ xold[j] = x[j]
+
+ if ((xold[k] * x[k]) < 0.0)
+ clamp[k] = 0.5 * clamp[k]
+ if ((xold[l] * x[l]) < 0.0)
+ clamp[l] = 0.5 * clamp[l]
+ xcen[i] = xcen[i] - x[k] / (1.0 + abs(x[k]) / (clamp[k] *
+ MAX_DELTA_PIX))
+ ycen[i] = ycen[i] - x[l] / (1.0 + abs(x[l]) / (clamp[l] *
+ MAX_DELTA_PIX))
+ xold[k] = x[k]
+ xold[l] = x[l]
+ magerr[i] =sumwt[i] * sqrt (c[j,j])
+
+ } else {
+
+ if ((xold[i] * x[i]) < 0.0)
+ clamp[i] = 0.5 * clamp[i]
+ mag[i] = mag[i] - x[i] / (1.0 + max (x[i] /
+ (MAX_DELTA_FAINTER * mag[i]), -x[i] / (MAX_DELTA_BRIGHTER *
+ mag[i])) / clamp[i])
+ xold[i] = x[i]
+ magerr[i] =sumwt[i] * sqrt (c[i,i])
+ }
+
+
+ # There are two milestones in the convergence process: the fits
+ # proceed normally until each star's magnitude changes by less
+ # than its standard error or MAX_NEW_ERRMAG magnitudes, whichever
+ # is greater, and its x and y centroids change by less than 0.02
+ # pixel. At this point the least squares begins to apply
+ # down-weighting of pixels with large residuals as described
+ # above. The fits then continue until each star's
+ # magnitude changes by less than MAX (MAX_NEW_ERRMAG * std. error,
+ # MAX_NEW_RELBRIGHT2 magnitude), ad its centroids change by
+ # less than 0.002 pixel.
+
+ if (redo)
+ next
+
+ if (clip) {
+ if (abs (x[j]) > max (MAX_NEW_ERRMAG * magerr[i],
+ MAX_NEW_RELBRIGHT2 * mag[i])) {
+ redo = true
+ } else if (recenter == YES) {
+ df = (MAX_NEW_ERRMAG * sumwt[i]) ** 2
+ if (x[k] ** 2 > max (df * c[k,k], MAX_PIXERR2))
+ redo = true
+ else if (x[l] ** 2 > max (df * c[l,l], MAX_PIXERR2))
+ redo = true
+ }
+ } else {
+ if (abs (x[j]) > max (magerr[i], MAX_NEW_RELBRIGHT1 *
+ mag[i])) {
+ redo = true
+ } else if (recenter == YES) {
+ df = sumwt[i] ** 2
+ if (x[k] ** 2 > max (df * c[k,k], MAX_PIXERR1))
+ redo = true
+ else if (x[l] ** 2 > max (df * c[l,l], MAX_PIXERR1))
+ redo = true
+ }
+ }
+ }
+end
+
+
+# DP_NTCENTROID -- Check the new centroids to see if they have moved too
+# far off the edge of the image.
+
+procedure dp_ntcentroid (ids, xcen, ycen, mag, sky, nier, group_size, ixmin,
+ ixmax, iymin, iymax, fitradsq, fitsky, groupsky, mean_sky, redo,
+ verbose)
+
+int ids[ARB] # array of ids
+real xcen[ARB] # array of x centers
+real ycen[ARB] # array of y centers
+real mag[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+int nier[ARB] # array of error codes
+int group_size # size of the group
+int ixmin,ixmax # subraster x limits
+int iymin,iymax # subraster y limits
+real fitradsq # fit radius squared
+int fitsky # fit the sky value
+int groupsky # use the group sky value
+real mean_sky # the mean sky value
+bool redo # redo fit
+int verbose # verbose mode
+
+int i
+real dx, dy
+
+begin
+ # Check whether the centroid of any star has moved so far outside
+ # the picture that it has fewer than four or five pixels within
+ # one fitting radius.
+
+ do i = 1, group_size {
+
+ # If the centroid of the star is outside the picture in x or
+ # y, then DX or DY is its distance from the center of the edge
+ # pixel; otherwise DX and DY are zero.
+
+ dx = max (ixmin - xcen[i], xcen[i] - ixmax, 0.0)
+ dy = max (iymin - ycen[i], ycen[i] - iymax, 0.0)
+ if ((dx <= MAX_PIX_INCREMENT) && (dy <= MAX_PIX_INCREMENT))
+ next
+ if (((dx + 1.0) ** 2 + (dy + 1.0) ** 2) < fitradsq)
+ next
+
+ # Print a warning message about the star.
+ if (verbose == YES) {
+ call printf (
+ "\tStar %-5d has been deleted: new center too far off image\n")
+ call pargi (i)
+ }
+
+ # Adjust the sky.
+ if ((fitsky == NO) && (groupsky == YES) && (group_size > 1))
+ mean_sky = (mean_sky * group_size - sky[i]) / (group_size - 1)
+
+ # Delete it.
+ call dp_remove (i, group_size, ids, xcen, ycen, mag, sky, nier,
+ NSTERR_OFFIMAGE)
+ if (group_size < 1)
+ break
+ redo = true
+ }
+end
+
+
+# DP_NTFMAG -- Check for faint stars.
+
+procedure dp_ntfmag (mag, group_size, faint, ifaint)
+
+real mag[ARB] # array of magnitudes
+int group_size # size of the group
+real faint # faintest magnitude
+int ifaint # index of faintest magnitude
+
+int i
+
+begin
+ faint = 1.0
+ ifaint = 0
+ do i = 1, group_size {
+ if (mag[i] > MIN_REL_BRIGHT)
+ next
+ if (mag[i] <= faint) {
+ faint = mag[i]
+ ifaint = i
+ }
+ mag[i] = MIN_REL_BRIGHT
+ }
+end
+
+
+# DP_FSNOISE -- Compute the smallest signal to noise ratio.
+
+procedure dp_fsnoise (mag, magerr, group_size, faint, ifaint)
+
+real mag[ARB] # array of magnitudes
+real magerr[ARB] # array of magnitude errors
+int group_size # size of group
+real faint # faint value
+int ifaint # faint index
+
+int i
+real weight
+
+begin
+ faint = 0.0
+ ifaint = 0
+ do i = 1, group_size {
+ weight = magerr[i] / mag[i]
+ if (weight < faint)
+ next
+ faint = weight
+ ifaint = i
+ }
+end
+
+
+# DP_REMOVE -- Remove the i-th star from the list of stars in the current
+# group by moving it to the end of the group.
+
+procedure dp_remove (i, nstar, ids, xcen, ycen, mag, sky, nier, pier)
+
+int i # the star to be removed
+int nstar # the number of stars in the group
+int ids[ARB] # the array of star ids
+real xcen[ARB] # the array of star x positions
+real ycen[ARB] # the array of star y positions
+real mag[ARB] # the array of magnitudes
+real sky[ARB] # the array of sky values.
+int nier[ARB] # array of error codes
+int pier # error code for deleted star
+
+int ihold, phold
+real xhold, yhold, shold, mhold
+
+begin
+ nier[i] = pier
+ if (i != nstar) {
+
+ ihold = ids[i]
+ xhold = xcen[i]
+ yhold = ycen[i]
+ shold = sky[i]
+ mhold = mag[i]
+ phold = nier[i]
+
+ ids[i] = ids[nstar]
+ xcen[i] = xcen[nstar]
+ ycen[i] = ycen[nstar]
+ sky[i] = sky[nstar]
+ mag[i] = mag[nstar]
+ nier[i] = nier[nstar]
+
+ ids[nstar] = ihold
+ xcen[nstar] = xhold
+ ycen[nstar] = yhold
+ sky[nstar] = shold
+ mag[nstar] = mhold
+ nier[nstar] = phold
+ }
+ nstar = nstar - 1
+end
diff --git a/noao/digiphot/daophot/nstar/dpntwrite.x b/noao/digiphot/daophot/nstar/dpntwrite.x
new file mode 100644
index 00000000..248a9f28
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/dpntwrite.x
@@ -0,0 +1,600 @@
+include <tbset.h>
+include <time.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/nstardef.h"
+
+
+# DP_TPNEWNSTAR -- Create a new NSTAR output ST table.
+
+procedure dp_tpnewnstar (dao, nst, colpoint)
+
+pointer dao # pointer to the daophot structure
+pointer nst # pointer to output photometry file
+pointer colpoint[ARB] # array of column pointers
+
+
+int i
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for table definition.
+ call smark (sp)
+ call salloc (colnames, NST_NOUTCOL * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, NST_NOUTCOL * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, NST_NOUTCOL * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, NST_NOUTCOL, TY_INT)
+ call salloc (col_len, NST_NOUTCOL, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (GROUP, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+ call strcpy (MAGERR, Memc[colnames+5*SZ_COLNAME+5], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+6*SZ_COLNAME+6], SZ_COLNAME)
+ call strcpy (NITER, Memc[colnames+7*SZ_COLNAME+7], SZ_COLNAME)
+ call strcpy (SHARP, Memc[colnames+8*SZ_COLNAME+8], SZ_COLNAME)
+ call strcpy (CHI, Memc[colnames+9*SZ_COLNAME+9], SZ_COLNAME)
+ call strcpy (PIER, Memc[colnames+10*SZ_COLNAME+10], SZ_COLNAME)
+ call strcpy (PERROR, Memc[colnames+11*SZ_COLNAME+11], SZ_COLNAME)
+
+ # Se up the column format definitions.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+ call strcpy ("%14.3f", Memc[colformat+5*SZ_COLFMT+5], SZ_COLFMT)
+ call strcpy ("%15.7g", Memc[colformat+6*SZ_COLFMT + 6], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+7*SZ_COLFMT+7], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+8*SZ_COLFMT+8], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+9*SZ_COLFMT+9], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+10*SZ_COLFMT+10], SZ_COLFMT)
+ call strcpy ("%13s", Memc[colformat+11*SZ_COLFMT+11], SZ_COLFMT)
+
+ # Set up the column unit definitions.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("MAGNITIDES", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+ call strcpy ("MAGNITIDES", Memc[colunits+5*SZ_COLUNITS+5], SZ_COLUNITS)
+ call strcpy ("COUNTS", Memc[colunits+6*SZ_COLUNITS+6], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+7*SZ_COLUNITS+7], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+8*SZ_COLUNITS+8], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+9*SZ_COLUNITS+9], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+10*SZ_COLUNITS+10], SZ_COLUNITS)
+ call strcpy ("PERRORS", Memc[colunits+11*SZ_COLUNITS+11], SZ_COLUNITS)
+
+ # Define the column datatypes.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_INT
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+ Memi[col_dtype+4] = TY_REAL
+ Memi[col_dtype+5] = TY_REAL
+ Memi[col_dtype+6] = TY_REAL
+ Memi[col_dtype+7] = TY_INT
+ Memi[col_dtype+8] = TY_REAL
+ Memi[col_dtype+9] = TY_REAL
+ Memi[col_dtype+10] = TY_INT
+ Memi[col_dtype+11] = -13
+
+ # Define columnlengths.
+ do i = 1, NST_NOUTCOL
+ Memi[col_len+i-1] = 1
+
+ # Define and create the table.
+ call tbcdef (nst, colpoint, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], NST_NOUTCOL)
+ call tbtcre (nst)
+
+ # Write out some header parameters.
+ call dp_tnstarpars (dao, nst)
+
+ call sfree (sp)
+
+end
+
+
+define NST_NAME1STR "#N%4tID%10tGROUP%16tXCENTER%26tYCENTER%36tMAG%48t\
+MERR%62tMSKY%80t\\\n"
+define NST_UNIT1STR "#U%4t##%10t##%16tpixels%26tpixels%36tmagnitudes%48t\
+magnitudes%62tcounts%80t\\\n"
+define NST_FORMAT1STR "#F%4t%%-9d%10t%%-6d%16t%%-10.3f%26t%%-10.3f%36t\
+%%-12.3f%48t%%-14.3f%62t%%-15.7g%80t \n"
+
+define NST_NAME2STR "#N%12tNITER%18tSHARPNESS%30tCHI%42tPIER%48tPERROR%80t\\\n"
+define NST_UNIT2STR "#U%12t##%18t##%30t##%42t##%48tperrors%80t\\\n"
+define NST_FORMAT2STR "#F%12t%%-17d%18t%%-12.3f%30t%%-12.3f%42t%%-6d\
+%48t%%-13s%80t \n"
+
+# DP_XPNEWNSTAR -- Create a new NSTAR output text file.
+
+procedure dp_xpnewnstar (dao, nst)
+
+pointer dao # pointer to the daophot structure
+int nst # the output file descriptor
+
+
+begin
+ # Write out some header parameters.
+ call dp_xnstarpars (dao, nst)
+
+ # Write out the header banner.
+ call fprintf (nst, "#\n")
+ call fprintf (nst, NST_NAME1STR)
+ call fprintf (nst, NST_UNIT1STR)
+ call fprintf (nst, NST_FORMAT1STR)
+ call fprintf (nst, "#\n")
+ call fprintf (nst, NST_NAME2STR)
+ call fprintf (nst, NST_UNIT2STR)
+ call fprintf (nst, NST_FORMAT2STR)
+ call fprintf (nst, "#\n")
+end
+
+
+# DP_XNSTARPARS -- Add parameters to the header of the output NSTAR text file.
+
+procedure dp_xnstarpars (dao, nst)
+
+pointer dao # pointer to the daophot structure
+int nst # the output file descriptor
+
+pointer psffit, sp, outstr, date, time, comment
+bool itob()
+int envfind()
+
+begin
+ # Get pointers
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+ call salloc (comment, SZ_LINE, TY_CHAR)
+ Memc[comment] = EOS
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <=0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (nst, "IRAF", Memc[outstr], "version", Memc[comment])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call dp_sparam (nst, "USER", Memc[outstr], "name", Memc[comment])
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (nst, "HOST", Memc[outstr], "computer", Memc[comment])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (nst, "DATE", Memc[date], "yyyy-mm-dd", Memc[comment])
+ call dp_sparam (nst, "TIME", Memc[time], "hh:mm:ss", Memc[comment])
+ call dp_sparam (nst, "PACKAGE", "daophot", "name", Memc[comment])
+ call dp_sparam (nst, "TASK", "nstar", "name", Memc[comment])
+
+ # Write out the file names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_FNAME)
+ call dp_sparam (nst, "IMAGE", Memc[outstr], "imagename",
+ Memc[comment])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_FNAME)
+ call dp_sparam (nst, "GRPFILE", Memc[outstr], "filename", Memc[comment])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_FNAME)
+ call dp_sparam (nst, "PSFIMAGE", Memc[outstr], "imagename",
+ Memc[comment])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_FNAME)
+ call dp_sparam (nst, "NSTARFILE", Memc[outstr], "filename",
+ Memc[comment])
+ if (DP_OUTREJFILE(dao) == EOS)
+ call dp_sparam (nst, "REJFILE", "\"\"", "filename", Memc[comment])
+ else {
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_FNAME)
+ call dp_sparam (nst, "REJFILE", Memc[outstr], "filename",
+ Memc[comment])
+ }
+
+ # Write out the data dependent parameters.
+ call dp_rparam (nst, "SCALE", DP_SCALE(dao), "units/pix",
+ Memc[comment])
+ call dp_rparam (nst, "DATAMIN", DP_MINGDATA(dao), "counts",
+ Memc[comment])
+ call dp_rparam (nst, "DATAMAX", DP_MAXGDATA(dao), "counts",
+ Memc[comment])
+ call dp_rparam (nst, "GAIN", DP_PHOTADU(dao), "number", Memc[comment])
+ call dp_rparam (nst, "READNOISE", DP_READNOISE(dao), "electrons",
+ Memc[comment])
+
+ # Write out the observing parameters.
+ call dp_sparam (nst, "OTIME", DP_OTIME(dao), "timeunit", Memc[comment])
+ call dp_rparam (nst, "XAIRMASS", DP_XAIRMASS(dao), "number",
+ Memc[comment])
+ call dp_sparam (nst, "IFILTER", DP_IFILTER(dao), "filter",
+ Memc[comment])
+
+ # Write out the fitting parameters.
+ call dp_bparam (nst, "RECENTER", itob (DP_RECENTER(dao)), "switch",
+ Memc[comment])
+ call dp_bparam (nst, "FITSKY", itob (DP_FITSKY(dao)), "switch",
+ Memc[comment])
+ call dp_bparam (nst, "GRPSKY", itob (DP_GROUPSKY(dao)), "switch",
+ Memc[comment])
+ call dp_rparam (nst, "PSFMAG", DP_PSFMAG(psffit), "magnitude",
+ Memc[comment])
+ call dp_rparam (nst, "PSFRAD", DP_SPSFRAD(dao), "scaleunit",
+ Memc[comment])
+ call dp_rparam (nst, "FITRAD", DP_SFITRAD(dao), "scaleunit",
+ Memc[comment])
+ call dp_iparam (nst, "MAXITER", DP_MAXITER(dao), "number",
+ Memc[comment])
+ call dp_iparam (nst, "MAXGROUP", DP_MAXGROUP(dao), "number",
+ Memc[comment])
+ call dp_rparam (nst, "FLATERROR", DP_FLATERR(dao), "percentage",
+ Memc[comment])
+ call dp_rparam (nst, "PROFERROR", DP_PROFERR(dao), "percentage",
+ Memc[comment])
+ call dp_iparam (nst, "CLIPEXP", DP_CLIPEXP(dao), "number",
+ Memc[comment])
+ call dp_rparam (nst, "CLIPRANGE", DP_CLIPRANGE(dao), "sigma",
+ Memc[comment])
+ call dp_rparam (nst, "MERGERAD", DP_SMERGERAD(dao), "scaleunit",
+ Memc[comment])
+
+ call sfree(sp)
+end
+
+
+# DP_TNSTARPARS -- Add parameters to the header of the output NSTAR ST table.
+
+procedure dp_tnstarpars (dao, nst)
+
+pointer dao # pointer to the daophot structure
+pointer nst # pointer to the output photometry table
+
+pointer psffit, sp, outstr, date, time
+bool itob()
+int envfind()
+
+begin
+ # Get pointers
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <=0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (nst, "IRAF", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call tbhadt (nst, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (nst, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (nst, "DATE", Memc[date])
+ call tbhadt (nst, "TIME", Memc[time])
+ call tbhadt (nst, "PACKAGE", "daophot")
+ call tbhadt (nst, "TASK", "nstar")
+
+ # Write out the file names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_FNAME)
+ call tbhadt (nst, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_FNAME)
+ call tbhadt (nst, "GRPFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_FNAME)
+ call tbhadt (nst, "PSFIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_FNAME)
+ call tbhadt (nst, "NSTARFILE", Memc[outstr])
+ if (DP_OUTREJFILE(dao) == EOS)
+ call tbhadt (nst, "REJFILE", "\"\"")
+ else {
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_FNAME)
+ call tbhadt (nst, "REJFILE", Memc[outstr])
+ }
+
+ # Write out the data dependent parameters.
+ call tbhadr (nst, "SCALE", DP_SCALE(dao))
+ call tbhadr (nst, "DATAMIN", DP_MINGDATA(dao))
+ call tbhadr (nst, "DATAMAX", DP_MAXGDATA(dao))
+ call tbhadr (nst, "GAIN", DP_PHOTADU(dao))
+ call tbhadr (nst, "READNOISE", DP_READNOISE(dao))
+
+ # Write out the observing parameters.
+ call tbhadt (nst, "OTIME", DP_OTIME(dao))
+ call tbhadr (nst, "XAIRMASS", DP_XAIRMASS(dao))
+ call tbhadt (nst, "IFILTER", DP_IFILTER(dao))
+
+ # Write out the fitting parameters.
+ call tbhadb (nst, "RECENTER", itob (DP_RECENTER(dao)))
+ call tbhadb (nst, "FITSKY", itob (DP_FITSKY(dao)))
+ call tbhadb (nst, "GRPSKY", itob (DP_GROUPSKY(dao)))
+ call tbhadr (nst, "PSFMAG", DP_PSFMAG(psffit))
+ call tbhadr (nst, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (nst, "FITRAD", DP_SFITRAD(dao))
+ call tbhadi (nst, "MAXITER", DP_MAXITER(dao))
+ call tbhadi (nst, "MAXGROUP", DP_MAXGROUP(dao))
+ call tbhadr (nst, "FLATERROR", DP_FLATERR(dao))
+ call tbhadr (nst, "PROFERROR", DP_PROFERR(dao))
+ call tbhadi (nst, "CLIPEXP", DP_CLIPEXP(dao))
+ call tbhadr (nst, "CLIPRANGE", DP_CLIPRANGE(dao))
+ call tbhadr (nst, "MERGERAD", DP_SMERGERAD(dao))
+
+ call sfree(sp)
+end
+
+
+# DP_TNTWRITE -- Write out the NSTAR results to an ST table.
+
+procedure dp_tntwrite (dao, im, nst, rej, niter, old_size, output_row,
+ routput_row, colpoint)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+pointer nst # output photometry file descriptor
+int rej # output rejections file descriptor
+int niter # number of iterations
+int old_size # original size of group
+int output_row # output photometry file row number
+int routput_row # output rejections file row number
+pointer colpoint[ARB] # column pointer array
+
+int i, id, nkeep, nreject, pier, plen, iter
+pointer psffit, nstar, apsel, sp, perror
+real xcen, ycen, mag, errmag, sharp
+int dp_gnsterr()
+
+begin
+ # Get some daophot pointers.
+ nstar = DP_NSTAR(dao)
+ apsel = DP_APSEL(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Fill in the INDEFS.
+ nkeep = DP_NNUM(nstar)
+ nreject = old_size - nkeep
+ if (nreject > 0) {
+ call amovkr (INDEFR, Memr[DP_APMAG(apsel)+nkeep], nreject)
+ call amovkr (INDEFR, Memr[DP_APERR(apsel)+nkeep], nreject)
+ call amovkr (INDEFR, Memr[DP_APCHI(apsel)+nkeep], nreject)
+ }
+
+ call smark (sp)
+ call salloc (perror, SZ_FNAME, TY_CHAR)
+
+ # Now write out the results.
+ do i = 1, old_size {
+
+ # Get the results.
+ id = Memi[DP_APID (apsel)+i-1]
+ xcen = Memr[DP_APXCEN (apsel)+i-1]
+ ycen = Memr[DP_APYCEN (apsel)+i-1]
+ if (IS_INDEFR(xcen) || IS_INDEFR(ycen))
+ next
+ call dp_wout (dao, im, xcen, ycen, xcen, ycen, 1)
+ mag = Memr[DP_APMAG(apsel)+i-1]
+ errmag = Memr[DP_APERR(apsel)+i-1]
+ if (! IS_INDEFR(mag)) {
+ if (! IS_INDEFR(errmag))
+ errmag = 1.085736 * errmag / mag
+ sharp = 1.4427 * Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1] * Memr[DP_NNUMER(nstar)+i-1] /
+ (mag * DP_PSFHEIGHT(psffit) * Memr[DP_NDENOM(nstar)+i-1])
+ if ((sharp < MIN_SHARP) || (sharp > MAX_SHARP))
+ sharp = INDEFR
+ mag = DP_PSFMAG (psffit) - 2.5 * log10 (mag)
+ } else
+ sharp = INDEFR
+ pier = Memi[DP_NIER(nstar)+i-1]
+ if (pier == NSTERR_OK)
+ iter = niter
+ else
+ iter = 0
+ plen = dp_gnsterr (pier, Memc[perror], SZ_FNAME)
+
+ # Write the results to the standard output.
+ if (DP_VERBOSE (dao) == YES) {
+ call printf (
+ "\tID: %5d XCEN: %8.2f YCEN: %8.2f MAG: %8.2f\n")
+ call pargi (id)
+ call pargr (xcen)
+ call pargr (ycen)
+ call pargr (mag)
+ }
+
+ # Write the output row to the proper table.
+ if ((rej != NULL) && (pier != NSTERR_OK)) {
+ routput_row = routput_row + 1
+ call tbrpti (rej, colpoint[1], id, 1, routput_row)
+ call tbrpti (rej, colpoint[2], DP_NGNUM(nstar), 1, routput_row)
+ call tbrptr (rej, colpoint[3], xcen, 1, routput_row)
+ call tbrptr (rej, colpoint[4], ycen, 1, routput_row)
+ call tbrptr (rej, colpoint[5], mag, 1, routput_row)
+ call tbrptr (rej, colpoint[6], errmag, 1, routput_row)
+ call tbrptr (rej, colpoint[7], Memr[DP_APMSKY(apsel)+i-1],
+ 1, routput_row)
+ call tbrpti (rej, colpoint[8], iter, 1, routput_row)
+ call tbrptr (rej, colpoint[9], sharp, 1, routput_row)
+ call tbrptr (rej, colpoint[10], Memr[DP_APCHI(apsel)+i-1],
+ 1, routput_row)
+ call tbrpti (rej, colpoint[11], pier, 1, routput_row)
+ call tbrptt (rej, colpoint[12], Memc[perror], plen, 1,
+ routput_row)
+ } else {
+ output_row = output_row + 1
+ call tbrpti (nst, colpoint[1], id, 1, output_row)
+ call tbrpti (nst, colpoint[2], DP_NGNUM(nstar), 1, output_row)
+ call tbrptr (nst, colpoint[3], xcen, 1, output_row)
+ call tbrptr (nst, colpoint[4], ycen, 1, output_row)
+ call tbrptr (nst, colpoint[5], mag, 1, output_row)
+ call tbrptr (nst, colpoint[6], errmag, 1, output_row)
+ call tbrptr (nst, colpoint[7], Memr[DP_APMSKY(apsel)+i-1],
+ 1, output_row)
+ call tbrpti (nst, colpoint[8], iter, 1, output_row)
+ call tbrptr (nst, colpoint[9], sharp, 1, output_row)
+ call tbrptr (nst, colpoint[10], Memr[DP_APCHI(apsel)+i-1],
+ 1, output_row)
+ call tbrpti (nst, colpoint[11], pier, 1, output_row)
+ call tbrptt (nst, colpoint[12], Memc[perror], plen, 1,
+ output_row)
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+define NST_DATA1STR "%-9d%10t%-6d%16t%-10.3f%26t%-10.3f%36t%-12.3f%48t\
+%-14.3f%62t%-15.7g%80t\\\n"
+define NST_DATA2STR "%12t%-6d%18t%-12.3f%30t%-12.3f%42t%-6d%48t%-13.13s%80t \n"
+
+# DP_XNTWRITE -- Write out the NSTAR results to a text file.
+
+procedure dp_xntwrite (dao, im, nst, rej, niter, old_size)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int nst # the output photometry file descriptor
+int rej # the output rejections file descriptor
+int niter # the number of the iteration
+int old_size # old size of group
+
+int i, id, nkeep, nreject, pier, plen, iter
+pointer nstar, psffit, apsel, sp, perror
+real xcen, ycen, mag, errmag, sharp
+int dp_gnsterr()
+
+begin
+ # Get some daophot pointers.
+ nstar = DP_NSTAR(dao)
+ psffit = DP_PSFFIT(dao)
+ apsel = DP_APSEL(dao)
+
+ # Fill in the results for the rejected stars with INDEFS.
+ nkeep = DP_NNUM(nstar)
+ nreject = old_size - nkeep
+ if (nreject > 0) {
+ call amovkr (INDEFR, Memr[DP_APMAG(apsel)+nkeep], nreject)
+ call amovkr (INDEFR, Memr[DP_APERR(apsel)+nkeep], nreject)
+ call amovkr (INDEFR, Memr[DP_APCHI(apsel)+nkeep], nreject)
+ }
+
+ call smark (sp)
+ call salloc (perror, SZ_FNAME, TY_CHAR)
+
+ # Now write out the results.
+ do i = 1, old_size {
+
+ # Get the results.
+ id = Memi[DP_APID (apsel)+i-1]
+ xcen = Memr[DP_APXCEN (apsel)+i-1]
+ ycen = Memr[DP_APYCEN (apsel)+i-1]
+ if (IS_INDEFR(xcen) || IS_INDEFR(ycen))
+ next
+ call dp_wout (dao, im, xcen, ycen, xcen, ycen, 1)
+ mag = Memr[DP_APMAG(apsel)+i-1]
+ errmag = Memr[DP_APERR(apsel)+i-1]
+ if (! IS_INDEFR(mag)) {
+ if (! IS_INDEFR(errmag))
+ errmag = 1.085736 * errmag / mag
+ sharp = 1.4427 * Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1] * Memr[DP_NNUMER(nstar)+i-1] /
+ (mag * DP_PSFHEIGHT(psffit) * Memr[DP_NDENOM(nstar)+i-1])
+ if ((sharp < MIN_SHARP) || (sharp > MAX_SHARP))
+ sharp = INDEFR
+ mag = DP_PSFMAG (psffit) - 2.5 * log10 (mag)
+ } else
+ sharp = INDEFR
+ pier = Memi[DP_NIER(nstar)+i-1]
+ if (pier == NSTERR_OK)
+ iter = niter
+ else
+ iter = 0
+ plen = dp_gnsterr (pier, Memc[perror], SZ_FNAME)
+
+ # Write the results to the standard output.
+ if (DP_VERBOSE (dao) == YES) {
+ call printf (
+ "\tID: %5d XCEN: %8.2f YCEN: %8.2f MAG: %8.2f\n")
+ call pargi (id)
+ call pargr (xcen)
+ call pargr (ycen)
+ call pargr (mag)
+ }
+
+ # Write the results to the output file.
+ if ((rej != NULL) && (pier != NSTERR_OK)) {
+ call fprintf (rej, NST_DATA1STR)
+ call pargi (id)
+ call pargi (DP_NGNUM(nstar))
+ call pargr (xcen)
+ call pargr (ycen)
+ call pargr (mag)
+ call pargr (errmag)
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ call fprintf (rej, NST_DATA2STR)
+ call pargi (iter)
+ call pargr (sharp)
+ call pargr (Memr[DP_APCHI(apsel)+i-1])
+ call pargi (pier)
+ call pargstr (Memc[perror])
+ } else {
+ call fprintf (nst, NST_DATA1STR)
+ call pargi (id)
+ call pargi (DP_NGNUM(nstar))
+ call pargr (xcen)
+ call pargr (ycen)
+ call pargr (mag)
+ call pargr (errmag)
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ call fprintf (nst, NST_DATA2STR)
+ call pargi (iter)
+ call pargr (sharp)
+ call pargr (Memr[DP_APCHI(apsel)+i-1])
+ call pargi (pier)
+ call pargstr (Memc[perror])
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_GNSTERR -- Set the NSTAR task error code string.
+
+int procedure dp_gnsterr (ier, perror, maxch)
+
+int ier # the integer error code
+char perror # the output error code string
+int maxch # the maximum size of the error code string
+
+int plen
+int gstrcpy()
+
+begin
+ switch (ier) {
+ case NSTERR_OK:
+ plen = gstrcpy ("No_error", perror, maxch)
+ case NSTERR_BIGGROUP:
+ plen = gstrcpy ("Big_group", perror, maxch)
+ case NSTERR_INDEFSKY:
+ plen = gstrcpy ("Bad_sky", perror, maxch)
+ case NSTERR_NOPIX:
+ plen = gstrcpy ("Npix_too_few", perror, maxch)
+ case NSTERR_SINGULAR:
+ plen = gstrcpy ("Singular", perror, maxch)
+ case NSTERR_FAINT:
+ plen = gstrcpy ("Too_faint", perror, maxch)
+ case NSTERR_MERGE:
+ plen = gstrcpy ("Merged", perror, maxch)
+ case NSTERR_OFFIMAGE:
+ plen = gstrcpy ("Off_image", perror, maxch)
+ default:
+ plen = gstrcpy ("No_error", perror, maxch)
+ }
+
+ return (plen)
+end
diff --git a/noao/digiphot/daophot/nstar/mkpkg b/noao/digiphot/daophot/nstar/mkpkg
new file mode 100644
index 00000000..327f3487
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/mkpkg
@@ -0,0 +1,24 @@
+# NSTAR task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpggroup.x "../../lib/ptkeysdef.h" ../lib/daophotdef.h \
+ ../lib/apseldef.h
+ dpmemnstar.x ../lib/daophotdef.h ../lib/nstardef.h
+ dpnconfirm.x ../lib/daophotdef.h
+ dpnstar.x <imhdr.h> <tbset.h> \
+ <mach.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/nstardef.h
+ dpnstarfit.x <imhdr.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/nstardef.h \
+ <mach.h>
+ dpntwrite.x <tbset.h> <time.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/nstardef.h
+ t_nstar.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/nstar/t_nstar.x b/noao/digiphot/daophot/nstar/t_nstar.x
new file mode 100644
index 00000000..8f6c542e
--- /dev/null
+++ b/noao/digiphot/daophot/nstar/t_nstar.x
@@ -0,0 +1,308 @@
+include <fset.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# T_NSTAR -- Procedure to fit the PSF to multiple stars.
+
+procedure t_nstar ()
+
+pointer image # input image descriptor
+pointer groupfile # input group file descriptor
+pointer psfimage # input PSF image descriptor
+pointer nstarfile # output photometry file descriptor
+pointer rejfile # output rejections file descriptor
+int verbose # print messages
+int verify # verify the critical parameters
+int update # update the parameter set
+int cache # cache the input image pixels
+
+pointer sp, outfname, im, psfim, dao, str
+int imlist, limlist, alist, lalist, pimlist, lpimlist, olist, lolist
+int rlist, lrlist, root, grp, nst, rejfd, wcs, req_size, old_size
+int buf_size, memstat
+bool ap_text
+
+pointer immap(), tbtopn()
+int strlen(), strncmp(), fnldir(), fstati(), open(), btoi()
+int access(), imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb()
+int fntgfnb(), clgwrd(), sizeof(), dp_memstat()
+bool clgetb(), itob()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Allocate working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (groupfile, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (nstarfile, SZ_FNAME, TY_CHAR)
+ call salloc (rejfile, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the input and output file names.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("groupfile", Memc[groupfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("nstarfile", Memc[nstarfile], SZ_FNAME)
+ call clgstr ("rejfile", Memc[rejfile], SZ_FNAME)
+
+ # Get the task mode parameters.
+ verbose = btoi (clgetb ("verbose"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb ("cache"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[groupfile], NO)
+ lalist = fntlenb (alist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ olist = fntopnb (Memc[nstarfile], NO)
+ lolist = fntlenb (olist)
+ rlist = fntopnb (Memc[rejfile], NO)
+ lrlist = fntlenb (rlist)
+
+ # Test that the lengths of the photometry file, psf image, and
+ # output file lists are the same as the length of the input image
+ # list.
+
+ if ((limlist != lalist) && (strncmp (Memc[groupfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and group file list lengths")
+ }
+
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and psf file list lengths")
+ }
+
+ if ((limlist != lolist) && (strncmp (Memc[nstarfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and nstar file list lengths")
+ }
+
+ if ((lrlist > 0) && (limlist != lrlist) && (strncmp (Memc[rejfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and rejections file list lengths")
+ }
+
+ # Open the daophot structure and get some parameters.
+ call dp_gppars (dao)
+
+ # Set some parameters.
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Verify and update the parameters if appropriate.
+ if (verify == YES) {
+ call dp_nconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+ # Initialize the photometry structure.
+ call dp_apsetup (dao)
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Initialize the nstar structure.
+ call dp_nstarsetup (dao)
+
+ # Loop over the images.
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open the input image.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ # Open the input group table.
+ if (fntgfnb (alist, Memc[groupfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[groupfile], SZ_FNAME)
+ root = fnldir (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[groupfile+root],
+ DEF_LENDEFNAME) == 0 || (root == strlen (Memc[groupfile])))
+ call dp_inname (Memc[image], Memc[outfname], "grp",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ grp = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ grp = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Open and read the PSF image.
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || (root == strlen (Memc[psfimage])))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ psfim = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_readpsf (dao, psfim)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+
+ # Open the output NSTAR file. If the output is DEF_DEFNAME,
+ # dir$default or a directory specification then the extension
+ # "nst" is added to the image name and a suitable version number
+ # is appended to the output name.
+
+ if (fntgfnb (olist, Memc[nstarfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[nstarfile], SZ_FNAME)
+ root = fnldir (Memc[nstarfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[nstarfile+root],
+ DEF_LENDEFNAME) == 0 || (root == strlen (Memc[nstarfile]))) {
+ call dp_outname (Memc[image], Memc[outfname], "nst",
+ Memc[outfname], SZ_FNAME)
+ } else
+ call strcpy (Memc[nstarfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ nst = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ nst = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ if (lrlist <= 0) {
+ rejfd = NULL
+ Memc[outfname] = EOS
+ } else {
+ if (fntgfnb (rlist, Memc[rejfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[rejfile], SZ_FNAME)
+ root = fnldir (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[rejfile+root],
+ DEF_LENDEFNAME) == 0 || (root == strlen (Memc[rejfile])))
+ call dp_outname (Memc[image], Memc[outfname], "nrj",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ rejfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ rejfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ }
+ call dp_sets (dao, OUTREJFILE, Memc[outfname])
+
+ # Do the PSF fitting.
+ call dp_nphot (dao, im, grp, nst, rejfd, ap_text)
+
+ # Close the input image.
+ call imunmap (im)
+
+ # Close the group file.
+ if (ap_text)
+ call close (grp)
+ else
+ call tbtclo (grp)
+
+ # Close the PSF image.
+ call imunmap (psfim)
+
+ # Close the output photometry file.
+ if (DP_TEXT(dao) == YES)
+ call close (nst)
+ else
+ call tbtclo (nst)
+
+ # Close the output rejections file.
+ if (rejfd != NULL) {
+ if (DP_TEXT(dao) == YES)
+ call close (rejfd)
+ else
+ call tbtclo (rejfd)
+ }
+
+ # Uncache memory.
+ call fixmem (old_size)
+
+ }
+
+ # Close the image/file lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+
+ # Close the nstar structure.
+ call dp_nsclose (dao)
+
+ # Close the PSF structure.
+ call dp_fitclose (dao)
+
+ # Close the photometry structure.
+ call dp_apclose (dao)
+
+ # Free the daophot structure.
+ call dp_free (dao)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/peak.par b/noao/digiphot/daophot/peak.par
new file mode 100644
index 00000000..e3600d38
--- /dev/null
+++ b/noao/digiphot/daophot/peak.par
@@ -0,0 +1,17 @@
+# Parameters for the PEAK task
+
+image,f,a,,,,"Image corresponding to photometry"
+photfile,f,a,default,,,"Input photometry file (default: image.mag.?)"
+psfimage,f,a,default,,,"PSF image (default: image.psf.?)"
+peakfile,f,a,"default",,,"Output photometry file (default: image.pk.?)"
+rejfile,f,a,"default",,,"Output rejections file (default: image.rej.?)"
+datapars,pset,h,"",,,Data dependent parameters
+daopars,pset,h,"",,,Psf fitting parameters
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,Verify critical peak parameters?
+update,b,h,)_.update,,,Update critical peak parameters?
+verbose,b,h,)_.verbose,,,Print peak messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/peak/dpmempk.x b/noao/digiphot/daophot/peak/dpmempk.x
new file mode 100644
index 00000000..97c7ff48
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dpmempk.x
@@ -0,0 +1,72 @@
+include "../lib/daophotdef.h"
+include "../lib/peakdef.h"
+
+
+# DP_PKSETUP -- Initialize the PEAK fitting structure.
+
+procedure dp_pksetup (dao)
+
+pointer dao # pointer to the daophot structure
+
+pointer peak
+
+begin
+ call malloc (DP_PEAK(dao), LEN_PKSTRUCT, TY_STRUCT)
+ peak = DP_PEAK(dao)
+
+ DP_PKNTERM(peak) = 0
+ DP_PKCLAMP(peak) = NULL
+ DP_PKNORMAL(peak) = NULL
+ DP_PKRESID(peak) = NULL
+ DP_PKDERIV(peak) = NULL
+ DP_PKRESULT(peak) = NULL
+ DP_PKOLDRESULT(peak) = NULL
+end
+
+
+# DP_MEMPK -- Allocate memory for the PEAK fitting arrays.
+
+procedure dp_mempk (dao, nterm)
+
+pointer dao # pointer to the daophot structure
+int nterm # the number of terms to be fit
+
+pointer peak
+
+begin
+ peak = DP_PEAK(dao)
+
+ call malloc (DP_PKCLAMP(peak), nterm, TY_REAL)
+ call malloc (DP_PKNORMAL(peak), nterm * nterm, TY_REAL)
+ call malloc (DP_PKRESID(peak), nterm * nterm, TY_REAL)
+ call malloc (DP_PKDERIV(peak), nterm * nterm, TY_REAL)
+ call malloc (DP_PKRESULT(peak), nterm * nterm, TY_REAL)
+ call malloc (DP_PKOLDRESULT(peak), nterm * nterm, TY_REAL)
+ DP_PKNTERM(peak) = nterm
+end
+
+
+# DP_PKCLOSE -- Free the PEAK fitting structure.
+
+procedure dp_pkclose (dao)
+
+pointer dao # pointer to the daophot structure
+
+pointer peak
+
+begin
+ peak = DP_PEAK(dao)
+ if (DP_PKCLAMP(peak) != NULL)
+ call mfree (DP_PKCLAMP(peak), TY_REAL)
+ if (DP_PKNORMAL(peak) != NULL)
+ call mfree (DP_PKNORMAL(peak), TY_REAL)
+ if (DP_PKRESID(peak) != NULL)
+ call mfree (DP_PKRESID(peak), TY_REAL)
+ if (DP_PKDERIV(peak) != NULL)
+ call mfree (DP_PKDERIV(peak), TY_REAL)
+ if (DP_PKRESULT(peak) != NULL)
+ call mfree (DP_PKRESULT(peak), TY_REAL)
+ if (DP_PKOLDRESULT(peak) != NULL)
+ call mfree (DP_PKOLDRESULT(peak), TY_REAL)
+ call mfree (peak, TY_STRUCT)
+end
diff --git a/noao/digiphot/daophot/peak/dppeakphot.x b/noao/digiphot/daophot/peak/dppeakphot.x
new file mode 100644
index 00000000..182b10d8
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dppeakphot.x
@@ -0,0 +1,277 @@
+include <imhdr.h>
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/peakdef.h"
+
+
+# DP_PEAKPHOT -- Fit the PSF to a single star.
+
+procedure dp_peakphot (dao, im, tp, tpout, tprej, ap_text)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int tp # the input photometry file descriptor
+int tpout # the ouput photometry file descriptor
+int tprej # the rejections file descriptor
+bool ap_text # which style of photometry
+
+real rel_bright, xold, yold, x, y, dx, dy, mag, sky, errmag
+real chi, sharp, radius, itx, ity, otx, oty
+pointer psffit, key, sp, subim, colpoint, indices, fields, perror
+int id, in_nrow, instar, lowx, lowy, nxpix, nypix, niter, out_nrow
+int rout_nrow, nterm, ier, plen
+
+int tbpsta(), dp_rrphot(), dp_pkfit(), dp_gpkerr()
+pointer dp_gsubrast()
+
+begin
+ # Get the daophot pointers.
+ psffit = DP_PSFFIT (dao)
+
+ # Store the original fitting radius.
+ radius = DP_FITRAD(dao)
+
+ # Check that the fitting radius is less than the psf radius.
+ DP_FITRAD(dao) = min (DP_FITRAD(dao), DP_PSFRAD(dao))
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (indices, NAPPAR, TY_INT)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (colpoint, PK_NOUTCOL, TY_INT)
+ call salloc (perror, SZ_FNAME, TY_CHAR)
+
+ # Initialze the output table.
+ if (DP_TEXT(dao) == YES) {
+ call dp_xnewpeak (dao, tpout)
+ if (tprej != NULL)
+ call dp_xnewpeak (dao, tprej)
+ } else {
+ call dp_tnewpeak (dao, tpout, Memi[colpoint])
+ if (tprej != NULL)
+ call dp_tnewpeak (dao, tprej, Memi[colpoint])
+ }
+
+ # Intialize the input table.
+ if (ap_text) {
+ call pt_kyinit (key)
+ Memi[indices] = DP_PAPID
+ Memi[indices+1] = DP_PAPXCEN
+ Memi[indices+2] = DP_PAPYCEN
+ Memi[indices+3] = DP_PAPMAG1
+ Memi[indices+4] = DP_PAPSKY
+ call dp_gappsf (Memi[indices], Memc[fields], NAPRESULT)
+ in_nrow = 0
+ } else {
+ call dp_tpkinit (tp, Memi[indices])
+ in_nrow = tbpsta (tp, TBL_NROWS)
+ }
+
+ # Initialize the photometry file reading code.
+ instar = 0
+
+ # Initialize the fitting code.
+ if (DP_RECENTER(dao) == YES)
+ nterm = 3
+ else
+ nterm = 1
+ if (DP_FITSKY(dao) == YES)
+ nterm = nterm + 1
+ call dp_mempk (dao, nterm)
+
+ out_nrow = 0
+ rout_nrow = 0
+ repeat {
+
+ # Read in the photometry for a single star.
+ if (dp_rrphot (tp, key, Memc[fields], Memi[indices], id, itx,
+ ity, sky, mag, instar, in_nrow) == EOF)
+ break
+
+ # Convert to and from logical coordinates.
+ call dp_win (dao, im, itx, ity, x, y, 1)
+ call dp_wout (dao, im, x, y, otx, oty, 1)
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Star: %5d X: %8.2f Y: %8.2f Mag: %8.2f Sky: %8.2f\n")
+ call pargi (id)
+ call pargr (otx)
+ call pargr (oty)
+ call pargr (mag)
+ call pargr (sky)
+ }
+
+ # Check that the center is defined.
+ if (IS_INDEFR(x) || IS_INDEFR(y)) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "\tWarning: X and/or Y for star %d are undefined\n")
+ call pargi (id)
+ }
+ next
+ }
+
+ # Read in the subraster.
+ subim = dp_gsubrast (im, x, y, DP_FITRAD(dao), lowx, lowy,
+ nxpix, nypix)
+ if (subim == NULL) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "\tWarning: Cannot read in image data for star %d\n")
+ call pargi (id)
+ }
+ next
+ }
+
+ # Save the old x and y values for use with the variable psf
+ # option.
+ xold = x
+ yold = y
+ call dp_wpsf (dao, im, xold, yold, xold, yold, 1)
+
+ # Compute the relative centers and the relative brightness and
+ # fit the star.
+ if (IS_INDEFR(sky)) {
+
+ ier = PKERR_INDEFSKY
+
+ } else {
+
+ x = x - lowx + 1.0
+ y = y - lowy + 1.0
+ dx = (xold - 1.0) / DP_PSFX(psffit) - 1.0
+ dy = (yold - 1.0) / DP_PSFY(psffit) - 1.0
+ if (IS_INDEFR(mag))
+ mag = DP_PSFMAG (psffit) + DELTA_MAG
+ rel_bright = DAO_RELBRIGHT (psffit, mag)
+ ier = dp_pkfit (dao, Memr[subim], nxpix, nypix, DP_FITRAD(dao),
+ x, y, dx, dy, rel_bright, sky, errmag, chi, sharp, niter)
+ x = x + lowx - 1.0
+ y = y + lowy - 1.0
+ }
+
+ call dp_wout (dao, im, x, y, otx, oty, 1)
+
+ if (ier != PKERR_OK) {
+
+ # Set fitting parameters to INDEF.
+ mag = INDEFR
+ niter = 0
+ errmag = INDEFR
+ chi = INDEFR
+ sharp = INDEFR
+
+ if (DP_VERBOSE(dao) == YES) {
+ switch (ier) {
+ case PKERR_INDEFSKY:
+ call printf (
+ "\tWarning: The sky value for star %d is undefined\n")
+ call pargi (id)
+ case PKERR_NOPIX:
+ call printf (
+ "\tWarning: Too few pixels to fit star %d\n")
+ call pargi (id)
+ case PKERR_SINGULAR:
+ call printf (
+ "\tWarning: Singular matrix computed for star %d\n")
+ call pargi (id)
+ case PKERR_FAINT:
+ call printf ("\tWarning: Star %d too faint\n")
+ call pargi (id)
+ default:
+ call printf (
+ "\tWarning: Unknown error detected for star %d\n")
+ call pargi (id)
+ }
+ }
+
+ } else {
+
+ # Compute the results.
+ mag = DP_PSFMAG (psffit) - 2.5 * log10 (rel_bright)
+ errmag = 1.085736 * errmag / rel_bright
+ if (errmag >= 2.0)
+ errmag = INDEFR
+
+ if (DP_VERBOSE (dao) == YES) {
+ call printf (
+ "\tFIT: Star: %5d X: %8.2f Y: %8.2f Mag: %8.2f Sky =%8.2f\n")
+ call pargi (id)
+ call pargr (otx)
+ call pargr (oty)
+ call pargr (mag)
+ call pargr (sky)
+ }
+ }
+
+ # Get the error code.
+ plen = dp_gpkerr (ier, Memc[perror], SZ_FNAME)
+
+ # Now write the results to the output photometry or rejections
+ # file.
+ if (DP_TEXT(dao) == YES) {
+ if ((tprej != NULL) && (ier != PKERR_OK))
+ call dp_xpkwrite (tprej, id, otx, oty, mag, errmag, sky,
+ niter, chi, sharp, ier, Memc[perror], plen)
+ else
+ call dp_xpkwrite (tpout, id, otx, oty, mag, errmag, sky,
+ niter, chi, sharp, ier, Memc[perror], plen)
+ } else {
+ if ((tprej != NULL) && (ier != PKERR_OK)) {
+ rout_nrow = rout_nrow + 1
+ call dp_tpkwrite (tprej, Memi[colpoint], id, otx, oty, mag,
+ errmag, sky, niter, chi, sharp, ier,
+ Memc[perror], plen, rout_nrow)
+ } else {
+ out_nrow = out_nrow + 1
+ call dp_tpkwrite (tpout, Memi[colpoint], id, otx, oty, mag,
+ errmag, sky, niter, chi, sharp, ier, Memc[perror],
+ plen, out_nrow)
+ }
+ }
+ }
+
+ # Free the text file descriptor.
+ if (ap_text)
+ call pt_kyfree (key)
+
+ # Restore the original fitting radius.
+ DP_FITRAD(dao) = radius
+ DP_SFITRAD(dao) = DP_FITRAD(dao) * DP_SCALE(dao)
+
+ call sfree (sp)
+end
+
+
+# DP_GPKERR -- Set the PEAK task error code string.
+
+int procedure dp_gpkerr (ier, perror, maxch)
+
+int ier # the integer error code
+char perror # the output error code string
+int maxch # the maximum size of the error code string
+
+int plen
+int gstrcpy()
+
+begin
+ switch (ier) {
+ case PKERR_OK:
+ plen = gstrcpy ("No_error", perror, maxch)
+ case PKERR_INDEFSKY:
+ plen = gstrcpy ("Bad_sky", perror, maxch)
+ case PKERR_NOPIX:
+ plen = gstrcpy ("Npix_too_few", perror, maxch)
+ case PKERR_SINGULAR:
+ plen = gstrcpy ("Singular", perror, maxch)
+ case PKERR_FAINT:
+ plen = gstrcpy ("Too_faint", perror, maxch)
+ default:
+ plen = gstrcpy ("No_error", perror, maxch)
+ }
+
+ return (plen)
+end
diff --git a/noao/digiphot/daophot/peak/dppkconfirm.x b/noao/digiphot/daophot/peak/dppkconfirm.x
new file mode 100644
index 00000000..c7dc6333
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dppkconfirm.x
@@ -0,0 +1,25 @@
+# DP_PKCONFIRM -- Procedure to confirm the critical peak parameters.
+
+procedure dp_pkconfirm (dao)
+
+pointer dao # pointer to the daophot structure
+
+begin
+ call printf ("\n")
+
+ # Confirm recentering and sky fitting.
+ call dp_vrecenter (dao)
+ call dp_vfitsky (dao)
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/peak/dppkfit.x b/noao/digiphot/daophot/peak/dppkfit.x
new file mode 100644
index 00000000..7818100c
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dppkfit.x
@@ -0,0 +1,411 @@
+include <mach.h>
+include "../lib/daophotdef.h"
+include "../lib/peakdef.h"
+
+# DP_PKFIT -- Do the actual fit.
+
+int procedure dp_pkfit (dao, subim, nx, ny, radius, x, y, dx, dy, rel_bright,
+ sky, errmag, chi, sharp, iter)
+
+pointer dao # pointer to the DAOPHOT Structure
+real subim[nx,ny] # pointer to the image subraster
+int nx, ny # size of the image subraster
+real radius # the fitting radius
+real x, y # initial estimate of the stellar position
+real dx, dy # distance of star from the psf position
+real rel_bright # initial estimate of stellar brightness
+real sky # the sky value associated with this star
+real errmag # error estimate for this star
+real chi # estimated goodness of fit parameter
+real sharp # broadness of the profile compared to the PSF
+int iter # number of iterations needed for a fit.
+
+bool clip, redo
+int i, flag, npix
+pointer psffit, peak
+real ronoise, numer, denom, chiold, sum_weight, noise, wcrit
+int dp_fitbuild()
+
+begin
+ # Get the pointer to the PSF structure.
+ psffit = DP_PSFFIT (dao)
+ peak = DP_PEAK(dao)
+
+ # Initialize the parameters which control the fit.
+
+ chiold = 1.0
+ sharp = INDEFR
+ clip = false
+ ronoise = (DP_READNOISE(dao) / DP_PHOTADU(dao)) ** 2
+
+ call amovkr (1.0, Memr[DP_PKCLAMP(peak)], DP_PKNTERM(peak))
+ call amovkr (0.0, Memr[DP_PKOLDRESULT(peak)], DP_PKNTERM(peak))
+
+ # Iterate until a solution is found.
+
+ for (iter = 1; iter <= DP_MAXITER(dao); iter = iter + 1) {
+
+ # Initialize the matrices and vectors required by the fit.
+
+ chi = 0.0
+ numer = 0.0
+ denom = 0.0
+ sum_weight = 0.0
+ call aclrr (Memr[DP_PKRESID(peak)], DP_PKNTERM(peak))
+ call aclrr (Memr[DP_PKNORMAL(peak)], DP_PKNTERM(peak) *
+ DP_PKNTERM(peak))
+
+ # Set up the critical error limit.
+ if (iter >= WCRIT_NMAX)
+ wcrit = WCRIT_MAX
+ else if (iter >= WCRIT_NMED)
+ wcrit = WCRIT_MED
+ else if (iter >= WCRIT_NMIN)
+ wcrit = WCRIT_MIN
+ else
+ wcrit = MAX_REAL
+
+
+ # Build up the vector of residuals and the normal matrix.
+
+ npix = dp_fitbuild (dao, subim, nx, ny, radius, x, y, dx, dy,
+ rel_bright, sky, chiold, chi, clip, iter,
+ Memr[DP_PKCLAMP(peak)], Memr[DP_PKNORMAL(peak)],
+ Memr[DP_PKRESID(peak)], Memr[DP_PKDERIV(peak)],
+ DP_PKNTERM[(peak)], numer, denom, sum_weight)
+
+ # Return if the iteration was unsuccessful.
+
+ if (npix < MIN_NPIX)
+ return (PKERR_NOPIX)
+
+ # Invert the matrix. Return if inversion was unsuccessful or
+ # if any of the diagonal elements are less or equal to 0.0.
+
+ call invers (Memr[DP_PKNORMAL(peak)], DP_PKNTERM(peak),
+ DP_PKNTERM(peak), flag)
+ if (flag != 0)
+ return (PKERR_SINGULAR)
+ do i = 1, DP_PKNTERM(peak) {
+ if (Memr[DP_PKNORMAL(peak)+(i-1)*DP_PKNTERM(peak)+i-1] <= 0.0)
+ return (PKERR_SINGULAR)
+ }
+ # Solve the matrix.
+
+ call mvmul (Memr[DP_PKNORMAL(peak)], DP_PKNTERM(peak),
+ DP_PKNTERM(peak), Memr[DP_PKRESID(peak)],
+ Memr[DP_PKRESULT(peak)])
+
+ # In the beginning the brightness of the star will not be
+ # permitted to change by more than two magnitudes per
+ # iteration (that is to say if the estimate is getting
+ # brighter, it may not get brighter by more than 525%
+ # per iteration, and if it is getting fainter, it may not
+ # get fainter by more than 84% per iteration). The x and y
+ # coordinates of the centroid will be allowed to change by
+ # no more than one-half pixel per iteration. Any time
+ # that a parameter correction changes sign, the maximum
+ # permissible change in that parameter will be reduced
+ # by a factor of 2.
+
+ # Perform the sign check.
+
+ do i = 1, DP_PKNTERM(peak) {
+ if ((Memr[DP_PKOLDRESULT(peak)+i-1] *
+ Memr[DP_PKRESULT(peak)+i-1]) < 0.0)
+ Memr[DP_PKCLAMP(peak)+i-1] = 0.5 *
+ Memr[DP_PKCLAMP(peak)+i-1]
+ else
+ Memr[DP_PKCLAMP(peak)+i-1] = min (1.0, 1.1 *
+ Memr[DP_PKCLAMP(peak)+i-1])
+ Memr[DP_PKOLDRESULT(peak)+i-1] = Memr[DP_PKRESULT(peak)+i-1]
+ }
+
+ # Compute the new x, y, sky, and magnitude.
+ rel_bright = rel_bright + Memr[DP_PKRESULT(peak)] /
+ (1.0 + max (Memr[DP_PKRESULT(peak)] /
+ (MAX_DELTA_BRIGHTER * rel_bright), -Memr[DP_PKRESULT(peak)] /
+ (MAX_DELTA_FAINTER * rel_bright)) / Memr[DP_PKCLAMP(peak)])
+
+ # Return if the star becomes too faint)
+ if (rel_bright < MIN_REL_BRIGHT)
+ return (PKERR_FAINT)
+
+ if (DP_RECENTER(dao) == YES) {
+ x = x + Memr[DP_PKRESULT(peak)+1] / (1.0 +
+ abs (Memr[DP_PKRESULT(peak)+1]) / (MAX_DELTA_PIX *
+ Memr[DP_PKCLAMP(peak)+1]))
+ y = y + Memr[DP_PKRESULT(peak)+2] / (1.0 +
+ abs (Memr[DP_PKRESULT(peak)+2]) / (MAX_DELTA_PIX *
+ Memr[DP_PKCLAMP(peak)+2]))
+ }
+
+ if (DP_FITSKY(dao) == YES) {
+ noise = sqrt ((abs (sky / DP_PHOTADU(dao)) + ronoise))
+ sky = sky + max (-3.0 * noise, min (Memr[DP_PKRESULT(peak)+
+ DP_PKNTERM(peak)-1], 3.0 * noise))
+ }
+
+ # Force at least one iteration before checking for convergence.
+ if (iter <= 1)
+ next
+
+ # Start on the assumption the fit has converged.
+
+ redo = false
+
+ # Check for convergence. If the most recent computed correction
+ # to the brightness is larger than 0.1% of the brightness or
+ # 0.05 * sigma of the brightness whichever is larger, convergence
+ # has not been achieved.
+
+ errmag = chiold * sqrt (Memr[DP_PKNORMAL(peak)])
+ if (clip) {
+ if (abs (Memr[DP_PKRESULT(peak)]) > max ((MAX_NEW_ERRMAG *
+ errmag), (MAX_NEW_RELBRIGHT1 * rel_bright))) {
+ redo = true
+ } else {
+ if (DP_RECENTER(dao) == YES) {
+ if (max (abs (Memr[DP_PKRESULT(peak)+1]),
+ abs (Memr[DP_PKRESULT(peak)+2])) > MAX_PIXERR1)
+ redo = true
+ }
+ if (DP_FITSKY(dao) == YES) {
+ if (abs (Memr[DP_PKRESULT(peak)+DP_PKNTERM(peak)-1]) >
+ 1.0e-4 * sky)
+ redo = true
+ }
+ }
+ } else {
+ if (abs (Memr[DP_PKRESULT(peak)]) > max (errmag,
+ (MAX_NEW_RELBRIGHT2 * rel_bright))) {
+ redo = true
+ } else {
+ if (DP_RECENTER(dao) == YES) {
+ if (max (abs (Memr[DP_PKRESULT(peak)+1]),
+ abs (Memr[DP_PKRESULT(peak)+2])) > MAX_PIXERR2)
+ redo = true
+ }
+ if (DP_FITSKY(dao) == YES) {
+ if (abs (Memr[DP_PKRESULT(peak)+DP_PKNTERM(peak)-1]) >
+ 1.0e-4 * sky)
+ redo = true
+ }
+ }
+ }
+ if (redo)
+ next
+
+ if ((iter < DP_MAXITER(dao)) && (! clip)) {
+ if (DP_CLIPEXP(dao) > 0)
+ clip = true
+ call aclrr (Memr[DP_PKOLDRESULT(peak)], DP_PKNTERM(peak))
+ call amaxkr (Memr[DP_PKCLAMP(peak)], MAX_CLAMPFACTOR,
+ Memr[DP_PKCLAMP(peak)], DP_PKNTERM(peak))
+ } else {
+ sharp = 1.4427 * Memr[DP_PSFPARS(psffit)] *
+ Memr[DP_PSFPARS(psffit)+1] * numer / (DP_PSFHEIGHT(psffit) *
+ rel_bright * denom)
+ if (sharp <= MIN_SHARP || sharp >= MAX_SHARP)
+ sharp = INDEFR
+ break
+ }
+ }
+
+ if (iter > DP_MAXITER(dao))
+ iter = iter - 1
+ if ((errmag / rel_bright) >= wcrit)
+ return (PKERR_FAINT)
+ else
+ return (PKERR_OK)
+end
+
+
+# DP_FITBUILD -- Build the normal and vector of residuals for the fit.
+
+int procedure dp_fitbuild (dao, subim, nx, ny, radius, x, y, xfrom_psf,
+ yfrom_psf, rel_bright, sky, chiold, chi, clip, iter, clamp, normal,
+ resid, deriv, nterm, numer, denom, sum_weight)
+
+pointer dao # pointer to the DAOPHOT Structure
+real subim[nx,ny] # subimage containing star
+int nx, ny # size of the image subraster
+real radius # the fitting radius
+real x, y # initial estimate of the position
+real xfrom_psf, yfrom_psf # distance from the psf star
+real rel_bright # initial estimate of stellar brightness
+real sky # the sky value associated with this star
+real chiold # previous estimate of gof
+real chi # estimated goodness of fit parameter
+bool clip # clip the weights ?
+int iter # current iteration number
+real clamp[ARB] # clamp array
+real normal[nterm,ARB] # normal matrix
+real resid[ARB] # residual matrix
+real deriv[ARB] # derivative matrix
+int nterm # the number of terms to be fit
+real numer, denom # used in sharpness calculation
+real sum_weight # sum of the weights
+
+int i, j, ix, iy, lowx, lowy, highx, highy, npix
+pointer psffit
+real fitradsq, pererr, peakerr, datamin, datamax, read_noise
+real dx, dy, dxsq, dysq, radsq, dvdx, dvdy, d_pixval
+real pred_pixval, sigma, sigmasq, relerr, weight
+real rhosq, pixval, dfdsig
+
+real dp_usepsf()
+
+begin
+ # Get the pointer to the PSF structure.
+ psffit = DP_PSFFIT (dao)
+
+ # Set up some constants.
+ fitradsq = radius * radius
+ read_noise = (DP_READNOISE(dao) / DP_PHOTADU(dao)) ** 2
+ pererr = 0.01 * DP_FLATERR(dao)
+ peakerr = 0.01 * DP_PROFERR(dao) /
+ (Memr[DP_PSFPARS(psffit)] * Memr[DP_PSFPARS(psffit)+1])
+ if (IS_INDEFR (DP_MINGDATA(dao)))
+ datamin = -MAX_REAL
+ else
+ datamin = DP_MINGDATA(dao)
+ if (IS_INDEFR (DP_MAXGDATA(dao)))
+ datamax = MAX_REAL
+ else
+ datamax = DP_MAXGDATA(dao)
+
+ # Define the size of the subraster to be used in the fit.
+ lowx = max (1, int (x - radius))
+ lowy = max (1, int (y - radius))
+ highx = min (nx, int (x + radius) + 1)
+ highy = min (ny, int (y + radius) + 1)
+
+ npix = 0
+ do iy = lowy, highy {
+
+ dy = real (iy) - y
+ dysq = dy * dy
+
+ do ix = lowx, highx {
+
+ # Is this pixel in the good data range.
+ pixval = subim[ix,iy]
+ if (pixval < datamin || pixval > datamax)
+ next
+
+ # Is this pixel inside the fitting radius?
+ dx = real(ix) - x
+ dxsq = dx * dx
+ radsq = (dxsq + dysq) / fitradsq
+ if ((1.0 - radsq) <= PEAK_EPSILONR)
+ next
+
+ # We have a good pixel within the fitting radius.
+ deriv[1] = dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), xfrom_psf,
+ yfrom_psf, dvdx, dvdy)
+ if (((rel_bright * deriv[1] + sky) > datamax) && (iter >= 3))
+ next
+ if (DP_RECENTER(dao) == YES) {
+ deriv[2] = rel_bright * dvdx
+ deriv[3] = rel_bright * dvdy
+ }
+ if (DP_FITSKY(dao) == YES)
+ deriv[nterm] = 1.0
+
+ # Get the residual from the PSF fit and the pixel
+ # intensity as predicted by the fit
+ d_pixval = (pixval - sky) - rel_bright * deriv[1]
+ pred_pixval = max (0.0, pixval - d_pixval)
+
+ # Calculate the anticipated error in the intensity of
+ # in this pixel including READOUT noise, photon statistics
+ # and the error of interpolating within the PSF.
+
+ sigmasq = pred_pixval / DP_PHOTADU (dao) + read_noise +
+ (pererr * pred_pixval) ** 2 + (peakerr *
+ (pred_pixval - sky)) ** 2
+ if (sigmasq <= 0.0)
+ next
+ sigma = sqrt (sigmasq)
+ relerr = abs (d_pixval / sigma)
+
+ # Compute the radial wweighting function.
+ weight = 5.0 / (5.0 + radsq / (1.0 - radsq))
+
+ # Now add this pixel into the quantities which go to make
+ # up the sharpness index.
+ rhosq = dxsq / Memr[DP_PSFPARS(psffit)] ** 2 + dysq /
+ Memr[DP_PSFPARS(psffit)+1] ** 2
+
+ # Include in the sharpness calculation only those pixels
+ # which are within NCORE_SIGMASQ core-sigmasq of the
+ # centroid. This saves time and floating underflows
+ # bu excluding pixels which contribute less than one
+ # part in a million to the fit.
+
+ if (rhosq <= NCORE_SIGMASQ) {
+ rhosq = 0.6931472 * rhosq
+ dfdsig = exp (-rhosq) * (rhosq - 1.0)
+ #pred_pixval = max (0.0, pixval - sky) + sky
+ numer = numer + dfdsig * d_pixval / sigmasq
+ denom = denom + (dfdsig ** 2) / sigmasq
+ }
+
+
+ # Derive the weight of this pixel. First of all the weight
+ # depends on the distance of the pixel from the centroid of
+ # the star --- it is determined from a function which is very
+ # nearly unity for radii much smaller than the fitting radius,
+ # and which goes to zero for radii very near the fitting
+ # radius. Then reject any pixels with 10 sigma residuals
+ # after the first iteration.
+
+ chi = chi + weight * relerr
+ sum_weight = sum_weight + weight
+
+ # Now the weight is scaled to the inverse square of the
+ # expected mean error.
+
+ weight = weight / sigmasq
+
+ # Reduce the weight of a bad pixel. A pixel having a residual
+ # of 2.5 sigma gets reduced to half weight; a pixel having
+ # a residual of of 5.0 sigma gets weight 1/257.
+
+ if (clip)
+ weight = weight / (1.0 + (relerr / (DP_CLIPRANGE(dao) *
+ chiold)) ** DP_CLIPEXP(dao))
+
+ # Now add this pixel into the vector of residuals
+ # and the normal matrix.
+ do i = 1, nterm {
+ resid[i] = resid[i] + d_pixval * deriv[i] * weight
+ do j = 1, nterm {
+ normal[i,j] = normal[i,j] + deriv[i] * deriv[j] *
+ weight
+ }
+ }
+
+ npix = npix + 1
+ }
+ }
+
+ # Compute the goodness of fit index CHI. CHI is pulled toward its
+ # expected value of unity before being stored in CHIOLD to keep the
+ # statistics of a small number of pixels from dominating the error
+ # analysis.
+
+ if (sum_weight > nterm) {
+ chi = CHI_NORM * chi / sqrt (sum_weight * (sum_weight - nterm))
+ chiold = ((sum_weight - MIN_SUMWT) * chi + MIN_SUMWT) / sum_weight
+ } else {
+ chi = 1.0
+ chiold = 1.0
+ }
+
+ return (npix)
+end
diff --git a/noao/digiphot/daophot/peak/dppkwrite.x b/noao/digiphot/daophot/peak/dppkwrite.x
new file mode 100644
index 00000000..97f770bf
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dppkwrite.x
@@ -0,0 +1,365 @@
+include <tbset.h>
+include <time.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/peakdef.h"
+
+# DP_TNEWPEAK -- Create a new output PEAK ST table.
+
+procedure dp_tnewpeak (dao, tp, colpoint)
+
+pointer dao # pointer to the daophot strucuture
+pointer tp # pointer to the output table
+int colpoint[ARB] # array of column pointers
+
+int i
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for the table definition.
+ call smark (sp)
+ call salloc (colnames, PK_NOUTCOL * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, PK_NOUTCOL * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, PK_NOUTCOL * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, PK_NOUTCOL, TY_INT)
+ call salloc (col_len, PK_NOUTCOL, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (MAGERR, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+5*SZ_COLNAME+5], SZ_COLNAME)
+ call strcpy (NITER, Memc[colnames+6*SZ_COLNAME+6], SZ_COLNAME)
+ call strcpy (SHARP, Memc[colnames+7*SZ_COLNAME+7], SZ_COLNAME)
+ call strcpy (CHI, Memc[colnames+8*SZ_COLNAME+8], SZ_COLNAME)
+ call strcpy (PIER, Memc[colnames+9*SZ_COLNAME+9], SZ_COLNAME)
+ call strcpy (PERROR, Memc[colnames+10*SZ_COLNAME+10], SZ_COLNAME)
+
+ # Define the column formats.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("%14.3f", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+ call strcpy ("%15.7g", Memc[colformat+5*SZ_COLFMT+5], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+6*SZ_COLFMT+6], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+7*SZ_COLFMT+7], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+8*SZ_COLFMT+8], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+9*SZ_COLFMT+9], SZ_COLFMT)
+ call strcpy ("%13s", Memc[colformat+10*SZ_COLFMT+10], SZ_COLFMT)
+
+ # Define the column units.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+ call strcpy ("ADU", Memc[colunits+5*SZ_COLUNITS+5], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+6*SZ_COLUNITS+6], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+7*SZ_COLUNITS+7], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+8*SZ_COLUNITS+8], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+9*SZ_COLUNITS+9], SZ_COLUNITS)
+ call strcpy ("PERRORS", Memc[colunits+10*SZ_COLUNITS+10], SZ_COLUNITS)
+
+ # Define the column data types.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_REAL
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+ Memi[col_dtype+4] = TY_REAL
+ Memi[col_dtype+5] = TY_REAL
+ Memi[col_dtype+6] = TY_INT
+ Memi[col_dtype+7] = TY_REAL
+ Memi[col_dtype+8] = TY_REAL
+ Memi[col_dtype+9] = TY_INT
+ Memi[col_dtype+10] = -13
+
+ # Define the column lengths.
+ do i = 1, PK_NOUTCOL
+ Memi[col_len+i-1] = 1
+
+ # Define and create the table.
+ call tbcdef (tp, colpoint, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], PK_NOUTCOL)
+ call tbtcre (tp)
+
+ # Write out some header parameters.
+ call dp_tpeakpars (dao, tp)
+
+ call sfree (sp)
+end
+
+
+define PK_NAME1STR "#N%4tID%10tXCENTER%20tYCENTER%30tMAG%42tMERR%56tMSKY%71t\
+NITER%80t\\\n"
+define PK_UNIT1STR "#U%4t##%10tpixels%20tpixels%30tmagnitudes%42t\
+magnitudes%56tcounts%71t##%80t\\\n"
+define PK_FORMAT1STR "#F%4t%%-9d%10t%%-10.3f%20t%%-10.3f%30t%%-12.3f%42t\
+%%-14.3f%56t%%-15.7g%71t%%-6d%80t \n"
+
+define PK_NAME2STR "#N%12tSHARPNESS%24tCHI%36tPIER%42tPERROR%80t\\\n"
+define PK_UNIT2STR "#U%12t##%24t##%36t##%42tperrors%80t\\\n"
+define PK_FORMAT2STR "#F%12t%%-23.3f%24t%%-12.3f%36t%%-6d%42t%%-13s%80t \n"
+
+
+# DP_XNEWPEAK -- Create a new PEAK output text file.
+
+procedure dp_xnewpeak (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # the output file descriptor
+
+begin
+ # Write out some header parameters.
+ call dp_xpeakpars (dao, tp)
+
+ # Print out the banner file.
+ call fprintf (tp, "#\n")
+ call fprintf (tp, PK_NAME1STR)
+ call fprintf (tp, PK_UNIT1STR)
+ call fprintf (tp, PK_FORMAT1STR)
+ call fprintf (tp, "#\n")
+ call fprintf (tp, PK_NAME2STR)
+ call fprintf (tp, PK_UNIT2STR)
+ call fprintf (tp, PK_FORMAT2STR)
+ call fprintf (tp, "#\n")
+end
+
+
+# DP_TPEAKPARS -- Add parameters to the header of the PEAK ST table.
+
+procedure dp_tpeakpars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+pointer tp # pointer to the output table
+
+pointer sp, psffit, outstr, date, time
+bool itob()
+int envfind()
+
+begin
+ # Define some daophot pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IRAF", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) <= 0)
+ call tbhadt (tp, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (tp, "DATE", Memc[date])
+ call tbhadt (tp, "TIME", Memc[time])
+ call tbhadt (tp, "PACKAGE", "daophot")
+ call tbhadt (tp, "TASK", "peak")
+
+ # Write out the files names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PHOTFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSFIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PEAKFILE", Memc[outstr])
+ if (DP_OUTREJFILE(dao) == EOS)
+ call tbhadt (tp, "REJFILE", "\"\"")
+ else {
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "REJFILE", Memc[outstr])
+ }
+
+ # Define the data characteristics.
+ call tbhadr (tp, "SCALE", DP_SCALE(dao))
+ call tbhadr (tp, "DATAMIN", DP_MINGDATA(dao))
+ call tbhadr (tp, "DATAMAX", DP_MAXGDATA(dao))
+ call tbhadr (tp, "GAIN", DP_PHOTADU(dao))
+ call tbhadr (tp, "READNOISE", DP_READNOISE(dao))
+
+ # Define the observing parameters.
+ call tbhadt (tp, "OTIME", DP_OTIME(dao))
+ call tbhadr (tp, "XAIRMASS", DP_XAIRMASS(dao))
+ call tbhadt (tp, "IFILTER", DP_IFILTER(dao))
+
+ # Define the fitting parameters.
+ call tbhadb (tp, "RECENTER", itob (DP_RECENTER(dao)))
+ call tbhadb (tp, "FITSKY", itob (DP_FITSKY(dao)))
+ call tbhadr (tp, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (tp, "FITRAD", DP_SFITRAD(dao))
+ call tbhadr (tp, "PSFMAG", DP_PSFMAG(psffit))
+ call tbhadi (tp, "MAXITER", DP_MAXITER(dao))
+ call tbhadr (tp, "FLATERROR", DP_FLATERR(dao))
+ call tbhadr (tp, "PROFERROR", DP_PROFERR(dao))
+ call tbhadi (tp, "CLIPEXP", DP_CLIPEXP(dao))
+ call tbhadr (tp, "CLIPRANGE", DP_CLIPRANGE(dao))
+ #call tbhadi (tp, "MAXNSTAR", DP_MAXNSTAR(dao))
+
+ call sfree(sp)
+end
+
+
+# DP_XPEAKPARS -- Add parameters to the header of the output PEAK text file.
+
+procedure dp_xpeakpars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # the output file descriptor
+
+pointer sp, psffit, outstr, date, time
+bool itob()
+int envfind()
+
+begin
+ # Define some daophot pointers.
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the id.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IRAF", Memc[outstr], "version", "")
+ if (envfind ("userid", Memc[outstr], SZ_LINE) <= 0)
+ call dp_sparam (tp, "USER", Memc[outstr], "name", "")
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "HOST", Memc[outstr], "computer", "")
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (tp, "DATE", Memc[date], "yyyy-mm-dd", "")
+ call dp_sparam (tp, "TIME", Memc[time], "hh:mm:ss", "")
+ call dp_sparam (tp, "PACKAGE", "daophot", "name", "")
+ call dp_sparam (tp, "TASK", "peak", "name", "")
+
+ # Write out the files names.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PHOTFILE", Memc[outstr], "filename", "")
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSFIMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PEAKFILE", Memc[outstr], "filename", "")
+
+ if (DP_OUTREJFILE(dao) == EOS)
+ call dp_sparam (tp, "REJFILE", "\"\"", "filename", "")
+ else {
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "REJFILE", Memc[outstr], "filename", "")
+ }
+
+ # Define the data characteristics.
+ call dp_rparam (tp, "SCALE", DP_SCALE(dao), "units/pix", "")
+ call dp_rparam (tp, "DATAMIN", DP_MINGDATA(dao), "counts", "")
+ call dp_rparam (tp, "DATAMAX", DP_MAXGDATA(dao), "counts", "")
+ call dp_rparam (tp, "GAIN", DP_PHOTADU(dao), "e-/adu", "")
+ call dp_rparam (tp, "READNOISE", DP_READNOISE(dao), "electrons", "")
+
+ # Define the observing parameters.
+ call dp_sparam (tp, "OTIME", DP_OTIME(dao), "timeunit", "")
+ call dp_rparam (tp, "XAIRMASS", DP_XAIRMASS(dao), "number", "")
+ call dp_sparam (tp, "IFILTER", DP_IFILTER(dao), "filter", "")
+
+ # Define the fitting parameters.
+ call dp_bparam (tp, "RECENTER", itob (DP_RECENTER(dao)), "switch", "")
+ call dp_bparam (tp, "FITSKY", itob (DP_FITSKY(dao)), "switch", "")
+ call dp_rparam (tp, "PSFRAD", DP_SPSFRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "FITRAD", DP_SFITRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "PSFMAG", DP_PSFMAG(psffit), "magnitudes", "")
+ call dp_iparam (tp, "MAXITER", DP_MAXITER(dao), "number", "")
+ call dp_rparam (tp, "FLATERROR", DP_FLATERR(dao), "percentage", "")
+ call dp_rparam (tp, "PROFERROR", DP_PROFERR(dao), "percentage", "")
+ call dp_iparam (tp, "CLIPEXP", DP_CLIPEXP(dao), "number", "")
+ call dp_rparam (tp, "CLIPRANGE", DP_CLIPRANGE(dao), "sigma", "")
+ #call dp_iparam (tp, "MAXNSTAR", DP_MAXNSTAR(dao), "number", "")
+
+ call sfree(sp)
+end
+
+
+# DP_TPKWRITE -- Write the output photometry record to a PEAK ST table.
+
+procedure dp_tpkwrite (tpout, colpoint, id, x, y, mag, errmag, sky, niter, chi,
+ sharp, pier, perror, plen, star)
+
+pointer tpout # pointer to the output table
+int colpoint[ARB] # array of column pointers
+int id # id of the star
+real x, y # position of the star
+real mag # magnitude of the star
+real errmag # error magnitude of the star
+real sky # value of sky
+int niter # number of iterations
+real chi # chi squared value
+real sharp # sharpness characteristic
+int pier # the error code
+char perror[ARB] # the error string
+int plen # the length of the error code string
+int star # row number
+
+begin
+ call tbrpti (tpout, colpoint[1], id, 1, star)
+ call tbrptr (tpout, colpoint[2], x, 1, star)
+ call tbrptr (tpout, colpoint[3], y, 1, star)
+ call tbrptr (tpout, colpoint[4], mag, 1, star)
+ call tbrptr (tpout, colpoint[5], errmag, 1, star)
+ call tbrptr (tpout, colpoint[6], sky, 1, star)
+ call tbrpti (tpout, colpoint[7], niter, 1, star)
+ call tbrptr (tpout, colpoint[8], sharp, 1, star)
+ call tbrptr (tpout, colpoint[9], chi, 1, star)
+ call tbrpti (tpout, colpoint[10], pier, 1, star)
+ call tbrptt (tpout, colpoint[11], perror, plen, 1, star)
+end
+
+
+define PK_DATA1STR "%-9d%10t%-10.3f%20t%-10.3f%30t%-12.3f%42t%-14.3f%56t\
+%-15.7g%71t%-6d%80t\\\n"
+define PK_DATA2STR "%12t%-12.3f%24t%-12.3f%36t%-6d%42t%-13.13s%80t \n"
+
+# DP_XPKWRITE -- Write the output photometry record to a PEAK text file.
+
+procedure dp_xpkwrite (tpout, id, x, y, mag, errmag, sky, niter, chi, sharp,
+ pier, perror, plen)
+
+int tpout # the output file descriptor
+int id # id of the star
+real x, y # position of the star
+real mag # magnitude of the star
+real errmag # error magnitude of the star
+real sky # value of sky
+int niter # number of iterations
+real chi # chi squared value
+real sharp # sharpness characteristic
+int pier # the error code
+char perror[ARB] # the error string
+int plen # the length of the error code string
+
+begin
+ call fprintf (tpout, PK_DATA1STR)
+ call pargi (id)
+ call pargr (x)
+ call pargr (y)
+ call pargr (mag)
+ call pargr (errmag)
+ call pargr (sky)
+ call pargi (niter)
+ call fprintf (tpout, PK_DATA2STR)
+ call pargr (sharp)
+ call pargr (chi)
+ call pargi (pier)
+ call pargstr (perror)
+end
diff --git a/noao/digiphot/daophot/peak/dprrphot.x b/noao/digiphot/daophot/peak/dprrphot.x
new file mode 100644
index 00000000..36aed88f
--- /dev/null
+++ b/noao/digiphot/daophot/peak/dprrphot.x
@@ -0,0 +1,98 @@
+include "../lib/apseldef.h"
+
+# DP_TPKINIT -- Procedure to initialize for reading the "standard" fields from
+# a photometry table. The "standard" fields being ID, X, Y, MAG, ERR, and SKY
+
+procedure dp_tpkinit (tp, colpoint)
+
+pointer tp # the table descriptor
+pointer colpoint[ARB] # the column descriptor
+
+begin
+ # Get the results one by one
+ # First the ID
+ call tbcfnd (tp, ID, colpoint[1], 1)
+ if (colpoint[1] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (ID)
+ }
+
+ # Then the position
+ call tbcfnd (tp, XCENTER, colpoint[2], 1)
+ if (colpoint[2] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (XCENTER)
+ }
+
+ call tbcfnd (tp, YCENTER, colpoint[3], 1)
+ if (colpoint[3] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (YCENTER)
+ }
+
+ # Now the Magnitude
+ call tbcfnd (tp, MAG, colpoint[4], 1)
+ if (colpoint[4] == NULL) # No column
+ call tbcfnd (tp, APMAG, colpoint[4], 1)
+ if (colpoint[4] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (APMAG)
+ }
+
+ # The sky
+ call tbcfnd (tp, SKY, colpoint[5], 1)
+ if (colpoint[5] == NULL)
+ call tbcfnd (tp, SKY, colpoint[5], 1)
+ if (colpoint[5] == NULL) {
+ call eprintf ("Column %s not found\n")
+ call pargstr (SKY)
+ }
+end
+
+
+# DP_RRPHOT -- Fetch the photometry for a single star from either a
+# table or a text photometry file.
+
+int procedure dp_rrphot (tp, key, fields, indices, id, x, y, sky, mag,
+ instar, nrow)
+
+int tp # the input file descriptor
+pointer key # pointer to text apphot structure
+char fields[ARB] # character fields
+int indices[ARB] # columns pointers
+int id # star id
+real x # x center value
+real y # y center value
+real sky # sky value
+real mag # magnitude
+int instar # current record
+int nrow # maximum number of rows for ST table
+
+bool nullflag
+int nrec
+int dp_apsel()
+
+begin
+ # If nrow is 0 the file file is a text file otherwise it is a table.
+
+ if (nrow == 0) {
+
+ nrec = dp_apsel (key, tp, fields, indices, id, x, y, sky, mag)
+ if (nrec != EOF)
+ instar = instar + 1
+
+ } else if ((instar + 1) <= nrow) {
+
+ instar = instar + 1
+ call tbrgti (tp, indices[1], id, nullflag, 1, instar)
+ call tbrgtr (tp, indices[2], x, nullflag, 1, instar)
+ call tbrgtr (tp, indices[3], y, nullflag, 1, instar)
+ call tbrgtr (tp, indices[4], mag, nullflag, 1, instar)
+ call tbrgtr (tp, indices[5], sky, nullflag, 1, instar)
+ nrec = instar
+
+ } else
+ nrec = EOF
+
+ return (nrec)
+end
diff --git a/noao/digiphot/daophot/peak/mkpkg b/noao/digiphot/daophot/peak/mkpkg
new file mode 100644
index 00000000..f3570728
--- /dev/null
+++ b/noao/digiphot/daophot/peak/mkpkg
@@ -0,0 +1,22 @@
+# PEAK task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpmempk.x ../lib/daophotdef.h ../lib/peakdef.h
+ dppeakphot.x <imhdr.h> <tbset.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/peakdef.h
+ dppkconfirm.x
+ dppkfit.x <mach.h> ../lib/daophotdef.h \
+ ../lib/peakdef.h
+ dppkwrite.x <tbset.h> <time.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/peakdef.h
+ dprrphot.x ../lib/apseldef.h
+ t_peak.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/peak/t_peak.x b/noao/digiphot/daophot/peak/t_peak.x
new file mode 100644
index 00000000..2022fe16
--- /dev/null
+++ b/noao/digiphot/daophot/peak/t_peak.x
@@ -0,0 +1,299 @@
+include <fset.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# T_PEAK -- Procedure to fit the PSF to single stars.
+
+procedure t_peak ()
+
+pointer image # name of the image
+pointer photfile # input photometry file
+pointer psfimage # the PSF image
+pointer peakfile # output PEAK photometry file
+pointer rejfile # output PEAK rejections file
+
+pointer sp, im, psfim, outfname, dao, str
+int apd, root, verbose, verify, cache, update, pkfd, rejfd
+int imlist, limlist, alist, lalist, pimlist, lpimlist, olist, lolist
+int rlist, lrlist, wcs, req_size, old_size, buf_size, memstat
+bool ap_text
+
+pointer immap(), tbtopn()
+int open(), fnldir(), strlen(), strncmp(), fstati(), btoi()
+int access(), imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb()
+int fntgfnb(), clgwrd(), sizeof(), dp_memstat()
+bool clgetb(), itob()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (peakfile, SZ_FNAME, TY_CHAR)
+ call salloc (rejfile, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("peakfile", Memc[peakfile], SZ_FNAME)
+ call clgstr ("rejfile", Memc[rejfile], SZ_FNAME)
+ verbose = btoi (clgetb ("verbose"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb ("cache"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[photfile], NO)
+ lalist = fntlenb (alist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ olist = fntopnb (Memc[peakfile], NO)
+ lolist = fntlenb (olist)
+ rlist = fntopnb (Memc[rejfile], NO)
+ lrlist = fntlenb (rlist)
+
+ # Test that the lengths of the photometry file, psf image, and
+ # output file lists are the same as the length of the input image
+ # list.
+
+ if ((limlist != lalist) && (strncmp (Memc[photfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and input photometry file list lengths")
+ }
+
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and psf image list lengths")
+ }
+
+ if ((limlist != lolist) && (strncmp (Memc[peakfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and output photometry file list lengths")
+ }
+
+ if ((lrlist != 0) && (limlist != lolist) && (strncmp (Memc[rejfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and rejections file list lengths")
+ }
+
+ # Initialize the DAOPHOT structure, and get the pset parameters.
+ call dp_gppars (dao)
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Verify the standard algorithm parameters.
+ if (verify == YES) {
+ call dp_pkconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Initialize the PEAK structure.
+ call dp_pksetup (dao)
+
+ # Loop over the list of images.
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open the image.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ # Open the input photometry file.
+ if (fntgfnb (alist, Memc[photfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[photfile], SZ_FNAME)
+ root = fnldir (Memc[photfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[photfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[photfile]))
+ call dp_inname (Memc[image], Memc[outfname], "mag",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[photfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ apd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ apd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Read in the PSF function.
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage]))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ psfim = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_readpsf (dao, psfim)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+
+ # Open the output photometry file. If the output is "default",
+ # dir$default or a directory specification then the extension .pk
+ # is added to the image name and a suitable version number is
+ # appended to the output name.
+
+ if (fntgfnb (olist, Memc[peakfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[peakfile], SZ_FNAME)
+ root = fnldir (Memc[peakfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[peakfile + root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[peakfile]))
+ call dp_outname (Memc[image], Memc[outfname], "pk",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[peakfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ pkfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ pkfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ # Open the output rejections file if any are defined. If the
+ # output is "default", dir$default or a directory specification
+ # then the extension .prj is added to the image name and a
+ # suitable version number is appended to the output file name.
+
+ if (lrlist <= 0) {
+ rejfd = NULL
+ Memc[outfname] = EOS
+ } else {
+ if (fntgfnb (rlist, Memc[rejfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[rejfile], SZ_FNAME)
+ root = fnldir (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[rejfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[rejfile]))
+ call dp_outname (Memc[image], Memc[outfname], "prj",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[rejfile], Memc[outfname], SZ_FNAME)
+ if (DP_TEXT(dao) == YES)
+ rejfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ rejfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ }
+ call dp_sets (dao, OUTREJFILE, Memc[outfname])
+
+ # Now go and do the PSF fitting.
+ call dp_peakphot (dao, im, apd, pkfd, rejfd, ap_text)
+
+ # Close the input image.
+ call imunmap (im)
+
+ # Close the input photometry file.
+ if (ap_text)
+ call close (apd)
+ else
+ call tbtclo (apd)
+
+ # Close the PSF image.
+ call imunmap (psfim)
+
+ # Close the output photometry file.
+ if (DP_TEXT(dao) == YES)
+ call close (pkfd)
+ else
+ call tbtclo (pkfd)
+
+ # Close the output rejections file.
+ if (rejfd != NULL) {
+ if (DP_TEXT(dao) == YES)
+ call close (rejfd)
+ else
+ call tbtclo (rejfd)
+ }
+
+ # Uncache memory.
+ call fixmem (old_size)
+
+ }
+
+ # Close the image/file lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (rlist)
+
+ # Free the PEAK structure.
+ call dp_pkclose (dao)
+
+ # Free the PSF structure.
+ call dp_fitclose (dao)
+
+ # Free the daophot structure.
+ call dp_free (dao)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/pexamine.par b/noao/digiphot/daophot/pexamine.par
new file mode 100644
index 00000000..7b3d133a
--- /dev/null
+++ b/noao/digiphot/daophot/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"
+first_star,i,h,1,1,,First star in the catalog to load
+max_nstars,i,h,10000,1,,Maximum number of stars to load
+use_display,b,h,yes,,,Use the image display?
+match_radius,r,h,2.0,,,Matching radius for positional coincidence on display
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor [x y wcs] key [cmd]"
+graphics,s,h,)_.graphics,,,The graphics device
diff --git a/noao/digiphot/daophot/pfmerge.par b/noao/digiphot/daophot/pfmerge.par
new file mode 100644
index 00000000..90ef9507
--- /dev/null
+++ b/noao/digiphot/daophot/pfmerge.par
@@ -0,0 +1,6 @@
+# Parameters for the PFMERGE task
+
+inphotfiles,f,a,,,,"List of input photometry files to be merged"
+outphotfile,f,a,,,,"Output photometry file"
+verbose,b,h,)_.verbose,,,Print pfmerge messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/phot.par b/noao/digiphot/daophot/phot.par
new file mode 100644
index 00000000..99f1896d
--- /dev/null
+++ b/noao/digiphot/daophot/phot.par
@@ -0,0 +1,24 @@
+# PHOT parameters
+
+image,f,a,,,,"Input image(s)"
+coords,f,a,"default",,,"Input coordinate list(s) (default: image.coo.?)"
+output,f,a,"default",,,"Output photometry file(s) (default: image.mag.?)"
+skyfile,f,a,"",,,"Input sky value file(s)"
+plotfile,f,h,"",,,"Output plot metacode file"
+datapars,pset,h,"",,,"Data dependent parameters"
+centerpars,pset,h,"",,,"Centering parameters"
+fitskypars,pset,h,"",,,"Sky fitting parameters"
+photpars,pset,h,"",,,"Photometry parameters"
+interactive,b,h,no,,,"Interactive mode?"
+radplots,b,h,no,,,Plot the radial profiles?
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor: [x y wcs] key [cmd]"
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,"Verify critical phot parameters?"
+update,b,h,)_.update,,,"Update critical phot parameters?"
+verbose,b,h,)_.verbose,,,"Print phot messages?"
+graphics,s,h,)_.graphics,,,"Graphics device"
+display,s,h,)_.display,,,"Display device"
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/photpars.par b/noao/digiphot/daophot/photpars.par
new file mode 100644
index 00000000..bf25672c
--- /dev/null
+++ b/noao/digiphot/daophot/photpars.par
@@ -0,0 +1,7 @@
+# PHOTPARS Parameter File
+
+weighting,s,h,constant,"|constant|",,Photometric weighting scheme
+apertures,s,h,"3.",,,List of aperture radii in scale units
+zmag,r,h,25.,,,Zero point of magnitude scale
+mkapert,b,h,no,,,Draw apertures on the display
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/psf.par b/noao/digiphot/daophot/psf.par
new file mode 100644
index 00000000..888dbeb9
--- /dev/null
+++ b/noao/digiphot/daophot/psf.par
@@ -0,0 +1,27 @@
+# Parameters for the PSF task
+
+image,f,a,,,,"Input image(s) for which to build PSF"
+photfile,f,a,default,,,"Input photometry file(s) (default: image.mag.?)"
+pstfile,f,a,"",,,"Input psf star list(s) (default: image.pst.?)"
+psfimage,f,a,default,,,"Output PSF image(s) (default: image.psf.?)"
+opstfile,f,a,default,,,"Output PSF star list(s) (default: image.pst.?)"
+groupfile,f,a,default,,,"Output PSF star group file(s) (default: image.psg.?)"
+plotfile,f,h,"",,,"Output plot metacode file"
+datapars,pset,h,"",,,"Data dependent parameters"
+daopars,pset,h,"",,,"Psf fitting parameters"
+matchbyid,b,h,yes,,,"Match psf star list to photometry file(s) by id number?"
+interactive,b,h,yes,,,"Compute the psf interactively?"
+mkstars,b,h,no,,,"Mark deleted and accepted psf stars?"
+showplots,b,h,yes,,,"Show plots of PSF stars?"
+plottype,s,h,"mesh","|mesh|contour|radial|",,"Default plot type (mesh|contour|radial)"
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor: [x y wcs] key [cmd]"
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,"Verify critical psf parameters?"
+update,b,h,)_.update,,,"Update critical psf parameters?"
+verbose,b,h,)_.verbose,,,"Print psf messages?"
+graphics,s,h,)_.graphics,,,"Graphics device"
+display,s,h,)_.display,,,"Display device"
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/psf/README b/noao/digiphot/daophot/psf/README
new file mode 100644
index 00000000..4d390489
--- /dev/null
+++ b/noao/digiphot/daophot/psf/README
@@ -0,0 +1,2 @@
+This directory contains the routines for making up the PSF to be used by
+the fitting routines in the PSF.
diff --git a/noao/digiphot/daophot/psf/dpaddstar.x b/noao/digiphot/daophot/psf/dpaddstar.x
new file mode 100644
index 00000000..c723a2b3
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpaddstar.x
@@ -0,0 +1,188 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_ADDSTAR -- Add the star at the given position to the PSF if it exists and
+# passes the selection criteria.
+
+int procedure dp_addstar (dao, im, x, y, mag, idnum, gd, mgd, showplots)
+
+pointer dao # pointer to daophot structure
+pointer im # pointer to image
+real x, y # position of proposed PSF star
+real mag # mag of proposed PSF star
+int idnum # id number of desired star
+pointer gd # pointer to the graphics stream
+pointer mgd # pointer to the metacode descriptor
+bool showplots # show plots?
+
+real tx, ty, logood, higood
+pointer srim
+int x1, x2, y1, y2, starnum, saturated
+bool star_ok
+
+real dp_statr(), dp_pstatr()
+pointer dp_psubrast()
+int dp_locstar(), dp_idstar(), dp_stati(), dp_pstati()
+
+begin
+ # Convert coordinates for display.
+ if (showplots)
+ call dp_ltov (im, x, y, tx, ty, 1)
+ else
+ call dp_wout (dao, im, x, y, tx, ty, 1)
+
+ # Check that the position of the star is within the image.
+ if (idnum == 0 && (x < 1.0 || x > real (IM_LEN(im,1)) || y < 1.0 || y >
+ real (IM_LEN(im,2)))) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star at %g,%g is outside the image\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ return (ERR)
+ }
+
+ # Find the star in the aperture photometry list
+ if (idnum == 0)
+ starnum = dp_locstar (dao, im, x, y)
+ else
+ starnum = dp_idstar (dao, im, idnum)
+ if (starnum == 0) {
+ if (DP_VERBOSE(dao) == YES) {
+ if (idnum > 0) {
+ call printf ("Star %d not found in the photometry file\n")
+ call pargi (idnum)
+ } else {
+ call printf (
+ "Star at %g,%g not found in the photometry file\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ }
+ return (ERR)
+ } else if (starnum < 0) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Star %d is too near the edge of the image\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ } else if (starnum <= dp_pstati (dao, PNUM)) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d is already a PSF star\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Check for INDEF valued sky.
+ if (IS_INDEFR (dp_pstatr (dao, CUR_PSFSKY))) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d has an undefined sky value\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+
+ logood = dp_statr (dao, MINGDATA)
+ if (IS_INDEFR(logood))
+ logood = -MAX_REAL
+ higood = dp_statr (dao, MAXGDATA)
+ if (IS_INDEFR(higood))
+ higood = MAX_REAL
+
+ # Get the data subraster, check for saturation and bad pixels,
+ # and compute the min and max data values inside the subraster.
+ srim = dp_psubrast (dao, im, logood, higood, x1, x2, y1, y2, saturated)
+ if (srim == NULL) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Star %d has low bad pixels inside fitrad\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Check for saturation.
+ if (saturated == YES && dp_stati (dao, SATURATED) == NO) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Star %d has high bad pixels inside fitrad\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ call mfree (srim, TY_REAL)
+ return (ERR)
+ }
+
+ # Now let's look at the extracted subraster.
+ if (showplots) {
+ call dp_showpsf (dao, im, Memr[srim], (x2 - x1 + 1), (y2 - y1 + 1),
+ x1, y1, gd, star_ok)
+ } else if (saturated == YES) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Warning: Star %d contains high bad pixels inside fitrad\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ star_ok = true
+ } else if (dp_pstatr (dao, CUR_PSFMIN) < logood || dp_pstatr (dao,
+ CUR_PSFMAX) > higood) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Warning: Star %d contains bad pixels outside fitrad\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ star_ok = true
+ } else
+ star_ok = true
+
+ # The star is rejected by the user.
+ if (! star_ok) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d rejected by user\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ call mfree (srim, TY_REAL)
+ return (ERR)
+ }
+
+ # Save the plot in the metacode file.
+ if (mgd != NULL)
+ call dp_plotpsf (dao, im, Memr[srim], (x2 - x1 + 1), (y2 - y1 + 1),
+ x1, y1, mgd)
+
+ # Add the star to the PSF star list by swapping its position with the
+ # position of the star currently in PNUM + 1.
+ call dp_aplswap (dao, dp_pstati (dao, CUR_PSF), dp_pstati (dao,
+ PNUM) + 1)
+
+ # Increment the number of psf stars.
+ call dp_pseti (dao, PNUM, dp_pstati (dao, PNUM) + 1)
+
+ # Reallocate the fitting array space.
+ call dp_lmempsf (dao)
+
+ # Enter the new initial values.
+ call dp_xyhpsf (dao, dp_pstati (dao, PNUM), mag, saturated)
+
+ # Print message.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d has been added to the PSF star list\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ call dp_ltov (im, dp_pstatr (dao, CUR_PSFX),
+ dp_pstatr(dao, CUR_PSFY), tx, ty, 1)
+ call printf (
+ "\tX: %7.2f Y: %7.2f Mag: %7.3f Dmin: %g Dmax: %g\n")
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (dp_pstatr (dao, CUR_PSFMAG))
+ call pargr (dp_pstatr (dao, CUR_PSFMIN))
+ call pargr (dp_pstatr (dao, CUR_PSFMAX))
+ }
+
+ call mfree (srim, TY_REAL)
+ return (OK)
+end
diff --git a/noao/digiphot/daophot/psf/dpcontpsf.x b/noao/digiphot/daophot/psf/dpcontpsf.x
new file mode 100644
index 00000000..27b6bdfc
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpcontpsf.x
@@ -0,0 +1,449 @@
+include <error.h>
+include <mach.h>
+include <gset.h>
+include <config.h>
+include <xwhen.h>
+include <fset.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+define DUMMY 6
+define XCEN 0.5
+define YCEN 0.52
+define EDGE1 0.1
+define EDGE2 0.93
+define SZ_LABEL 10
+define SZ_FMT 20
+
+# DP_CONTPSF -- Draw a contour plot of a data subraster containing. The
+# data floor and ceiling are set by the user, but the contour interval
+# is chosen by the routine.
+
+procedure dp_contpsf (dao, subras, ncols, nlines, title, gp)
+
+pointer dao # pointer to DAOPHOT structure
+real subras[ncols,nlines] # data subraster
+int ncols, nlines # dimesnions of subraster
+char title[ARB] # title string
+pointer gp # pointer to graphics descriptor
+
+bool perimeter
+char system_id[SZ_LINE], label[SZ_LINE]
+int epa, status, old_onint, tcojmp[LEN_JUMPBUF]
+int wkid, nset, ncontours, dashpat, nhi
+pointer sp, temp, psf
+real interval, floor, ceiling, zero, finc, ybot
+real vx1, vx2, vy1, vy2, wx1, wx2, wy1, wy2
+real first_col, last_col, first_row, last_row
+
+bool fp_equalr()
+extern dp_conint()
+common /tcocom/ tcojmp
+
+int first
+int isizel, isizem, isizep, nrep, ncrt, ilab, nulbll, ioffd
+int ioffm, isolid, nla, nlm
+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
+ # Get the pointer to the DAOPHOT PSF fitting substructure.
+ psf = DP_PSF (dao)
+
+ # First of all, intialize conrec's block data before altering any
+ # parameters in common.
+ first = 1
+ call conbd
+
+ # Set local variables.
+ zero = 0.0
+ floor = DP_CFLOOR (psf)
+ ceiling = DP_CCEILING (psf)
+ nhi = -1
+ dashpat = 528
+
+ # Suppress the contour labelling by setting the common
+ # parameter "ilab" to zero.
+ ilab = 0
+
+ # The floor and ceiling are in absolute units, but the zero shift is
+ # applied first, so correct the numbers for the zero shift. Zero is
+ # a special number for the floor and ceiling, so do not change value
+ # if set to zero.
+
+ if (abs (floor) > EPSILON)
+ floor = floor - zero
+ if (abs (ceiling) > EPSILON)
+ ceiling = ceiling - zero
+
+ # User can specify either the number of contours or the contour
+ # interval, or let conrec pick a nice number. Set ncontours to 0
+ # and encode the FINC param expected by conrec.
+
+ ncontours = 0
+ if (ncontours <= 0) {
+ interval = 0
+ if (interval <= 0)
+ finc = 0
+ else
+ finc = interval
+ } else
+ finc = - abs (ncontours)
+
+ # Make a copy of the data and do the contouring on this.
+ call smark (sp)
+ call salloc (temp, ncols * nlines, TY_REAL)
+ call amovr (subras, Memr[temp], nlines * ncols)
+
+ first_col = 1.0
+ last_col = real (ncols)
+ first_row = 1.0
+ last_row = real (nlines)
+
+ # Apply the zero point shift.
+ if (abs (zero) > EPSILON)
+ call asubkr (Memr[temp], zero, Memr[temp], ncols * nlines)
+
+ # Open device and make contour plot.
+ call gopks (STDERR)
+ wkid = 1
+ call gclear (gp)
+ call gopwk (wkid, DUMMY, gp)
+ call gacwk (wkid)
+
+ # The viewport can be set by the user. If not, the viewport is
+ # assumed to be centered on the device. In either case, the
+ # viewport to window mapping is established in dp_map_viewport
+ # and conrec's automatic mapping scheme is avoided by setting nset=1.
+ vx1 = 0.10
+ vx2 = 0.90
+ vy1 = 0.10
+ vy2 = 0.90
+ call dp_map_viewport (gp, ncols, nlines, vx1, vx2, vy1, vy2, false)
+ nset = 1
+
+ perimeter = TRUE
+ if (perimeter)
+ # Suppress conrec's plot label generation.
+ ioffm = 1
+ else {
+ # Draw plain old conrec perimeter, set ioffm = 0 to enable label.
+ ioffm = 0
+ call perim (ncols - 1, 1, nlines - 1, 1)
+ }
+
+ # Install interrupt exception handler.
+ call zlocpr (dp_conint, epa)
+ call xwhen (X_INT, epa, old_onint)
+
+ # Make the contour plot. If an interrupt occurs ZSVJMP is reeentered
+ # with an error status.
+ call zsvjmp (tcojmp, status)
+ if (status == OK) {
+ call conrec (Memr[temp], ncols, ncols, nlines, floor, ceiling,
+ finc, nset, nhi, -dashpat)
+ } else {
+ call gcancel (gp)
+ call fseti (STDOUT, F_CANCEL, OK)
+ }
+
+ # Now find window and output text string title. The window is
+ # set to the full image coordinates for labelling.
+ call gswind (gp, first_col, last_col, first_row, last_row)
+ if (perimeter)
+ call dp_cperimeter (gp)
+
+ call ggview (gp, wx1, wx2, wy1, wy2)
+ call gseti (gp, G_WCS, 0)
+ ybot = min (wy2 + .06, 0.99)
+ call gtext (gp, (wx1 + wx2) / 2.0, ybot, title, "h=c;v=t;f=b;s=.7")
+
+ # Add system id banner to plot.
+ call gseti (gp, G_CLIP, NO)
+ call sysid (system_id, SZ_LINE)
+ ybot = max (wy1 - 0.08, 0.01)
+ call gtext (gp, (wx1+wx2)/2.0, ybot, system_id, "h=c;v=b;s=.5")
+
+ if (perimeter) {
+ if (fp_equalr (hold(5), 1.0)) {
+ call sprintf (label, SZ_LINE,
+ "contoured from %g to %g, interval = %g")
+ call pargr (hold(1))
+ call pargr (hold(2))
+ call pargr (hold(3))
+ } else {
+ call sprintf (label, SZ_LINE,
+ "contoured from %g to %g, interval = %g, labels scaled by %g")
+ call pargr (hold(1))
+ call pargr (hold(2))
+ call pargr (hold(3))
+ call pargr (hold(5))
+ }
+ ybot = max (wy1 - 0.06, .03)
+ call gtext (gp, (wx1 + wx2) / 2.0, ybot, label, "h=c;v=b;s=.6")
+ }
+
+ call gswind (gp, first_col, last_col, first_row, last_row)
+ call gdawk (wkid)
+ call gclks ()
+ call sfree (sp)
+end
+
+
+# DP_CONINT -- Interrupt handler for the task contour. Branches back to
+# ZSVJMP in the main routine to permit shutdown without an error message.
+
+procedure dp_conint (vex, next_handler)
+
+int vex # virtual exception
+int next_handler # not used
+
+int tcojmp[LEN_JUMPBUF]
+common /tcocom/ tcojmp
+
+begin
+ call xer_reset()
+ call zdojmp (tcojmp, vex)
+end
+
+
+# DP_CPERIMETER -- draw and annotate the axes drawn around the perimeter
+# of the image pixels. The viewport and window have been set by
+# the calling procedure. Plotting is done in window coordinates.
+# This procedure is called by both crtpict and the ncar plotting routines
+# contour and hafton.
+
+procedure dp_cperimeter (gp)
+
+pointer gp # graphics descriptor
+real xs, xe, ys, ye # WCS coordinates of pixel window
+
+char label[SZ_LABEL], fmt1[SZ_FMT], fmt2[SZ_FMT], fmt3[SZ_FMT], fmt4[SZ_FMT]
+int i, first_col, last_col, first_tick, last_tick, bias
+int nchar, first_row, last_row, cnt_step, cnt_label
+real dist, kk, col, row, dx, dy, sz_char, cw, xsz, label_pos
+real xdist, ydist, xspace, yspace, k[3]
+bool ggetb()
+int itoc()
+real ggetr()
+data k/1.0,2.0,3.0/
+errchk ggwind, gseti, gctran, gline, gtext, itoc
+
+begin
+ # First, get window coordinates and turn off clipping.
+ call ggwind (gp, xs, xe, ys, ye)
+ call gseti (gp, G_CLIP, NO)
+
+ # A readable character width seems to be about 1.mm. A readable
+ # perimeter seperation seems to be about .80mm. If the physical
+ # size of the output device is contained in the graphcap file, the
+ # NDC sizes of these measurements can be determined. If not,
+ # the separation between perimeter axes equals one quarter character
+ # width or one quarter percent of frame, which ever is larger, and
+ # the character size is set to 0.40.
+
+ cw = max (ggetr (gp, "cw"), 0.01)
+ if (ggetb (gp, "xs")) {
+ xsz = ggetr (gp, "xs")
+ dist = .80 / (xsz * 1000.)
+ sz_char = dist / cw
+ } else {
+ # Get character width and calculate perimeter separation.
+ dist = cw * 0.25
+ sz_char = 0.40
+ }
+
+ # Convert distance to user coordinates.
+ call ggscale (gp, xs, ys, dx, dy)
+ xdist = dist * dx
+ ydist = dist * dy
+
+ # Generate four possible format strings for gtext.
+ call sprintf (fmt1, SZ_LINE, "h=c;v=t;s=%.2f")
+ call pargr (sz_char)
+ call sprintf (fmt2, SZ_LINE, "h=c;v=b;s=%.2f")
+ call pargr (sz_char)
+ call sprintf (fmt3, SZ_LINE, "h=r;v=c;s=%.2f")
+ call pargr (sz_char)
+ call sprintf (fmt4, SZ_LINE, "h=l;v=c;s=%.2f")
+ call pargr (sz_char)
+
+ # Draw inner and outer perimeter
+ kk = k[1]
+ do i = 1, 2 {
+ xspace = kk * xdist
+ yspace = kk * ydist
+ call gline (gp, xs - xspace, ys - yspace, xe + xspace, ys - yspace)
+ call gline (gp, xe + xspace, ys - yspace, xe + xspace, ye + yspace)
+ call gline (gp, xe + xspace, ye + yspace, xs - xspace, ye + yspace)
+ call gline (gp, xs - xspace, ye + yspace, xs - xspace, ys - yspace)
+ kk = k[2]
+ }
+
+ # Now draw x axis tick marks, along both the bottom and top of
+ # the picture. First find the endpoint integer pixels.
+
+ first_col = int (xs)
+ last_col = int (xe)
+
+ # Determine increments of ticks and tick labels for x axis.
+ cnt_step = 1
+ cnt_label = 10
+ if (last_col - first_col > 256) {
+ cnt_step = 10
+ cnt_label = 100
+ } else if (last_col - first_col < 26) {
+ cnt_step = 1
+ cnt_label = 1
+ }
+
+ first_tick = first_col
+ bias = mod (first_tick, cnt_step)
+ last_tick = last_col + bias
+
+ do i = first_tick, last_tick, cnt_step {
+ col = real (i - bias)
+ call gline (gp, col, ys - k[1] * ydist, col, ys - k[2] * ydist)
+ call gline (gp, col, ye + k[1] * ydist, col, ye + k[2] * ydist)
+
+ if (mod ((i - bias), cnt_label) == 0) {
+
+ # Label tick mark; calculate number of characters needed.
+ nchar = 3
+ if (int (col) == 0)
+ nchar = 1
+ if (int (col) >= 1000)
+ nchar = 4
+ if (itoc (int(col), label, nchar) <= 0)
+ label[1] = EOS
+
+ # Position label slightly below outer perimeter. Seperation
+ # is twenty percent of a character width, in WCS.
+ label_pos = ys - (k[2] * ydist + (cw * 0.20 * dy))
+ call gtext (gp, col, label_pos, label, fmt1)
+
+ # Position label slightly above outer perimeter.
+ label_pos = ye + (k[2] * ydist + (cw * 0.20 * dy))
+ call gtext (gp, col, label_pos, label, fmt2)
+ }
+ }
+
+ # Label the y axis tick marks along the left and right sides of the
+ # picture. First find the integer pixel endpoints.
+
+ first_row = int (ys)
+ last_row = int (ye)
+
+ # Determine increments of ticks and tick labels for y axis.
+ cnt_step = 1
+ cnt_label = 10
+ if (last_row - first_row > 256) {
+ cnt_step = 10
+ cnt_label = 100
+ } else if (last_row - first_row < 26) {
+ cnt_step = 1
+ cnt_label = 1
+ }
+
+ first_tick = first_row
+ bias = mod (first_tick, cnt_step)
+ last_tick = last_row + bias
+
+ do i = first_tick, last_tick, cnt_step {
+ row = real (i - bias)
+ call gline (gp, xs - k[1] * xdist, row, xs - k[2] * xdist, row)
+ call gline (gp, xe + k[1] * xdist, row, xe + k[2] * xdist, row)
+
+ if (mod ((i - bias), cnt_label) == 0) {
+
+ # Label tick mark; calculate number of characters needed
+ nchar = 3
+ if (int (row) == 0)
+ nchar = 1
+ else if (int (row) >= 1000)
+ nchar = 4
+ if (itoc (int(row), label, nchar) <= 0)
+ label[1] = EOS
+
+ # Position label slightly to the left of outer perimeter.
+ # Separation twenty percent of a character width, in WCS.
+ label_pos = xs - (k[2] * xdist + (cw * 0.20 * dx))
+ call gtext (gp, label_pos, row, label, fmt3)
+
+ # Position label slightly to the right of outer perimeter.
+ label_pos = xe + (k[2] * xdist + (cw * 0.20 * dx))
+ call gtext (gp, label_pos, row, label, fmt4)
+ }
+ }
+end
+
+
+# DP_MAP_VIEWPORT -- Set device viewport for contour and hafton plots. If not
+# specified by user, a default viewport centered on the device is used.
+
+procedure dp_map_viewport (gp, ncols, nlines, ux1, ux2, uy1, uy2, fill)
+
+pointer gp # graphics pointer
+int ncols # number of image cols
+int nlines # number of image lines
+real ux1, ux2, uy1, uy2 # NDC coordinates of requested viewort
+bool fill # fill viewport (vs enforce unity aspect ratio?)
+
+real ncolsr, nlinesr, ratio, aspect_ratio
+real x1, x2, y1, y2, ext, xdis, ydis
+data ext /0.25/
+bool fp_equalr()
+real ggetr()
+
+begin
+ ncolsr = real (ncols)
+ nlinesr = real (nlines)
+ if (fp_equalr (ux1, 0.0) && fp_equalr (ux2, 0.0) &&
+ fp_equalr (uy1, 0.0) && fp_equalr (uy2, 0.0)) {
+
+ x1 = EDGE1
+ x2 = EDGE2
+ y1 = EDGE1
+ y2 = EDGE2
+
+ # Calculate optimum viewport, as in NCAR's conrec, hafton.
+ ratio = min (ncolsr, nlinesr) / max (ncolsr, nlinesr)
+ if (ratio >= ext) {
+ if (ncols > nlines)
+ y2 = (y2 - y1) * nlinesr / ncolsr + y1
+ else
+ x2 = (x2 - x1) * ncolsr / nlinesr + x1
+ }
+
+ xdis = x2 - x1
+ ydis = y2 - y1
+
+ # So far, the viewport has been calculated so that equal numbers of
+ # image pixels map to equal distances in NDC space, regardless of
+ # the aspect ratio of the device. If the parameter "fill" has been
+ # set to no, the user wants to compensate for a non-unity aspect
+ # ratio and make equal numbers of image pixels map to into the same
+ # physical distance on the device, not the same NDC distance.
+
+ if (! fill) {
+ aspect_ratio = ggetr (gp, "ar")
+ if (fp_equalr (aspect_ratio, 0.0))
+ aspect_ratio = 1.0
+ xdis = xdis * aspect_ratio
+ }
+
+ ux1 = XCEN - (xdis / 2.0)
+ ux2 = XCEN + (xdis / 2.0)
+ uy1 = YCEN - (ydis / 2.0)
+ uy2 = YCEN + (ydis / 2.0)
+ }
+
+ # Set window and viewport for WCS 1.
+ call gseti (gp, G_WCS, 1)
+ call gsview (gp, ux1, ux2, uy1, uy2)
+ call gswind (gp, 1.0, ncolsr, 1.0, nlinesr)
+ call set (ux1, ux2, uy1, uy2, 1.0, ncolsr, 1.0, nlinesr, 1)
+end
diff --git a/noao/digiphot/daophot/psf/dpdelstar.x b/noao/digiphot/daophot/psf/dpdelstar.x
new file mode 100644
index 00000000..22ba579f
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpdelstar.x
@@ -0,0 +1,112 @@
+include <imhdr.h>
+include <mach.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_DELSTAR -- Delete the star at the given position from the list of PSF
+# stars if it exists and passes the selection criteria.
+
+int procedure dp_delstar (dao, im, x, y, idnum, gd, showplots)
+
+pointer dao # pointer to daophot structure
+pointer im # pointer to image
+real x, y # position of proposed PSF star
+int idnum # id number of desired star
+pointer gd # pointer to the graphics stream
+bool showplots # show plots?
+
+real tx, ty
+pointer srim
+int starnum, saturated, x1, x2, y1, y2
+bool star_ok
+
+pointer dp_psubrast()
+int dp_locstar(), dp_idstar(), dp_pstati()
+
+begin
+ # Convert coordinates for display.
+ if (showplots)
+ call dp_ltov (im, x, y, tx, ty, 1)
+ else
+ call dp_wout (dao, im, x, y, tx, ty, 1)
+
+ # Check that the position of the star is within the image.
+ if (idnum == 0 && (x < 1.0 || x > real (IM_LEN(im,1)) || y < 1.0 || y >
+ real (IM_LEN(im,2)))) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star at %g,%g is outside the image\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ return (ERR)
+ }
+
+ # Find the star in the aperture photometry list.
+ if (idnum == 0)
+ starnum = dp_locstar (dao, im, x, y)
+ else
+ starnum = dp_idstar (dao, im, idnum)
+ if (starnum == 0) {
+ if (DP_VERBOSE(dao) == YES) {
+ if (idnum > 0) {
+ call printf ("Star %d not found in the photometry file\n")
+ call pargi (idnum)
+ } else {
+ call printf (
+ "Star at %g,%g not found in the photometry file\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ }
+ return (ERR)
+ } else if (starnum < 0 || starnum > dp_pstati (dao, PNUM)) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ( "Star %d not found in the PSF star list\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Get the data subraster, check for bad pixels and compute the min
+ # and max.
+ if (showplots) {
+ srim = dp_psubrast (dao, im, -MAX_REAL, MAX_REAL, x1, x2,
+ y1, y2, saturated)
+ if (srim == NULL) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d error reading data subraster\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ star_ok = false
+ } else {
+ call dp_showpsf (dao, im, Memr[srim], (x2 - x1 + 1),
+ (y2 - y1 + 1), x1, y1, gd, star_ok)
+ call mfree (srim, TY_REAL)
+ }
+ } else
+ star_ok = true
+
+ if (star_ok) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("PSF star %d saved by user\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Delete the star from the list by moving it to the position
+ # currently occupied by PNUM and moving everything else up.
+ call dp_pfreorder (dao, dp_pstati (dao, CUR_PSF), dp_pstati (dao,
+ PNUM))
+
+ # Decrement the number of psf stars.
+ call dp_pseti (dao, PNUM, dp_pstati(dao, PNUM) - 1)
+
+ # Print message.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d has been deleted from the PSF star list\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+
+ return (OK)
+end
diff --git a/noao/digiphot/daophot/psf/dpfitpsf.x b/noao/digiphot/daophot/psf/dpfitpsf.x
new file mode 100644
index 00000000..2b1c6bbc
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpfitpsf.x
@@ -0,0 +1,1693 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+include "../lib/peakdef.h"
+
+# DP_FITPSF -- Compute the PSF function.
+
+int procedure dp_fitpsf (dao, im, errmsg, maxch)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+char errmsg[ARB] # string containing error message
+int maxch # max characters in errmsg
+
+int nfunc, func
+pointer sp, flist, fstr, psf, psffit
+int dp_pstati(), dp_unsatstar(), dp_fitana(), dp_ifitana()
+int dp_fitlt(), dp_fctdecode(), dp_strwrd(), strdic()
+
+begin
+ # Get some daophot pointers.
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Test to see if there are any psf stars.
+ if (dp_pstati (dao, PNUM) <= 0) {
+ call sprintf (errmsg, maxch, "The PSF star list is empty")
+ return (ERR)
+ }
+
+ # Test to see if there are any unsaturated stars. At the same time
+ # make sure that the first star is unsaturated.
+ if (dp_unsatstar (dao) <= 0) {
+ call sprintf (errmsg, maxch,
+ "There are no unsaturated PSF stars")
+ return (ERR)
+ }
+
+ # Determine the analytic function.
+ call smark (sp)
+ call salloc (flist, SZ_FNAME, TY_CHAR)
+ call salloc (fstr, SZ_FNAME, TY_CHAR)
+ call dp_stats (dao, FUNCLIST, Memc[flist], SZ_FNAME)
+ nfunc = dp_fctdecode (Memc[flist], Memc[fstr], SZ_FNAME)
+ func = dp_strwrd (1, Memc[fstr], SZ_FNAME, Memc[flist])
+ func = strdic (Memc[fstr], Memc[fstr], SZ_LINE, FCTN_FTYPES)
+
+ # Compute the analytic part of the PSF function.
+ if (nfunc > 1 || func == FCTN_AUTO) {
+
+ # Loop over all the analytic functions.
+ if (func == FCTN_AUTO) {
+ call strcpy (FCTN_FTYPES, Memc[flist], SZ_FNAME)
+ nfunc = FCTN_NFTYPES
+ }
+
+ # Find the best fitting analytic function.
+ if (dp_ifitana (dao, im, Memc[flist], nfunc) == ERR) {
+ call sprintf (errmsg, maxch,
+ "Analytic function solution failed to converge")
+ call sfree (sp)
+ return (ERR)
+ } else if (DP_VERBOSE(dao) == YES)
+ call dp_listpars (dao)
+
+ } else {
+
+ # Save the analytic function for the new fit.
+ call strcpy (Memc[fstr], DP_FUNCTION(dao), SZ_LINE)
+
+ # Initialize the parameters.
+ call dp_reinit (dao)
+
+ # Fit the analytic part of the function.
+ if (dp_fitana (dao, im, Memr[DP_PXCEN(psf)], Memr[DP_PYCEN(psf)],
+ Memr[DP_PH(psf)], Memi[DP_PSAT(psf)], DP_PNUM(psf)) == ERR) {
+ call sprintf (errmsg, maxch,
+ "Analytic function solution failed to converge")
+ call sfree (sp)
+ return (ERR)
+ } else if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nFitting function %s norm scatter: %g\n")
+ call pargstr (DP_FUNCTION(dao))
+ call pargr (DP_PSIGANA(psf))
+ call dp_listpars (dao)
+ }
+ }
+ call sfree (sp)
+
+ # Compute the look-up table.
+ if (dp_fitlt (dao, im) == ERR) {
+ call sprintf (errmsg, maxch,
+ "Too few stars to compute PSF lookup tables")
+ return (ERR)
+ } else if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nComputed %d lookup table(s)\n")
+ call pargi (DP_NVLTABLE(psffit)+DP_NFEXTABLE(psffit))
+ }
+
+ return (OK)
+end
+
+
+# DP_UNSATSTAR -- Make sure there is at least one unsaturated star.
+
+int procedure dp_unsatstar (dao)
+
+pointer dao # pointer to the daophot structure
+
+int i, first_unsat, nstar
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+ first_unsat = 0
+
+ nstar = 0
+ do i = 1, DP_PNUM(psf) {
+ if (Memi[DP_PSAT(psf)+i-1] == YES)
+ next
+ nstar = nstar + 1
+ if (first_unsat == 0)
+ first_unsat = i
+ }
+
+ if (first_unsat > 1)
+ call dp_pfswap (dao, 1, first_unsat)
+
+ return (nstar)
+end
+
+
+# DP_REINIT -- Reinitialize the psf function parameters.
+
+procedure dp_reinit (dao)
+
+pointer dao # pointer to the daophot structure
+
+pointer psffit
+bool streq()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ # Define the psf function.
+ if (streq (DP_FUNCTION(dao), "gauss"))
+ DP_PSFUNCTION(psffit) = FCTN_GAUSS
+ else if (streq (DP_FUNCTION(dao), "moffat25"))
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT25
+ else if (streq (DP_FUNCTION(dao), "moffat15"))
+ DP_PSFUNCTION(psffit) = FCTN_MOFFAT15
+ else if (streq (DP_FUNCTION(dao), "penny1"))
+ DP_PSFUNCTION(psffit) = FCTN_PENNY1
+ else if (streq (DP_FUNCTION(dao), "penny2"))
+ DP_PSFUNCTION(psffit) = FCTN_PENNY2
+ else if (streq (DP_FUNCTION(dao), "lorentz"))
+ DP_PSFUNCTION(psffit) = FCTN_LORENTZ
+ else
+ call error (0, "Unknown PSF function\n")
+
+ switch (DP_VARORDER(dao)) {
+ case -1:
+ DP_NVLTABLE(psffit) = 0
+ case 0:
+ DP_NVLTABLE(psffit) = 1
+ case 1:
+ DP_NVLTABLE(psffit) = 3
+ case 2:
+ DP_NVLTABLE(psffit) = 6
+ }
+ if (DP_FEXPAND(dao) == NO)
+ DP_NFEXTABLE(psffit) = 0
+ else
+ DP_NFEXTABLE(psffit) = 5
+
+ # Set the initial values of the function parameters.
+ switch (DP_PSFUNCTION(psffit)) {
+ case FCTN_GAUSS:
+ DP_PSFNPARS(psffit) = 2
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ case FCTN_MOFFAT25:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ Memr[DP_PSFPARS(psffit)+3] = 2.5
+ case FCTN_MOFFAT15:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ Memr[DP_PSFPARS(psffit)+3] = 1.5
+ case FCTN_PENNY1:
+ DP_PSFNPARS(psffit) = 4
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.75
+ Memr[DP_PSFPARS(psffit)+3] = 0.0
+ case FCTN_PENNY2:
+ DP_PSFNPARS(psffit) = 5
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.75
+ Memr[DP_PSFPARS(psffit)+3] = 0.0
+ Memr[DP_PSFPARS(psffit)+4] = 0.0
+ case FCTN_LORENTZ:
+ DP_PSFNPARS(psffit) = 3
+ Memr[DP_PSFPARS(psffit)] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+1] = DP_FWHMPSF(dao) / 2.0
+ Memr[DP_PSFPARS(psffit)+2] = 0.0
+ default:
+ call error (0, "Unknown PSF function\n")
+ }
+end
+
+
+# DP_IFITANA -- Fit the PSF stars to each of the analytic functions in
+# turn to determine which one gives the best fit.
+
+int procedure dp_ifitana (dao, im, funclist, nfunc)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+char funclist # the list of functions to be fit
+int nfunc # number of functions
+
+int i, psftype, npars
+pointer psf, psffit, sp, fstr, func
+pointer ixtmp, iytmp, ihtmp, istmp, xtmp, ytmp, htmp, ptmp, stmp
+real osig, osum, height, dhdxc, dhdyc, junk, ofactor, factor
+int dp_strwrd(), strdic(), dp_fitana()
+real dp_profile()
+
+begin
+ # Get some pointers.
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate some temporary storage space.
+ call smark (sp)
+ call salloc (fstr, SZ_FNAME, TY_CHAR)
+ call salloc (func, SZ_FNAME, TY_CHAR)
+
+ call salloc (ixtmp, DP_PNUM(psf), TY_REAL)
+ call salloc (iytmp, DP_PNUM(psf), TY_REAL)
+ call salloc (ihtmp, DP_PNUM(psf), TY_REAL)
+ call salloc (istmp, DP_PNUM(psf), TY_INT)
+
+ call salloc (xtmp, DP_PNUM(psf), TY_REAL)
+ call salloc (ytmp, DP_PNUM(psf), TY_REAL)
+ call salloc (htmp, DP_PNUM(psf), TY_REAL)
+ call salloc (stmp, DP_PNUM(psf), TY_INT)
+ call salloc (ptmp, MAX_NFCTNPARS, TY_REAL)
+
+ # Initialize.
+ call strcpy (DP_FUNCTION(dao), Memc[func], SZ_FNAME)
+ npars = 0
+ osig = MAX_REAL
+ call amovr (Memr[DP_PXCEN(psf)], Memr[ixtmp], DP_PNUM(psf))
+ call amovr (Memr[DP_PYCEN(psf)], Memr[iytmp], DP_PNUM(psf))
+ call amovr (Memr[DP_PH(psf)], Memr[ihtmp], DP_PNUM(psf))
+ call amovi (Memi[DP_PSAT(psf)], Memi[istmp], DP_PNUM(psf))
+ ofactor = dp_profile (DP_PSFUNCTION(psffit), 0.0, 0.0,
+ Memr[DP_PSFPARS(psffit)], dhdxc, dhdyc, junk, 0)
+
+ factor = 1
+ do i = 1, nfunc {
+
+ # Get the function name and set it.
+ if (dp_strwrd (i, Memc[fstr], SZ_FNAME, funclist) <= 0)
+ next
+ if (strdic (Memc[fstr], Memc[fstr], SZ_FNAME, FCTN_FTYPES) <= 0)
+ next
+ call strcpy (Memc[fstr], DP_FUNCTION(dao), SZ_FNAME)
+
+ # Start from the same initial state.
+ call dp_reinit (dao)
+ call amovr (Memr[ixtmp], Memr[xtmp], DP_PNUM(psf))
+ call amovr (Memr[iytmp], Memr[ytmp], DP_PNUM(psf))
+ if (i == 1)
+ call amovr (Memr[ihtmp], Memr[htmp], DP_PNUM(psf))
+ else {
+ factor = ofactor / dp_profile (DP_PSFUNCTION(psffit), 0.0, 0.0,
+ Memr[DP_PSFPARS(psffit)], dhdxc, dhdyc, junk, 0)
+ call amulkr (Memr[ihtmp], factor, Memr[htmp], DP_PNUM(psf))
+ }
+ call amovi (Memi[istmp], Memi[stmp], DP_PNUM(psf))
+
+ call printf ("Trying function %s norm scatter = ")
+ call pargstr (Memc[fstr])
+
+ # Do the fit.
+ if (dp_fitana (dao, im, Memr[xtmp], Memr[ytmp], Memr[htmp],
+ Memi[stmp], DP_PNUM(psf)) == ERR) {
+ call printf ("error\n")
+ next
+ } else {
+ call printf ("%g\n")
+ call pargr (DP_PSIGANA(psf))
+ }
+
+ # Save the better fit.
+ if (DP_PSIGANA(psf) < osig) {
+ call strcpy (Memc[fstr], Memc[func], SZ_FNAME)
+ psftype = DP_PSFUNCTION(psffit)
+ height = DP_PSFHEIGHT(psffit)
+ npars = DP_PSFNPARS(psffit)
+ call amovr (Memr[DP_PSFPARS(psffit)], Memr[ptmp],
+ MAX_NFCTNPARS)
+ call amovr (Memr[xtmp], Memr[DP_PXCEN(psf)], DP_PNUM(psf))
+ call amovr (Memr[ytmp], Memr[DP_PYCEN(psf)], DP_PNUM(psf))
+ call amovr (Memr[htmp], Memr[DP_PH(psf)], DP_PNUM(psf))
+ call amovi (Memi[stmp], Memi[DP_PSAT(psf)], DP_PNUM(psf))
+ osig = DP_PSIGANA(psf)
+ osum = DP_PSUMANA(psf)
+ }
+ }
+
+ # Restore the best fit parameters.
+ if (npars > 0) {
+ call strcpy (Memc[func], DP_FUNCTION(dao), SZ_FNAME)
+ DP_PSFUNCTION(psffit) = psftype
+ DP_PSFHEIGHT(psffit) = height
+ DP_PSFNPARS(psffit) = npars
+ DP_PSIGANA(psf) = osig
+ DP_PSUMANA(psf) = osum
+ call amovr (Memr[ptmp], Memr[DP_PSFPARS(psffit)],
+ MAX_NFCTNPARS)
+ call printf ("Best fitting function is %s\n")
+ call pargstr (DP_FUNCTION(dao))
+ }
+
+ # Cleanup.
+ call sfree (sp)
+
+ if (npars > 0)
+ return (OK)
+ else
+ return (ERR)
+end
+
+
+# DP_FITANA -- Fit the analytic part of the psf function
+
+int procedure dp_fitana (dao, im, pxcen, pycen, ph, pstat, npsfstars)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real pxcen[ARB] # x coordinates of the psf stars
+real pycen[ARB] # y coordinates of the psf stars
+real ph[ARB] # heights of the psf stars
+int pstat[ARB] # saturation status of psf stars
+int npsfstars # the number of psf stars
+
+int i, niter, istar, mpar, lx, ly, nx, ny, ier
+pointer apsel, psf, psffit, data
+real fitrad, rsq, oldchi, sumfree
+pointer imgs2r()
+
+begin
+ # Get the psf fitting structure pointer.
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Define some variables.
+ oldchi = 0.0
+ mpar = 2
+ fitrad = DP_FITRAD(dao)
+ rsq = fitrad ** 2
+
+ # Get some memory.
+ call dp_amempsf (dao)
+
+ # Initialize the fit.
+ call amovkr (0.5, Memr[DP_PCLAMP(psf)], DP_PSFNPARS(psffit))
+ call aclrr (Memr[DP_PZ(psf)], DP_PSFNPARS(psffit))
+ call aclrr (Memr[DP_POLD(psf)], DP_PSFNPARS(psffit))
+ Memr[DP_PCLAMP(psf)] = 2.0
+ Memr[DP_PCLAMP(psf)+1] = 2.0
+
+ call aclrr (Memr[DP_PXOLD(psf)], npsfstars)
+ call aclrr (Memr[DP_PYOLD(psf)], npsfstars)
+ call amovkr (1.0, Memr[DP_PXCLAMP(psf)], npsfstars)
+ call amovkr (1.0, Memr[DP_PYCLAMP(psf)], npsfstars)
+
+ # Iterate.
+ do niter = 1, MAX_NPSFITER {
+
+ # Initialize the current integration.
+ call aclrr (Memr[DP_PV(psf)], DP_PSFNPARS(psffit))
+ call aclrr (Memr[DP_PC(psf)], DP_PSFNPARS(psffit) *
+ DP_PSFNPARS(psffit))
+
+ # Loop over the stars.
+ DP_PSIGANA(psf) = 0.0
+ DP_PSUMANA(psf) = 0.0
+ do istar = 1, npsfstars {
+
+ # Test for saturation.
+ if (pstat[istar] == YES)
+ next
+
+ # Define the subraster to be read in.
+ lx = int (pxcen[istar] - fitrad) + 1
+ ly = int (pycen[istar] - fitrad) + 1
+ nx = (int (pxcen[istar] + fitrad) - lx) + 1
+ ny = (int (pycen[istar] + fitrad) - ly) + 1
+
+ # Is the star off the image?
+ if (lx > IM_LEN(im,1) || ly > IM_LEN(im,2) || (lx + nx - 1) <
+ 1 || (ly + ny - 1) < 1) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d is outside the image\n")
+ call pargi (Memi[DP_APID(apsel)+istar-1])
+ }
+ next
+ }
+
+ # Is the star too near the edge of the frame?
+ if (lx < 1 || ly < 1 || (lx + nx - 1) > IM_LEN(im,1) ||
+ (ly + ny - 1) > IM_LEN(im,2)) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "Star %d is too near the edge of the image\n")
+ call pargi (Memi[DP_APID(apsel)+istar-1])
+ }
+ next
+ }
+
+ # Read in the subraster.
+ data = imgs2r (im, lx, lx + nx - 1, ly, ly + ny - 1)
+
+ # Fit x, y, and height for the PSF star istar.
+ call dp_xyhiter (DP_PSFUNCTION(psffit),
+ Memr[DP_PSFPARS(psffit)], rsq, Memr[data], nx, ny, lx, ly,
+ pxcen[istar], pycen[istar],
+ Memr[DP_APMSKY(apsel)+istar-1], ph[istar],
+ Memr[DP_PXCLAMP(psf)+istar-1],
+ Memr[DP_PYCLAMP(psf)+istar-1], Memr[DP_PXOLD(psf)+istar-1],
+ Memr[DP_PYOLD(psf)+istar-1])
+
+ # Fit the parameters for the entire list of stars
+ call dp_paccum (DP_PSFUNCTION(psffit),
+ Memr[DP_PSFPARS(psffit)], DP_PSFNPARS(psffit), mpar, rsq,
+ Memr[data], nx, ny, lx, ly, pxcen[istar],
+ pycen[istar], Memr[DP_APMSKY(apsel)+istar-1],
+ ph[istar], niter, Memr[DP_PC(psf)],
+ Memr[DP_PV(psf)], Memr[DP_PTMP(psf)], DP_PSIGANA(psf),
+ DP_PSUMANA(psf))
+ }
+
+ # Invert the matrix and compute the new parameters.
+ call invers (Memr[DP_PC(psf)], DP_PSFNPARS(psffit), mpar, ier)
+ call mvmul (Memr[DP_PC(psf)], DP_PSFNPARS(psffit), mpar,
+ Memr[DP_PV(psf)], Memr[DP_PZ(psf)])
+
+ do i = 1, mpar {
+ if ((Memr[DP_PZ(psf)+i-1] * Memr[DP_POLD(psf)+i-1]) < 0.0)
+ Memr[DP_PCLAMP(psf)+i-1] = 0.5 *
+ Memr[DP_PCLAMP(psf)+i-1]
+ else
+ Memr[DP_PCLAMP(psf)+i-1] = 1.1 *
+ Memr[DP_PCLAMP(psf)+i-1]
+ }
+ call amovr (Memr[DP_PZ(psf)], Memr[DP_POLD(psf)], mpar)
+ call amulr (Memr[DP_PZ(psf)], Memr[DP_PCLAMP(psf)],
+ Memr[DP_PZ(psf)], mpar)
+
+ Memr[DP_PZ(psf)] = max (-0.1 * Memr[DP_PSFPARS(psffit)],
+ min (0.1 * Memr[DP_PSFPARS(psffit)], Memr[DP_PZ(psf)]))
+ Memr[DP_PZ(psf)+1] = max (-0.1 * Memr[DP_PSFPARS(psffit)+1],
+ min (0.1 * Memr[DP_PSFPARS(psffit)+1], Memr[DP_PZ(psf)+1]))
+ #if (mpar > 2)
+ #Memr[DP_PZ(psf)+2] = Memr[DP_PZ(psf)+2] /
+ #(1.0 + abs (Memr[DP_PZ(psf)+2]) /
+ #(min (0.1, 1.0 - abs (Memr[DP_PSFPARS(psffit)+2]))))
+ call aaddr (Memr[DP_PSFPARS(psffit)], Memr[DP_PZ(psf)],
+ Memr[DP_PSFPARS(psffit)], mpar)
+
+ # Check for convergence.
+ sumfree = DP_PSUMANA(psf) - real (mpar + 3 * npsfstars)
+ if (sumfree > 0.0 && DP_PSIGANA(psf) >= 0.0)
+ DP_PSIGANA(psf) = sqrt (DP_PSIGANA(psf) / sumfree)
+ else
+ DP_PSIGANA(psf) = 9.999
+
+ if (mpar == DP_PSFNPARS(psffit)) {
+ if (abs (oldchi / DP_PSIGANA(psf) - 1.0) < 1.0e-5) {
+ DP_PSFHEIGHT(psffit) = ph[1]
+ if (IS_INDEFR(Memr[DP_PMAG(psf)]))
+ DP_PSFMAG(psffit) = Memr[DP_APMAG(apsel)]
+ else
+ DP_PSFMAG(psffit) = Memr[DP_PMAG(psf)]
+ DP_PSFX(psffit) = real (IM_LEN(im,1) - 1) / 2.0
+ DP_PSFY(psffit) = real (IM_LEN(im,2) - 1) / 2.0
+ return (OK)
+ } else
+ oldchi = DP_PSIGANA(psf)
+ } else {
+ if (abs (oldchi / DP_PSIGANA(psf) - 1.0) < 1.0e-3) {
+ mpar = mpar + 1
+ oldchi = 0.0
+ } else
+ oldchi = DP_PSIGANA(psf)
+ }
+ }
+
+ return (ERR)
+end
+
+
+# DP_XYHITER -- Increment the initial x, y, and height values for a star.
+
+procedure dp_xyhiter (psftype, params, rsq, data, nx, ny, lx, ly, x, y, sky, h,
+ xclamp, yclamp, xold, yold)
+
+int psftype # analytic point spread function type
+real params[ARB] # current function parameter values
+real rsq # the fitting radius squared
+real data[nx,ARB] # the input image data
+int nx, ny # the dimensions of the input image data
+int lx, ly # the coordinates of the ll corner of the image data
+real x, y # the input/output stellar coordinates
+real sky # the input sky value
+real h # the input/output height value
+real xclamp, yclamp # the input/output clamping factors for x and y
+real xold, yold # the input/output x and y correction factors
+
+int i, j
+real dhn, dhd, dxn, dxd, dyn, dyd, dx, dy, wt, dhdxc, dhdyc, junk, p, dp
+real prod
+real dp_profile()
+
+begin
+ dhn = 0.0
+ dhd = 0.0
+ dxn = 0.0
+ dxd = 0.0
+ dyn = 0.0
+ dyd = 0.0
+
+ do j = 1, ny {
+ dy = real ((ly + j) - 1) - y
+ do i = 1, nx {
+ dx = real ((lx + i) - 1) - x
+ wt = (dx ** 2 + dy ** 2) / rsq
+ #if (wt >= 1.0)
+ if (wt >= 0.999998)
+ next
+ p = dp_profile (psftype, dx, dy, params, dhdxc, dhdyc, junk, 0)
+ dp = data[i,j] - h * p - sky
+ dhdxc = dhdxc * h
+ dhdyc = dhdyc * h
+ wt = 5.0 / (5.0 + (wt / (1.0 - wt)))
+ prod = wt * p
+ dhn = dhn + prod * dp
+ dhd = dhd + prod * p
+ prod = wt * dhdxc
+ dxn = dxn + prod * dp
+ dxd = dxd + prod * dhdxc
+ prod = wt * dhdyc
+ dyn = dyn + prod * dp
+ dyd = dyd + prod * dhdyc
+ }
+ }
+
+ h = h + (dhn / dhd)
+ dxn = dxn / dxd
+ if ((xold * dxn) < 0.0)
+ xclamp = 0.5 * xclamp
+ xold = dxn
+ x = x + (dxn / (1.0 + (abs(dxn) / xclamp)))
+ dyn = dyn / dyd
+ if ((yold * dyn) < 0.0)
+ yclamp = 0.5 * yclamp
+ yold = dyn
+ y = y + (dyn / (1.0 + (abs(dyn) / yclamp)))
+end
+
+
+# DP_PACCUM -- Accumulate the data for the parameter fit.
+
+procedure dp_paccum (psftype, params, npars, mpars, rsq, data, nx, ny, lx,
+ ly, x, y, sky, h, iter, c, v, temp, chi, sumwt)
+
+int psftype # analytic point spread function type
+real params[ARB] # current function parameter values
+int npars # number of function parameters
+int mpars # the number of active parameters
+real rsq # the fitting radius squared
+real data[nx,ARB] # the input image data
+int nx, ny # the dimensions of the input image data
+int lx, ly # the coordinates of the ll corner of the image data
+real x, y # the input/output stellar coordinates
+real sky # the input sky value
+real h # the input/output height value
+int iter # the current iteration
+real c[npars,ARB] # accumulation matrix
+real v[ARB] # accumulation vector
+real temp[ARB] # temporary storage vector
+real chi # the chi sum
+real sumwt # the number of points sum
+
+int i, j, k, l
+real peak, dx, dy, wt, dhdxc, dhdyc, p, dp
+real dp_profile()
+
+begin
+ peak = h * dp_profile (psftype, 0.0, 0.0, params, dhdxc, dhdyc, temp, 0)
+ do j = 1, ny {
+ dy = real ((ly + j) - 1) - y
+ do i = 1, nx {
+ dx = real ((lx + i) - 1) - x
+ wt = (dx ** 2 + dy ** 2) / rsq
+ #if (wt >= 1.0)
+ if (wt >= 0.999998)
+ next
+ p = dp_profile (psftype, dx, dy, params, dhdxc, dhdyc, temp, 1)
+ dp = data[i,j] - h * p - sky
+ do k = 1, mpars
+ temp[k] = h * temp[k]
+ chi = chi + (dp / peak) ** 2
+ sumwt = sumwt + 1.0
+ wt = 5.0 / (5.0 + (wt / (1.0 - wt)))
+ if (iter >= 4)
+ wt = wt / (1.0 + abs (20.0 * dp / peak))
+ do k = 1, mpars {
+ v[k] = v[k] + wt * dp * temp[k]
+ do l = 1, mpars {
+ c[l,k] = c[l,k] + wt * temp[l] * temp[k]
+ }
+ }
+ }
+ }
+end
+
+
+# DP_FITLT -- Given the analytic function compute the lookup tables.
+
+int procedure dp_fitlt (dao, im)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+
+int istar, nexp, lx, mx, ly, my, iter, nclean, ndata, fit_saturated, nfit
+int nunsat
+double volume
+pointer apsel, psf, psffit, sp, wimname, wim, data
+real datamin, datamax, sumfree, resid, dfdx, dfdy, junk
+int dp_dclean(), dp_resana(), dp_ltcompute(), dp_fsaturated()
+double dp_pnorm()
+pointer immap(), imps2r(), dp_subrast()
+real dp_profile(), dp_sweight()
+define fitsaturated_ 11
+
+begin
+ # Get some pointers.
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Check to see whether lookup tables are required.
+ nexp = DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)
+ if (nexp <= 0)
+ return (OK)
+
+ # Return if there are too few stars to fit the lookup tables.
+ if (DP_PNUM(psf) < nexp)
+ return (ERR)
+
+ # Determine the number of saturated stars.
+ nunsat = 0
+ do istar = 1, DP_PNUM(psf) {
+ if (Memi[DP_PSAT(psf)+istar-1] == NO)
+ next
+ if ((Memr[DP_PH(psf)+istar-1] * dp_profile (DP_PSFUNCTION(psffit),
+ 0.0, 0.0, Memr[DP_PSFPARS(psffit)], dfdx, dfdy, junk, 0) +
+ Memr[DP_APMSKY(apsel)+istar-1]) <= datamax)
+ next
+ Memi[DP_PSAT(psf)+istar-1] = YES
+ Memr[DP_PH(psf)+istar-1] = INDEFR
+ nunsat = nunsat + 1
+ }
+ nunsat = DP_PNUM(psf) - nunsat
+
+ # Return if there are too few unsaturated psf stars to fit the lookup
+ # tables.
+ if (nunsat < nexp)
+ return (ERR)
+
+ # Allocate memory for computing lookup tables.
+ call dp_tmempsf (dao)
+
+ # Define some constants.
+ fit_saturated = DP_SATURATED(dao)
+ if (IS_INDEFR(DP_MINGDATA(dao)))
+ datamin = -MAX_REAL
+ else
+ datamin = DP_MINGDATA(dao)
+ if (IS_INDEFR(DP_MAXGDATA(dao)))
+ datamax = MAX_REAL
+ else
+ datamax = DP_MAXGDATA(dao)
+ sumfree = sqrt (DP_PSUMANA(psf) / (DP_PSUMANA(psf) - (nexp +
+ 3.0 * DP_PNUM(psf))))
+
+ # Get the image name.
+ call smark (sp)
+ call salloc (wimname, SZ_FNAME, TY_CHAR)
+ call mktemp ("tmp", Memc[wimname], SZ_FNAME)
+
+ # Open a temporary image to hold the weights.
+ wim = immap (Memc[wimname], NEW_IMAGE, 0)
+ IM_NDIM(wim) = 2
+ IM_LEN(wim,1) = DP_PNUM(psf)
+ IM_LEN(wim,2) = DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit)
+ IM_PIXTYPE(wim) = TY_REAL
+
+ # Compute the constant part of the psf in preparation for normalizing
+ # the lookup tables.
+ if (nexp > 1)
+ call dp_pconst (DP_PSFUNCTION(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PH(psf)], Memr[DP_PCONST(psf)], DP_PSFSIZE(psffit))
+
+ nfit = 0
+
+fitsaturated_
+
+ # Compute the look-up table.
+ do iter = 1, DP_NCLEAN(dao) + 1 {
+
+ # Initialize the fitting arrays.
+ call aclrr (Memr[DP_PV(psf)], nexp)
+ call aclrr (Memr[DP_PC(psf)], nexp * nexp)
+ call aclrr (Memr[DP_PSUMN(psf)], DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit))
+ call aclrr (Memr[DP_PSUMSQ(psf)], DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit))
+ call aclrr (Memr[DP_PSFLUT(psffit)], nexp * DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit))
+
+ # Loop over the PSF stars.
+ do istar = 1, DP_PNUM(psf) {
+
+ # Get the weight image.
+ DP_PSUMW(psf) = imps2r (wim, istar, istar, 1,
+ DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit))
+ call aclrr (Memr[DP_PSUMW(psf)], DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit))
+
+ # Skip saturated star?
+ if (IS_INDEFR(Memr[DP_PH(psf)+istar-1]))
+ next
+
+ # Get the data.
+ data = dp_subrast (im, Memr[DP_PXCEN(psf)+istar-1],
+ Memr[DP_PYCEN(psf)+istar-1], DP_PSFRAD(dao), lx, mx,
+ ly, my)
+
+ # Is the star off the image?
+ if (lx > IM_LEN(im,1) || ly > IM_LEN(im,2) || mx < 1 ||
+ my < 1) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d is outside the image\n")
+ call pargi (Memi[DP_APID(apsel)+istar-1])
+ }
+ next
+ }
+
+ # Clean bad pixels outside the fitting radius but inside
+ # the psf radius from the subraster.
+ nclean = dp_dclean (Memr[data], (mx - lx + 1), (my - ly + 1),
+ lx, ly, Memr[DP_PXCEN(psf)+istar-1], Memr[DP_PYCEN(psf)+
+ istar-1], DP_FITRAD(dao), datamin, datamax)
+
+ # Subtract the analytic part of the fit from the data
+ # and compute the normalized residual of the star.
+ ndata = dp_resana (im, DP_PSFUNCTION(psffit),
+ Memr[DP_PSFPARS(psffit)], Memr[data], (mx - lx + 1),
+ (my - ly + 1), lx, ly, Memr[DP_PXCEN(psf)],
+ Memr[DP_PYCEN(psf)], Memr[DP_APMSKY(apsel)],
+ Memr[DP_PH(psf)], DP_PNUM(psf), istar, DP_PSFRAD(dao),
+ DP_FITRAD(dao), datamax, resid)
+
+ # Compute the proper weight for the star.
+ if (IS_INDEFR(Memr[DP_PH(psf)+istar-1]) ||
+ Memr[DP_PH(psf)+istar-1] <= 0.0) {
+ Memr[DP_PWEIGHT(psf)+istar-1] = 0.0
+ } else if (Memi[DP_PSAT(psf)+istar-1] == YES) {
+ Memr[DP_PWEIGHT(psf)+istar-1] = 0.5 *
+ Memr[DP_PH(psf)+istar-1] / Memr[DP_PH(psf)]
+ } else {
+ Memr[DP_PWEIGHT(psf)+istar-1] = (Memr[DP_PH(psf)+
+ istar-1] / Memr[DP_PH(psf)]) * dp_sweight (resid,
+ sumfree, DP_PSIGANA(psf))
+ }
+
+ # Compute the expansion vector.
+ call dp_eaccum (Memr[DP_PXCEN(psf)+istar-1],
+ Memr[DP_PYCEN(psf)+istar-1], DP_PSFX(psffit),
+ DP_PSFY(psffit), Memr[DP_PTMP(psf)], DP_NVLTABLE(psffit),
+ DP_NFEXTABLE(psffit))
+
+ # Compute the contribution to the lookup table of the
+ # particular star.
+ call dp_ltinterp (Memr[data], (mx - lx + 1), (my - ly + 1),
+ lx, ly, Memr[DP_PXCEN(psf)+istar-1], Memr[DP_PYCEN(psf)+
+ istar-1], Memr[DP_APMSKY(apsel)+istar-1],
+ Memr[DP_PH(psf)+istar-1] / Memr[DP_PH(psf)],
+ Memr[DP_PWEIGHT(psf)+istar-1], Memr[DP_PSUMN(psf)],
+ Memr[DP_PSUMW(psf)], Memr[DP_PSUMSQ(psf)],
+ Memr[DP_PSIGMA(psf)], Memr[DP_POLDLUT(psf)],
+ Memr[DP_PTMP(psf)], Memr[DP_PSFLUT(psffit)], nexp,
+ DP_PSFSIZE(psffit), datamax, iter, DP_NCLEAN(dao) + 1)
+
+ call mfree (data, TY_REAL)
+ }
+
+ call imflush (wim)
+
+ # Compute the lookup table.
+ if (dp_ltcompute (Memr[DP_PXCEN(psf)], Memr[DP_PYCEN(psf)],
+ DP_PNUM(psf), DP_PSFX(psffit), DP_PSFY(psffit),
+ Memr[DP_PSUMN(psf)], wim, Memr[DP_PSFLUT(psffit)],
+ Memr[DP_PC(psf)], Memr[DP_PTMP(psf)], Memr[DP_PV(psf)],
+ nexp, DP_PSFSIZE(psffit), DP_NVLTABLE(psffit),
+ DP_NFEXTABLE(psffit)) == ERR) {
+ call sfree (sp)
+ return (ERR)
+ }
+
+
+ # Compute the standard deviation arrays for the next pass.
+ if (iter < (DP_NCLEAN(dao) + 1)) {
+ if (nunsat <= nexp)
+ break
+ call amovr (Memr[DP_PSFLUT(psffit)], Memr[DP_POLDLUT(psf)],
+ nexp * DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit))
+ call dp_stdcompute (Memr[DP_PSUMN(psf)], Memr[DP_PSUMSQ(psf)],
+ Memr[DP_PSIGMA(psf)], DP_PSFSIZE(psffit),
+ DP_PSFSIZE(psffit), nexp)
+ }
+
+ }
+
+ if (nexp > 1) {
+
+ # Accumulate the v vector.
+ call dp_vaccum (Memr[DP_PXCEN(psf)], Memr[DP_PYCEN(psf)],
+ Memr[DP_PH(psf)], Memr[DP_PWEIGHT(psf)], DP_PNUM(psf),
+ DP_PSFX(psffit), DP_PSFY(psffit), Memr[DP_PTMP(psf)],
+ Memr[DP_PV(psf)], nexp, DP_NVLTABLE(psffit),
+ DP_NFEXTABLE(psffit))
+
+ # Compute the constant part of the psf.
+ volume = dp_pnorm (Memr[DP_PCONST(psf)], Memr[DP_PSIGMA(psf)],
+ DP_PSFSIZE(psffit))
+
+ # Normalize lookup tables.
+ call dp_ltnorm (Memr[DP_PCONST(psf)], Memr[DP_PV(psf)],
+ Memr[DP_PSFLUT(psffit)], Memr[DP_PSIGMA(psf)], nexp,
+ DP_PSFSIZE(psffit), volume)
+
+ }
+
+ # Make a copy of the psf.
+ call dp_pcopy (Memr[DP_PSFLUT(psffit)], Memr[DP_POLDLUT(psf)],
+ DP_PSFSIZE(psffit), DP_PSFSIZE(psffit), nexp)
+
+ # Include the saturated psf stars in the fit.
+ if (fit_saturated == YES) {
+ nfit = dp_fsaturated (dao, im, Memi[DP_APID(apsel)],
+ Memr[DP_PXCEN(psf)], Memr[DP_PYCEN(psf)], Memr[DP_PH(psf)],
+ Memr[DP_APMSKY(apsel)], Memi[DP_PSAT(psf)], DP_PNUM(psf))
+ fit_saturated = NO
+ if (nfit > 0) {
+ nunsat = nunsat + nfit
+ if (nexp > 1)
+ call aaddr (Memr[DP_PCONST(psf)], Memr[DP_POLDLUT(psf)],
+ Memr[DP_PCONST(psf)], DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit))
+ goto fitsaturated_
+ }
+ }
+
+ # Cleanup the temporary images and arrays.
+ call imunmap (wim)
+ call imdelete (Memc[wimname])
+ call sfree (sp)
+
+ return (OK)
+end
+
+
+# DP_DCLEAN -- Clean bad pixels that are outside the fitting radius from
+# the data. Note that the star must not be considered to be saturated to
+# arrive at this point.
+
+int procedure dp_dclean (data, nx, ny, lx, ly, x, y, fitrad, datamin, datamax)
+
+real data[nx,ARB] # the input image data
+int nx, ny # the dimensions of the input image data
+int lx, ly # the coordinates of the ll image corner
+real x, y # the input/output stellar coordinates
+real fitrad # the fitting radius
+real datamin # the min good data value
+real datamax # the max good data value
+
+bool redo
+int i, j, l, k, nclean
+real frad2, dy2, dr2, sumd, sumn
+
+begin
+ nclean = 0
+ repeat {
+
+ redo = false
+ frad2 = fitrad ** 2
+
+ do j = 1, ny {
+
+ dy2 = (real ((ly - 1) + j) - y) ** 2
+ if (dy2 < frad2)
+ next
+ do i = 1, nx {
+
+ if (data[i,j] >= datamin && data[i,j] <= datamax)
+ next
+ dr2 = dy2 + (real ((lx - 1) + i) - x) ** 2
+ if (dr2 < frad2)
+ next
+
+ sumd = 0.0
+ sumn = 0.0
+ do l = max (1, j-1), min (ny, j+2) {
+ do k = max (1, i-1), min (nx, i+2) {
+ if (data[k,l] < datamin || data[k,l] > datamax)
+ next
+ sumd = sumd + data[k,l]
+ sumn = sumn + 1.0
+ }
+ }
+ if (sumn < 2.5)
+ redo = true
+ else {
+ nclean = nclean + 1
+ data[i,j] = sumd / sumn
+ }
+ }
+ }
+
+ } until (! redo)
+
+ return (nclean)
+end
+
+
+# DP_RESANA -- Compute the residuals from the analytic function.
+
+int procedure dp_resana (im, psftype, params, data, nx, ny, lx, ly,
+ x, y, sky, h, nstar, psfstar, psfrad, fitrad, maxgdata, resid)
+
+pointer im # the input image descriptor
+int psftype # analytic point spread function type
+real params[ARB] # current function parameter values
+real data[nx,ARB] # the input image data
+int nx, ny # the dimensions of the input image data
+int lx, ly # the coordinates of the ll image corner
+real x[ARB] # the input x coords of the psf stars
+real y[ARB] # the input y coords of the psf stars
+real sky[ARB] # the input sky values of the psf stars
+real h[ARB] # the input height values of the psf stars
+int nstar # the number of psf stars
+int psfstar # the psf star in question
+real psfrad # the psf radius
+real fitrad # the fitting radius
+real maxgdata # the maximum good data value
+real resid # standard deviation of fit
+
+int i, j, istar, rx, ry, x1, x2, y1, y2, nresid
+real frad2, dx, dy, dy2, dr2, p, dhdxc, dhdyc, junk
+int dp_lsubrast()
+real dp_profile()
+
+begin
+ frad2 = fitrad ** 2
+ rx = lx + nx - 1
+ ry = ly + ny - 1
+
+ resid = 0.0
+ nresid = 0
+ do istar = 1, nstar {
+
+ # Check for saturation.
+ if (IS_INDEFR(h[istar]))
+ next
+
+ # Does the subraster of another PSF star overlap the current
+ # subraster ?.
+ if (dp_lsubrast (im, x[istar], y[istar], psfrad, x1, x2,
+ y1, y2) == ERR)
+ next
+ if (x2 < lx || y2 < ly || x1 > rx || y1 > ry)
+ next
+
+ # Check the limits of overlap.
+ if (x1 < lx)
+ x1 = lx
+ if (x2 > rx)
+ x2 = rx
+ if (y1 < ly)
+ y1 = ly
+ if (y2 > ry)
+ y2 = ry
+
+ # Subract off the analytic part of the fits and accumulate
+ # the residuals for the psf star.
+ do j = y1 - ly + 1, y2 - ly + 1 {
+ dy = real ((ly - 1) + j) - y[istar]
+ dy2 = dy ** 2
+ do i = x1 - lx + 1, x2 - lx + 1 {
+ if (data[i,j] > maxgdata)
+ next
+ dx = real ((lx - 1) + i) - x[istar]
+ p = dp_profile (psftype, dx, dy, params, dhdxc, dhdyc,
+ junk, 0)
+ data[i,j] = data[i,j] - h[istar] * p
+ if (istar != psfstar)
+ next
+ dr2 = dy2 + dx ** 2
+ if (dr2 >= frad2)
+ next
+ resid = resid + (data[i,j] - sky[istar]) ** 2
+ nresid = nresid + 1
+ }
+ }
+ }
+
+ if (nresid <= 0)
+ resid = 0.0
+ else
+ resid = sqrt (resid / nresid) / (h[psfstar] * dp_profile (psftype,
+ 0.0, 0.0, params, dhdxc, dhdyc, junk, 0))
+
+ return (nresid)
+end
+
+
+# DP_SWEIGHT -- Compute the weight for the star.
+
+real procedure dp_sweight (resid, sumfree, sumana)
+
+real resid # normalized residual wrt analytic fit
+real sumfree # number of degrees of freedom
+real sumana # number of points contributing to analytic fit
+
+real weight
+
+begin
+ weight = resid * sumfree / sumana
+ weight = 1.0 / (1.0 + (weight / 2.0) ** 2)
+ return (weight)
+end
+
+
+# DP_EACCUM -- Calcuate the expansion vector for a single PSF star.
+
+procedure dp_eaccum (x, y, xmid, ymid, junk, nvexp, nfexp)
+
+real x, y # the stellar coordinates
+real xmid, ymid # the psf coordinates
+real junk[ARB] # temporary storage vector
+int nvexp # the number of variable psf look-up tables
+int nfexp # the number of pixel expansion tables
+
+int j
+
+begin
+ # The variable psf terms.
+ switch (nvexp) {
+ case 1:
+ junk[1] = 1.0
+ case 3:
+ junk[1] = 1.0
+ junk[2] = ((x - 1.0) / xmid) - 1.0
+ junk[3] = ((y - 1.0) / ymid) - 1.0
+ case 6:
+ junk[1] = 1.0
+ junk[2] = ((x - 1.0) / xmid) - 1.0
+ junk[3] = ((y - 1.0) / ymid) - 1.0
+ junk[4] = (1.5 * (junk[2] ** 2)) - 0.5
+ junk[5] = junk[2] * junk[3]
+ junk[6] = (1.5 * (junk[3] ** 2)) - 0.5
+ }
+
+ # The fractional pixel expansion terms if any.
+ if (nfexp > 0) {
+ j = nvexp + 1
+ junk[j] = 2.0 * (x - real (nint(x)))
+ j = j + 1
+ junk[j] = 2.0 * (y - real (nint(y)))
+ j = j + 1
+ junk[j] = (1.5 * (junk[j-2] ** 2)) - 0.5
+ j = j + 1
+ junk[j] = junk[j-3] * junk[j-2]
+ j = j + 1
+ junk[j] = (1.5 * (junk[j-3] ** 2)) - 0.5
+ }
+
+end
+
+
+# DP_LTINTERP -- Compute the contribution to the lookup table of a single
+# PSF star.
+
+procedure dp_ltinterp (data, nx, ny, lx, ly, x, y, sky, hratio, weight, sumn,
+ sumw, sumsq, sig, old, temp, psflut, nexp, nxlut, maxgdata, iter, niter)
+
+real data[nx,ARB] # the input image data
+int nx, ny # the dimensions of the input image data
+int lx, ly # the coordinates of the ll image corner
+real x, y # the input/output stellar coordinates
+real sky # sky value for star
+real hratio # scale factor for star
+real weight # weight for the star
+real sumn[nxlut,ARB] # number of points
+real sumw[nxlut,ARB] # sum of the weights
+real sumsq[nxlut,ARB] # sum of the residuals
+real sig[nxlut,ARB] # residuals of previous iteration
+real old[nexp,nxlut,ARB] # old lookup table
+real temp[ARB] # the single star expansion vector
+real psflut[nexp,nxlut,ARB] # the psf lookup table
+int nexp, nxlut # the dimensions of the lookup table
+real maxgdata # maximum good data value
+int iter # the current iteration
+int niter # the maximum number of iterations
+
+bool omit
+int i, j, k, kx, ky, ii, jj, middle, jysq, irsq, midsq
+real jy, ix, dx, dy, diff, dfdx, dfdy, wt, oldsum
+real bicubic()
+
+begin
+ middle = (nxlut + 1) / 2
+ midsq = middle ** 2
+ do j = 1, nxlut {
+ jysq = (j - middle) ** 2
+ if (jysq > midsq)
+ next
+ jy = y + real (j - (nxlut + 1) / 2) / 2.0 - real (ly - 1)
+ ky = int (jy)
+ if (ky < 2 || (ky + 2) > ny)
+ next
+ dy = jy - real (ky)
+ do i = 1, nxlut {
+ irsq = jysq + (i - middle) ** 2
+ if (irsq > midsq)
+ next
+ ix = x + real (i - (nxlut + 1) / 2) / 2.0 - real (lx - 1)
+ kx = int (ix)
+ if (kx < 2 || (kx + 2) > nx)
+ next
+ omit = false
+ do jj = ky - 1, ky + 2 {
+ do ii = kx - 1, kx + 2 {
+ if (data[ii,jj] <= maxgdata)
+ next
+ omit = true
+ }
+ }
+ if (omit)
+ next
+ dx = ix - real (kx)
+ diff = (bicubic (data[kx-1,ky-1], nx, dx, dy, dfdx, dfdy) -
+ sky) / hratio
+ if (iter == 1 || sig[i,j] <= 0.0) {
+ wt = 1.0
+ } else {
+ oldsum = 0.0
+ do k = 1, nexp
+ oldsum = oldsum + old[k,i,j] * temp[k]
+ if ((iter - 1) <= max (3, (niter - 1) / 2))
+ wt = 1.0 / (1.0 + abs (diff - oldsum) / sig[i,j])
+ else
+ wt = 1.0 / (1.0 + ((diff - oldsum) / sig[i,j]) ** 2)
+ }
+ wt = wt * weight
+ sumn[i,j] = sumn[i,j] + 1.0
+ sumw[i,j] = wt
+ sumsq[i,j] = sumsq[i,j] + abs (diff)
+ psflut[1,i,j] = psflut[1,i,j] + wt * diff
+ if (nexp <= 1)
+ next
+ do k = 2, nexp
+ psflut[k,i,j] = psflut[k,i,j] + (temp[k] * wt * diff)
+ }
+ }
+end
+
+
+# DP_LTCOMPUTE -- Compute the lookup table.
+
+int procedure dp_ltcompute (x, y, npsf, xmid, ymid, sumn, wim, psflut, c,
+ junk, v, nexp, nxlut, nvexp, nfexp)
+
+real x[ARB] # array of psf star x coordinates
+real y[ARB] # array of psf star y coordinates
+int npsf # the number of psf stars
+real xmid, ymid # the mid-point of the psf
+real sumn[nxlut,ARB] # number of points
+pointer wim # pointer to the temporary weight image
+real psflut[nexp,nxlut,ARB] # the psf lookup table
+real c[nexp,ARB] # the expansion matrix
+real junk[ARB] # temporary junk vector
+real v[ARB] # temporary vector
+int nexp, nxlut # the size of the lookup table
+int nvexp, nfexp # size of the expansion look-up tables
+
+int i, j, k, l, line, istar, ier, middle, midsq, jysq, irsq
+pointer sumw
+real weight
+pointer imgs2r()
+
+begin
+ middle = (nxlut + 1) / 2
+ midsq = middle ** 2
+ do j = 1, nxlut {
+ jysq = (j - middle) ** 2
+ if (jysq > midsq)
+ next
+ do i = 1, nxlut {
+ irsq = (i - middle) ** 2 + jysq
+ if (irsq > midsq)
+ next
+ if (nint (sumn[i,j]) < nexp)
+ return (ERR)
+ line = i + (j - 1) * nxlut
+ sumw = imgs2r (wim, 1, npsf, line, line)
+ do k = 1, nexp
+ do l = 1, nexp
+ c[k,l] = 0.0
+ do istar = 1, npsf {
+ weight = Memr[sumw+istar-1]
+ if (weight <= 0.0)
+ next
+ call dp_eaccum (x[istar], y[istar], xmid, ymid, junk,
+ nvexp, nfexp)
+ do k = 1, nexp
+ do l = 1, nexp
+ c[k,l] = c[k,l] + weight * junk[k] * junk[l]
+ }
+ call invers (c, nexp, nexp, ier)
+ call mvmul (c, nexp, nexp, psflut[1,i,j], v)
+ do k = 1, nexp
+ psflut[k,i,j] = v[k]
+ }
+ }
+
+ return (OK)
+end
+
+
+# DP_STDCOMPUTE -- Estimate the standard deviation of the fit.
+
+procedure dp_stdcompute (sumn, sumsq, sigma, nx, ny, nexp)
+
+real sumn[nx,ARB] # number of point
+real sumsq[nx,ARB] # sum of the standard deviations
+real sigma[nx,ARB] # output standard deviation array
+int nx, ny # size of the arrays
+int nexp # number of expansion vectors
+
+int i, j
+
+begin
+ do j = 1, ny {
+ do i = 1, nx {
+ if (sumn[i,j] <= nexp)
+ sigma[i,j] = 0.0
+ else
+ sigma[i,j] = 1.2533 * sumsq[i,j] / sqrt (sumn[i,j] *
+ (sumn[i,j] - nexp))
+ }
+ }
+end
+
+
+# DP_VACCUM -- Accumulate the expansion vector.
+
+procedure dp_vaccum (x, y, h, weight, nstar, xmid, ymid, junk, avetrm,
+ nexp, nvexp, nfexp)
+
+real x[ARB] # the stellar x coordinates
+real y[ARB] # the stellar y coordinates
+real h[ARB] # the stellar heights
+real weight[ARB] # the stellar weights
+int nstar # number of stars
+real xmid, ymid # the psf coordinates
+real junk[ARB] # temporary storage vector
+real avetrm[ARB] # the expansion vector
+int nexp # the total number of expansion terms
+int nvexp # number of variable expansion terms
+int nfexp # number of fractional pixel expansion terms
+
+int k, j
+
+begin
+ # Zero the accumulation vector
+ do j = 1, nexp
+ avetrm[j] = 0.0
+
+ do k = 1, nstar {
+ if (IS_INDEFR(h[k]))
+ next
+
+ # The variable psf expansion terms.
+ switch (nvexp) {
+ case 1:
+ junk[1] = 1.0
+ case 3:
+ junk[1] = 1.0
+ junk[2] = ((x[k] - 1.0) / xmid) - 1.0
+ junk[3] = ((y[k] - 1.0) / ymid) - 1.0
+ case 6:
+ junk[1] = 1.0
+ junk[2] = ((x[k] - 1.0) / xmid) - 1.0
+ junk[3] = ((y[k] - 1.0) / ymid) - 1.0
+ junk[4] = (1.5 * (junk[2] ** 2)) - 0.5
+ junk[5] = junk[2] * junk[3]
+ junk[6] = (1.5 * (junk[3] ** 2)) - 0.5
+ }
+
+ # The fractional pixel expansion terms if any.
+ if (nfexp > 0) {
+ j = nvexp + 1
+ junk[j] = 2.0 * (x[k] - real (nint(x[k])))
+ j = j + 1
+ junk[j] = 2.0 * (y[k] - real (nint(y[k])))
+ j = j + 1
+ junk[j] = (1.5 * (junk[j-2] ** 2)) - 0.5
+ j = j + 1
+ junk[j] = junk[j-3] * junk[j-2]
+ j = j + 1
+ junk[j] = (1.5 * (junk[j-3] ** 2)) - 0.5
+ }
+
+ # Accumulate the expansion vector.
+ do j = 1, nexp
+ avetrm[j] = avetrm[j] + weight[k] * junk[j]
+ }
+
+ # Average the expansion vector.
+ do j = nexp, 1, -1
+ avetrm[j] = avetrm[j] / avetrm[1]
+end
+
+
+# DP_PCONST -- Compute the analytic part of the psf.
+
+procedure dp_pconst (psftype, params, hpsf1, ana, nxlut)
+
+int psftype # the type of analytic psf function
+real params[ARB] # the analytic parameters array
+real hpsf1 # the height of the psf function
+real ana[nxlut,ARB] # the computed analytic function
+int nxlut # the size of the constant lookup table
+
+int i, j, middle, midsq, dj2, dr2
+real dx, dy, dfdx, dfdy, junk
+real dp_profile()
+
+begin
+ # Compute the constant part of the psf.
+ middle = (nxlut + 1) / 2
+ midsq = middle ** 2
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ dy = real (j - middle) / 2.0
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ dx = real (i - middle) / 2.0
+ ana[i,j] = hpsf1 * dp_profile (psftype, dx, dy, params,
+ dfdx, dfdy, junk, 0)
+ }
+ }
+end
+
+
+# DP_PNORM -- Compute the psf normalization parameters.
+
+double procedure dp_pnorm (ana, pixels, nxlut)
+
+real ana[nxlut,ARB] # the computed analytic function
+real pixels[ARB] # pixel storage array
+int nxlut # the size of the constant lookup table
+
+int i, j, middle, midsq, edgesq, npts, dj2, dr2
+double vol
+real median
+real pctile()
+
+begin
+ # Ensure that the profile which will be added and subtracted
+ # from the various lookup tables has a median value of zero
+ # around the rim
+
+ middle = (nxlut + 1) / 2
+ midsq = middle ** 2
+ edgesq = (middle - 2) ** 2
+ npts = 0
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ if (dr2 < edgesq)
+ next
+ npts = npts + 1
+ pixels[npts] = ana[i,j]
+ }
+ }
+ median = pctile (pixels, npts, (npts+1) / 2)
+
+ vol = 0.0d0
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ ana[i,j] = ana[i,j] - median
+ vol = vol + double (ana[i,j])
+ }
+ }
+
+ return (vol)
+end
+
+
+# DP_LTNORM -- Compute the final lookup table.
+
+procedure dp_ltnorm (ana, v, psflut, pixels, nexp, nxlut, volume)
+
+real ana[nxlut,ARB] # analytic part of the profile
+real v[ARB] # the expansion vector
+real psflut[nexp,nxlut,ARB] # the psf lookup table
+real pixels[ARB] # scratch array for determining median
+int nexp, nxlut # the size of the lookup table
+double volume # total flux in the constant psf
+
+int i, j, k, middle, midsq, edgesq, npts, dj2, dr2
+double sum
+real median, dmedian
+real pctile()
+
+begin
+ # Ensure that the psf which will be added and subtracted from the
+ # various lookup tables has a median value of zero around the rim.
+
+ middle = (nxlut + 1) / 2
+ midsq = middle ** 2
+ edgesq = (middle - 2) ** 2
+ do k = 2, nexp {
+
+ npts = 0
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ if (dr2 < edgesq)
+ next
+ npts = npts + 1
+ pixels[npts] = psflut[k,i,j]
+ }
+ }
+
+ median = pctile (pixels, npts, (npts+1) / 2)
+ dmedian = v[k] * median
+
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ psflut[k,i,j] = psflut[k,i,j] - median
+ psflut[1,i,j] = psflut[1,i,j] + dmedian
+ }
+ }
+ }
+
+ # Determine the net volume of each of the higher order PSF
+ # tables and force it to zero by subtracting a scaled copy
+ # of the constant psf. Scale the part that has been subtracted
+ # off by the mean polynomial term and add it in to the constant
+ # part of the psf so that at the centroid of the psf stars
+ # positions the psf remains unchanged.
+
+ do k = 2, nexp {
+
+ sum = 0.0d0
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ sum = sum + double (psflut[k,i,j])
+ }
+ }
+
+ median = real (sum / volume)
+ dmedian = v[k] * median
+
+ do j = 1, nxlut {
+ dj2 = (j - middle) ** 2
+ if (dj2 > midsq)
+ next
+ do i = 1, nxlut {
+ dr2 = (i - middle) ** 2 + dj2
+ if (dr2 > midsq)
+ next
+ psflut[k,i,j] = psflut[k,i,j] - median * ana[i,j]
+ psflut[1,i,j] = psflut[1,i,j] + dmedian * ana[i,j]
+ }
+ }
+ }
+end
+
+
+# DP_FSATURATED -- Fit the saturated stars.
+
+int procedure dp_fsaturated (dao, im, id, xcen, ycen, h, sky, sat, nstars)
+
+pointer dao # pointer to the main daophot structure
+pointer im # pointer to the input image
+int id[ARB] # array of stellar ids
+real xcen[ARB] # array of stellar y coordinates
+real ycen[ARB] # array of stellar y coordinates
+real h[ARB] # array of stellar amplitudes
+real sky[ARB] # array of sky values
+int sat[ARB] # array of saturation indicators
+int nstars # number of stars
+
+int nfit, nsat, istar, lowx, lowy, nxpix, nypix, recenter, fitsky
+int clipexp, ier, niter
+pointer psf, psffit, subim, psflut
+real x, y, dx, dy, skyval, scale, errmag, chi, sharp, cliprange
+int dp_pkfit()
+pointer dp_gsubrast()
+
+begin
+ # Get some pointers.
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Allocate memory.
+ call dp_pksetup (dao)
+ call dp_mempk (dao, 3)
+
+ # Save the default values of some critical parameters.
+ recenter = DP_RECENTER(dao)
+ fitsky = DP_FITSKY(dao)
+ psflut = DP_PSFLUT(psffit)
+ clipexp = DP_CLIPEXP(dao)
+ cliprange = DP_CLIPRANGE(dao)
+
+ # Set some fitting parameters.
+ DP_RECENTER(dao) = YES
+ DP_FITSKY(dao) = NO
+ DP_CLIPEXP(dao) = 8
+ DP_CLIPRANGE(dao) = 2.5
+ DP_PSFLUT(psffit) = DP_POLDLUT(psf)
+
+ nfit = 0
+ nsat = 0
+ do istar = 1, nstars {
+
+ # Skip saturated stars.
+ if (sat[istar] == NO)
+ next
+ nsat = nsat + 1
+
+ # Get the data.
+ subim = dp_gsubrast (im, xcen[istar], ycen[istar], DP_PSFRAD(dao),
+ lowx, lowy, nxpix, nypix)
+ if (subim == NULL)
+ next
+
+ # Set the intial values for the fit parameters.
+ x = xcen[istar] - lowx + 1.0
+ y = ycen[istar] - lowy + 1.0
+ dx = (xcen[istar] - 1.0) / DP_PSFX(psffit) - 1.0
+ dy = (ycen[istar] - 1.0) / DP_PSFY(psffit) - 1.0
+ skyval = sky[istar]
+ scale = 3.0
+
+ # Fit the star.
+ ier = dp_pkfit (dao, Memr[subim], nxpix, nypix, 0.5 *
+ DP_PSFRAD(dao), x, y, dx, dy, scale, skyval, errmag, chi,
+ sharp, niter)
+
+ # Compute the fit parameters.
+ if (ier != PKERR_OK) {
+ scale = INDEFR
+ errmag = INDEFR
+ niter = 0
+ chi = INDEFR
+ sharp = INDEFR
+ } else {
+ nfit = nfit + 1
+ xcen[istar] = x + lowx - 1.0
+ ycen[istar] = y + lowy - 1.0
+ h[istar] = scale * h[1]
+ errmag = 1.085736 * errmag / scale
+ if (errmag >= 2.0)
+ errmag = INDEFR
+ scale = DP_PSFMAG(psffit) - 2.5 * log10 (scale)
+ }
+
+ if (DP_VERBOSE(dao) == YES) {
+ if (nsat == 1)
+ call printf ("\nFit for saturated stars\n")
+ call printf (
+ " %6d %7.2f %7.2f %8.3f %6.3f %3d %7.2f %7.2f\n")
+ call pargi (id[istar])
+ call pargr (xcen[istar])
+ call pargr (ycen[istar])
+ call pargr (scale)
+ call pargr (errmag)
+ call pargi (niter)
+ call pargr (chi)
+ call pargr (sharp)
+ }
+ }
+
+ if (DP_VERBOSE(dao) == YES && nsat > 0)
+ call printf ("\n")
+
+ # Restore the default values of some critical parameters.
+ DP_RECENTER(dao) = recenter
+ DP_FITSKY(dao) = fitsky
+ DP_CLIPEXP(dao) = clipexp
+ DP_CLIPRANGE(dao) = cliprange
+ DP_PSFLUT(psffit) = psflut
+
+ # Free memory.
+ call dp_pkclose (dao)
+
+ return (nfit)
+end
+
+
+# DP_PCOPY -- Make a copy of the psf in correct storage order.
+
+procedure dp_pcopy (inlut, outlut, nx, ny, nexp)
+
+real inlut[nexp,nx,ny] # the input look-up table
+real outlut[nx,ny,nexp] # the output look-up table
+int nx,ny,nexp # the size of the look-up table
+
+int k,i,j
+
+begin
+ do k = 1, nexp {
+ do j = 1, ny {
+ do i = 1, nx {
+ outlut[i,j,k] = inlut[k,i,j]
+ }
+ }
+ }
+end
diff --git a/noao/digiphot/daophot/psf/dpispstars.x b/noao/digiphot/daophot/psf/dpispstars.x
new file mode 100644
index 00000000..85a4c669
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpispstars.x
@@ -0,0 +1,329 @@
+include <fset.h>
+include <ctype.h>
+include <gset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+define HELPFILE "daophot$psf/mkpsflist.key"
+
+# DP_IPFSTARS -- Construct a stellar PSF from one or more stars in an image
+# frame.
+
+int procedure dp_ipfstars (dao, im, maxnpsf, lolimit, radius, gd, mgd, id,
+ mkstars, interactive, showplots)
+
+pointer dao # pointer to DAOPHOT structure
+pointer im # pointer to IRAF image
+int maxnpsf # maximum number of psf stars
+real lolimit # lower magnitude limit for stars
+real radius # the confusion radius for good psf stars
+pointer gd # pointer to graphics descriptor
+pointer mgd # pointer to the metacode file
+pointer id # pointer to image display stream
+bool mkstars # marked the selected and deleted psf stars
+bool interactive # interactive mode
+bool showplots # show the plots
+
+int key, nxstar, wcs, idnum, istar, ip
+pointer apsel, sp, cmd, str
+real wx, wy
+
+real dp_pstatr()
+int clgcur(), dp_pqverify(), dp_locstar(), dp_idstar(), dp_nxstar()
+int dp_pstati(), ctoi(), dp_addstar(), dp_delstar()
+
+begin
+ # Get some pointers
+ apsel = DP_APSEL(dao)
+
+ # Allocate some working space.
+ call smark (sp)
+ call salloc (str, SZ_LINE, TY_CHAR)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Initialize some variables.
+ key = 'a'
+ nxstar = 0
+ call dp_pseti (dao, PNUM, 0)
+
+ # Begin to build the PSF.
+ while (clgcur ("icommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE) !=
+ EOF) {
+
+ # Correct for tv coordinates if necessary.
+ call dp_vtol (im, wx, wy, wx, wy, 1)
+
+ switch (key) {
+
+ # Quit the interactive cursor loop.
+ case 'q':
+ if (interactive) {
+ if (dp_pqverify() == YES)
+ break
+ } else
+ break
+
+ # Print the help page.
+ case '?':
+ if (id == NULL)
+ call pagefile (HELPFILE, "")
+ else
+ call gpagefile (id, HELPFILE, "")
+
+ # Add next candidate star to the PSF.
+ case 'n':
+ if (dp_pstati (dao, PNUM) >= maxnpsf) {
+ call printf ("Number of psf stars is >= to maxnpsf\n")
+ next
+ }
+ idnum = dp_nxstar (Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMSKY(apsel)],
+ Memr[DP_APMAG(apsel)], DP_APNUM(apsel), nxstar, lolimit,
+ radius)
+ if (idnum <= 0) {
+ call printf ("No more good psf stars in photometry list\n")
+ next
+ }
+ if (dp_addstar (dao, im, wx, wy, INDEFR, idnum, gd, mgd,
+ showplots) == ERR)
+ next
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX), dp_pstatr (dao,
+ CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ # Add the star nearest the cursor position to the PSF.
+ case 'a':
+ if (dp_pstati (dao, PNUM) >= maxnpsf) {
+ call printf ("Number of psf stars is >= to maxnpsf\n")
+ next
+ }
+ if (dp_addstar (dao, im, wx, wy, INDEFR, 0, gd, mgd,
+ showplots) == ERR)
+ next
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX), dp_pstatr (dao,
+ CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ # Delete the star nearest the cursor position from the PSF.
+ case 'd':
+ if (dp_delstar (dao, im, wx, wy, 0, gd, showplots) == ERR)
+ next
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX), dp_pstatr (dao,
+ CUR_PSFY), GM_CROSS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ # List all the current psf stars.
+ case 'l':
+ if (interactive)
+ call dp_listpsf (dao, im)
+
+ # Locate the star in the aperture photometry file and print out
+ # the photometry.
+ case 'p':
+ if (interactive)
+ istar = dp_locstar (dao, im, wx, wy)
+ else
+ next
+ if (istar > 0)
+ call dp_pshow (dao, im, istar)
+ else if (istar == 0)
+ call printf ("Star not found in the photometry file\n")
+ else
+ call printf (
+ "Star off or too near the edge of the image\n")
+
+ # Colon command mode.
+ case ':':
+ for (ip = 1; IS_WHITE(Memc[cmd+ip-1]); ip = ip + 1)
+ ;
+ switch (Memc[cmd+ip-1]) {
+
+ case 'p':
+ if (! interactive)
+ next
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ istar = dp_locstar (dao, im, wx, wy)
+ else
+ istar = dp_idstar (dao, im, idnum)
+ if (istar > 0)
+ call dp_pshow (dao, im, istar)
+ else if (istar == 0)
+ call printf (
+ "Star not found in the photometry file\n")
+ else
+ call printf (
+ "Star is off or too near the edge of the image.\n")
+
+ case 'a':
+ if (dp_pstati (dao, PNUM) >= maxnpsf) {
+ call printf (
+ "Number of psf stars is >= to maxnpsf\n")
+ next
+ }
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ idnum = 0
+ if (dp_addstar (dao, im, wx, wy, INDEFR, idnum, gd, mgd,
+ showplots) == ERR)
+ next
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX),
+ dp_pstatr (dao, CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ case 'd':
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ idnum = 0
+ if (dp_delstar (dao, im, wx, wy, idnum, gd, showplots) ==
+ ERR)
+ next
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX),
+ dp_pstatr (dao, CUR_PSFY), GM_CROSS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ default:
+ call printf ("Unknown keystroke command\n")
+ }
+
+ default:
+ call printf ("Unknown keystroke command\n")
+ }
+ }
+
+ # Free up memory.
+ call sfree (sp)
+
+ return (dp_pstati (dao, PNUM))
+end
+
+
+define QUERY "[Hit return to continue, q to quit]"
+
+# DP_PQVERIFY -- Print a message in the status line asking the user if they
+# really want to quit, returning YES if they really want to quit, NO otherwise.
+
+int procedure dp_pqverify ()
+
+int ch
+pointer tty
+int getci()
+pointer ttyodes()
+
+begin
+ # Open terminal and print query.
+ tty = ttyodes ("terminal")
+ call ttyclearln (STDOUT, tty)
+ call ttyso (STDOUT, tty, YES)
+ call printf (QUERY)
+ call flush (STDOUT)
+
+ # Get character.
+ call fseti (STDIN, F_RAW, YES)
+ if (getci (STDIN, ch) == EOF)
+ ;
+
+ # Reset and close terminal.
+ call fseti (STDIN, F_RAW, NO)
+ call ttyso (STDOUT, tty, NO)
+ call ttyclearln (STDOUT, tty)
+ call printf ("\n")
+ call flush (STDOUT)
+ call ttycdes (tty)
+
+ # Return YES for the quit command, otherwise NO.
+ if (ch == 'q') {
+ return (YES)
+ } else {
+ return (NO)
+ }
+end
+
+
+
+# DP_NXSTAR -- Select the next psf star form the photometry list.
+
+int procedure dp_nxstar (ids, xcen, ycen, sky, mag, nstar, nxstar, lolimit,
+ radius)
+
+int ids[ARB] # array of star ids
+real xcen[ARB] # array of x coordinates
+real ycen[ARB] # array of y coordinates
+real sky[ARB] # array of sky values
+real mag[ARB] # array of magnitudes
+int nstar # the number of stars
+int nxstar # the current star
+real lolimit # lower data limit
+real radius # minimum separation
+
+bool omit
+int istar, jstar
+real radsq, dy2, dr2
+
+begin
+ radsq = radius * radius
+
+ # Check the first star.
+ if ((mag[1] > lolimit) && (nxstar == 0)) {
+ nxstar = 1
+ return (ids[1])
+ }
+
+ # Loop over the candidate psf stars.
+ do istar = nxstar + 1, nstar {
+
+ # Test that the candidate psf stars are not saturated and
+ # are sufficiently far from the edge of the frame.
+
+ if (mag[istar] <= lolimit)
+ next
+
+ # Text that there are no brighter stars with a distance squared
+ # of radsq.
+ omit = false
+ do jstar = 1, istar - 1 {
+ dy2 = abs (ycen[jstar] - ycen[istar])
+ if (dy2 >= radius)
+ next
+ dr2 = (xcen[jstar] - xcen[istar]) ** 2 + dy2 ** 2
+ if (dr2 >= radsq)
+ next
+ omit = true
+ break
+ }
+
+ if (omit)
+ next
+
+ nxstar = istar
+ return (ids[istar])
+ }
+
+ return (0)
+end
diff --git a/noao/digiphot/daophot/psf/dplocstar.x b/noao/digiphot/daophot/psf/dplocstar.x
new file mode 100644
index 00000000..9925f44b
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dplocstar.x
@@ -0,0 +1,109 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+# DP_LOCSTAR -- Given an x,y position locate the star in the aperture
+# photometry list which is within a critical radius of the input position.
+
+int procedure dp_locstar (dao, im, x, y)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real x, y # input position
+
+int i
+pointer psf, apsel
+real crit_rad, fitrad, rad, ax, ay
+
+begin
+ # Set up some constants.
+ psf = DP_PSF(dao)
+ apsel = DP_APSEL(dao)
+ crit_rad = DP_MATCHRAD(dao) * DP_MATCHRAD(dao)
+ fitrad = DP_FITRAD(dao)
+
+ # Search the list.
+ do i = 1, DP_APNUM(apsel) {
+
+ # Compute distance of star from the cursur position.
+ ax = Memr[DP_APXCEN(apsel)+i-1]
+ ay = Memr[DP_APYCEN(apsel)+i-1]
+ if (! IS_INDEFR(ax) && ! IS_INDEFR(ay))
+ rad = (ax - x) * (ax - x) + (ay - y) * (ay - y)
+ else
+ rad = MAX_REAL
+
+ # Found the star.
+ if (rad <= crit_rad) {
+
+ DP_CUR_PSF(psf) = i
+ DP_CUR_PSFID(psf) = Memi[DP_APID(apsel)+i-1]
+ DP_CUR_PSFX(psf) = ax
+ DP_CUR_PSFY(psf) = ay
+ DP_CUR_PSFSKY(psf) = Memr[DP_APMSKY(apsel)+i-1]
+ DP_CUR_PSFMAG(psf) = Memr[DP_APMAG(apsel)+i-1]
+
+ # Is the star too close to the edge ?
+ if (int (ax - fitrad) < 0 || int (ax + fitrad) > IM_LEN(im,1) ||
+ int (ay - fitrad) < 0 || int (ay + fitrad) > IM_LEN(im,2))
+ return (-i)
+ else
+ return (i)
+ }
+ }
+
+ return (0)
+end
+
+
+# DP_IDSTAR -- Given an id number locate the star in the aperture
+# photometry list.
+
+int procedure dp_idstar (dao, im, idnum)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int idnum # id number from photometry list
+
+int i
+pointer psf, apsel
+real fitrad, x, y
+
+begin
+ # Set up some constants.
+ psf = DP_PSF(dao)
+ apsel = DP_APSEL(dao)
+ fitrad = DP_FITRAD(dao)
+
+ # Search the list.
+ do i = 1, DP_APNUM (apsel) {
+
+ # Test the id number.
+ if (idnum != Memi[DP_APID(apsel)+i-1])
+ next
+
+ # Found the star.
+ x = Memr[DP_APXCEN(apsel)+i-1]
+ y = Memr[DP_APYCEN(apsel)+i-1]
+ DP_CUR_PSF(psf) = i
+ DP_CUR_PSFID(psf) = Memi[DP_APID(apsel)+i-1]
+ DP_CUR_PSFX(psf) = Memr[DP_APXCEN(apsel)+i-1]
+ DP_CUR_PSFY(psf) = Memr[DP_APYCEN(apsel)+i-1]
+ DP_CUR_PSFSKY(psf) = Memr[DP_APMSKY(apsel)+i-1]
+ DP_CUR_PSFMAG(psf) = Memr[DP_APMAG(apsel)+i-1]
+
+ # Is the star too close to the edge ?
+ if (IS_INDEFR(x) || IS_INDEFR(y))
+ return (0)
+ else if (int (x - fitrad) < 0 || int (x + fitrad) >
+ IM_LEN(im,1) || int (y - fitrad) < 0 || int (y + fitrad) >
+ IM_LEN(im,2))
+ return (-i)
+ else
+ return (i)
+ }
+
+ return (0)
+end
diff --git a/noao/digiphot/daophot/psf/dpmempsf.x b/noao/digiphot/daophot/psf/dpmempsf.x
new file mode 100644
index 00000000..d198c778
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpmempsf.x
@@ -0,0 +1,217 @@
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+
+# DP_PSFSETUP -- Procedure to set up the PSF parameters.
+
+procedure dp_psfsetup (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer psf
+
+begin
+ # Allocate memory for the psf fitting structure.
+ call malloc (DP_PSF(dp), LEN_PSFSTRUCT, TY_STRUCT)
+ psf = DP_PSF(dp)
+
+ # Set the size of the data box t be extracted.
+ DP_LENUSERAREA(psf) = MIN_LENUSERAREA
+
+ # Initialize the psf fitting structure.
+ DP_PC(psf) = NULL
+ DP_PV(psf) = NULL
+ DP_PTMP(psf) = NULL
+ DP_PZ(psf) = NULL
+ DP_PCLAMP(psf) = NULL
+ DP_POLD(psf) = NULL
+ DP_PSIGANA(psf) = 0.0
+ DP_PSUMANA(psf) = 0.0
+
+ # Initialize the parameters for the current PSF star.
+ DP_CUR_PSF(psf) = 0
+ DP_CUR_PSFID(psf) = 0
+ DP_CUR_PSFX(psf) = INDEFR
+ DP_CUR_PSFY(psf) = INDEFR
+ DP_CUR_PSFSKY(psf) = INDEFR
+ DP_CUR_PSFMAG(psf) = INDEFR
+
+ # Initialize the PSF star list arrays.
+ DP_PNUM (psf) = 0
+ DP_PXCEN(psf) = NULL
+ DP_PYCEN(psf) = NULL
+ DP_PMAG(psf) = NULL
+ DP_PH(psf) = NULL
+ DP_PWEIGHT(psf) = NULL
+ DP_PSAT(psf) = NULL
+ DP_PXCLAMP(psf) = NULL
+ DP_PYCLAMP(psf) = NULL
+ DP_PXOLD(psf) = NULL
+ DP_PYOLD(psf) = NULL
+
+ # Initialize the look-up table arrays.
+ DP_PSUMN(psf) = NULL
+ DP_PSUMW(psf) = NULL
+ DP_PSUMSQ(psf) = NULL
+ DP_PSIGMA(psf) = NULL
+ DP_PCONST(psf) = NULL
+ DP_POLDLUT(psf) = NULL
+
+ # Allocate space for and initialize the plot sub-structure.
+ DP_PLOTTYPE(psf) = PSF_MESHPLOT
+ DP_MANGV(psf) = 30.
+ DP_MANGH(psf) = -30.
+ DP_MFLOOR(psf) = 0.
+ DP_MCEILING(psf) = 0.
+ DP_CFLOOR(psf) = 0.0
+ DP_CCEILING(psf) = 0.0
+end
+
+
+# DP_LMEMPSF -- Allocate memory required for fitting the list of psf stars.
+
+procedure dp_lmempsf (dao)
+
+pointer dao # pointer to daophot structure
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+ if (DP_PNUM(psf) > 0) {
+ call realloc (DP_PXCEN(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PYCEN(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PMAG(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PH(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PWEIGHT(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PSAT(psf), DP_PNUM(psf), TY_INT)
+ call realloc (DP_PXCLAMP(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PYCLAMP(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PXOLD(psf), DP_PNUM(psf), TY_REAL)
+ call realloc (DP_PYOLD(psf), DP_PNUM(psf), TY_REAL)
+ }
+end
+
+
+# DP_AMEMPSF -- Allocate the memory required for fitting the analytic
+# PSF.
+
+procedure dp_amempsf (dao)
+
+pointer dao # pointer to daophot structure
+
+int npars
+pointer psf, psffit
+
+begin
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+ npars = DP_PSFNPARS(psffit)
+
+ call realloc (DP_PC(psf), npars * npars, TY_REAL)
+ call realloc (DP_PV(psf), npars, TY_REAL)
+ call realloc (DP_PZ(psf), npars, TY_REAL)
+ call realloc (DP_PCLAMP(psf), npars, TY_REAL)
+ call realloc (DP_POLD(psf), npars, TY_REAL)
+ call realloc (DP_PTMP(psf), MAX_NFCTNPARS, TY_REAL)
+end
+
+
+# DP_TMEMPSF -- Allocate the memory required for fitting the lookup tables.
+
+procedure dp_tmempsf (dao)
+
+pointer dao # pointer to daophot structure
+
+int nexp
+pointer psf, psffit
+
+begin
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ nexp = DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)
+ DP_PSFSIZE(psffit) = 2 * (nint (2.0 * DP_PSFRAD(dao)) + 1) + 1
+ DP_PSFRAD(dao) = (real (DP_PSFSIZE(psffit) - 1) / 2.0 - 1.0) / 2.0
+ DP_SPSFRAD(dao) = DP_PSFRAD(dao) * DP_SCALE(dao)
+ DP_RPSFRAD(dao) = DP_PSFRAD(dao) * DP_SCALE(dao)
+
+ call realloc (DP_PC(psf), nexp * nexp, TY_REAL)
+ call realloc (DP_PV(psf), nexp, TY_REAL)
+ call realloc (DP_PTMP(psf), nexp, TY_REAL)
+
+ call realloc (DP_PSUMN(psf), DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit),
+ TY_REAL)
+ call realloc (DP_PSUMSQ(psf), DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit),
+ TY_REAL)
+ call realloc (DP_PSIGMA(psf), DP_PSFSIZE(psffit) * DP_PSFSIZE(psffit),
+ TY_REAL)
+ call realloc (DP_POLDLUT(psf), nexp * DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit), TY_REAL)
+ if (nexp > 1)
+ call realloc (DP_PCONST(psf), DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit), TY_REAL)
+
+ call realloc (DP_PSFLUT(psffit), nexp * DP_PSFSIZE(psffit) *
+ DP_PSFSIZE(psffit), TY_REAL)
+end
+
+
+# DP_PSFCLOSE -- Procedure to set up the PSF parameters.
+
+procedure dp_psfclose (dp)
+
+pointer dp # pointer to daophot structure
+
+pointer psf
+
+begin
+ psf = DP_PSF(dp)
+
+ if (DP_PC(psf) != NULL)
+ call mfree (DP_PC(psf), TY_REAL)
+ if (DP_PV(psf) != NULL)
+ call mfree (DP_PV(psf), TY_REAL)
+ if (DP_PTMP(psf) != NULL)
+ call mfree (DP_PTMP(psf), TY_REAL)
+ if (DP_PZ(psf) != NULL)
+ call mfree (DP_PZ(psf), TY_REAL)
+ if (DP_PCLAMP(psf) != NULL)
+ call mfree (DP_PCLAMP(psf), TY_REAL)
+ if (DP_POLD(psf) != NULL)
+ call mfree (DP_POLD(psf), TY_REAL)
+
+ if (DP_PXCEN(psf) != NULL)
+ call mfree (DP_PXCEN(psf), TY_REAL)
+ if (DP_PYCEN(psf) != NULL)
+ call mfree (DP_PYCEN(psf), TY_REAL)
+ if (DP_PMAG(psf) != NULL)
+ call mfree (DP_PMAG(psf), TY_REAL)
+ if (DP_PH(psf) != NULL)
+ call mfree (DP_PH(psf), TY_REAL)
+ if (DP_PWEIGHT(psf) != NULL)
+ call mfree (DP_PWEIGHT(psf), TY_REAL)
+ if (DP_PSAT(psf) != NULL)
+ call mfree (DP_PSAT(psf), TY_INT)
+ if (DP_PXCLAMP(psf) != NULL)
+ call mfree (DP_PXCLAMP(psf), TY_REAL)
+ if (DP_PYCLAMP(psf) != NULL)
+ call mfree (DP_PYCLAMP(psf), TY_REAL)
+ if (DP_PXOLD(psf) != NULL)
+ call mfree (DP_PXOLD(psf), TY_REAL)
+ if (DP_PYOLD(psf) != NULL)
+ call mfree (DP_PYOLD(psf), TY_REAL)
+
+ if (DP_PSUMN(psf) != NULL)
+ call mfree (DP_PSUMN(psf), TY_REAL)
+ if (DP_PSUMSQ(psf) != NULL)
+ call mfree (DP_PSUMSQ(psf), TY_REAL)
+ if (DP_PSIGMA(psf) != NULL)
+ call mfree (DP_PSIGMA(psf), TY_REAL)
+ if (DP_PCONST(psf) != NULL)
+ call mfree (DP_PCONST(psf), TY_REAL)
+ if (DP_POLDLUT(psf) != NULL)
+ call mfree (DP_POLDLUT(psf), TY_REAL)
+
+ call mfree (psf, TY_STRUCT)
+end
diff --git a/noao/digiphot/daophot/psf/dpmkpsf.x b/noao/digiphot/daophot/psf/dpmkpsf.x
new file mode 100644
index 00000000..2af7dbed
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpmkpsf.x
@@ -0,0 +1,361 @@
+include <gset.h>
+include <ctype.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+define HELPFILE "daophot$psf/mkpsf.key"
+
+# DP_MKPSF -- Construct a stellar PSF from one or more stars in an image frame.
+
+procedure dp_mkpsf (dao, im, psfim, opst, psfgr, gd, mgd, id, mkstars,
+ interactive, showplots)
+
+pointer dao # pointer to the main daophot structure
+pointer im # pointer to the input image
+pointer psfim # pointer to the output psfimage
+int opst # the psf star list file descriptor
+int psfgr # the psf group file descriptor
+pointer gd # pointer to graphics descriptor
+pointer mgd # pointer to the metacode file
+pointer id # pointer to image display stream
+bool mkstars # mark the added and deleted psf stars
+bool interactive # interactive mode
+bool showplots # show the plots
+
+real wx, wy
+pointer apsel, sp, cmd, str
+int i, key, wcs, idnum, istar, ip, npsf, verbose
+bool psf_new, psf_computed, psf_written
+
+real dp_pstatr()
+int clgcur(), dp_qverify(), dp_locstar(), dp_idstar(), dp_stati()
+int dp_pstati(), ctoi(), dp_addstar(), dp_delstar(), dp_subpsf()
+int dp_fitpsf()
+bool dp_updatepsf()
+
+begin
+ # Get some pointers
+ apsel = DP_APSEL(dao)
+
+ # Allocate some working space.
+ call smark (sp)
+ call salloc (str, SZ_LINE, TY_CHAR)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+
+ # Initialize some variables.
+ key = 'a'
+ if (dp_pstati (dao, PNUM) > 0)
+ psf_new = false
+ else
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+
+ # Begin to build the PSF.
+ while (clgcur ("icommands", wx, wy, wcs, key, Memc[cmd], SZ_LINE) !=
+ EOF) {
+
+ # Convert coordinates if necessary.
+ call dp_vtol (im, wx, wy, wx, wy, 1)
+
+ switch (key) {
+
+ # Quit the interactive cursor loop.
+ case 'q':
+
+ if (interactive) {
+ if (dp_qverify (dao, im, psfim, opst, psfgr, psf_new,
+ psf_computed, psf_written) == NO)
+ next
+ } else if (dp_updatepsf (dao, im, psfim, opst, psfgr, psf_new,
+ psf_computed, psf_written)) {
+ psf_computed = true
+ psf_written = true
+ }
+
+ # Delete any empty psf and group files lying around.
+ if (! psf_written)
+ call dp_rmpsf (dao, psfim, opst, psfgr)
+
+ # Delete the PSF stars.
+ call dp_pseti (dao, PNUM, 0)
+
+ break
+
+ # Print the help page.
+ case '?':
+ if (id == NULL)
+ call pagefile (HELPFILE, "")
+ else
+ call gpagefile (id, HELPFILE, "")
+
+ # Add the star nearest the cursor position to the PSF.
+ case 'a':
+ if (dp_addstar (dao, im, wx, wy, INDEFR, 0, gd, mgd,
+ showplots) == ERR)
+ next
+ psf_new = false
+ psf_computed = false
+ psf_written = false
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX), dp_pstatr (dao,
+ CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ # Subtract the star nearest the cursor position from the PSF
+ # using the current best fit.
+ case 's':
+ if (psf_new) {
+ call printf ("The PSF star list is empty\n")
+ next
+ }
+ if (! psf_computed) {
+ call printf ("The PSF is not uptodate\n")
+ next
+ }
+ if (dp_subpsf (dao, im, wx, wy, 0, gd, mgd, showplots) == ERR)
+ next
+ if (dp_pstati (dao, PNUM) <= 0)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+
+ # Delete the star nearest the cursor position from the PSF.
+ case 'd':
+ if (dp_delstar (dao, im, wx, wy, 0, gd, showplots) == ERR)
+ next
+ if (dp_pstati (dao, PNUM) <= 0)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX), dp_pstatr (dao,
+ CUR_PSFY), GM_CROSS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ # List all the current psf stars.
+ case 'l':
+ if (interactive)
+ call dp_listpsf (dao, im)
+
+ # Fit the PSF.
+ case 'f':
+
+ # Reread the stars is necessary.
+ if (dp_pstati (dao, PNUM) > 0 && (psf_new || psf_computed)) {
+ npsf = dp_pstati (dao, PNUM)
+ call dp_pseti (dao, PNUM, 0)
+ call dp_reinit (dao)
+ verbose = dp_stati (dao, VERBOSE)
+ call dp_seti (dao, VERBOSE, NO)
+ do i = 1, npsf
+ if (dp_addstar (dao, im, wx, wy, INDEFR,
+ Memi[DP_APID(apsel)+i-1], gd, mgd,
+ false) == OK)
+ psf_new = false
+ call dp_seti (dao, VERBOSE, verbose)
+ }
+
+ # Fit the psf.
+ if (psf_new) {
+ call printf ("The PSF star list is empty\n")
+ } else if (dp_fitpsf (dao, im, Memc[str], SZ_LINE) == OK) {
+ psf_computed = true
+ } else {
+ call printf ("%s\n")
+ call pargstr (Memc[str])
+ }
+
+ # Review the fit.
+ case 'r':
+ if (psf_new) {
+ call printf ("The PSF star list is empty\n")
+ } else if (! psf_computed) {
+ call printf ("The PSF is not uptodate\n")
+ } else {
+ i = 1
+ repeat {
+ if (dp_subpsf (dao, im, wx, wy,
+ Memi[DP_APID(apsel)+i-1], gd, mgd,
+ showplots) == OK) {
+ if (dp_pstati (dao, PNUM) <= 0)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ } else
+ i = i + 1
+ } until (i > dp_pstati(dao, PNUM))
+ }
+
+ # Rebuild the PSF from scratch.
+ case 'z':
+
+ # Print message.
+ if (interactive) {
+ call dp_stats (dao, OUTPHOTFILE, Memc[str], SZ_FNAME)
+ call printf (
+ "PSF star list, image, and output files deleted\n")
+ }
+
+ # Delete the previous psf an dgroup files if any.
+ call dp_rmpsf (dao, psfim, opst, psfgr)
+
+ # Delete the PSF stars.
+ call dp_pseti (dao, PNUM, 0)
+
+ # Reopen the psf image and group files.
+ call dp_oppsf (dao, psfim, opst, psfgr)
+
+ # Reset the reduction flags.
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+
+ # Write out the PSF.
+ case 'w':
+ if (dp_updatepsf (dao, im, psfim, opst, psfgr, psf_new,
+ psf_computed, psf_written)) {
+ psf_computed = true
+ psf_written = true
+ }
+
+ # Locate the star in the aperture photometry file and print out
+ # the photometry.
+ case 'p':
+ if (interactive)
+ istar = dp_locstar (dao, im, wx, wy)
+ else
+ next
+ if (istar > 0)
+ call dp_pshow (dao, im, istar)
+ else if (istar == 0)
+ call printf ("Star not found in the photometry file.\n")
+ else
+ call printf (
+ "Star off or too near the edge of the image.\n")
+
+ # Command mode
+ case ':':
+ for (ip = 1; IS_WHITE(Memc[cmd+ip-1]); ip = ip + 1)
+ ;
+ switch (Memc[cmd+ip-1]) {
+
+ case 'p':
+ if (Memc[cmd+ip] != EOS && Memc[cmd+ip] != ' ') {
+ call dp_pcolon (dao, psfim, opst, psfgr, Memc[cmd],
+ psf_new, psf_computed, psf_written)
+ next
+ }
+ if (! interactive)
+ next
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ istar = dp_locstar (dao, im, wx, wy)
+ else
+ istar = dp_idstar (dao, im, idnum)
+ if (istar > 0)
+ call dp_pshow (dao, im, istar)
+ else if (istar == 0)
+ call printf (
+ "Star not found in the photometry file\n")
+ else
+ call printf (
+ "Star is off or too near the edge of the image.\n")
+
+ case 'a':
+ if (Memc[cmd+ip] != EOS && Memc[cmd+ip] != ' ') {
+ call dp_pcolon (dao, psfim, opst, psfgr, Memc[cmd],
+ psf_new, psf_computed, psf_written)
+ next
+ }
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ idnum = 0
+ if (dp_addstar (dao, im, wx, wy, INDEFR, idnum, gd, mgd,
+ showplots) == ERR)
+ next
+ psf_new = false
+ psf_computed = false
+ psf_written = false
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX),
+ dp_pstatr (dao, CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ case 's':
+ if (Memc[cmd+ip] != EOS && Memc[cmd+ip] != ' ') {
+ call dp_pcolon (dao, psfim, opst, psfgr, Memc[cmd],
+ psf_new, psf_computed, psf_written)
+ next
+ }
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ idnum = 0
+ if (! psf_computed) {
+ call printf ("The PSF has not been fit\n")
+ next
+ }
+ if (! psf_computed) {
+ call printf ("Warning: The PSF is not uptodate\n")
+ next
+ }
+ if (dp_subpsf (dao, im, wx, wy, idnum, gd, mgd,
+ showplots) == ERR)
+ next
+ if (dp_pstati (dao, PNUM) <= 0)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+
+ case 'd':
+ if (Memc[cmd+ip] != EOS && Memc[cmd+ip] != ' ') {
+ call dp_pcolon (dao, psfim, opst, psfgr, Memc[cmd],
+ psf_new, psf_computed, psf_written)
+ next
+ }
+ ip = ip + 1
+ if (ctoi (Memc[cmd], ip, idnum) <= 0)
+ idnum = 0
+ if (dp_delstar (dao, im, wx, wy, idnum, gd,
+ showplots) == ERR)
+ next
+ if (dp_pstati (dao, PNUM) <= 0)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr (dao, CUR_PSFX),
+ dp_pstatr (dao, CUR_PSFY), GM_CROSS, -5.0, -5.0)
+ if (gd == id)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ default:
+ call dp_pcolon (dao, psfim, opst, psfgr, Memc[cmd],
+ psf_new, psf_computed, psf_written)
+ }
+
+ default:
+ call printf ("Unknown keystroke command\n")
+ }
+ }
+
+ # Free up memory.
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dppcolon.x b/noao/digiphot/daophot/psf/dppcolon.x
new file mode 100644
index 00000000..9934f244
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppcolon.x
@@ -0,0 +1,271 @@
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_PCOLON -- Process the PSF fitting colon commands.
+
+procedure dp_pcolon (dao, psfim, opst, psfgr, cmdstr, psf_new, psf_computed,
+ psf_written)
+
+pointer dao # pointer to the daophot structure
+pointer psfim # pointer to the output psf image
+int opst # the output psf star list file descriptor
+int psfgr # the output psf group file descriptor
+char cmdstr[ARB] # the input command string
+bool psf_new # is the psf star list defined ?
+bool psf_computed # has the psf been fit ?
+bool psf_written # has the psf been updated ?
+
+bool bval
+int ncmd, ival
+pointer sp, cmd, str1, str2, str3
+real rval
+
+bool itob()
+int strdic(), nscan(), btoi(), dp_stati(), open(), dp_fctdecode()
+int dp_pstati(), strlen()
+pointer immap(), tbtopn()
+real dp_statr()
+errchk immap(), open(), tbtopn()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+ call salloc (str1, SZ_LINE, TY_CHAR)
+ call salloc (str2, SZ_LINE, TY_CHAR)
+ call salloc (str3, SZ_LINE, TY_CHAR)
+
+ # Get the command.
+ call sscan (cmdstr)
+ call gargwrd (Memc[cmd], SZ_LINE)
+ if (Memc[cmd] == EOS) {
+ call sfree (sp)
+ return
+ }
+
+ # Process the command
+ ncmd = strdic (Memc[cmd], Memc[cmd], SZ_LINE, PSF_CMDS)
+ switch (ncmd) {
+
+ case PSFCMD_PSFIMAGE:
+ call gargwrd (Memc[str1], SZ_LINE)
+ call gargwrd (Memc[str2], SZ_LINE)
+ call gargwrd (Memc[str3], SZ_LINE)
+ if (nscan() == 1) {
+ call dp_stats (dao, PSFIMAGE, Memc[str1], SZ_LINE)
+ call dp_stats (dao, OUTREJFILE, Memc[str2], SZ_LINE)
+ call dp_stats (dao, OUTPHOTFILE, Memc[str3], SZ_LINE)
+ call printf ("psfim = %s opstfile = %s grpfile = %s\n")
+ call pargstr (Memc[str1])
+ call pargstr (Memc[str2])
+ call pargstr (Memc[str3])
+ } else if (nscan() == 4) {
+ if (psfim != NULL)
+ call imunmap (psfim)
+ psfim = NULL
+ if (opst != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (opst)
+ else
+ call tbtclo (opst)
+ }
+ opst = NULL
+ if (psfgr != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (psfgr)
+ else
+ call tbtclo (psfgr)
+ }
+ psfgr = NULL
+ iferr {
+ psfim = immap (Memc[str1], NEW_IMAGE, dp_pstati (dao,
+ LENUSERAREA))
+ if (dp_stati (dao, TEXT) == YES)
+ opst = open (Memc[str2], NEW_FILE, TEXT_FILE)
+ else
+ opst = tbtopn (Memc[str2], NEW_FILE, 0)
+ if (dp_stati (dao, TEXT) == YES)
+ psfgr = open (Memc[str3], NEW_FILE, TEXT_FILE)
+ else
+ psfgr = tbtopn (Memc[str3], NEW_FILE, 0)
+ } then {
+ if (psfim != NULL)
+ call imunmap (psfim)
+ psfim = NULL
+ if (opst != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (opst)
+ else
+ call tbtclo (opst)
+ }
+ opst = NULL
+ if (psfgr != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (psfgr)
+ else
+ call tbtclo (psfgr)
+ }
+ psfgr = NULL
+ call dp_sets (dao, PSFIMAGE, "")
+ call dp_sets (dao, OUTREJFILE, "")
+ call dp_sets (dao, OUTPHOTFILE, "")
+ } else {
+ call dp_sets (dao, PSFIMAGE, Memc[str1])
+ call dp_sets (dao, OUTREJFILE, Memc[str2])
+ call dp_sets (dao, OUTPHOTFILE, Memc[str2])
+ }
+ psf_written = false
+ }
+
+ case PSFCMD_FUNCTION:
+ call gargwrd (Memc[str1], SZ_LINE)
+ if (nscan() == 1) {
+ call dp_stats (dao, FUNCLIST, Memc[str1], SZ_LINE)
+ call strcpy (Memc[str1+1], Memc[str2],
+ strlen (Memc[str1]) - 2)
+ call printf ("function = %s\n")
+ call pargstr (Memc[str2])
+ } else if (dp_fctdecode (Memc[str1], Memc[str2], SZ_FNAME) > 0) {
+ call dp_sets (dao, FUNCLIST, Memc[str2])
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_VARORDER:
+ call gargi (ival)
+ if (nscan() == 1) {
+ call printf ("varorder = %d\n")
+ call pargi (dp_stati (dao, VARORDER))
+ } else if (ival >= -1 && ival <= 2) {
+ call dp_seti (dao, VARORDER, ival)
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_FEXPAND:
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("fexpand = %b\n")
+ call pargb (itob (dp_stati (dao, FEXPAND)))
+ } else {
+ call dp_seti (dao, FEXPAND, btoi (bval))
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_PSFRAD:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("psfrad = %g scale units\n")
+ call pargr (dp_statr (dao, SPSFRAD))
+ } else {
+ call dp_setr (dao, SPSFRAD, rval)
+ call dp_setr (dao, RPSFRAD, rval)
+ call dp_setr (dao, PSFRAD, rval / dp_statr (dao, SCALE))
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_FITRAD:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("fitrad = %g scale units\n")
+ call pargr (dp_statr (dao, SFITRAD))
+ } else {
+ call dp_setr (dao, SFITRAD, rval)
+ call dp_setr (dao, FITRAD, rval / dp_statr (dao, SCALE))
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_MATCHRAD:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("matchrad = %g scale units\n")
+ call pargr (dp_statr (dao, SMATCHRAD))
+ } else {
+ call dp_setr (dao, SMATCHRAD, rval)
+ call dp_setr (dao, MATCHRAD, rval / dp_statr (dao, SCALE))
+ }
+
+ case PSFCMD_NCLEAN:
+ call gargi (ival)
+ if (nscan() == 1) {
+ call printf ("nclean = %d\n")
+ call pargi (dp_stati (dao, NCLEAN))
+ } else if (ival >= 0) {
+ call dp_seti (dao, NCLEAN, ival)
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_SATURATED:
+ call gargb (bval)
+ if (nscan() == 1) {
+ call printf ("saturated = %b\n")
+ call pargb (itob (dp_stati (dao, SATURATED)))
+ } else {
+ call dp_seti (dao, SATURATED, btoi (bval))
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_SCALE:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("scale = %g units per pixel\n")
+ call pargr (dp_statr (dao, SCALE))
+ } else {
+ call dp_setr (dao, FWHMPSF, dp_statr (dao, SFWHMPSF) / rval)
+ call dp_setr (dao, PSFRAD, dp_statr (dao, SPSFRAD) / rval)
+ call dp_setr (dao, FITRAD, dp_statr (dao, SFITRAD) / rval)
+ call dp_setr (dao, MATCHRAD, dp_statr (dao, SMATCHRAD) / rval)
+ call dp_setr (dao, SCALE, rval)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_FWHMPSF:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("fwhmpsf = %g scale units\n")
+ call pargr (dp_statr (dao, SFWHMPSF))
+ } else {
+ call dp_setr (dao, SFWHMPSF, rval)
+ call dp_setr (dao, FWHMPSF, rval / dp_statr (dao, SCALE))
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_DATAMIN:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("datamin = %g counts\n")
+ call pargr (dp_statr (dao, MINGDATA))
+ } else {
+ call dp_setr (dao, MINGDATA, rval)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ }
+
+ case PSFCMD_DATAMAX:
+ call gargr (rval)
+ if (nscan() == 1) {
+ call printf ("datamax = %g counts\n")
+ call pargr (dp_statr (dao, MAXGDATA))
+ } else {
+ call dp_setr (dao, MAXGDATA, rval)
+ psf_new = true
+ psf_computed = false
+ psf_written = false
+ }
+
+ default:
+ call printf ("Unknown or ambiguous colon command\7\n")
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dppconfirm.x b/noao/digiphot/daophot/psf/dppconfirm.x
new file mode 100644
index 00000000..092cfec3
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppconfirm.x
@@ -0,0 +1,26 @@
+# DP_PCONFIRM -- Procedure to confirm the critical psf parameters.
+
+procedure dp_pconfirm (dao)
+
+pointer dao # pointer to the daophot structure
+
+begin
+ call printf ("\n")
+
+ # Verify the functional form of the psf.
+ call dp_vfunction(dao)
+ call dp_vvarorder (dao)
+ #call dp_vfexpand (dao)
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/psf/dpplotpsf.x b/noao/digiphot/daophot/psf/dpplotpsf.x
new file mode 100644
index 00000000..4b80c50f
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpplotpsf.x
@@ -0,0 +1,49 @@
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_PLOTPSF -- Plot the psf using the default plot type.
+
+procedure dp_plotpsf (dao, im, subrast, ncols, nlines, x1, y1, gd)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+real subrast[ncols,nlines] # image subraster
+int ncols, nlines # dimensions of the subraster
+int x1, y1 # coordinates of the lower left corner
+pointer gd # pointer to the graphics stream
+
+real tx, ty
+pointer sp, title
+real dp_pstatr()
+int dp_pstati()
+
+begin
+ # Return if the graphics stream is undefined.
+ if (gd == NULL)
+ return
+
+ # Comvert the coordinates if necessary.
+ call dp_wout (dao, im, dp_pstatr(dao, CUR_PSFX), dp_pstatr(dao,
+ CUR_PSFY), tx, ty, 1)
+
+ # Construct the title.
+ call smark (sp)
+ call salloc (title, SZ_LINE, TY_CHAR)
+ call sprintf (Memc[title], SZ_LINE, "Star: %d X: %g Y: %g Mag: %g")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (dp_pstatr (dao, CUR_PSFMAG))
+
+ # Initialize plot.
+ if (dp_pstati (dao, PLOTTYPE) == PSF_MESHPLOT)
+ call dp_surfpsf (dao, subrast, ncols, nlines, Memc[title], gd)
+ else if (dp_pstati (dao, PLOTTYPE) == PSF_CONTOURPLOT)
+ call dp_contpsf (dao, subrast, ncols, nlines, Memc[title], gd)
+ else if (dp_pstati (dao, PLOTTYPE) == PSF_RADIALPLOT)
+ call dp_radpsf (dao, subrast, ncols, nlines, x1, y1,
+ Memc[title], gd)
+
+ call gdeactivate (gd, 0)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dppset.x b/noao/digiphot/daophot/psf/dppset.x
new file mode 100644
index 00000000..d98b22bd
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppset.x
@@ -0,0 +1,81 @@
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_PSETS -- Set a psf fitting string parameter.
+#
+#procedure dp_psets (dao, param, str)
+
+#pointer dao # pointer to daophot structure
+#int param # parameter
+#char str[ARB] # string value
+
+#begin
+# switch (param) {
+# default:
+# call error (0, "DP_PSETS: Unknown psf fitting string parameter")
+# }
+#end
+
+
+# DP_PSETI -- Set a daophot psf fitting integer parameter.
+
+procedure dp_pseti (dao, param, ival)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+int ival # integer value
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+
+ switch (param) {
+ case CUR_PSF:
+ DP_CUR_PSF(psf) = ival
+ case CUR_PSFID:
+ DP_CUR_PSFID(psf) = ival
+ case PNUM:
+ DP_PNUM(psf) = ival
+ case PLOTTYPE:
+ DP_PLOTTYPE(psf) = ival
+ case LENUSERAREA:
+ DP_LENUSERAREA(psf) = ival
+ default:
+ call error (0, "DP_PSETI: Unknown integer psf fitting parameter")
+ }
+end
+
+
+# DP_PSETR -- Set a real psf fitting parameter.
+
+procedure dp_psetr (dao, param, rval)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+real rval # real value
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+
+ switch (param) {
+ case CUR_PSFX:
+ DP_CUR_PSFX(psf) = rval
+ case CUR_PSFY:
+ DP_CUR_PSFY(psf) = rval
+ case CUR_PSFSKY:
+ DP_CUR_PSFSKY(psf) = rval
+ case CUR_PSFMAG:
+ DP_CUR_PSFMAG(psf) = rval
+ case CUR_PSFMIN:
+ DP_CUR_PSFMIN(psf) = rval
+ case CUR_PSFMAX:
+ DP_CUR_PSFMAX(psf) = rval
+ case CUR_PSFGMAX:
+ DP_CUR_PSFGMAX(psf) = rval
+ default:
+ call error (0, "DP_SETR: Unknown real psf fitting parameter")
+ }
+end
diff --git a/noao/digiphot/daophot/psf/dppsfutil.x b/noao/digiphot/daophot/psf/dppsfutil.x
new file mode 100644
index 00000000..17df56f6
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppsfutil.x
@@ -0,0 +1,381 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+# DP_PFSWAP -- Swap two stars in the PSF star list.
+
+procedure dp_pfswap (dao, star1, star2)
+
+pointer dao # pointer to the daophot structure
+int star1 # index of first star to be swapped
+int star2 # index of second star to be swapped
+
+pointer apsel, psf
+
+begin
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+ call dp_10swap (star1, star2, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)], Memr[DP_PXCEN(psf)],
+ Memr[DP_PYCEN(psf)], Memr[DP_PH(psf)], Memr[DP_PMAG(psf)],
+ Memi[DP_PSAT(psf)])
+end
+
+
+# DP_PFREORDER -- Move a star in the PSF star list to the end of the
+# list.
+
+procedure dp_pfreorder (dao, star, nstars)
+
+pointer dao # pointer to the daophot structure
+int star # index of star to be deleted
+int nstars # index of second star to be swapped
+
+pointer apsel, psf
+
+begin
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+ call dp_10reorder (star, Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], Memr[DP_PXCEN(psf)], Memr[DP_PYCEN(psf)],
+ Memr[DP_PH(psf)], Memr[DP_PMAG(psf)], Memi[DP_PSAT(psf)], nstars)
+end
+
+
+# DP_APLSWAP -- Swap two stars in the daophot photometry substructure.
+
+procedure dp_aplswap (dao, star1, star2)
+
+pointer dao # pointer to the daophot structure
+int star1 # index of first star to be swapped
+int star2 # index of second star to be swapped
+
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dao)
+ call dp_5swap (star1, star2, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)])
+end
+
+
+# DP_XYHPSF -- Compute the initial x, y, and height of the current PSF star.
+
+procedure dp_xyhpsf (dao, star, mag, saturated)
+
+pointer dao # pointer to the daophot structure
+int star # star for which x, y, h is to be computed
+real mag # magnitude of proposed psf star
+int saturated # is the star saturated
+
+pointer apsel, psf, psffit
+real dhdxc, dhdyc, junk
+real dp_profile()
+
+begin
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ Memr[DP_PXCEN(psf)+star-1] = Memr[DP_APXCEN(apsel)+star-1]
+ Memr[DP_PYCEN(psf)+star-1] = Memr[DP_APYCEN(apsel)+star-1]
+ if (saturated == YES)
+ Memr[DP_PH(psf)+star-1] = INDEFR
+ else
+ Memr[DP_PH(psf)+star-1] = (DP_CUR_PSFGMAX(psf) -
+ Memr[DP_APMSKY(apsel)+star-1]) /
+ dp_profile (DP_PSFUNCTION(psffit),
+ 0.0, 0.0, Memr[DP_PSFPARS(psffit)], dhdxc, dhdyc, junk, 0)
+ Memr[DP_PMAG(psf)+star-1] = mag
+ Memi[DP_PSAT(psf)+star-1] = saturated
+end
+
+
+# DP_LISTPSF -- List the PSF stars.
+
+procedure dp_listpsf (dao, im)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+
+real x, y
+pointer apsel, psf
+int i
+
+begin
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+
+ call printf ("\nCurrent PSF star list\n")
+ do i = 1, DP_PNUM(psf) {
+ call dp_ltov (im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], x, y, 1)
+ call printf (
+ " Star: %4d X: %7.2f Y: %7.2f Mag: %7.2f Sky: %10.1f\n")
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ call pargr (x)
+ call pargr (y)
+ call pargr (Memr[DP_APMAG(apsel)+i-1])
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ }
+ call printf ("\n")
+end
+
+
+# DP_LISTPARS -- List the analytic PSF parameters.
+
+procedure dp_listpars (dao)
+
+pointer dao # pointer to the daophot structure
+
+pointer psffit
+
+begin
+ psffit = DP_PSFFIT(dao)
+ call printf ("\nAnalytic PSF fit \n")
+ call printf (
+ " Function: %s X: %g Y: %g Height: %g Psfmag: %g\n")
+ call pargstr (DP_FUNCTION(dao))
+ call pargr (DP_PSFX(psffit))
+ call pargr (DP_PSFY(psffit))
+ call pargr (DP_PSFHEIGHT(psffit))
+ call pargr (DP_PSFMAG(psffit))
+
+ switch (DP_PSFUNCTION(psffit)) {
+ case FCTN_GAUSS:
+ call printf (" Par1: %g Par2: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ case FCTN_MOFFAT15:
+ call printf (
+ " Par1: %g Par2: %g XYterm: %g Moffat: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ call pargr (Memr[DP_PSFPARS(psffit)+2])
+ call pargr (1.5)
+ case FCTN_PENNY1:
+ call printf (" Par1: %g Par2: %g Par3: %g Par4: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ call pargr (Memr[DP_PSFPARS(psffit)+2])
+ call pargr (Memr[DP_PSFPARS(psffit)+3])
+ case FCTN_MOFFAT25:
+ call printf (
+ " Par1: %g Par2: %g XYterm: %g Moffat: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ call pargr (Memr[DP_PSFPARS(psffit)+2])
+ call pargr (2.5)
+ case FCTN_PENNY2:
+ call printf (
+ " Par1: %g Par2: %g Par3: %g Par4: %g Par5: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ call pargr (Memr[DP_PSFPARS(psffit)+2])
+ call pargr (Memr[DP_PSFPARS(psffit)+3])
+ call pargr (Memr[DP_PSFPARS(psffit)+4])
+ case FCTN_LORENTZ:
+ call printf (" Par1: %g Par2: %g Par3: %g\n")
+ call pargr (Memr[DP_PSFPARS(psffit)])
+ call pargr (Memr[DP_PSFPARS(psffit)+1])
+ call pargr (Memr[DP_PSFPARS(psffit)+2])
+ }
+end
+
+
+# DP_PSHOW -- Print photometry for the given star
+
+procedure dp_pshow (dao, im, istar)
+
+pointer dao # pointer to the main daophot descriptor
+pointer im # the input image descriptor
+int istar # star to be printed
+
+real x, y
+pointer apsel
+
+begin
+ apsel = DP_APSEL(dao)
+ call dp_ltov (im, Memr[DP_APXCEN(apsel)+istar-1],
+ Memr[DP_APYCEN(apsel)+istar-1], x, y, 1)
+ call printf (
+ "Star: %4d X: %7.2f Y: %7.2f Mag: %7.2f Sky: %10.1f\n")
+ call pargi (Memi[DP_APID(apsel)+istar-1])
+ call pargr (x)
+ call pargr (y)
+ call pargr (Memr[DP_APMAG(apsel)+istar-1])
+ call pargr (Memr[DP_APMSKY(apsel)+istar-1])
+end
+
+
+# DP_10REORDER -- Move a PSF star to the end of the list.
+
+procedure dp_10reorder (star, id, x, y, mag, sky, xfit, yfit, hfit, pmag,
+ sat, nstars)
+
+int star # star to be moved to the end of the list
+int id[ARB] # the ids of the stars
+real x[ARB] # the x positions of the stars
+real y[ARB] # the y positions of the stars
+real mag[ARB] # the magnitudes of the stars
+real sky[ARB] # the sky values of the stars
+real xfit[ARB] # the current x fit array
+real yfit[ARB] # the current y fit array
+real hfit[ARB] # the current height of the stars
+real pmag[ARB] # the psf star list magnitude
+int sat[ARB] # are the star saturated
+int nstars # number of stars in the list
+
+int i, ihold, sfhold
+real xhold, yhold, mhold, shold, xfhold, yfhold, hfhold, mfhold
+
+begin
+ ihold = id[star]
+ xhold = x[star]
+ yhold = y[star]
+ mhold = mag[star]
+ shold = sky[star]
+ xfhold = xfit[star]
+ yfhold = yfit[star]
+ hfhold = hfit[star]
+ mfhold = pmag[star]
+ sfhold = sat[star]
+
+ do i = star + 1, nstars {
+ id[i-1] = id[i]
+ x[i-1] = x[i]
+ y[i-1] = y[i]
+ mag[i-1] = mag[i]
+ sky[i-1] = sky[i]
+ xfit[i-1] = xfit[i]
+ yfit[i-1] = yfit[i]
+ hfit[i-1] = hfit[i]
+ pmag[i-1] = pmag[i]
+ sat[i-1] = sat[i]
+ }
+
+ id[nstars] = ihold
+ x[nstars] = xhold
+ y[nstars] = yhold
+ mag[nstars] = mhold
+ sky[nstars] = shold
+ xfit[nstars] = xfhold
+ yfit[nstars] = yfhold
+ hfit[nstars] = hfhold
+ pmag[nstars] = mfhold
+ sat[nstars] = sfhold
+end
+
+
+# DP_5SWAP -- Exchange the position of two stars in the APPHOT photometry
+# results.
+
+procedure dp_5swap (star1, star2, id, x, y, mag, sky)
+
+int star1, star2 # the indices of the two stars to exchange
+int id[ARB] # the ids of the stars
+real x[ARB] # the x postions of the stars
+real y[ARB] # the y positions of the stars
+real mag[ARB] # the magnitudes of the stars
+real sky[ARB] # the sky values of the stars
+
+int ihold
+real xhold, yhold, mhold, shold
+
+begin
+ ihold = id[star1]
+ xhold = x[star1]
+ yhold = y[star1]
+ mhold = mag[star1]
+ shold = sky[star1]
+
+ id[star1] = id[star2]
+ x[star1] = x[star2]
+ y[star1] = y[star2]
+ mag[star1] = mag[star2]
+ sky[star1] = sky[star2]
+
+ id[star2] = ihold
+ x[star2] = xhold
+ y[star2] = yhold
+ mag[star2] = mhold
+ sky[star2] = shold
+end
+
+
+# DP_10SWAP -- Exchange the position of two stars in the APPHOT photometry
+# and PSF fitting results.
+
+procedure dp_10swap (star1, star2, id, x, y, mag, sky, xfit, yfit, hfit, pmag,
+ sat)
+
+int star1, star2 # the indices of the two stars to exchange
+int id[ARB] # the ids of the stars
+real x[ARB] # the x postions of the stars
+real y[ARB] # the y positions of the stars
+real mag[ARB] # the magnitudes of the stars
+real sky[ARB] # the sky values of the stars
+real xfit[ARB] # the current x fit array
+real yfit[ARB] # the current y fit array
+real hfit[ARB] # the current height of the stars
+real pmag[ARB] # the psf star list magnitudes
+int sat[ARB] # are the star saturated
+
+int ihold, sfhold
+real xhold, yhold, mhold, shold, xfhold, yfhold, hfhold, mfhold
+
+begin
+ ihold = id[star1]
+ xhold = x[star1]
+ yhold = y[star1]
+ mhold = mag[star1]
+ shold = sky[star1]
+ xfhold = xfit[star1]
+ yfhold = yfit[star1]
+ hfhold = hfit[star1]
+ mfhold = pmag[star1]
+ sfhold = sat[star1]
+
+ id[star1] = id[star2]
+ x[star1] = x[star2]
+ y[star1] = y[star2]
+ mag[star1] = mag[star2]
+ sky[star1] = sky[star2]
+ xfit[star1] = xfit[star2]
+ yfit[star1] = yfit[star2]
+ hfit[star1] = hfit[star2]
+ pmag[star1] = pmag[star2]
+ sat[star1] = sat[star2]
+
+ id[star2] = ihold
+ x[star2] = xhold
+ y[star2] = yhold
+ mag[star2] = mhold
+ sky[star2] = shold
+ xfit[star2] = xfhold
+ yfit[star2] = yfhold
+ hfit[star2] = hfhold
+ pmag[star2] = mfhold
+ sat[star2] = sfhold
+end
+
+
+# DP_ISSAT -- Is the candidate PSF star saturated ?
+
+int procedure dp_issat (dao, starno)
+
+pointer dao # pointer to the daophot structure
+int starno # the star index number
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+ if (Memi[DP_PSAT(psf)+starno-1] == YES)
+ return (YES)
+ else
+ return (NO)
+end
diff --git a/noao/digiphot/daophot/psf/dppstat.x b/noao/digiphot/daophot/psf/dppstat.x
new file mode 100644
index 00000000..4b3f903f
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppstat.x
@@ -0,0 +1,80 @@
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+#
+## DP_PSTATS -- Fetch a psf fitting string parameter.
+#
+#procedure dp_pstats (dao, param, str, maxch)
+#
+#pointer dao # pointer to daophot structure
+#int param # parameter
+#char str[ARB] # string value
+#int maxch # maximum number of characters
+#
+#begin
+# switch (param) {
+# default:
+# call error (0, "DP_PSTATS: Unknown psf fitting string parameter")
+# }
+#end
+#
+
+# DP_PSTATI -- Fetch a psf fitting integer parameter.
+
+int procedure dp_pstati (dao, param)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+
+ switch (param) {
+ case CUR_PSF:
+ return (DP_CUR_PSF(psf))
+ case CUR_PSFID:
+ return (DP_CUR_PSFID(psf))
+ case PNUM:
+ return (DP_PNUM(psf))
+ case PLOTTYPE:
+ return (DP_PLOTTYPE(psf))
+ case LENUSERAREA:
+ return (DP_LENUSERAREA(psf))
+ default:
+ call error (0, "DP_PSTATI: Unknown psf fitting integer parameter")
+ }
+end
+
+
+# DP_PSTATR -- Fetch a psf fitting real parameter.
+
+real procedure dp_pstatr (dao, param)
+
+pointer dao # pointer to daophot structure
+int param # parameter
+
+pointer psf
+
+begin
+ psf = DP_PSF(dao)
+
+ switch (param) {
+ case CUR_PSFX:
+ return (DP_CUR_PSFX(psf))
+ case CUR_PSFY:
+ return (DP_CUR_PSFY(psf))
+ case CUR_PSFSKY:
+ return (DP_CUR_PSFSKY(psf))
+ case CUR_PSFMAG:
+ return (DP_CUR_PSFMAG(psf))
+ case CUR_PSFMIN:
+ return (DP_CUR_PSFMIN(psf))
+ case CUR_PSFMAX:
+ return (DP_CUR_PSFMAX(psf))
+ case CUR_PSFGMAX:
+ return (DP_CUR_PSFGMAX(psf))
+ default:
+ call error (0, "DP_PSTATR: Unknown psf fitting parameter")
+ }
+end
diff --git a/noao/digiphot/daophot/psf/dppsubrast.x b/noao/digiphot/daophot/psf/dppsubrast.x
new file mode 100644
index 00000000..1fafb408
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppsubrast.x
@@ -0,0 +1,172 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_PSUBRAST -- Fetch the prospective PSF star data and check it for bad
+# pixel values.
+
+pointer procedure dp_psubrast (dao, im, lowbad, highbad, x1, x2, y1, y2,
+ saturated)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+real lowbad, highbad # minimum and maximum good data values
+int x1, x2 # output x limits of the extracted subraster
+int y1, y2 # output y limits of the extracted subraster
+int saturated # is the star saturated ?
+
+pointer psf, buf
+real psfrad, fitrad
+int dp_chksr()
+pointer dp_subrast()
+
+begin
+ # Initialize.
+ psf = DP_PSF(dao)
+ buf = NULL
+ psfrad = DP_PSFRAD(dao)
+ fitrad = DP_FITRAD(dao)
+
+ # Get the data.
+ buf = dp_subrast (im, DP_CUR_PSFX(psf), DP_CUR_PSFY(psf), psfrad,
+ x1, x2, y1, y2)
+ if (buf == NULL)
+ return (NULL)
+
+ # Check for bad pixels in subraster, compute the min and max.
+ if (dp_chksr (DP_CUR_PSFX(psf), DP_CUR_PSFY(psf), Memr[buf],
+ x2 - x1 + 1, y2 - y1 + 1, x1, y1, psfrad, fitrad,
+ lowbad, highbad, saturated, DP_CUR_PSFMIN(psf),
+ DP_CUR_PSFMAX(psf), DP_CUR_PSFGMAX(psf)) == ERR) {
+ call mfree (buf, TY_REAL)
+ return (NULL)
+ }
+
+ return (buf)
+end
+
+
+# DL_LSUBRAST -- Give a valid PSF star compute the limits of the data to
+# be extracted around it.
+
+int procedure dp_lsubrast (im, xcen, ycen, radius, x1, x2, y1, y2)
+
+pointer im # input image descriptor
+real xcen, ycen # center of subraster
+real radius # radius of the box
+int x1, y1, x2, y2 # boundaries of subraster
+
+begin
+ # Calculate start position of extraction box.
+ x1 = int (xcen - radius) - 2
+ x2 = int (xcen + radius) + 3
+ y1 = int (ycen - radius) - 2
+ y2 = int (ycen + radius) + 3
+ if (x1 > IM_LEN(im,1) || x2 < 1 || y1 > IM_LEN(im,2) || y2 < 1)
+ return (ERR)
+
+ x1 = max (1, x1)
+ x2 = min (IM_LEN(im,1), x2)
+ y1 = max (1, y1)
+ y2 = min (IM_LEN(im,2), y2)
+ return (OK)
+end
+
+
+# DP_SUBRAST -- Given a valid PSF star extract the data around it.
+
+pointer procedure dp_subrast (im, xcen, ycen, radius, x1, x2, y1, y2)
+
+pointer im # input image descriptor
+real xcen, ycen # center of subraster
+real radius # radius of the box
+int x1, y1, x2, y2 # boundaries of subraster
+
+int j, ncols
+pointer buf, ptr, imbuf
+pointer imgs2r()
+
+begin
+ # Calculate start position of extraction box.
+ x1 = int (xcen - radius) - 2
+ x2 = int (xcen + radius) + 3
+ y1 = int (ycen - radius) - 2
+ y2 = int (ycen + radius) + 3
+ if (x1 > IM_LEN(im,1) || x2 < 1 || y1 > IM_LEN(im,2) || y2 < 1)
+ return (NULL)
+
+ x1 = max (1, x1)
+ x2 = min (IM_LEN(im,1), x2)
+ y1 = max (1, y1)
+ y2 = min (IM_LEN(im,2), y2)
+ call malloc (buf, (x2 - x1 + 1) * (y2 - y1 + 1), TY_REAL)
+
+ ptr = buf
+ ncols = x2 - x1 + 1
+ do j = y1, y2 {
+ imbuf = imgs2r (im, x1, x2, j, j)
+ call amovr (Memr[imbuf], Memr[ptr], ncols)
+ ptr = ptr + ncols
+ }
+
+ return (buf)
+end
+
+
+# DP_CHKSR -- Check the input subraster for bad pixels.
+
+int procedure dp_chksr (x, y, sr, xdim, ydim, x1, y1, psfrad, fitrad, lowbad,
+ highbad, saturated, dmin, dmax, gmax)
+
+real x, y # position of the star
+real sr[xdim,ydim] # the data subraster
+int xdim, ydim # the dimensions of the subraster
+int x1, y1 # the lower left hand coordinates of the array
+real psfrad # the psf radius
+real fitrad # the fitting radius
+real lowbad, highbad # the good data limits
+int saturated # is the star saturated
+real dmin, dmax # output data limits
+real gmax # maximum good data limit
+
+int i,j
+real pradsq, fradsq, dy2, r2
+
+begin
+ pradsq = psfrad * psfrad
+ fradsq = fitrad * fitrad
+ dmin = MAX_REAL
+ dmax = -MAX_REAL
+ gmax = -MAX_REAL
+ saturated = NO
+
+ # Loop through the pixels looking for bad values.
+ do j = 1, ydim {
+ dy2 = (y - (y1 + j -1)) ** 2
+ if (dy2 > pradsq)
+ next
+ do i = 1, xdim {
+ r2 = (x - (x1 + i - 1)) ** 2 + dy2
+ if (r2 > pradsq)
+ next
+ if (sr[i,j] < dmin)
+ dmin = sr[i,j]
+ if (sr[i,j] > dmax)
+ dmax = sr[i,j]
+ if (sr[i,j] < lowbad || sr[i,j] > highbad) {
+ if (r2 <= fradsq) {
+ if (sr[i,j] < lowbad)
+ return (ERR)
+ else if (saturated == NO)
+ saturated = YES
+ }
+ } else {
+ if (sr[i,j] > gmax)
+ gmax = sr[i,j]
+ }
+ }
+ }
+
+ return (OK)
+end
diff --git a/noao/digiphot/daophot/psf/dpptconfirm.x b/noao/digiphot/daophot/psf/dpptconfirm.x
new file mode 100644
index 00000000..21047440
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpptconfirm.x
@@ -0,0 +1,21 @@
+# DP_PTCONFIRM -- Confirm the critical PSTSELECT parameters.
+
+procedure dp_ptconfirm (dao)
+
+pointer dao # pointer to the daophot structure
+
+begin
+ call printf ("\n")
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the fitting radius.
+ call dp_vfitrad (dao)
+
+ # Confirm the data minimum and maximum values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/psf/dppwrtgrp.x b/noao/digiphot/daophot/psf/dppwrtgrp.x
new file mode 100644
index 00000000..e0aad167
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppwrtgrp.x
@@ -0,0 +1,642 @@
+include <time.h>
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+
+# DP_WNEISTARS -- Identify the neighbour stars of the psf stars and write them
+# out in groups.
+
+procedure dp_wneistars (dao, im, psfgr)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int psfgr # the output group file descriptor
+
+bool newfile
+int top_star, psf_star, nei1, nei2
+pointer psf
+int dp_neistars()
+
+begin
+ psf = DP_PSF(dao)
+ newfile = true
+ top_star = DP_PNUM(psf) + 1
+ do psf_star = 1, DP_PNUM(psf) {
+ if (dp_neistars (dao, psf_star, top_star, nei1, nei2) <= 0)
+ ;
+ call dp_pwrtgrp (dao, im, psfgr, psf_star, nei1, nei2, newfile)
+ if (newfile)
+ newfile = false
+ }
+end
+
+
+# DP_NEISTARS -- Identify the neighbours and friends of the neighbours for
+# an individual PSF star.
+
+int procedure dp_neistars (dao, psf_star, top_star, nei1, nei2)
+
+pointer dao # pointer to the daophot structure
+int psf_star # the psf star in question
+int top_star # pointer to the current top_star
+int nei1, nei2 # pointer to to the list of neighbours
+
+int j, nei_star
+pointer apsel
+real rsq1, rsq2, rsq
+
+begin
+ # Define some pointers
+ apsel = DP_APSEL(dao)
+
+ # These are thhe values used by daophot ii. I have decided to keep
+ # the old values because I have kept the old grouping algorithm.
+ #rsq1 = (1.5 * DP_PSFRAD(dao) + 2.0 * DP_FITRAD(dao) + 1.0) ** 2
+ #rsq2 = (2.0 * DP_FITRAD(dao) + 1.0) ** 2
+
+ rsq1 = (DP_PSFRAD(dao) + 2.0 * DP_FITRAD(dao) + 1.0) ** 2
+ rsq2 = (2.0 * DP_FITRAD(dao)) ** 2
+
+ # Find the neighbour stars for a given psf star. This step is the
+ # same as the daophot ii step although I am using a smaller critical
+ # radius.
+
+ nei1 = top_star
+ for (j = top_star; j <= DP_APNUM(apsel); j = j + 1) {
+ rsq = (Memr[DP_APXCEN(apsel)+j-1] -
+ Memr[DP_APSEL(apsel)+psf_star-1]) ** 2 +
+ (Memr[DP_APYCEN(apsel)+j-1] -
+ Memr[DP_APYCEN(apsel)+psf_star-1]) ** 2
+ if (rsq > rsq1)
+ next
+ call dp_5swap (j, top_star, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)])
+ top_star = top_star +1
+ }
+ nei2 = top_star - 1
+
+ # Find the friends of the neighbor stars. I do this on a per psf
+ # star basis. I do not find friends of all the neighbor stars
+ # only the neighbour stars for a particular psf star. This is
+ # because I found the daophot ii algorithm could produce too
+ # may odd stars.
+
+ do nei_star = nei1, nei2 {
+ for (j = top_star; j <= DP_APNUM(apsel); j = j + 1) {
+ rsq = (Memr[DP_APXCEN(apsel)+j-1] -
+ Memr[DP_APSEL(apsel)+nei_star-1]) ** 2 +
+ (Memr[DP_APYCEN(apsel)+j-1] -
+ Memr[DP_APYCEN(apsel)+nei_star-1]) ** 2
+ if (rsq > rsq2)
+ next
+ call dp_5swap (j, top_star, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)])
+ top_star = top_star +1
+ }
+ }
+ nei2 = top_star - 1
+
+ return (nei2 - nei1 + 1)
+end
+
+
+# DP_PWRTGRP -- Add a group to the PSF output group file.
+
+procedure dp_pwrtgrp (dao, im, psfgr, psf_star, nei1_star, nei2_star, new_table)
+
+pointer dao # the pointer to the daophot structure
+pointer im # the input image descriptor
+int psfgr # the group file descriptor
+int psf_star # the psf star index
+int nei1_star, nei2_star # the first and last neighbour star indices
+bool new_table # should a new table be created
+
+int group
+
+begin
+ # Chexk to see if the PSF group file is open.
+ if (psfgr == NULL)
+ return
+
+ # Create the table.
+ if (new_table) {
+
+ # Initialize.
+ group = 1
+
+ # Make a new group.
+ if (DP_TEXT(dao) == YES)
+ call dp_pxnewgrp (dao, im, psfgr, psf_star, nei1_star,
+ nei2_star, group)
+ else
+ call dp_ptnewgrp (dao, im, psfgr, psf_star, nei1_star,
+ nei2_star, group)
+
+ } else {
+
+ # Increment.
+ group = group + 1
+
+ # Add to the file.
+ if (DP_TEXT(dao) == YES)
+ call dp_pxaddgrp (dao, im, psfgr, psf_star, nei1_star,
+ nei2_star, group)
+ else
+ call dp_ptaddgrp (dao, im, psfgr, psf_star, nei1_star,
+ nei2_star, group)
+ }
+
+end
+
+
+define NCOLUMN 5
+
+# DP_WPLIST -- Write the list of psf stars to the output psf star list.
+
+procedure dp_wplist (dao, im, opst)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int opst # the output psf star list descriptor
+
+pointer apsel, psf, sp, ocolpoint, tx, ty
+int dp_stati()
+bool itob()
+
+begin
+ # Get some daophot pointers.
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (ocolpoint, NCOLUMN, TY_POINTER)
+ call salloc (tx, DP_PNUM(psf), TY_REAL)
+ call salloc (ty, DP_PNUM(psf), TY_REAL)
+
+ # Initialize the output file.
+ if (dp_stati (dao, TEXT) == YES) {
+ call dp_pxgrppars (dao, opst)
+ call dp_xpbanner (opst)
+ } else {
+ call dp_tpdefcol (opst, Memi[ocolpoint])
+ call dp_ptgrppars (dao, opst)
+ }
+
+ # Write out the stars.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[tx], Memr[ty], DP_PNUM(psf))
+ call dp_wpstars (opst, Memi[ocolpoint], itob (dp_stati (dao, TEXT)),
+ Memi[DP_APID(apsel)], Memr[tx], Memr[ty], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], DP_PNUM(psf))
+
+ # Free memory.
+ call sfree (sp)
+end
+
+
+define PGR_NAMESTR "#N%4tID%10tGROUP%16tXCENTER%26tYCENTER%36tMAG%48t\
+MSKY%80t\\\n"
+define PGR_UNITSTR "#U%4t##%10t##%16tpixels%26tpixels%36tmagnitudes%48t\
+counts%80t\\\n"
+define PGR_FORMATSTR "#F%4t%%-9d%10t%%-6d%16t%%-10.3f%26t%%-10.3f%36t\
+%%-12.3f%48t%%-15.7g%80t \n"
+define PGR_DATASTR "%-9d%10t%-6d%16t%-10.3f%26t%-10.3f%36t%-12.3f%48t\
+%-15.7g%80t \n"
+
+# DP_PXNEWGRP -- Create a new PSF output group text file and write the
+# first group to it.
+
+procedure dp_pxnewgrp (dao, im, tp, psf_star, nei1_star, nei2_star, group)
+
+pointer dao # pointer to the daophot structure.
+pointer im # pointer to the input image
+int tp # the output file descriptor
+int psf_star # the psf star index
+int nei1_star, nei2_star # the first and last neighbour star indices
+int group # current group
+
+real tx, ty
+pointer apsel
+int i
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Define some pointers.
+ apsel = DP_APSEL(dao)
+
+ # Write out the header parameters.
+ call dp_pxgrppars (dao, tp)
+
+ # Set up the column definitions.
+ call fprintf (tp, "#\n")
+ call fprintf (tp, PGR_NAMESTR)
+ call fprintf (tp, PGR_UNITSTR)
+ call fprintf (tp, PGR_FORMATSTR)
+ call fprintf (tp, "#\n")
+
+ # Write out the psf star.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+psf_star-1],
+ Memr[DP_APYCEN(apsel)+psf_star-1], tx, ty, 1)
+ call fprintf (tp, PGR_DATASTR)
+ call pargi (Memi[DP_APID(apsel)+psf_star-1])
+ call pargi (group)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (Memr[DP_APMAG(apsel)+psf_star-1])
+ call pargr (Memr[DP_APMSKY(apsel)+psf_star-1])
+
+ # Write out the neighbour stars.
+ do i = nei1_star, nei2_star {
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], tx, ty, 1)
+ call fprintf (tp, PGR_DATASTR)
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ call pargi (group)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (Memr[DP_APMAG(apsel)+i-1])
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ }
+end
+
+
+# DP_PTNEWGRP -- Create a new PSF output group ST table and add to a new
+# group to it.
+
+procedure dp_ptnewgrp (dao, im, tp, psf_star, nei1_star, nei2_star, group)
+
+pointer dao # pointer to the daophot structure.
+pointer im # the input image descriptor
+pointer tp # pointer to table
+int psf_star # the psf star index
+int nei1_star, nei2_star # the first and last psf star indices
+int group # current group
+
+real tx, ty
+pointer sp, colnames, colunits, colformat, coldtype, collen, colpoint
+pointer apsel
+int i, j, row
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Define some pointers.
+ apsel = DP_APSEL(dao)
+
+ # Allocate space for table definition.
+ call smark (sp)
+ call salloc (colpoint, PSF_NOUTCOLS, TY_INT)
+ call salloc (colnames, PSF_NOUTCOLS * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, PSF_NOUTCOLS * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, PSF_NOUTCOLS * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (coldtype, PSF_NOUTCOLS, TY_INT)
+ call salloc (collen, PSF_NOUTCOLS, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (GROUP, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+5*SZ_COLNAME+5], SZ_COLNAME)
+
+ # Set up the format definitions.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("%6d", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("%10.2f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("%10.2f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("%12.3f", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+ call strcpy ("%15.7g", Memc[colformat+5*SZ_COLFMT+5], SZ_COLFMT)
+
+ # Define the column units.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("NUMBER", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+ call strcpy ("COUNTS", Memc[colunits+5*SZ_COLUNITS+5], SZ_COLUNITS)
+
+ # Define the datatypes of the columns.
+ Memi[coldtype] = TY_INT
+ Memi[coldtype+1] = TY_INT
+ Memi[coldtype+2] = TY_REAL
+ Memi[coldtype+3] = TY_REAL
+ Memi[coldtype+4] = TY_REAL
+ Memi[coldtype+5] = TY_REAL
+
+ # Initialize the column length parameter.
+ do i = 1, PSF_NOUTCOLS {
+ j = i - 1
+ Memi[collen+j] = 1
+ }
+
+ # Define the table.
+ call tbcdef (tp, Memi[colpoint], Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[coldtype], Memi[collen], PSF_NOUTCOLS)
+
+ # Create the table.
+ call tbtcre (tp)
+
+ # Write out the psf star.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+psf_star-1],
+ Memr[DP_APYCEN(apsel)+psf_star-1], tx, ty, 1)
+ call tbrpti (tp, Memi[colpoint], Memi[DP_APID(apsel)+psf_star-1], 1, 1)
+ call tbrpti (tp, Memi[colpoint+1], group, 1, 1)
+ call tbrptr (tp, Memi[colpoint+2], tx, 1, 1)
+ call tbrptr (tp, Memi[colpoint+3], ty, 1, 1)
+ call tbrptr (tp, Memi[colpoint+4], Memr[DP_APMAG(apsel)+psf_star-1],
+ 1, 1)
+ call tbrptr (tp, Memi[colpoint+5], Memr[DP_APMSKY(apsel)+psf_star-1],
+ 1, 1)
+
+ # Now write out the group.
+ row = 2
+ do i = nei1_star, nei2_star {
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], tx, ty, 1)
+ call tbrpti (tp, Memi[colpoint], Memi[DP_APID(apsel)+i-1], 1, row)
+ call tbrpti (tp, Memi[colpoint+1], group, 1, row)
+ call tbrptr (tp, Memi[colpoint+2], tx, 1, row)
+ call tbrptr (tp, Memi[colpoint+3], ty, 1, row)
+ call tbrptr (tp, Memi[colpoint+4], Memr[DP_APMAG(apsel)+i-1],
+ 1, row)
+ call tbrptr (tp, Memi[colpoint+5], Memr[DP_APMSKY(apsel)+i-1],
+ 1, row)
+ row = row + 1
+ }
+
+ # Add the header parameters to the table.
+ call dp_ptgrppars (dao, tp)
+
+ call sfree (sp)
+end
+
+
+# DP_PTGRPPARS -- Add parameters to the header of the output PSF group ST
+# table.
+
+procedure dp_ptgrppars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+pointer tp # pointer to the table
+
+pointer sp, outstr, date, time
+int envfind()
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Allocate workin space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the task and date identifiers.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IRAF", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call tbhadt (tp, "USER", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "HOST", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call tbhadt (tp, "DATE", Memc[date])
+ call tbhadt (tp, "TIME", Memc[time])
+
+ # Define the package and task.
+ call tbhadt (tp, "PACKAGE", "daophot")
+ call tbhadt (tp, "TASK", "psf")
+
+ # Define the input and output files.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "IMAGE", Memc[outstr])
+
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PHOTFILE", Memc[outstr])
+ if (DP_COORDS(dao) == EOS)
+ call tbhadt (tp, "PSTFILE", "\"\"")
+ else {
+ call dp_froot (DP_COORDS(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSTFILE", Memc[outstr])
+ }
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "PSFIMAGE", DP_PSFIMAGE(dao))
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "OPSTFILE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call tbhadt (tp, "GRPSFILE", Memc[outstr])
+
+ # Data dependent parameters.
+ call tbhadr (tp, "SCALE", DP_SCALE(dao))
+
+ # Observing parameters.
+ call tbhadt (tp, "OTIME", DP_OTIME(dao))
+ call tbhadt (tp, "IFILTER", DP_IFILTER(dao))
+ call tbhadr (tp, "XAIRMASS", DP_XAIRMASS(dao))
+
+ # Grouping parameters.
+ call tbhadr (tp, "PSFRAD", DP_SPSFRAD(dao))
+ call tbhadr (tp, "FITRAD", DP_SFITRAD(dao))
+
+ call sfree(sp)
+end
+
+
+# DP_PXGRPPARS -- Add parameters to the header of the output PSF group text
+# file.
+
+procedure dp_pxgrppars (dao, tp)
+
+pointer dao # pointer to the daophot structure
+int tp # the output file descriptor
+
+pointer sp, outstr, date, time
+int envfind()
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Allocate workin space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Write the task and date identifiers.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("NOAO/IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IRAF", Memc[outstr], "version", "")
+ if (envfind ("userid", Memc[outstr], SZ_LINE) > 0)
+ call dp_sparam (tp, "USER", Memc[outstr], "name", "")
+ call gethost (Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "HOST", Memc[outstr], "computer", "")
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call dp_sparam (tp, "DATE", Memc[date], "yyyy-mm-dd", "")
+ call dp_sparam (tp, "TIME", Memc[time], "hh:mm:ss", "")
+
+ # Define the package and task.
+ call dp_sparam (tp, "PACKAGE", "daophot", "name", "")
+ call dp_sparam (tp, "TASK", "psf", "name", "")
+
+ # Define the input and output files.
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "IMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PHOTFILE", Memc[outstr], "filename", "")
+ if (DP_COORDS(dao) == EOS)
+ call dp_sparam (tp, "PSTFILE", "\"\"", "filename", "")
+ else {
+ call dp_froot (DP_COORDS(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSTFILE", Memc[outstr], "filename", "")
+ }
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "PSFIMAGE", Memc[outstr], "imagename", "")
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "GRPSFILE", Memc[outstr], "filename", "")
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call dp_sparam (tp, "OPSTFILE", Memc[outstr], "filename", "")
+
+ # Define the data dependent parameters.
+ call dp_rparam (tp, "SCALE", DP_SCALE(dao), "units/pix", "")
+
+ # Observing parameters.
+ call dp_sparam (tp, "OTIME", DP_OTIME(dao), "timeunit", "")
+ call dp_sparam (tp, "IFILTER", DP_IFILTER(dao), "filter", "")
+ call dp_rparam (tp, "XAIRMASS", DP_XAIRMASS(dao), "number", "")
+
+ # Grouping parameters.
+ call dp_rparam (tp, "PSFRAD", DP_SPSFRAD(dao), "scaleunit", "")
+ call dp_rparam (tp, "FITRAD", DP_SFITRAD(dao), "scaleunit", "")
+
+ call sfree(sp)
+end
+
+
+# DP_PXADDGRP -- Add a new group to the existing PSF output group text file.
+
+procedure dp_pxaddgrp (dao, im, tp, psf_star, nei1_star, nei2_star, group)
+
+pointer dao # pointer to daophot structure
+pointer im # the input image descriptor
+int tp # the output file descriptor
+int psf_star # the psf star index
+int nei1_star, nei2_star # the first and last neighbour star indices
+int group # current group
+
+real tx, ty
+pointer apsel
+int i
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Get some daophot pointers.
+ apsel = DP_APSEL(dao)
+
+ # Write out the psf star.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+psf_star-1],
+ Memr[DP_APYCEN(apsel)+psf_star-1], tx, ty, 1)
+ call fprintf (tp, PGR_DATASTR)
+ call pargi (Memi[DP_APID(apsel)+psf_star-1])
+ call pargi (group)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (Memr[DP_APMAG(apsel)+psf_star-1])
+ call pargr (Memr[DP_APMSKY(apsel)+psf_star-1])
+
+ # Now write out the group.
+ do i = nei1_star, nei2_star {
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], tx, ty, 1)
+ call fprintf (tp, PGR_DATASTR)
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ call pargi (group)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (Memr[DP_APMAG(apsel)+i-1])
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ }
+end
+
+
+# DP_PTADDGRP -- Add a new group to the existing PSF output group ST table.
+
+procedure dp_ptaddgrp (dao, im, tp, psf_star, nei1_star, nei2_star, group)
+
+pointer dao # pointer to daophot structure
+pointer im # the input image descriptor
+pointer tp # pointer to output table
+int psf_star # the psf star index
+int nei1_star, nei2_star # the first and last neighbor star indices
+int group # current group
+
+real tx, ty
+pointer apsel, sp, colpoint
+int i, nrows
+int tbpsta()
+
+begin
+ # Check to see if the PSF group file is open.
+ if (tp == NULL)
+ return
+
+ # Allocate space for the column pointers.
+ call smark (sp)
+ call salloc (colpoint, PSF_NOUTCOLS, TY_INT)
+
+ # Get some daophot pointers.
+ apsel = DP_APSEL(dao)
+
+ # Find the number of rows in the table and add on at the end.
+ nrows = tbpsta (tp, TBL_NROWS)
+
+ # Write out the psf star
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+psf_star-1],
+ Memr[DP_APYCEN(apsel)+psf_star-1], tx, ty, 1)
+ nrows = nrows + 1
+ call tbrpti (tp, Memi[colpoint], Memi[DP_APID(apsel)+psf_star-1],
+ 1, nrows)
+ call tbrpti (tp, Memi[colpoint+1], group, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+2], tx, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+3], ty, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+4], Memr[DP_APMAG(apsel)+psf_star-1],
+ 1, nrows)
+ call tbrptr (tp, Memi[colpoint+5], Memr[DP_APMSKY(apsel)+psf_star-1],
+ 1, nrows)
+
+ # Now write out the group.
+ do i = nei1_star, nei2_star {
+ nrows = nrows + 1
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], tx, ty, 1)
+ call tbrpti (tp, Memi[colpoint], Memi[DP_APID(apsel)+i-1], 1, nrows)
+ call tbrpti (tp, Memi[colpoint+1], group, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+2], tx, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+3], ty, 1, nrows)
+ call tbrptr (tp, Memi[colpoint+4], Memr[DP_APMAG(apsel)+i-1], 1,
+ nrows)
+ call tbrptr (tp, Memi[colpoint+5], Memr[DP_APMSKY(apsel)+i-1], 1,
+ nrows)
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dppwselmer.x b/noao/digiphot/daophot/psf/dppwselmer.x
new file mode 100644
index 00000000..24684b67
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dppwselmer.x
@@ -0,0 +1,220 @@
+include <tbset.h>
+include "../lib/apseldef.h"
+
+define NCOLUMN 5
+
+define PS_DATA1STR "%-9d%10t%-10.3f%20t%-10.3f%30t%-12.3f%42t%-15.7g%80t \n"
+
+# DP_XPSELMER -- Write the output photometry record to a text file.
+
+procedure dp_xpselmer (tpout, id, x, y, mag, sky)
+
+pointer tpout # pointer to the output table
+int id # id of the star
+real x, y # position of the star
+real mag # magnitude of the star
+real sky # value of sky
+
+begin
+ call fprintf (tpout, PS_DATA1STR)
+ call pargi (id)
+ call pargr (x)
+ call pargr (y)
+ call pargr (mag)
+ call pargr (sky)
+end
+
+
+# DP_TPSELMER -- Write out the PSF stars into an ST Table.
+
+procedure dp_tpselmer (tp_out, id, x, y, mag, sky, colpoint, row)
+
+int tp_out # the output table descriptor
+int id # the object id
+real x # the object x coordinate
+real y # the object y coordinate
+real mag # the object mangitude
+real sky # the object sky value
+int colpoint[ARB] # the column pointers
+int row # current table row
+
+begin
+ # Write out the data.
+ call tbrpti (tp_out, colpoint[1], id, 1, row)
+ call tbrptr (tp_out, colpoint[2], x, 1, row)
+ call tbrptr (tp_out, colpoint[3], y, 1, row)
+ call tbrptr (tp_out, colpoint[4], mag, 1, row)
+ call tbrptr (tp_out, colpoint[5], sky, 1, row)
+end
+
+
+# DP_XPSELPARS -- Add various parameters to the header of the photometry table.
+
+procedure dp_xpselpars (tp, image, maxnpsf, scale, psfrad, fitrad)
+
+pointer tp # pointer to the table
+char image[ARB] # input image name
+int maxnpsf # maximum number of psfstars
+real scale # the image scale
+real psfrad # the psf radius
+real fitrad # the fitting radius
+
+pointer sp, str
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Add the image name nad maxnpsf parameters.
+ call dp_imroot (image, Memc[str], SZ_FNAME)
+ call dp_sparam (tp, "IMAGE", Memc[str], "imagename", "")
+ call dp_iparam (tp, "MAXNPSF", maxnpsf, "number", "")
+ call dp_rparam (tp, "NEWSCALE", scale, "units", "")
+ call dp_rparam (tp, "PSFRAD", psfrad, "scaleunit", "")
+ call dp_rparam (tp, "FITRAD", fitrad, "scaleunit", "")
+
+ call sfree (sp)
+end
+
+
+define PS_NAME1STR "#N%4tID%10tXCENTER%20tYCENTER%30tMAG%42tMSKY%80t\\\n"
+define PS_UNIT1STR "#U%4t##%10tpixels%20tpixels%30tmagnitudes%42tcounts\
+%80t\\\n"
+define PS_FORMAT1STR "#F%4t%%-9d%10t%%-10.3f%20t%%-10.3f%30t%%-12.3f%42t\
+%%-15.7g%80t \n"
+
+# DP_XPBANNER -- Create a new text file banner.
+
+procedure dp_xpbanner (tp)
+
+pointer tp # pointer to the output file
+
+begin
+ # Print out the banner file.
+ call fprintf (tp, "#\n")
+ call fprintf (tp, PS_NAME1STR)
+ call fprintf (tp, PS_UNIT1STR)
+ call fprintf (tp, PS_FORMAT1STR)
+ call fprintf (tp, "#\n")
+end
+
+
+# DP_TPDEFCOL -- Define the columns for the output table
+
+procedure dp_tpdefcol (tp, colpoint)
+
+pointer tp # pointer to the output table
+int colpoint[ARB] # array of column pointers
+
+int i
+pointer sp, colnames, colunits, colformat, col_dtype, col_len
+
+begin
+ # Allocate space for the table definition.
+ call smark (sp)
+ call salloc (colnames, NCOLUMN * (SZ_COLNAME + 1), TY_CHAR)
+ call salloc (colunits, NCOLUMN * (SZ_COLUNITS + 1), TY_CHAR)
+ call salloc (colformat, NCOLUMN * (SZ_COLFMT + 1), TY_CHAR)
+ call salloc (col_dtype, NCOLUMN, TY_INT)
+ call salloc (col_len, NCOLUMN, TY_INT)
+
+ # Set up the column definitions.
+ call strcpy (ID, Memc[colnames], SZ_COLNAME)
+ call strcpy (XCENTER, Memc[colnames+SZ_COLNAME+1], SZ_COLNAME)
+ call strcpy (YCENTER, Memc[colnames+2*SZ_COLNAME+2], SZ_COLNAME)
+ call strcpy (MAG, Memc[colnames+3*SZ_COLNAME+3], SZ_COLNAME)
+ call strcpy (SKY, Memc[colnames+4*SZ_COLNAME+4], SZ_COLNAME)
+
+ # Define the column formats.
+ call strcpy ("%6d", Memc[colformat], SZ_COLFMT)
+ call strcpy ("10.3f", Memc[colformat+SZ_COLFMT+1], SZ_COLFMT)
+ call strcpy ("10.3f", Memc[colformat+2*SZ_COLFMT+2], SZ_COLFMT)
+ call strcpy ("12.3f", Memc[colformat+3*SZ_COLFMT+3], SZ_COLFMT)
+ call strcpy ("15.7g", Memc[colformat+4*SZ_COLFMT+4], SZ_COLFMT)
+
+ # Define the column units.
+ call strcpy ("NUMBER", Memc[colunits], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+SZ_COLUNITS+1], SZ_COLUNITS)
+ call strcpy ("PIXELS", Memc[colunits+2*SZ_COLUNITS+2], SZ_COLUNITS)
+ call strcpy ("MAGNITUDES", Memc[colunits+3*SZ_COLUNITS+3], SZ_COLUNITS)
+ call strcpy ("ADU", Memc[colunits+4*SZ_COLUNITS+4], SZ_COLUNITS)
+
+ # Define the column data types.
+ Memi[col_dtype] = TY_INT
+ Memi[col_dtype+1] = TY_REAL
+ Memi[col_dtype+2] = TY_REAL
+ Memi[col_dtype+3] = TY_REAL
+ Memi[col_dtype+4] = TY_REAL
+
+ # Define the column lengths.
+ do i = 1, NCOLUMN
+ Memi[col_len+i-1] = 1
+
+ # Define and create the table.
+ call tbcdef (tp, colpoint, Memc[colnames], Memc[colunits],
+ Memc[colformat], Memi[col_dtype], Memi[col_len], NCOLUMN)
+ call tbtcre (tp)
+
+ call sfree (sp)
+end
+
+
+# DP_TPSELPARS -- Add various parameters to the header of the photometry table.
+
+procedure dp_tpselpars (tp, image, maxnpsf, scale, psfrad, fitrad)
+
+pointer tp # pointer to the table
+char image[ARB] # the input image name
+int maxnpsf # maximum number of psf stars
+real scale # the image scale
+real psfrad # the psf radius
+real fitrad # the fitting radius
+
+pointer sp, str
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Add the min_group and max_group parameters.
+ call dp_imroot (image, Memc[str], SZ_FNAME)
+ call tbhadt (tp, "IMAGE", Memc[str])
+ call tbhadi (tp, "MAXNPSF", maxnpsf)
+ call tbhadr (tp, "SCALE", scale)
+ call tbhadr (tp, "PSFRAD", psfrad)
+ call tbhadr (tp, "FITRAD", fitrad)
+
+ call sfree (sp)
+end
+
+
+# DP_WPSTARS -- Write the psf stars to the output file.
+
+procedure dp_wpstars (tp_out, colpoint, text_file, ids, xcen, ycen, mag,
+ sky, npsf)
+
+int tp_out # the output file descriptor
+int colpoint[ARB] # array of column pointers
+bool text_file # is the output file a text file
+int ids[ARB] # array of star ids
+real xcen[ARB] # array of x coordinates
+real ycen[ARB] # array of y coordinates
+real mag[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+int npsf # the number of stars
+
+int istar, row
+
+begin
+ row = 0
+ do istar = 1, npsf {
+ if (text_file)
+ call dp_xpselmer (tp_out, ids[istar], xcen[istar], ycen[istar],
+ mag[istar], sky[istar])
+ else {
+ row = row + 1
+ call dp_tpselmer (tp_out, ids[istar], xcen[istar], ycen[istar],
+ mag[istar], sky[istar], colpoint, row)
+ }
+ }
+end
diff --git a/noao/digiphot/daophot/psf/dpqverify.x b/noao/digiphot/daophot/psf/dpqverify.x
new file mode 100644
index 00000000..6fff239f
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpqverify.x
@@ -0,0 +1,68 @@
+include <fset.h>
+
+define QUERY "[Hit return to continue, q to quit, w to force update of PSF]"
+
+# DP_QVERIFY -- Print a message in the status line asking the user if they
+# really want to quit, returning YES if they really want to quit, NO otherwise.
+
+int procedure dp_qverify (dao, im, psfim, opst, psfgr, psf_new, psf_computed,
+ psf_written)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+pointer psfim # the output psf image descriptor
+int opst # the output psf star list file descriptor
+int psfgr # the output psf group file descriptor
+bool psf_new # has the psf star list been defined ?
+bool psf_computed # is the psf fit defined ?
+bool psf_written # has the psf been saved ?
+
+int ch
+pointer tty
+bool dp_updatepsf()
+int getci()
+pointer ttyodes()
+
+begin
+ # Print status warning message.
+ if (psf_new)
+ call printf ("Warning: The PSF star list is undefined.\n")
+ else if (! psf_computed)
+ call printf ("Warning: The PSF fit is not current.\n")
+ else if (! psf_written)
+ call printf ("Warning: The PSF has not been saved.\n")
+
+ # Open terminal and print query.
+ tty = ttyodes ("terminal")
+ call ttyclearln (STDOUT, tty)
+ call ttyso (STDOUT, tty, YES)
+ call printf (QUERY)
+ call flush (STDOUT)
+
+ # Get character.
+ call fseti (STDIN, F_RAW, YES)
+ if (getci (STDIN, ch) == EOF)
+ ;
+
+ # Reset and close terminal.
+ call fseti (STDIN, F_RAW, NO)
+ call ttyso (STDOUT, tty, NO)
+ call ttyclearln (STDOUT, tty)
+ call printf ("\n")
+ call flush (STDOUT)
+ call ttycdes (tty)
+
+ # Return YES for the quit command, otherwise NO.
+ if (ch == 'q') {
+ return (YES)
+ } else if (ch == 'w') {
+ if (dp_updatepsf (dao, im, psfim, opst, psfgr, psf_new,
+ psf_computed, psf_written)) {
+ psf_computed = true
+ psf_written = true
+ }
+ return (NO)
+ } else {
+ return (NO)
+ }
+end
diff --git a/noao/digiphot/daophot/psf/dpradpsf.x b/noao/digiphot/daophot/psf/dpradpsf.x
new file mode 100644
index 00000000..7e649e7e
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpradpsf.x
@@ -0,0 +1,75 @@
+include <gset.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+define FRACTION 0.10
+
+# DP_RADPSF -- Draw a radial profile plot of a data subraster containing a
+# candidate psf star.
+
+procedure dp_radpsf (dao, subras, ncols, nlines, x1, y1, title, gp)
+
+pointer dao # pointer to DAOPHOT structure
+real subras[ncols,nlines] # data subraster
+int ncols, nlines # dimesnions of subraster
+int x1, y1 # coordinates of left hand corner
+char title[ARB] # title string
+pointer gp # pointer to graphics descriptor
+
+int npts
+pointer psf, sp, radius, intensity, str
+real ymin, ymax, r1, r2, i1, i2
+int dp_rivectors()
+
+begin
+ # Get the pointer to the DAOPHOT PSF fitting substructure.
+ psf = DP_PSF (dao)
+
+ # Allocate temporary space.
+ call smark (sp)
+ call salloc (radius, ncols * nlines, TY_REAL)
+ call salloc (intensity, ncols * nlines, TY_REAL)
+ call salloc (str, SZ_LINE, TY_CHAR)
+
+ # Compute the radial profile.
+ npts = dp_rivectors (subras, ncols, nlines, x1, y1, DP_CUR_PSFX(psf),
+ DP_CUR_PSFY(psf), DP_PSFRAD(dao), Memr[radius], Memr[intensity])
+ call alimr (Memr[intensity], npts, ymin, ymax)
+
+ # Make the plot.
+ call gclear (gp)
+ r1 = -FRACTION * DP_PSFRAD(dao)
+ r2 = DP_PSFRAD(dao) + FRACTION * DP_PSFRAD(dao)
+ i1 = ymin - FRACTION * (ymax - ymin)
+ i2 = ymax + FRACTION * (ymax - ymin)
+ call gswind (gp, r1, r2, i1, i2)
+ call glabax (gp, title, "Radius (pixels)", "Intensity (counts)")
+ call gpmark (gp, Memr[radius], Memr[intensity], npts, GM_PLUS, 1.0,
+ 1.0)
+
+ # Mark the zero radius line.
+ call gamove (gp, 0.0, i1)
+ call gadraw (gp, 0.0, i2)
+
+ # Mark the sky level.
+ call gamove (gp, r1, DP_CUR_PSFSKY(psf))
+ call gadraw (gp, r2, DP_CUR_PSFSKY(psf))
+
+ # Mark the half-width at half-maximum.
+ call gamove (gp, DP_FWHMPSF(dao) / 2.0, i1)
+ call gadraw (gp, DP_FWHMPSF(dao) / 2.0, i2)
+ call sprintf (Memc[str], SZ_LINE, "Half-width half-maximum = %0.2f")
+ call pargr (DP_FWHMPSF(dao) / 2.0)
+ call gtext (gp, DP_FWHMPSF(dao) / 2.0, i2, Memc[str],
+ "q=h;u=180;v=t;p=r")
+
+ # Mark the fitting radius.
+ call gamove (gp, DP_FITRAD(dao), i1)
+ call gadraw (gp, DP_FITRAD(dao), i2)
+ call sprintf (Memc[str], SZ_LINE, "Fitting radius = %0.2f")
+ call pargr (DP_FITRAD(dao))
+ call gtext (gp, DP_FITRAD(dao), i2, Memc[str], "q=h;u=180;v=t;p=r")
+
+ call gflush (gp)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dprmpsf.x b/noao/digiphot/daophot/psf/dprmpsf.x
new file mode 100644
index 00000000..dd76c4d4
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dprmpsf.x
@@ -0,0 +1,156 @@
+include <imhdr.h>
+include <fset.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+
+# DP_OPPSF -- Open the current psf image and the psf group file.
+
+procedure dp_oppsf (dao, psfim, opst, psfgr)
+
+pointer dao # pointer to the daophot structure
+pointer psfim # pointer to the psf image
+int opst # the psf star list descriptor
+int psfgr # the psf group file descriptor
+
+pointer sp, str
+int open(), dp_stati(), dp_pstati()
+pointer immap(), tbtopn()
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Reopen the PSF star and group files.
+ call dp_stats (dao, OUTREJFILE, Memc[str], SZ_FNAME)
+ if (dp_stati (dao, TEXT) == YES)
+ opst = open (Memc[str], NEW_FILE, TEXT_FILE)
+ else
+ opst = tbtopn (Memc[str], NEW_FILE, 0)
+ call dp_stats (dao, OUTPHOTFILE, Memc[str], SZ_FNAME)
+ if (dp_stati (dao, TEXT) == YES)
+ psfgr = open (Memc[str], NEW_FILE, TEXT_FILE)
+ else
+ psfgr = tbtopn (Memc[str], NEW_FILE, 0)
+
+ # Reopen the psf image.
+ call dp_stats (dao, PSFIMAGE, Memc[str], SZ_FNAME)
+ psfim = immap (Memc[str], NEW_IMAGE, dp_pstati (dao, LENUSERAREA))
+
+ call sfree (sp)
+end
+
+
+# DP_UPDATEPSF -- Update the psf on disk.
+
+bool procedure dp_updatepsf (dao, im, psfim, opst, psfgr, psf_new, psf_current,
+ psf_written)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+pointer psfim # pointer to the psf image
+int opst # the psf star list file descriptor
+int psfgr # the psf group file descriptor
+bool psf_new # is the psf star list defined ?
+bool psf_current # is the psf fit uptodate
+bool psf_written # has the psf been saved on disk
+
+bool update
+pointer sp, str
+int dp_fitpsf()
+
+begin
+ call smark (sp)
+ call salloc (str, SZ_LINE, TY_CHAR)
+
+ update = false
+ if (psfim == NULL) {
+ call printf ("Warning: The PSF image is undefined\n")
+ } else if (psfgr == NULL) {
+ call printf ("Warning: The PSF group file is undefined\n")
+ } else if (psf_new) {
+ call printf ("Warning: The PSF star list is undefined\n")
+ } else if (! psf_current) {
+ if (dp_fitpsf (dao, im, Memc[str], SZ_LINE) == OK) {
+ call dp_writepsf (dao, im, psfim)
+ call dp_wplist (dao, im, opst)
+ call dp_wneistars (dao, im, psfgr)
+ update = true
+ } else {
+ call printf ("%s\n")
+ call pargstr (Memc[str])
+ }
+ } else if (! psf_written) {
+ call dp_writepsf (dao, im, psfim)
+ call dp_wplist (dao, im, opst)
+ call dp_wneistars (dao, im, psfgr)
+ update = true
+ }
+
+ if (DP_VERBOSE(dao) == YES && update) {
+ call printf ("\nWriting PSF image %s\n")
+ call pargstr (IM_HDRFILE (psfim))
+ call dp_stats (dao, OUTREJFILE, Memc[str], SZ_FNAME)
+ call printf ("Writing output PSF star list %s\n")
+ call pargstr (Memc[str])
+ call dp_stats (dao, OUTPHOTFILE, Memc[str], SZ_FNAME)
+ call printf ("Writing output PSF star group file %s\n")
+ call pargstr (Memc[str])
+ }
+
+ call sfree (sp)
+
+ return (update)
+end
+
+
+# DP_RMPSF -- Close and delete the psf image and the psf group file.
+
+procedure dp_rmpsf (dao, psfim, opst, psfgr)
+
+pointer dao # pointer to the daophot structure
+pointer psfim # pointer to the psf image
+int opst # the psf star list file descriptor
+int psfgr # the psf group file descriptor
+
+pointer sp, temp
+int dp_stati(), access()
+
+begin
+ call smark (sp)
+ call salloc (temp, SZ_FNAME, TY_CHAR)
+
+ # Delete the psf star file. The access check is necessary because
+ # an empty tables file is automatically deleted by the system.
+ if (dp_stati (dao, TEXT) == YES) {
+ call fstats (opst, F_FILENAME, Memc[temp], SZ_FNAME)
+ call close (opst)
+ } else {
+ call tbtnam (opst, Memc[temp], SZ_FNAME)
+ call tbtclo (opst)
+ }
+ if (access (Memc[temp], 0, 0) == YES)
+ call delete (Memc[temp])
+ opst = NULL
+
+ # Delete the neighbours file. The access check is necessary because
+ # an empty tables file is automatically deleted by the system.
+ if (dp_stati (dao, TEXT) == YES) {
+ call fstats (psfgr, F_FILENAME, Memc[temp], SZ_FNAME)
+ call close (psfgr)
+ } else {
+ call tbtnam (psfgr, Memc[temp], SZ_FNAME)
+ call tbtclo (psfgr)
+ }
+ if (access (Memc[temp], 0, 0) == YES)
+ call delete (Memc[temp])
+ psfgr = NULL
+
+ # Delete the PSF image.
+ call strcpy (IM_HDRFILE(psfim), Memc[temp], SZ_FNAME)
+ call imunmap (psfim)
+ call imdelete (Memc[temp])
+ psfim = NULL
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dprstars.x b/noao/digiphot/daophot/psf/dprstars.x
new file mode 100644
index 00000000..21ca67d1
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dprstars.x
@@ -0,0 +1,156 @@
+include <gset.h>
+include <tbset.h>
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+
+# DP_RPSTARS -- Read in the IDS and x and y positions of the PSF stars.
+
+procedure dp_rpstars (dao, im, pst, text_file, gd, mgd, id, mkstars,
+ matchbyid, showplots)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int pst # the psf star list file descriptor
+bool text_file # text or table file ?
+pointer gd # the graphics descriptor
+pointer mgd # the plot file descriptor
+pointer id # the display device descriptor
+bool mkstars # mark the stars added to the psf
+bool matchbyid # match psf stars by id or position
+bool showplots # show the psf star plots
+
+real x, y, mag, rjunk
+pointer sp, fields, indices, key
+int i, nrow, idno
+real dp_pstatr()
+int tbpsta(), dp_apsel(), dp_addstar()
+
+begin
+ call smark (sp)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (indices, PSF_NINCOLS, TY_INT)
+
+ if (text_file) {
+ call pt_kyinit (key)
+ Memi[indices] = DP_PAPID
+ Memi[indices+1] = DP_PAPXCEN
+ Memi[indices+2] = DP_PAPYCEN
+ Memi[indices+3] = DP_PAPMAG1
+ call dp_gappsf (Memi[indices], Memc[fields], PSF_NINCOLS)
+ } else {
+ call dp_tptinit (pst, Memi[indices])
+ nrow = tbpsta (pst, TBL_NROWS)
+ }
+
+ i = 1
+ repeat {
+
+ # Read the next star.
+
+ if (text_file) {
+ if (dp_apsel (key, pst, Memc[fields], Memi[indices], idno,
+ x, y, rjunk, mag) == EOF)
+ break
+ } else {
+ if (i > nrow)
+ break
+ call dp_tptread (pst, Memi[indices], idno, x, y, mag, i)
+ }
+
+ call dp_win (dao, im, x, y, x, y, 1)
+
+ # Add it to the PSF star list.
+ if (idno > 0) {
+ if (matchbyid) {
+ if (dp_addstar (dao, im, x, y, mag, idno, gd, mgd,
+ showplots) == OK) {
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr(dao, CUR_PSFX),
+ dp_pstatr(dao, CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (id == gd)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+
+ }
+ } else {
+ if (dp_addstar (dao, im, x, y, INDEFR, 0, gd, mgd,
+ showplots) == OK) {
+ if (mkstars && id != NULL) {
+ call gmark (id, dp_pstatr(dao, CUR_PSFX),
+ dp_pstatr(dao, CUR_PSFY), GM_PLUS, -5.0, -5.0)
+ if (id == gd)
+ call gflush (id)
+ else
+ call gframe (id)
+ }
+ }
+ }
+ }
+
+ i = i + 1
+ }
+
+ if (text_file)
+ call pt_kyfree (key)
+ call sfree (sp)
+end
+
+
+# DP_TPTINIT -- Set up the input psf star list ST table column pointers.
+
+procedure dp_tptinit (pst, column)
+
+int pst # the psf star list file descriptor
+int column[ARB] # array of column pointers
+
+begin
+ call tbcfnd (pst, ID, column[1], 1)
+ if (column[1] == NULL)
+ call tbcfnd (pst, "ID", column[1], 1)
+ if (column[1] == NULL)
+ call error (0, "Error reading ID column from PSF star file\n")
+
+ call tbcfnd (pst, XCENTER, column[2], 1)
+ if (column[2] == NULL)
+ call tbcfnd (pst, "XCENTER", column[2], 1)
+ if (column[2] == NULL)
+ call error (0, "Error reading XCENTER column from PSF star file\n")
+
+ call tbcfnd (pst, YCENTER, column[3], 1)
+ if (column[3] == NULL)
+ call tbcfnd (pst, "YCENTER", column[3], 1)
+ if (column[3] == NULL)
+ call error (0, "Error reading YCENTER column from PSF star file\n")
+
+ call tbcfnd (pst, MAG, column[4], 1)
+ if (column[4] == NULL)
+ call tbcfnd (pst, APMAG, column[4], 1)
+ if (column[4] == NULL)
+ call error (0, "Error reading MAG column from PSF star file\n")
+end
+
+
+# DP_TPTREAD -- Read the id from an ST table.
+
+procedure dp_tptread (pst, column, idno, x, y, mag, rowno)
+
+pointer pst # pointer to the ST table
+int column[ARB] # array of column pointers
+int idno # the output id number
+real x, y # the output x and y position
+real mag # the output magnitude
+int rowno # the row number
+
+bool nullflag
+
+begin
+ call tbrgti (pst, column[1], idno, nullflag, 1, rowno)
+ if (nullflag)
+ idno = 0
+ call tbrgtr (pst, column[2], x, nullflag, 1, rowno)
+ call tbrgtr (pst, column[3], y, nullflag, 1, rowno)
+ call tbrgtr (pst, column[4], mag, nullflag, 1, rowno)
+end
diff --git a/noao/digiphot/daophot/psf/dpshowpsf.x b/noao/digiphot/daophot/psf/dpshowpsf.x
new file mode 100644
index 00000000..ec5a7766
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpshowpsf.x
@@ -0,0 +1,287 @@
+include <mach.h>
+include <ctype.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+define HELPFILE "daophot$psf/showpsf.key"
+
+# DP_SHOWPSF -- Interactively make surface and/or contour plots of the
+# data subraster around the current PSF star.
+
+procedure dp_showpsf (dao, im, subrast, ncols, nlines, x1, y1, gd, star_ok)
+
+pointer dao # pointer to DAOPHOT structure
+pointer im # the input image descriptor
+real subrast[ncols,nlines] # image subraster
+int ncols, nlines # dimensions of the subraster
+int x1, y1 # coordinates of left hand corner
+pointer gd # pointer to the graphics stream
+bool star_ok # true if PSF star ok
+
+real hibad, wx, wy, rval
+pointer sp, cmd, title, psf
+int wcs, key, ip
+bool do_replot
+
+int clgcur(), ctor()
+
+begin
+ # Return if the graphics stream is undefined.
+ if (gd == NULL)
+ return
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (cmd, SZ_LINE, TY_CHAR)
+ call salloc (title, SZ_LINE, TY_CHAR)
+
+ # Initialize various daophot pointers.
+ psf = DP_PSF (dao)
+
+ # Initialize the contour plot parameters.
+ DP_CCEILING (psf) = 0.0
+ DP_CFLOOR (psf) = 0.0
+
+ # Define the hibad parameter.
+ hibad = DP_MAXGDATA(dao)
+ if (IS_INDEFR(hibad))
+ hibad = MAX_REAL
+
+ # Create the plot title.
+ call dp_ltov (im, DP_CUR_PSFX(psf), DP_CUR_PSFY(psf), wx, wy, 1)
+ call sprintf (Memc[title], SZ_LINE, "Star: %d X: %g Y: %g Mag: %g\n")
+ call pargi (DP_CUR_PSFID(psf))
+ call pargr (wx)
+ call pargr (wy)
+ call pargr (DP_CUR_PSFMAG(psf))
+
+ # Initialize plot.
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT)
+ call dp_surfpsf (dao, subrast, ncols, nlines, Memc[title], gd)
+ else if (DP_PLOTTYPE(psf) == PSF_CONTOURPLOT)
+ call dp_contpsf (dao, subrast, ncols, nlines, Memc[title], gd)
+ else if (DP_PLOTTYPE(psf) == PSF_RADIALPLOT)
+ call dp_radpsf (dao, subrast, ncols, nlines, x1, y1, Memc[title],
+ gd)
+
+ if (DP_CUR_PSFMAX(psf) > hibad)
+ call printf ("Warning: Star is probably saturated\n")
+ do_replot = false
+
+ while (clgcur ("gcommands", wx, wy, wcs, key, Memc[cmd],
+ SZ_LINE) != EOF) {
+
+ switch (key) {
+
+ # Print the help page
+ case '?':
+ if (gd == NULL)
+ call pagefile (HELPFILE, "")
+ else
+ call gpagefile (gd, HELPFILE, "")
+
+ # Print out the photometry for the star.
+ case 'p':
+ call printf ("Star: %d Mag: %7.2f Coords: %7.2f %7.2f\n")
+ call pargi (DP_CUR_PSFID(psf))
+ call pargr (DP_CUR_PSFMAG(psf))
+ call pargr (DP_CUR_PSFX(psf))
+ call pargr (DP_CUR_PSFY(psf))
+
+ # Print out the plot parameters.
+ case 't':
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT) {
+ call printf ("Surface plot: angv = %6.1f angh = %6.1f ")
+ call pargr (DP_MANGV(psf))
+ call pargr (DP_MANGH(psf))
+ call printf (" Minimum: %7.1f Maximum: %7.1f\n")
+ call pargr (DP_CUR_PSFMIN(psf))
+ call pargr (DP_CUR_PSFMAX(psf))
+ } else if (DP_PLOTTYPE(psf) == PSF_CONTOURPLOT) {
+ call printf ("Contour plot: floor = %6.1f ceil = %6.1f ")
+ call pargr (DP_CFLOOR(psf))
+ call pargr (DP_CCEILING(psf))
+ call printf (" Minimum: %7.1f Maximum: %7.1f\n")
+ call pargr (DP_CUR_PSFMIN(psf))
+ call pargr (DP_CUR_PSFMAX(psf))
+ } else if (DP_PLOTTYPE(psf) == PSF_RADIALPLOT) {
+ call printf (
+ "Profile plot: Minimum: %7.1f Maximum: %7.1f\n")
+ call pargr (DP_CUR_PSFMIN(psf))
+ call pargr (DP_CUR_PSFMAX(psf))
+ } else
+ call printf ("Unknown plot type.\n")
+
+ # Accept star and quit cursor loop.
+ case 'a':
+ star_ok = true
+ break
+
+ # Star rejected
+ case 'd':
+ star_ok = false
+ break
+
+ # Increase vertical viewing angle of mesh plot by 15 degrees.
+ case 'n':
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT) {
+ DP_MANGV (psf) = DP_MANGV (psf) + 15.
+ do_replot = true
+ } else
+ call printf ("This key only active for mesh plots.\n")
+
+ # Decrease vertical viewing angle of mesh plot by 15 degrees.
+ case 's':
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT) {
+ DP_MANGV (psf) = DP_MANGV (psf) - 15.
+ do_replot = true
+ } else
+ call printf ("This key only active for mesh plots.\n")
+
+ # Decrease horizontal viewing angle of mesh plot by 15 degrees.
+ case 'w':
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT) {
+ DP_MANGH (psf) = DP_MANGH (psf) - 15.
+ do_replot = true
+ } else
+ call printf ("This key only active for mesh plots.\n")
+
+ # Increase horizontal viewing angle of mesh plot by 15 degrees.
+ case 'e':
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT) {
+ DP_MANGH (psf) = DP_MANGH (psf) + 15.
+ do_replot = true
+ } else
+ call printf ("This key only active for mesh plots.\n")
+
+ # Plot the default mesh plot.
+ case 'm':
+ DP_PLOTTYPE(psf) = PSF_MESHPLOT
+ DP_MANGV (psf) = 30.
+ DP_MANGH (psf) = -30.
+ DP_MFLOOR(psf) = 0.0
+ DP_MCEILING(psf) = 0.0
+ do_replot = true
+
+ # Plot the default contour plots.
+ case 'c':
+ DP_PLOTTYPE(psf) = PSF_CONTOURPLOT
+ DP_CFLOOR(psf) = 0.0
+ DP_CCEILING(psf) = 0.0
+ do_replot = true
+
+ # Plot the radial profile plots.
+ case 'r':
+ DP_PLOTTYPE(psf) = PSF_RADIALPLOT
+ do_replot = true
+
+ # Command mode.
+ case ':':
+ for (ip=1; IS_WHITE (Memc[cmd+ip-1]); ip=ip+1)
+ ;
+
+ switch (Memc[cmd+ip-1]) {
+
+ # Set surface plot and angles
+ case 'm':
+ DP_PLOTTYPE(psf) = PSF_MESHPLOT
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, DP_MANGV(psf)) <= 0)
+ DP_MANGV(psf) = 30.
+ if (ctor (Memc[cmd], ip, DP_MANGH(psf)) <= 0)
+ DP_MANGH(psf) = -30.
+ do_replot = true
+
+ case 'c':
+ # Set surface contour and levels
+ DP_PLOTTYPE(psf) = PSF_CONTOURPLOT
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, DP_CFLOOR(psf)) <= 0)
+ DP_CFLOOR(psf) = 0.0
+ if (ctor (Memc[cmd], ip, DP_CCEILING(psf)) <= 0)
+ DP_CCEILING(psf) = 0.0
+ do_replot = true
+
+ case 'r':
+ # PLot radial profile.
+ DP_PLOTTYPE(psf) = PSF_RADIALPLOT
+ do_replot = true
+
+ # Set vertical angle
+ case 'v':
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, rval) <= 0) {
+ call printf (
+ "Surface plot vertical viewing angle: %g\n")
+ call pargr (DP_MANGV(psf))
+ } else {
+ DP_MANGV(psf) = rval
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT)
+ do_replot = true
+ }
+
+ # Set horizontal angle
+ case 'h':
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, rval) <= 0) {
+ call printf (
+ "Surface plot horizontal viewing angle: %g\n")
+ call pargr (DP_MANGH(psf))
+ } else {
+ DP_MANGH(psf) = rval
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT)
+ do_replot = true
+ }
+
+ # Set the floor value.
+ case 'l':
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, rval) <= 0) {
+ call printf (
+ "Contour plot floor value: %g\n")
+ call pargr (DP_CFLOOR(psf))
+ } else {
+ DP_CFLOOR(psf) = rval
+ if (DP_PLOTTYPE(psf) == PSF_CONTOURPLOT)
+ do_replot = true
+ }
+
+ # Set the ceiling value.
+ case 'u':
+ ip = ip + 1
+ if (ctor (Memc[cmd], ip, rval) <= 0) {
+ call printf (
+ "Contour plot ceiling value: %g\n")
+ call pargr (DP_CCEILING(psf))
+ } else {
+ DP_CCEILING(psf) = rval
+ if (DP_PLOTTYPE(psf) == PSF_CONTOURPLOT)
+ do_replot = true
+ }
+
+ default:
+ call printf ("Unknown keystroke or cursor command.\007\n")
+ }
+
+ default:
+ call printf ("Unknown keystroke or cursor command.\007\n")
+ }
+
+ # Replot the data.
+ if (do_replot) {
+ if (DP_PLOTTYPE(psf) == PSF_MESHPLOT)
+ call dp_surfpsf (dao, subrast, ncols, nlines, Memc[title],
+ gd)
+ else if (DP_PLOTTYPE(psf) == PSF_CONTOURPLOT)
+ call dp_contpsf (dao, subrast, ncols, nlines, Memc[title],
+ gd)
+ else if (DP_PLOTTYPE(psf) == PSF_RADIALPLOT)
+ call dp_radpsf (dao, subrast, ncols, nlines, x1, y1,
+ Memc[title], gd)
+ do_replot = false
+ }
+ }
+
+ call gdeactivate (gd, 0)
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/dpspstars.x b/noao/digiphot/daophot/psf/dpspstars.x
new file mode 100644
index 00000000..69b14933
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpspstars.x
@@ -0,0 +1,194 @@
+include <mach.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+define NCOLUMN 5
+
+# DP_GPSTARS -- Select the psf stars.
+
+procedure dp_gpstars (dao, im, tp_in, tp_out, text_file, maxnpsf, gd, mgd, id,
+ mkstars, interactive, use_cmdfile)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int tp_in # the input file descriptor
+int tp_out # the output file descriptor
+bool text_file # text or table file
+int maxnpsf # the maximum number of psf stars
+pointer gd # pointer to the graphics stream
+pointer mgd # pointer to the plot metacode file
+pointer id # pointer to the image display stream
+bool mkstars # mark the accepted and deleted stars
+bool interactive # interactive mode
+bool use_cmdfile # cursor command file mode
+
+int ier, npsf
+pointer apsel, sp, ocolpoint, index
+real radius
+int dp_pfstars(), dp_ipfstars()
+
+begin
+ # Get some daophot pointers.
+ apsel = DP_APSEL(dao)
+
+ # Define the radius for determining proximity.
+ radius = DP_PSFRAD(dao) + DP_FITRAD(dao) + 2.0
+
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (ocolpoint, NCOLUMN, TY_POINTER)
+ call salloc (index, DP_APNUM(apsel), TY_INT)
+
+ # Initialize the output file.
+ if (text_file) {
+ call seek (tp_in, BOF)
+ call dp_apheader (tp_in, tp_out)
+ call dp_xpselpars (tp_out, DP_INIMAGE(dao), maxnpsf, DP_SCALE(dao),
+ DP_SPSFRAD(dao), DP_SFITRAD(dao))
+ call dp_xpbanner (tp_out)
+ } else {
+ call dp_tpdefcol (tp_out, Memi[ocolpoint])
+ call tbhcal (tp_in, tp_out)
+ call dp_tpselpars (tp_out, DP_INIMAGE(dao), maxnpsf, DP_SCALE(dao),
+ DP_SPSFRAD(dao), DP_SFITRAD(dao))
+ }
+
+ # Change all the INDEFS to a large negative number.
+ call dp_chindef (Memr[DP_APMAG(apsel)], Memr[DP_APMAG(apsel)],
+ DP_APNUM(apsel), -MAX_REAL)
+
+ # Sort the stars.
+ call quick (Memr[DP_APMAG(apsel)], DP_APNUM(apsel), Memi[index], ier)
+ call dp_irectify (Memi[DP_APID(apsel)], Memi[index], DP_APNUM(apsel))
+ call dp_rectify (Memr[DP_APXCEN(apsel)], Memi[index], DP_APNUM(apsel))
+ call dp_rectify (Memr[DP_APYCEN(apsel)], Memi[index], DP_APNUM(apsel))
+ call dp_rectify (Memr[DP_APMSKY(apsel)], Memi[index], DP_APNUM(apsel))
+
+ # Select the stars and write them to the output file.
+ if (use_cmdfile)
+ npsf = dp_ipfstars (dao, im, maxnpsf, -MAX_REAL, radius, gd,
+ mgd, id, mkstars, false, false)
+ else if (interactive)
+ npsf = dp_ipfstars (dao, im, maxnpsf, -MAX_REAL, radius, gd,
+ mgd, id, mkstars, true, true)
+ else
+ npsf = dp_pfstars (dao, im, Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], Memr[DP_APMSKY(apsel)],
+ DP_APNUM(apsel), maxnpsf, -MAX_REAL, radius, mgd)
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nTotal of %d PSF stars selected\n")
+ call pargi (npsf)
+ }
+
+ # Write out the stars.
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)], npsf)
+ call dp_wpstars (tp_out, Memi[ocolpoint], text_file,
+ Memi[DP_APID(apsel)], Memr[DP_APXCEN(apsel)],
+ Memr[DP_APYCEN(apsel)], Memr[DP_APMAG(apsel)],
+ Memr[DP_APMSKY(apsel)], npsf)
+
+ # Free memory.
+ call sfree (sp)
+end
+
+
+# DP_CHINDEF -- Change all the INDEFS to a legal number which is a lower limit.
+
+procedure dp_chindef (a, b, npix, lolimit)
+
+real a[ARB] # the input array.
+real b[ARB] # the output array.
+int npix # number of points
+real lolimit # the lower limit
+
+int i
+
+begin
+ do i = 1, npix {
+ if (IS_INDEFR(a[i]))
+ b[i] = lolimit
+ else
+ b[i] = a[i]
+ }
+end
+
+
+# DP_PFSTARS -- Select the psf stars.
+
+int procedure dp_pfstars (dao, im, ids, xcen, ycen, mag, sky, nstar, maxnpsf,
+ lolimit, radius, mgd)
+
+pointer dao # pointer to the daophot structure
+pointer im # pointer to the input image
+int ids[ARB] # array of star ids
+real xcen[ARB] # array of x coordinates
+real ycen[ARB] # array of y coordinates
+real mag[ARB] # array of magnitudes
+real sky[ARB] # array of sky values
+int nstar # the number of stars
+int maxnpsf # the maximum number of psf stars
+real lolimit # lower data limit
+real radius # minimum separation
+pointer mgd # pointer to the plot metacode file
+
+bool omit
+int istar, jstar, npsf
+real radsq, dy2, dr2
+int dp_addstar()
+
+begin
+ # Initialize the list.
+ call dp_pseti (dao, PNUM, 0)
+
+ # Set the radius.
+ radsq = radius * radius
+
+ # Get the first star.
+ if ((mag[1] > lolimit) && (dp_addstar (dao, im, xcen[1], ycen[1],
+ INDEFR, ids[1], NULL, mgd, false)) == OK) {
+ npsf = 1
+ } else
+ npsf = 0
+
+ # Loop over the candidate psf stars.
+ do istar = 2, nstar {
+
+ # Test for the maximum number of psf stars.
+ if (npsf >= maxnpsf)
+ break
+
+ # Test that the candidate psf stars are not saturated and
+ # are sufficiently far from the edge of the frame.
+
+ if (mag[istar] <= lolimit)
+ next
+
+ # Text that there are no brighter stars with a distance squared
+ # of radsq.
+ omit = false
+ do jstar = 1, istar - 1 {
+ dy2 = abs (ycen[jstar] - ycen[istar])
+ if (dy2 >= radius)
+ next
+ dr2 = (xcen[jstar] - xcen[istar]) ** 2 + dy2 ** 2
+ if (dr2 >= radsq)
+ next
+ omit = true
+ break
+ }
+
+ if (omit)
+ next
+
+ if (dp_addstar (dao, im, xcen[istar], ycen[istar], INDEFR,
+ ids[istar], NULL, mgd, false) == ERR)
+ next
+ npsf = npsf + 1
+ }
+
+ return (npsf)
+end
diff --git a/noao/digiphot/daophot/psf/dpsubpsf.x b/noao/digiphot/daophot/psf/dpsubpsf.x
new file mode 100644
index 00000000..8f15867a
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpsubpsf.x
@@ -0,0 +1,183 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+# DP_SUBPSF -- Add the star at the given position to the PSF if it exists and
+# passes the selection criteria.
+
+int procedure dp_subpsf (dao, im, x, y, idnum, gd, mgd, showplots)
+
+pointer dao # pointer to daophot structure
+pointer im # pointer to image
+real x, y # position of proposed PSF star
+int idnum # id number of desired star
+pointer gd # pointer to the graphics stream
+pointer mgd # pointer to the metacode descriptor
+bool showplots # show plots?
+
+real tx, ty
+pointer srim
+int x1, x2, y1, y2, starnum, saturated
+bool star_ok
+
+real dp_statr()
+pointer dp_psubrast()
+int dp_locstar(), dp_idstar(), dp_pstati(), dp_issat()
+
+begin
+ # Convert coordinates for display.
+ if (showplots)
+ call dp_ltov (im, x, y, tx, ty, 1)
+ else
+ call dp_wout (dao, im, x, y, tx, ty, 1)
+
+ # Check that the position of the star is within the image.
+ if (idnum == 0 && (x < 1.0 || x > real (IM_LEN(im,1)) || y < 1.0 || y >
+ real (IM_LEN(im,2)))) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star at %g,%g is outside the image\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ return (ERR)
+ }
+
+ # Find the star in the aperture photometry list
+ if (idnum == 0)
+ starnum = dp_locstar (dao, im, x, y)
+ else
+ starnum = dp_idstar (dao, im, idnum)
+ if (starnum == 0) {
+ if (DP_VERBOSE(dao) == YES) {
+ if (idnum > 0) {
+ call printf ("Star %d not found in the photometry file\n")
+ call pargi (idnum)
+ } else {
+ call printf (
+ "Star at %g,%g not found in the photometry file\n")
+ call pargr (tx)
+ call pargr (ty)
+ }
+ }
+ return (ERR)
+ } else if (starnum < 0 || starnum > dp_pstati (dao, PNUM)) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d not found in the PSF star list\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Check to see if the star is saturated.
+ if (dp_issat (dao, starnum) == YES) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d is saturated\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Get the data subraster, check for saturation and bad pixels,
+ # and compute the min and max data values inside the subraster.
+ srim = dp_psubrast (dao, im, -MAX_REAL, MAX_REAL, x1, x2, y1, y2,
+ saturated)
+ if (srim == NULL) {
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d error reading data subraster\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ return (ERR)
+ }
+
+ # Now let us do the subtraction.
+ call dp_spstar (dao, Memr[srim], (x2 - x1 + 1), (y2 - y1 + 1),
+ x1, y1, starnum, dp_statr (dao, PSFRAD) ** 2)
+
+ # Now let's look at the extracted subraster.
+ if (showplots) {
+ call dp_showpsf (dao, im, Memr[srim], (x2 - x1 + 1), (y2 - y1 + 1),
+ x1, y1, gd, star_ok)
+ } else
+ star_ok = true
+
+ if (star_ok) {
+ if (mgd != NULL)
+ call dp_plotpsf (dao, im, Memr[srim], (x2 - x1 + 1),
+ (y2 - y1 + 1), x1, y1, mgd)
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("PSF star %d saved by user\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+ call mfree (srim, TY_REAL)
+ return (ERR)
+ }
+
+ # Delete the star from the list by moving it to the position
+ # currently occupied by PNUM and moving everything else up.
+ call dp_pfreorder (dao, dp_pstati (dao, CUR_PSF),
+ dp_pstati (dao, PNUM))
+
+ # Decrement the list of psf stars.
+ call dp_pseti (dao, PNUM, dp_pstati (dao, PNUM) - 1)
+
+ # Print message.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Star %d has been deleted from the PSF star list\n")
+ call pargi (dp_pstati (dao, CUR_PSFID))
+ }
+
+ call mfree (srim, TY_REAL)
+ return (OK)
+end
+
+
+# DP_SPSTAR -- Subtract the fitted star from the data subraster.
+
+procedure dp_spstar (dao, data, nx, ny, x1, y1, starno, psfradsq)
+
+pointer dao # pointer to the daophot structure
+real data[nx,ARB] # the data subraster
+int nx, ny # the dimensions of the data subraster
+int x1, y1 # the coordinates of the ll pixel
+int starno # the index of the star in question
+real psfradsq # the psf radius squared
+
+int i, j
+pointer psf, psffit
+real xstar, ystar, scale, deltax, deltay, dx, dy, dysq, rsq, svdx, svdy
+real dp_usepsf()
+
+begin
+ # Define some daophot pointers
+ psf = DP_PSF(dao)
+ psffit = DP_PSFFIT(dao)
+
+ # Get the star position and scale factor.
+ xstar = Memr[DP_PXCEN(psf)+starno-1]
+ ystar = Memr[DP_PYCEN(psf)+starno-1]
+ deltax = (xstar - 1.0) / DP_PSFX(psffit) - 1.0
+ deltay = (ystar - 1.0) / DP_PSFY(psffit) - 1.0
+ xstar = xstar - x1 + 1
+ ystar = ystar - y1 + 1
+ scale = Memr[DP_PH(psf)+starno-1] / Memr[DP_PH(psf)]
+
+ do j = 1, ny {
+ dy = real (j) - ystar
+ dysq = dy ** 2
+ do i = 1, nx {
+ dx = real (i) - xstar
+ rsq = dx ** 2 + dysq
+ if (rsq >= psfradsq)
+ next
+ data[i,j] = data[i,j] - scale *
+ dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_POLDLUT(psf)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ deltax, deltay, svdx, svdy)
+ }
+ }
+
+ call alimr (data, nx * ny, DP_CUR_PSFMIN(psf), DP_CUR_PSFMAX(psf))
+end
diff --git a/noao/digiphot/daophot/psf/dpsurfpsf.x b/noao/digiphot/daophot/psf/dpsurfpsf.x
new file mode 100644
index 00000000..de4e9d6e
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpsurfpsf.x
@@ -0,0 +1,437 @@
+include <fset.h>
+include <mach.h>
+include <error.h>
+include <gset.h>
+include <config.h>
+include <xwhen.h>
+include "../lib/daophotdef.h"
+include "../lib/psfdef.h"
+
+define DUMMY 6
+
+# DP_SURFPSF -- Draw a perspective view of a subraster with a given altitude
+# and azimuth of the viewing angle. Floor and ceiling constraints may be
+# applied to the data before plotting.
+
+procedure dp_surfpsf (dao, subras, ncols, nlines, title, gd)
+
+pointer dao # pointer to DAOPHOT structure
+real subras[ncols,nlines] # pointer to subraster
+int ncols, nlines # dimensions of subraster
+char title[ARB] # title string
+pointer gd # pointer to graphics stream
+
+char sysidstr[SZ_LINE]
+int first, wkid, epa, status, old_onint, tsujmp[LEN_JUMPBUF]
+pointer sp, temp, work, psf
+real angh, angv, imcols, imlines, floor, ceiling, vpx1, vpx2, vpy1, vpy2
+
+extern dp_sonint()
+common /tsucom/ tsujmp
+common /noaovp/ vpx1, vpx2, vpy1, vpy2
+common /frstfg/ first
+
+begin
+ # Get the psf fitting substructure pointer.
+ psf = DP_PSF(dao)
+
+ # Initialize surface common blocks before changing any parameters.
+ first = 1
+ call srfabd ()
+
+ # Set local variables.
+ angh = DP_MANGH (psf)
+ angv = DP_MANGV (psf)
+ floor = DP_MFLOOR (psf)
+ ceiling = DP_MCEILING (psf)
+ floor = min (floor, ceiling)
+ ceiling = max (floor, ceiling)
+
+ # Allow room for axes and labels.
+ vpx1 = 0.10
+ vpx2 = 0.90
+ vpy1 = 0.10
+ vpy2 = 0.90
+
+ # Make a copy of the subraster so we can subtract the zero level.
+ imcols = real (ncols)
+ imlines = real (nlines)
+ call smark (sp)
+ call salloc (temp, ncols * nlines, TY_REAL)
+ call amovr (subras, Memr[temp], nlines * ncols)
+
+ # Allocate the working storage needed by EZSRFC.
+ call malloc (work, 2 * (2 * ncols * nlines + ncols + nlines), TY_REAL)
+
+ # Take off floor and ceiling if enabled (nonzero).
+ call dp_slimits (Memr[temp], ncols, nlines, floor, ceiling)
+
+ # Set up the titles and the viewport.
+ call gopks (STDERR)
+ wkid = 1
+ call gclear (gd)
+ call gopwk (wkid, DUMMY, gd)
+ call gacwk (wkid)
+ call gtext (gd, 0.5, .96, title, "s=0.8;f=b;h=c")
+ call sysid (sysidstr, SZ_LINE)
+ call gtext (gd, 0.5, .04, sysidstr, "h=c;v=b;s=.5")
+ call set (vpx1, vpx2, vpy1, vpy2, 1.0, 1024., 1.0, 1024., 1)
+
+ # Install interrupt exception handler.
+ call zlocpr (dp_sonint, epa)
+ call xwhen (X_INT, epa, old_onint)
+
+ # Plot the surface.
+ call zsvjmp (tsujmp, status)
+ if (status == OK)
+ call ezsrfc (Memr[temp], ncols, nlines, angh, angv, Memr[work])
+ else {
+ call gcancel (gd)
+ call fseti (STDOUT, F_CANCEL, OK)
+ }
+
+ # Draw the perimeter.
+ call gswind (gd, 1.0, imcols, 1.0, imlines)
+ call gseti (gd, G_CLIP, NO)
+ call dp_sperimeter (gd, Memr[temp], ncols, nlines, angh, angv)
+
+ # Clean up.
+ call gdawk (wkid)
+ call gclks ()
+ call mfree (work, TY_REAL)
+ call sfree (sp)
+end
+
+
+# DP_SONINT -- Interrupt handler for the task surface. Branches back to ZSVJMP
+# in the main routine to permit shutdown without an error message.
+
+procedure dp_sonint (vex, next_handler)
+
+int vex # virtual exception
+int next_handler # not used
+
+int tsujmp[LEN_JUMPBUF]
+common /tsucom/ tsujmp
+
+begin
+ call xer_reset()
+ call zdojmp (tsujmp, vex)
+end
+
+
+# DP_SLIMITS -- Apply the floor and ceiling constraints to the subraster.
+# If either value is exactly zero, it is not applied.
+
+procedure dp_slimits (ras, m, n, floor, ceiling)
+
+real ras[m,n]
+int m, n
+real floor, ceiling
+int i
+
+begin
+ do i = 1, n {
+ if (floor != 0)
+ call amaxkr (ras[1,i], floor, ras[1,i], m)
+ if (ceiling != 0)
+ call aminkr (ras[1,i], ceiling, ras[1,i], m)
+ }
+end
+
+
+define SZ_TLABEL 10
+
+# DP_SPERIMETER -- draw and label axes around the surface plot.
+
+procedure dp_sperimeter (gp, z, ncols, nlines, angh, angv)
+
+pointer gp # 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
+
+pointer sp, x_val, y_val, kvec
+char tlabel[SZ_TLABEL]
+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 i, j
+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 in calling procedure.
+ call ggwind (gp, 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) {
+ if (angv >= 0) {
+ # Case 1: xy rotation positive, looking down from above mid z.
+
+ # First draw x axis.
+ call amovkr (y2_perim, Memr[kvec], ncols + 2)
+ call dp_draw_axis (Memr[x_val+1], Memr[kvec], flo, ncols + 1)
+ call dp_label_axis (xcen, y2_perim+del, flo, "X-AXIS", -1, -2)
+ call dp_draw_ticksx (Memr[x_val+1], y2_perim, y2_perim+delta,
+ flo, ncols)
+ call dp_label_axis (xmin, y2_perim+del, flo, "1", -1, -2)
+ if (itoc (int (wc2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_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 dp_draw_axis (Memr[kvec], Memr[y_val+1], flo, nlines + 1)
+ call dp_label_axis (x2_perim+del, ycen, flo, "Y-AXIS", 2, -1)
+ call dp_draw_ticksy (x2_perim, x2_perim+delta, Memr[y_val+1],
+ flo, nlines)
+ call dp_label_axis (x2_perim+del, ymin, flo, "1", 2, -1)
+ if (itoc (int (wl2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_label_axis (x2_perim+del, Memr[y_val+nlines], flo,
+ tlabel, 2, -1)
+
+ } else {
+ # Case 2: xy rotation positive, looking up from below mid z.
+
+ # First draw x axis.
+ call amovkr (y1_perim, Memr[kvec], ncols + 2)
+ call dp_draw_axis (Memr[x_val], Memr[kvec], flo, ncols + 1)
+ call dp_label_axis (xcen, y1_perim-del, flo, "X-AXIS", -1, 2)
+ call dp_draw_ticksx (Memr[x_val+1], y1_perim, y1_perim-delta,
+ flo, ncols)
+ call dp_label_axis (xmin, y1_perim-del, flo, "1", -1, 2)
+ if (itoc (int (wc2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_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 dp_draw_axis (Memr[kvec], Memr[y_val], flo, nlines + 1)
+ call dp_label_axis (x1_perim-del, ycen, flo, "Y-AXIS", 2, 1)
+ call dp_draw_ticksy (x1_perim, x1_perim-delta, Memr[y_val+1],
+ flo, nlines)
+ call dp_label_axis (x1_perim-del, ymin, flo, "1", 2, 1)
+ if (itoc (int (wl2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_label_axis (x1_perim-del, Memr[y_val+nlines], flo,
+ tlabel, 2, 1)
+ }
+ }
+
+ if (angh < 0) {
+ if (angv > 0) {
+
+ # Case 3: xy rotation negative, looking down from above mid z
+ # (default). First draw x axis.
+ call amovkr (y1_perim, Memr[kvec], ncols + 2)
+ call dp_draw_axis (Memr[x_val+1], Memr[kvec], flo, ncols + 1)
+ call dp_label_axis (xcen, y1_perim-del, flo, "X-AXIS", 1, 2)
+ call dp_draw_ticksx (Memr[x_val+1], y1_perim, y1_perim-delta,
+ flo, ncols)
+ call dp_label_axis (xmin, y1_perim-del, flo, "1", 1, 2)
+ if (itoc (int (wc2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_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 dp_draw_axis (Memr[kvec], Memr[y_val], flo, nlines + 1)
+ call dp_label_axis (x2_perim+del, ycen, flo, "Y-AXIS", 2, -1)
+ call dp_draw_ticksy (x2_perim, x2_perim+delta, Memr[y_val+1],
+ flo, nlines)
+ call dp_label_axis (x2_perim+del, ymin, flo, "1", 2, -1)
+ if (itoc (int (wl2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_label_axis (x2_perim+del, Memr[y_val+nlines], flo,
+ tlabel, 2, -1)
+ } else {
+
+ # Case 4: xy rotation negative, looking up from below mid z.
+ # First draw x axis.
+ call amovkr (y2_perim, Memr[kvec], ncols + 2)
+ call dp_draw_axis (Memr[x_val], Memr[kvec], flo, ncols + 1)
+ call dp_label_axis (xcen, y2_perim+del, flo, "X-AXIS", 1, -2)
+ call dp_draw_ticksx (Memr[x_val+1], y2_perim, y2_perim+delta,
+ flo, ncols)
+ call dp_label_axis (xmin, y2_perim+del, flo, "1", 1, -2)
+ if (itoc (int (wc2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_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 dp_draw_axis (Memr[kvec], Memr[y_val+1], flo, nlines + 1)
+ call dp_label_axis (x1_perim-del, ycen, flo, "Y-AXIS", 2, 1)
+ call dp_draw_ticksy (x1_perim, x1_perim-delta, Memr[y_val+1],
+ flo, nlines)
+ call dp_label_axis (x1_perim-del, ymin, flo, "1", 2, 1)
+ if (itoc (int (wl2), tlabel, SZ_TLABEL) <= 0)
+ tlabel[1] = EOS
+ call dp_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
+
+
+# DP_DRAW_AXIS -- Draw the axes around the surface plot.
+
+procedure dp_draw_axis (xvals, yvals, zval, nvals)
+
+int nvals
+real xvals[nvals]
+real yvals[nvals]
+real zval
+pointer sp, xt, yt
+int i
+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
+
+
+define CSIZE 24
+
+
+# DP_LABEL_AXIS -- Draw the axes labels.
+
+procedure dp_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
+
+
+# DP_DRAW_TICKS -- Draw the x tick marks.
+
+procedure dp_draw_ticksx (x, y1, y2, zval, nvals)
+
+int nvals
+real x[nvals]
+real y1, y2
+real zval
+
+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
+
+
+# DP_DRAW_TICKSY -- Draw the y tick marks.
+
+procedure dp_draw_ticksy (x1, x2, y, zval, nvals)
+
+int nvals
+real x1, x2
+real y[nvals]
+real zval
+
+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
diff --git a/noao/digiphot/daophot/psf/dpwritepsf.x b/noao/digiphot/daophot/psf/dpwritepsf.x
new file mode 100644
index 00000000..239e4faf
--- /dev/null
+++ b/noao/digiphot/daophot/psf/dpwritepsf.x
@@ -0,0 +1,270 @@
+include <time.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+# DP_WRITEPSF -- Write out the PSF into an IRAF image.
+
+procedure dp_writepsf (dao, im, psfim)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+pointer psfim # pointer to the output psf image
+
+begin
+ # Check that the psfimage is open.
+ if (psfim == NULL)
+ return
+
+ # Write out the id and fitting parameters.
+ call dp_widpars (dao, psfim)
+
+ # Write out the psf function definition parameters.
+ call dp_wfuncpars (dao, psfim)
+
+ # Write out the list of PSF stars.
+ call dp_wstars (dao, im, psfim)
+
+ # Write out the lookup table.
+ call dp_wlt (dao, psfim)
+end
+
+
+# DP_WIDPARS -- Add the id and fitting parameters to the PSF image header
+
+procedure dp_widpars (dao, psfim)
+
+pointer dao # pointer to the daophot structure
+pointer psfim # the psf image descriptor
+
+pointer sp, outstr, date, time
+bool itob()
+int envfind()
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+ call salloc (date, SZ_DATE, TY_CHAR)
+ call salloc (time, SZ_DATE, TY_CHAR)
+
+ # Record IRAF version, user, host, date, time, package and task.
+ if (envfind ("version", Memc[outstr], SZ_LINE) <= 0)
+ call strcpy ("IRAF", Memc[outstr], SZ_LINE)
+ call dp_rmwhite (Memc[outstr], Memc[outstr], SZ_LINE)
+ call imastr (psfim, "IRAF", Memc[outstr])
+ call gethost (Memc[outstr], SZ_LINE)
+ call imastr (psfim, "HOST", Memc[outstr])
+ if (envfind ("userid", Memc[outstr], SZ_LINE) <= 0)
+ Memc[outstr] = EOS
+ call imastr (psfim, "USER", Memc[outstr])
+ call dp_date (Memc[date], Memc[time], SZ_DATE)
+ call imastr (psfim, "DATE", Memc[date])
+ call imastr (psfim, "TIME", Memc[time])
+
+ # Write out the package, task, and input/output file names.
+ call imastr (psfim, "PACKAGE", "daophot")
+ call imastr (psfim, "TASK", "psf")
+ call dp_imroot (DP_INIMAGE(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "IMAGE", Memc[outstr])
+ call dp_froot (DP_INPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "PHOTFILE", Memc[outstr])
+ call dp_froot (DP_COORDS(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "PSTFILE", Memc[outstr])
+ call dp_imroot (DP_PSFIMAGE(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "PSFIMAGE", Memc[outstr])
+ call dp_froot (DP_OUTREJFILE(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "OPSTFILE", Memc[outstr])
+ call dp_froot (DP_OUTPHOTFILE(dao), Memc[outstr], SZ_LINE)
+ call imastr (psfim, "GRPSFILE", Memc[outstr])
+
+ # Add information about fitting parameters.
+ call imaddr (psfim, "SCALE", DP_SCALE(dao))
+ call imaddr (psfim, "PSFRAD", DP_SPSFRAD (dao))
+ call imaddr (psfim, "FITRAD", DP_SFITRAD(dao))
+ call imaddr (psfim, "DATAMIN", DP_MINGDATA(dao))
+ call imaddr (psfim, "DATAMAX", DP_MAXGDATA(dao))
+ call imaddi (psfim, "NCLEAN", DP_NCLEAN(dao))
+ call imaddb (psfim, "USESAT", itob (DP_SATURATED(dao)))
+
+ # Define the image title.
+ call sprintf (IM_TITLE(psfim), SZ_IMTITLE, "PSF for image: %s")
+ call pargstr (DP_INIMAGE(dao))
+
+ call sfree (sp)
+end
+
+
+# DP_WFUNCPARS -- Write out the the parameters of the PSF function
+# to the PSF image.
+
+procedure dp_wfuncpars (dao, psfim)
+
+pointer dao # pointer to the daophot structure
+pointer psfim # image descriptor
+
+int i
+pointer sp, str, psffit
+bool itob()
+
+begin
+ psffit = DP_PSFFIT(dao)
+
+ call imastr (psfim, "FUNCTION", DP_FUNCTION(dao))
+ call imaddr (psfim, "PSFX", DP_PSFX(psffit))
+ call imaddr (psfim, "PSFY", DP_PSFY(psffit))
+ call imaddr (psfim, "PSFHEIGHT", DP_PSFHEIGHT(psffit))
+ call imaddr (psfim, "PSFMAG", DP_PSFMAG (psffit))
+
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ switch (DP_PSFUNCTION(psffit)) {
+ case FCTN_MOFFAT25:
+ call imaddi (psfim, "NPARS", DP_PSFNPARS(psffit)+1)
+ do i = 1, DP_PSFNPARS(psffit) {
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], Memr[DP_PSFPARS(psffit)+i-1])
+ }
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (DP_PSFNPARS(psffit)+1)
+ call imaddr (psfim, Memc[str], 2.5)
+ case FCTN_MOFFAT15:
+ call imaddi (psfim, "NPARS", DP_PSFNPARS(psffit)+1)
+ do i = 1, DP_PSFNPARS(psffit) {
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], Memr[DP_PSFPARS(psffit)+i-1])
+ }
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (DP_PSFNPARS(psffit)+1)
+ call imaddr (psfim, Memc[str], 1.5)
+ default:
+ call imaddi (psfim, "NPARS", DP_PSFNPARS(psffit))
+ do i = 1, DP_PSFNPARS(psffit) {
+ call sprintf (Memc[str], SZ_FNAME, "PAR%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], Memr[DP_PSFPARS(psffit)+i-1])
+ }
+ }
+
+ call imaddi (psfim, "VARORDER", DP_VARORDER(dao))
+ call imaddb (psfim, "FEXPAND", itob (DP_FEXPAND(dao)))
+
+ call sfree (sp)
+end
+
+
+# DP_WSTARS -- Write out the PSF star list to the PSF image.
+
+procedure dp_wstars (dao, im, psfim)
+
+pointer dao # pointer to the daophot descriptor
+pointer im # the input image descriptor
+pointer psfim # the psfimage descriptor
+
+real tx, ty
+pointer apsel, psf, sp, str
+int i
+
+begin
+ apsel = DP_APSEL(dao)
+ psf = DP_PSF(dao)
+
+ call smark (sp)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Write out the number of PSF stars.
+ call sprintf (Memc[str], SZ_FNAME, "NPSFSTAR")
+ call imaddi (psfim, Memc[str], DP_PNUM(psf))
+
+ # Write out the ids of all the PSF stars.
+ do i = 1, DP_PNUM(psf) {
+
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+i-1],
+ Memr[DP_APYCEN(apsel)+i-1], tx, ty, 1)
+ call sprintf (Memc[str], SZ_FNAME, "ID%d")
+ call pargi (i)
+ call imaddi (psfim, Memc[str], Memi[DP_APID(apsel)+i-1])
+
+ call sprintf (Memc[str], SZ_FNAME, "X%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], tx)
+
+ call sprintf (Memc[str], SZ_FNAME, "Y%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], ty)
+
+ call sprintf (Memc[str], SZ_FNAME, "MAG%d")
+ call pargi (i)
+ call imaddr (psfim, Memc[str], Memr[DP_APMAG(apsel)+i-1])
+ }
+
+ call sfree (sp)
+end
+
+
+# DP_WLT -- Write out the PSF lookup table to the output PSF image.
+
+procedure dp_wlt (dao, psfim)
+
+pointer dao # pointer to DAO Structure
+pointer psfim # image descriptor
+
+int nexp
+pointer psffit
+
+begin
+ psffit = DP_PSFFIT(dao)
+ nexp = DP_NVLTABLE(psffit) + DP_NFEXTABLE(psffit)
+
+ IM_PIXTYPE(psfim) = TY_REAL
+ if (nexp == 0) {
+ IM_NDIM(psfim) = 0
+ } else if (nexp == 1) {
+ IM_NDIM(psfim) = 2
+ IM_LEN(psfim,1) = DP_PSFSIZE(psffit)
+ IM_LEN(psfim,2) = DP_PSFSIZE(psffit)
+ } else {
+ IM_NDIM(psfim) = 3
+ IM_LEN(psfim,1) = DP_PSFSIZE(psffit)
+ IM_LEN(psfim,2) = DP_PSFSIZE(psffit)
+ IM_LEN(psfim,3) = nexp
+ }
+
+ if (nexp > 0)
+ call dp_wltim (psfim, Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_PSFSIZE(psffit), nexp)
+end
+
+
+# DP_WLTIM -- Write the lookup tables into the image pixels.
+
+procedure dp_wltim (psfim, psflut, nxlut, nylut, nexp)
+
+pointer psfim # image descriptor
+real psflut[nexp,nxlut,ARB] # the psf lookup table
+int nxlut, nylut,nexp # the dimensions of the psf look-up table
+
+int i, j, k
+pointer sp, v, buf
+int impnlr()
+
+begin
+ call smark (sp)
+ call salloc (v, IM_MAXDIM, TY_LONG)
+
+ call amovkl (long(1), Meml[v], IM_MAXDIM)
+ do k = 1, nexp {
+ do j = 1, nylut {
+ if (impnlr (psfim, buf, Meml[v]) == EOF)
+ ;
+ do i = 1, nxlut
+ Memr[buf+i-1] = psflut[k,i,j]
+ }
+ }
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/mkpkg b/noao/digiphot/daophot/psf/mkpkg
new file mode 100644
index 00000000..5dd38047
--- /dev/null
+++ b/noao/digiphot/daophot/psf/mkpkg
@@ -0,0 +1,70 @@
+# PSF task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpaddstar.x <imhdr.h> <mach.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpcontpsf.x <error.h> <mach.h> \
+ <gset.h> <config.h> \
+ <xwhen.h> <fset.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpdelstar.x <imhdr.h> ../lib/daophotdef.h \
+ ../lib/psfdef.h <mach.h>
+ dpfitpsf.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/psfdef.h ../lib/peakdef.h
+ dplocstar.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/psfdef.h
+ dpispstars.x <fset.h> <ctype.h> \
+ <gset.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/psfdef.h
+ dppcolon.x ../lib/daophotdef.h ../lib/psfdef.h
+ dpqverify.x <fset.h>
+ dpmempsf.x ../lib/daophotdef.h ../lib/psfdef.h
+ dpmkpsf.x <imhdr.h> <ctype.h> \
+ <gset.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/psfdef.h
+ dppconfirm.x
+ dppsfutil.x ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/psfdef.h
+ dpplotpsf.x ../lib/daophotdef.h ../lib/psfdef.h
+ dppset.x ../lib/daophotdef.h ../lib/psfdef.h
+ dppstat.x ../lib/daophotdef.h ../lib/psfdef.h
+ dppsubrast.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpptconfirm.x
+ dppwrtgrp.x <time.h> <tbset.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/psfdef.h
+ dppwselmer.x <tbset.h> ../lib/apseldef.h
+ dpradpsf.x <gset.h> ../lib/daophotdef.h \
+ ../lib/psfdef.h
+ dprmpsf.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dprstars.x <gset.h> <tbset.h> \
+ ../lib/apseldef.h ../lib/psfdef.h
+ dpshowpsf.x <mach.h> <ctype.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpspstars.x <mach.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/psfdef.h
+ dpsubpsf.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpsurfpsf.x <error.h> <mach.h> \
+ <gset.h> <config.h> \
+ <xwhen.h> <fset.h> \
+ ../lib/daophotdef.h ../lib/psfdef.h
+ dpwritepsf.x <time.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h \
+ ../lib/psfdef.h
+ t_psf.x <fset.h> <gset.h> \
+ <imhdr.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/psfdef.h
+ t_pstselect.x <fset.h> <gset.h> \
+ <imhdr.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h ../lib/psfdef.h
+ ;
diff --git a/noao/digiphot/daophot/psf/mkpsf.key b/noao/digiphot/daophot/psf/mkpsf.key
new file mode 100644
index 00000000..ed511025
--- /dev/null
+++ b/noao/digiphot/daophot/psf/mkpsf.key
@@ -0,0 +1,40 @@
+ Keystroke Commands
+
+? Print help
+p Print photometry for star nearest the cursor
+l List the current psf stars
+a Add star nearest cursor to psf star list
+f Fit the psf
+r Review the fit for all the psf stars
+s Subtract fitted psf from psf star nearest cursor
+d Delete psf star nearest cursor from psf star list
+w Write the psf to the psf image
+z Rebuild the psf from scratch
+q Quit task
+
+ Colon Commands
+
+:p [n] Print photometry for star n
+:a [n] Add star n to psf star list
+:d [n] Delete star n from psf star list
+:s [n] Subtract fitted psf from psf star n
+
+ Colon Parameter Editing Commands
+
+# Data dependent parameters which affect the psf computation
+
+:scale [value] Show/set the image scale (units / pixel)
+:fwhmpsf [value] Show/set the fwhm of psf (scale units)
+:datamin [value] Show/set the minimum good data value (counts)
+:datamax [value] Show/set the maximum good data value (counts)
+:matchrad [value] Show/set matching radius (scale units)
+
+# Psf computation parameters
+
+:psfimage [name,name] Show/set the psf image and groupfile
+:function [string] Show/set the analytic psf function
+:varorder [integer] Show/set order of psf function variability
+:nclean [integer] Show/set number of cleaning iterations
+:saturated [y/n] Show/set the use saturated star flag
+:psfrad [value] Show/set the psf radius (scale units)
+:fitrad [value] Show/set the fitting radius (scale units)
diff --git a/noao/digiphot/daophot/psf/mkpsflist.key b/noao/digiphot/daophot/psf/mkpsflist.key
new file mode 100644
index 00000000..0ed43c8a
--- /dev/null
+++ b/noao/digiphot/daophot/psf/mkpsflist.key
@@ -0,0 +1,15 @@
+ Keystroke Commands
+
+? Print help
+p Print photometry for star nearest the cursor
+l List the current psf stars
+n Select the next good candidate psf star from the list
+a Add star nearest cursor to psf star list
+d Delete psf star nearest cursor from psf star list
+q Quit task
+
+ Colon Commands
+
+:p [n] Print photometry for star n
+:a [n] Add star n to psf star list
+:d [n] Delete star n from psf star list
diff --git a/noao/digiphot/daophot/psf/showpsf.key b/noao/digiphot/daophot/psf/showpsf.key
new file mode 100644
index 00000000..7551477e
--- /dev/null
+++ b/noao/digiphot/daophot/psf/showpsf.key
@@ -0,0 +1,24 @@
+ Interactive Graphics Keystroke Commands
+
+? Print help
+p Print the photometry for this star
+t Print the plot parameters and data minimum and maximum
+a Accept star and proceed
+d Reject star and select another with image cursor
+m Plot the default mesh plot for this star
+n Increase vertical angle by 15 degrees (mesh plot only)
+s Decrease vertical angle by 15 degrees (mesh plot only)
+w Decrease horizontal angle by 15 degrees (mesh plot only)
+e Increase horizontal angle by 15 degrees (mesh plot only)
+c Plot the default contour plot for this star
+r Plot the radial profile for this star
+
+
+ Colon Graphics Commands
+
+:m [val] [val] Set the mesh plot vertical and horizontal viewing angles
+:v [val] Set the mesh plot vertical viewing angle
+:h [val] Set the mesh plot horizontal viewing angle
+:c [val] [val] Set the contour plot floor and ceiling levels
+:l [value] Set the contour plot floor level
+:u [value] Set the contour plot ceiling level
diff --git a/noao/digiphot/daophot/psf/t_psf.x b/noao/digiphot/daophot/psf/t_psf.x
new file mode 100644
index 00000000..b7444b3e
--- /dev/null
+++ b/noao/digiphot/daophot/psf/t_psf.x
@@ -0,0 +1,509 @@
+include <fset.h>
+include <imhdr.h>
+include <gset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+# T_PSF -- Generate a point spread function from one or more stars in the
+# image frame.
+
+procedure t_psf ()
+
+pointer image # the input image
+pointer photfile # input aperture photometry file
+pointer pstarfile # input psf star file
+pointer psfimage # output psf image
+pointer groupfile # output psf group file
+pointer opstfile # output psf star file
+pointer graphics # pointer to graphics device name
+pointer plotfile # pointer to plotfile name
+int cache # cache the input image pixels
+pointer display # pointer to display device name
+bool matchbyid # match psf stars by id or position
+bool interactive # the mode of task operation
+bool showplots # display plots of the psf stars
+pointer plottype # type of psf plot
+bool mkstars # mark deleted and accepted psf stars
+
+pointer sp, im, apd, psfim, dao, mgd, gd, id
+pointer outfname, curfile, str
+int imlist, limlist, alist, lalist, clist, lclist, pimlist, lpimlist
+int olist, lolist, oclist, loclist, up, verify, update, wcs
+int root, min_lenuserarea, pltype, pfd, pst, psfgr, opst
+int req_size, old_size, buf_size, memstat
+bool ap_text, pst_text
+
+pointer immap(), tbtopn(), gopen()
+int fnldir(), strlen(), strncmp(), btoi(), envfind(), ctoi(), clgwrd()
+int strdic(), open(), access(), fstati(), dp_stati(), dp_pstati()
+int imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb(), fntgfnb()
+int sizeof(), dp_memstat()
+bool streq(), clgetb(), itob(), dp_updatepsf()
+errchk gopen
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (pstarfile, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (groupfile, SZ_FNAME, TY_CHAR)
+ call salloc (opstfile, SZ_FNAME, TY_CHAR)
+ call salloc (plottype, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (graphics, SZ_FNAME, TY_CHAR)
+ call salloc (display, SZ_FNAME, TY_CHAR)
+ call salloc (plotfile, SZ_FNAME, TY_CHAR)
+ call salloc (curfile, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("pstfile", Memc[pstarfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("opstfile", Memc[opstfile], SZ_FNAME)
+ call clgstr ("groupfile", Memc[groupfile], SZ_FNAME)
+ cache = btoi (clgetb ("cache"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[photfile], NO)
+ lalist = fntlenb (alist)
+ clist = fntopnb (Memc[pstarfile], NO)
+ lclist = fntlenb (clist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ olist = fntopnb (Memc[groupfile], NO)
+ lolist = fntlenb (olist)
+ oclist = fntopnb (Memc[opstfile], NO)
+ loclist = fntlenb (oclist)
+
+ # Test that the lengths of the photometry file, psf image, and
+ # output file lists are the same as the length of the input image
+ # list.
+
+ # Compare the image and photometry file list lengths.
+ if ((limlist != lalist) && (strncmp (Memc[photfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and photometry file list lengths")
+ }
+
+ # Compare the image and psf star list lengths.
+ if ((lclist != 0) && (limlist != lclist) && (strncmp (Memc[pstarfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and psf star file list lengths")
+ }
+
+ # Compare the image and psf image list lengths.
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and psf file list lengths")
+ }
+
+ # Compare the image and groupfile list lengths.
+ if ((limlist != lolist) && (strncmp (Memc[groupfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and group file list lengths")
+ }
+
+ # Compare the image and output pstfile list lengths.
+ if ((limlist != loclist) && (strncmp (Memc[opstfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and output psf file list lengths")
+ }
+
+ # Initialize DAOPHOT main structure, get pset parameters.
+ call dp_gppars (dao)
+
+ # Verify the critical parameters and update if appropriate.
+ if (verify == YES) {
+ call dp_pconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+
+ # Initialize the photometry structure.
+ call dp_apselsetup (dao)
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Intialize the PSF fitting structure.
+ call dp_psfsetup (dao)
+
+ # Matching algorithm for stars in the psf star list.
+ matchbyid = clgetb ("matchbyid")
+
+ # Is the task interactive or not?
+ call clgstr ("icommands.p_filename", Memc[curfile], SZ_FNAME)
+ if (Memc[curfile] == EOS)
+ interactive = clgetb ("interactive")
+ else
+ interactive = false
+
+ # Get the graphics, display and plot file devices.
+ call clgstr ("graphics", Memc[graphics], SZ_FNAME)
+ call clgstr ("display", Memc[display], SZ_FNAME)
+ call clgstr ("plottype", Memc[plottype], SZ_FNAME)
+ call clgstr ("plotfile", Memc[plotfile], SZ_FNAME)
+
+ # Open graphics and display devices if appropriate.
+ if (interactive) {
+ call dp_seti (dao, VERBOSE, YES)
+ showplots = clgetb ("showplots")
+ if (Memc[graphics] == EOS)
+ gd = NULL
+ else {
+ iferr {
+ gd = gopen (Memc[graphics], APPEND+AW_DEFER, STDGRAPH)
+ } then {
+ call eprintf (
+ "Warning: Error opening graphics device. \n")
+ gd = NULL
+ }
+ }
+ if (Memc[display] == EOS)
+ id = NULL
+ else if (streq (Memc[graphics], Memc[display]))
+ id = gd
+ else {
+ iferr {
+ id = gopen (Memc[display], APPEND, STDIMAGE)
+ } then {
+ call eprintf (
+ "Warning: Graphics overlay not available for display device.\n")
+ id = NULL
+ }
+ }
+ if (id != NULL)
+ mkstars = clgetb ("mkstars")
+ else
+ mkstars = false
+ } else {
+ gd = NULL
+ id = NULL
+ call dp_seti (dao, VERBOSE, btoi (clgetb ("verbose")))
+ showplots = false
+ mkstars = false
+ }
+
+ # Open the plot file.
+ if (Memc[plotfile] == EOS)
+ pfd = NULL
+ else
+ pfd = open (Memc[plotfile], APPEND, BINARY_FILE)
+ if (pfd != NULL)
+ mgd = gopen (Memc[graphics], NEW_FILE, pfd)
+ else
+ mgd = NULL
+
+ # Set the default plot type.
+ pltype = strdic (Memc[plottype], Memc[plottype], SZ_FNAME, PSF_PLOTS)
+ call dp_pseti (dao, PLOTTYPE, pltype)
+
+ # Loop over the list of images.
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open input image
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Set up the display coordinate system.
+ if ((id != NULL) && (id != gd))
+ call dp_gswv (id, Memc[image], im, 4)
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ # Open the input photometry list and store the descriptor.
+ # PSF can read either an APPHOT PHOT file or an ST TABLE
+ # file.
+
+ if (fntgfnb (alist, Memc[photfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[photfile], SZ_FNAME)
+ root = fnldir (Memc[photfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[photfile+root], DEF_LENDEFNAME) ==
+ 0 || root == strlen (Memc[photfile]))
+ call dp_inname (Memc[image], Memc[outfname], "mag",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[photfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ apd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ apd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_wgetapert (dao, im, apd, dp_stati (dao, MAXNSTAR), ap_text)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Open the input photometry list and store the descriptor.
+ # PSF can read either an APPHOT PHOT file or an ST TABLE
+ # file.
+
+ if (lclist == 0) {
+ pst = NULL
+ Memc[outfname] = EOS
+ } else {
+ if (fntgfnb (clist, Memc[pstarfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[pstarfile], SZ_FNAME)
+ root = fnldir (Memc[pstarfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[pstarfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[pstarfile]))
+ call dp_inname (Memc[image], Memc[outfname], "pst",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[pstarfile], Memc[outfname], SZ_FNAME)
+ pst_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (pst_text)
+ pst = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ pst = tbtopn (Memc[outfname], READ_ONLY, 0)
+ }
+ call dp_sets (dao, COORDS, Memc[outfname])
+
+ # Open output image containing PSF, output file containing list
+ # of PSF stars actually used, and the file for PSF neighbors
+ # If the output is "default", dir$default or a directory
+ # specification then the extension "psf" is added to the PSF image
+ # and "psg" to the neighbors file. A suitable version number is
+ # added to the output name as well. Check that there is enough
+ # space in the image header user area to hold many PSF stars.
+
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage + root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage])) {
+ call dp_oimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ } else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (envfind ("min_lenuserarea", Memc[str], SZ_FNAME) > 0) {
+ up = 1
+ if (ctoi (Memc[str], up, min_lenuserarea) <= 0)
+ min_lenuserarea = MIN_LENUSERAREA
+ else
+ min_lenuserarea = max (MIN_LENUSERAREA, min_lenuserarea)
+ } else
+ min_lenuserarea = MIN_LENUSERAREA
+ call dp_pseti (dao, LENUSERAREA, min_lenuserarea)
+ psfim = immap (Memc[outfname], NEW_IMAGE, min_lenuserarea)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+
+ if (fntgfnb (olist, Memc[groupfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[groupfile], SZ_FNAME)
+ root = fnldir (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[groupfile + root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[groupfile])) {
+ call dp_outname (Memc[image], Memc[outfname], "psg",
+ Memc[outfname], SZ_FNAME)
+ } else
+ call strcpy (Memc[groupfile], Memc[outfname], SZ_FNAME)
+ if (dp_stati (dao, TEXT) == YES)
+ psfgr = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ psfgr = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+
+ if (fntgfnb (oclist, Memc[opstfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[opstfile], SZ_FNAME)
+ root = fnldir (Memc[opstfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[opstfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[opstfile])) {
+ call dp_outname (Memc[image], Memc[outfname], "pst",
+ Memc[outfname], SZ_FNAME)
+ } else
+ call strcpy (Memc[opstfile], Memc[outfname], SZ_FNAME)
+ if (dp_stati (dao, TEXT) == YES)
+ opst = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ opst = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTREJFILE, Memc[outfname])
+
+ # Print banner.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nComputing PSF for image: %s\n")
+ call pargstr (Memc[image])
+ call dp_stats (dao, INPHOTFILE, Memc[str], SZ_FNAME)
+ call printf ("%d stars read from %s\n\n")
+ call pargi (dp_stati (dao, APNUM))
+ call pargstr (Memc[str])
+ }
+
+ # Read in the PSF star list.
+ call dp_pseti (dao, PNUM, 0)
+ if (pst != NULL) {
+ call dp_rpstars (dao, im, pst, pst_text, gd, mgd, id, mkstars,
+ matchbyid, showplots)
+ if (DP_VERBOSE(dao) == YES) {
+ call dp_stats (dao, COORDS, Memc[str], SZ_FNAME)
+ call printf ("\n%d PSF stars read from %s\n\n")
+ call pargi (dp_pstati (dao, PNUM))
+ call pargstr (Memc[str])
+ }
+ }
+
+ # Make the PSF.
+ if (Memc[curfile] != EOS)
+ call dp_mkpsf (dao, im, psfim, opst, psfgr, gd, mgd, id, false,
+ false, false)
+ else if (interactive)
+ call dp_mkpsf (dao, im, psfim, opst, psfgr, gd, mgd, id,
+ mkstars, true, true)
+ else if (! dp_updatepsf (dao, im, psfim, opst, psfgr, false, false,
+ false))
+ call dp_rmpsf (dao, psfim, opst, psfgr)
+
+ # Close the input image.
+ call imunmap (im)
+
+ # Close the input photometry file.
+ if (apd != NULL) {
+ if (ap_text)
+ call close (apd)
+ else
+ call tbtclo (apd)
+ }
+
+ # Close the input psf star file.
+ if (pst != NULL) {
+ if (pst_text)
+ call close (pst)
+ else
+ call tbtclo (pst)
+ }
+
+ # Close PSF image.
+ if (psfim != NULL)
+ call imunmap (psfim)
+
+ # Close the output PSF star file.
+ if (opst != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (opst)
+ else
+ call tbtclo (opst)
+ }
+
+ # Close the group file.
+ if (psfgr != NULL) {
+ if (dp_stati (dao, TEXT) == YES)
+ call close (psfgr)
+ else
+ call tbtclo (psfgr)
+ }
+
+ # Uncache memory.
+ call fixmem (old_size)
+ }
+
+ # Close up the graphics and display streams.
+ if (id == gd && id != NULL)
+ call gclose (id)
+ else {
+ if (gd != NULL)
+ call gclose (gd)
+ if (id != NULL)
+ call gclose (id)
+ }
+
+ # Close the metacode plot files.
+ if (mgd != NULL)
+ call gclose (mgd)
+ if (pfd != NULL)
+ call close (pfd)
+
+ # Close the image / file lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (clist)
+ call imtclose (pimlist)
+ call fntclsb (olist)
+ call fntclsb (oclist)
+
+ # Free the photometry structure.
+ call dp_apclose (dao)
+
+ # Free the PSF fitting structure.
+ call dp_psfclose (dao)
+
+ # Free the PSF structure.
+ call dp_fitclose (dao)
+
+ # Close up the daophot structures.
+ call dp_free (dao)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/psf/t_pstselect.x b/noao/digiphot/daophot/psf/t_pstselect.x
new file mode 100644
index 00000000..497ab374
--- /dev/null
+++ b/noao/digiphot/daophot/psf/t_pstselect.x
@@ -0,0 +1,329 @@
+include <fset.h>
+include <imhdr.h>
+include <gset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+include "../lib/psfdef.h"
+
+# T_PSTSELECT -- Select good candidate PSF stars from a DAOPHOT photometry
+# file.
+
+procedure t_pstselect ()
+
+pointer image # input image
+pointer photfile # input rough photometry
+pointer pstfile # output PSTFILE table
+int maxnpsf # maximimum number of psf stars
+pointer plotfile # pointer to the plot metacode file
+bool interactive # interactive mode
+pointer plottype # default plot type
+int cache # cache the input image pixels
+int verify # verify the critical parameters
+int update # update the critical parameters
+pointer graphics # the graphics device
+pointer display # the display device
+bool mkstars # mark deleted and accepted psf stars
+
+pointer sp, pfd, dao, outfname, curfile, str, im, gd, id, mgd
+int imlist, limlist, alist, lalist, olist, lolist, root, apd, pmgd, pltype
+int wcs, req_size, old_size, buf_size, memstat()
+bool ap_text
+
+pointer immap(), gopen()
+int tbtopn(), open(), fnldir(), strlen(), strncmp(), fstati(), btoi()
+int access(), fntopnb(), fntlenb(), clgeti(), imtopen(), imtlen()
+int fntgfnb(), imtgetim(), strdic(), dp_stati(), clgwrd(), sizeof()
+int dp_memstat()
+bool clgetb(), itob(), streq()
+
+errchk gopen()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (pstfile, SZ_FNAME, TY_CHAR)
+ call salloc (plotfile, SZ_FNAME, TY_CHAR)
+ call salloc (plottype, SZ_FNAME, TY_CHAR)
+ call salloc (graphics, SZ_FNAME, TY_CHAR)
+ call salloc (display, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (curfile, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("pstfile", Memc[pstfile], SZ_FNAME)
+ maxnpsf = clgeti ("maxnpsf")
+ cache = btoi (clgetb ("cache"))
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[photfile], NO)
+ lalist = fntlenb (alist)
+ olist = fntopnb (Memc[pstfile], NO)
+ lolist = fntlenb (olist)
+
+ # Test that the lengths of the photometry file and psf star file
+ # lists are the same as the input image list.
+
+ if ((limlist != lalist) && (strncmp (Memc[photfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and photometry file list lengths\n")
+ }
+
+ if ((limlist != lolist) && (strncmp (Memc[pstfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "Incompatable image and photometry file list lengths\n")
+ }
+
+ # Initialize the DAOPHOT structure, and get the pset parameters.
+ call dp_gppars (dao)
+
+ # Confirm the parameters.
+ if (verify == YES) {
+ call dp_ptconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_LINE, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_LINE, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+
+ # Initialize the photometry structure.
+ call dp_apsetup (dao)
+
+ # Initialize the PSF fitting structure.
+ call dp_psfsetup (dao)
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Is the task interactive or not?
+ call clgstr ("icommands.p_filename", Memc[curfile], SZ_FNAME)
+ if (Memc[curfile] == EOS)
+ interactive = clgetb ("interactive")
+ else
+ interactive = false
+
+ # Get the graphics display and plot file devices.
+ call clgstr ("graphics", Memc[graphics], SZ_FNAME)
+ call clgstr ("display", Memc[display], SZ_FNAME)
+ call clgstr ("plottype", Memc[plottype], SZ_FNAME)
+ call clgstr ("plotfile", Memc[plotfile], SZ_FNAME)
+
+ # Open graphics and display devices if appropriate.
+ if (interactive) {
+ call dp_seti (dao, VERBOSE, YES)
+ if (Memc[graphics] == EOS)
+ gd = NULL
+ else {
+ iferr {
+ gd = gopen (Memc[graphics], APPEND+AW_DEFER, STDGRAPH)
+ } then {
+ call eprintf ("Warning: Error opening graphics device\n")
+ gd = NULL
+ }
+ }
+ if (Memc[display] == EOS)
+ id = NULL
+ else if (streq (Memc[graphics], Memc[display])) {
+ id = gd
+ } else {
+ iferr {
+ id = gopen (Memc[display], APPEND, STDIMAGE)
+ } then {
+ call eprintf (
+ "Warning: Graphics overlay not available for display device\n")
+ id = NULL
+ }
+ }
+ if (id != NULL)
+ mkstars = clgetb ("mkstars")
+ else
+ mkstars = false
+ } else {
+ gd = NULL
+ id = NULL
+ call dp_seti (dao, VERBOSE, btoi (clgetb ("verbose")))
+ mkstars = false
+ }
+
+ # Open the plot file.
+ if (Memc[plotfile] == EOS)
+ pmgd = NULL
+ else
+ pmgd = open (Memc[plotfile], APPEND, BINARY_FILE)
+ if (pmgd != NULL)
+ mgd = gopen (Memc[graphics], NEW_FILE, pmgd)
+ else
+ mgd = NULL
+
+ # Set the default plot type.
+ pltype = strdic (Memc[plottype], Memc[plottype], SZ_FNAME, PSF_PLOTS)
+ call dp_pseti (dao, PLOTTYPE, pltype)
+
+ # Loop over the list of input files
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open the input image.
+ im = immap (Memc[image], READ_ONLY, 0)
+ call dp_imkeys (dao, im)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Set up the display coordinate system.
+ if ((id != NULL) && (id != gd))
+ call dp_gswv (id, Memc[image], im, 4)
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * IM_LEN(im,1) * IM_LEN(im,2) *
+ sizeof (IM_PIXTYPE(im))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (im, INDEFI, buf_size)
+
+ # Open the input photometry table and read in the photometry.
+ if (fntgfnb (alist, Memc[photfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[photfile], SZ_FNAME)
+ root = fnldir (Memc[photfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[photfile+root], DEF_LENDEFNAME) ==
+ 0 || root == strlen (Memc[photfile]))
+ call dp_inname (Memc[image], Memc[outfname], "mag",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[photfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ apd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ apd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_wgetapert (dao, im, apd, DP_MAXNSTAR(dao), ap_text)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Open the output PSTSELECT file. If the output is "default",
+ # dir$default or a directory specification then the extension .pst
+ # is added to the image name and a suitable version number is
+ # appended to the output name.
+
+ if (fntgfnb (olist, Memc[pstfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[pstfile], SZ_FNAME)
+ root = fnldir (Memc[pstfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[pstfile + root], DEF_LENDEFNAME) ==
+ 0 || root == strlen (Memc[pstfile]))
+ call dp_outname (Memc[image], Memc[outfname], "pst",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[pstfile], Memc[outfname], SZ_FNAME)
+ if (ap_text)
+ pfd = open (Memc[outfname], NEW_FILE, TEXT_FILE)
+ else
+ pfd = tbtopn (Memc[outfname], NEW_FILE, 0)
+ call dp_sets (dao, OUTPHOTFILE, Memc[outfname])
+
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("\nSelecting PSF stars for image %s\n")
+ call pargstr (Memc[image])
+ call dp_stats (dao, INPHOTFILE, Memc[outfname], SZ_FNAME)
+ call printf ("\t%d stars read from file %s\n\n")
+ call pargi (dp_stati (dao, APNUM))
+ call pargstr (Memc[outfname])
+ }
+
+ # Now select the PSF stars.
+ if (Memc[curfile] != EOS)
+ call dp_gpstars (dao, im, apd, pfd, ap_text, maxnpsf, NULL,
+ mgd, NULL, false, false, true)
+ else if (interactive)
+ call dp_gpstars (dao, im, apd, pfd, ap_text, maxnpsf, gd, mgd,
+ id, mkstars, true, false)
+ else
+ call dp_gpstars (dao, im, apd, pfd, ap_text, maxnpsf, NULL,
+ mgd, NULL, false, false, false)
+
+ # Close the input image.
+ call imunmap (im)
+
+ # Close the photometry file.
+ if (ap_text)
+ call close (apd)
+ else
+ call tbtclo (apd)
+
+ # Close the output table.
+ if (ap_text)
+ call close (pfd)
+ else
+ call tbtclo (pfd)
+
+ # Uncache memory.
+ call fixmem (old_size)
+
+ }
+
+ # Close up the graphics and display streams.
+ if (id == gd && id != NULL)
+ call gclose (id)
+ else {
+ if (gd != NULL)
+ call gclose (gd)
+ if (id != NULL)
+ call gclose (id)
+ }
+
+ # Close the metacode plot files.
+ if (mgd != NULL)
+ call gclose (mgd)
+ if (pmgd != NULL)
+ call close (pmgd)
+
+ # Close the image/file lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (olist)
+
+ # Close the PSF structure.
+ call dp_fitclose (dao)
+
+ # Close the PSF fitting structure.
+ call dp_psfclose (dao)
+
+ # Free the photometry structure.
+ call dp_apclose (dao)
+
+ # Free the daophot structure.
+ call dp_free (dao)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/pstselect.par b/noao/digiphot/daophot/pstselect.par
new file mode 100644
index 00000000..555d23f4
--- /dev/null
+++ b/noao/digiphot/daophot/pstselect.par
@@ -0,0 +1,23 @@
+# Parameters for the PSTSELECT task
+
+image,f,a,,,,"Image for which to build psf star list"
+photfile,f,a,default,,,"Photometry file (default: image.mag.?)"
+pstfile,f,a,"default",,,"Output psf star list file (default: image.pst.?)"
+maxnpsf,i,a,25,1,,"Maximum number of psf stars"
+mkstars,b,h,no,,,"Mark deleted and accepted psf stars"
+plotfile,s,h,"",,,"Output plot metacode file"
+datapars,pset,h,"",,,"Data dependent parameters"
+daopars,pset,h,"",,,"Psf fitting parameters"
+interactive,b,h,no,,,"Select psf stars interactively?"
+plottype,s,h,mesh,"|mesh|contour|radial",,"Default plot type (mesh|contour|radial)"
+icommands,*imcur,h,"",,,"Image cursor: [x y wcs] key [cmd]"
+gcommands,*gcur,h,"",,,"Graphics cursor: [x y wcs] key [cmd]"
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the input image pixels in memory?"
+verify,b,h,)_.verify,,,"Verify critical pstselect parameters?"
+update,b,h,)_.update,,,"Update critical pstselect parameters?"
+verbose,b,h,)_.verbose,,,"Print pstselect messages?"
+graphics,s,h,)_.graphics,,,"Graphics device"
+display,s,h,)_.display,,,"Image display device"
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/seepsf.par b/noao/digiphot/daophot/seepsf.par
new file mode 100644
index 00000000..25a4faea
--- /dev/null
+++ b/noao/digiphot/daophot/seepsf.par
@@ -0,0 +1,9 @@
+# Parameters for the SEEPSF task
+
+psfimage,f,a,,,,"PSF image name"
+image,f,a,,,,"Output image name"
+dimension,i,h,INDEF,,,"Dimension of the output PSF image"
+xpsf,r,h,INDEF,,,"X distance from the PSF star"
+ypsf,r,h,INDEF,,,"Y distance from the PSF star"
+magnitude,r,h,INDEF,,,"Magnitude of the PSF star"
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/seepsf/dpmkimage.x b/noao/digiphot/daophot/seepsf/dpmkimage.x
new file mode 100644
index 00000000..3be872c9
--- /dev/null
+++ b/noao/digiphot/daophot/seepsf/dpmkimage.x
@@ -0,0 +1,110 @@
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# DP_MKIMAGE -- Make an image from the PSF.
+
+procedure dp_mkimage (dao, im_psf, im_out, dimen, xpsf, ypsf, magnitude)
+
+pointer dao # pointer to the DAOPHOT structure
+pointer im_psf # pointer to the psf image descriptor
+pointer im_out # pointer to the image descriptor
+int dimen # size of the image (square)
+real xpsf # x position of the psf
+real ypsf # y position of the psf
+real magnitude # magnitude of the PSF
+
+int i, j, psf_size, im_size
+pointer psffit, pixels, pixel
+real psfrad, dxfrom_psf, dyfrom_psf, dvdx, dvdy, start, delta, dx, dy, scale
+real dysq, drsq, psfradsq
+pointer imps2r()
+real imgetr(), dp_usepsf()
+errchk imgetr()
+
+begin
+ # Get the other pointers.
+ psffit = DP_PSFFIT (dao)
+ if (DP_PSFSIZE(psffit) > 0)
+ psfrad = (real (DP_PSFSIZE(psffit) - 1) / 2.0 - 1.0) / 2.0
+ else {
+ iferr {
+ scale = imgetr (im_psf, "SCALE")
+ } then {
+ psfrad = imgetr (im_psf, "PSFRAD")
+ } else {
+ psfrad = imgetr (im_psf, "PSFRAD") / scale
+ }
+ }
+ psfradsq = psfrad ** 2
+ psf_size = 2 * int (psfrad) + 1
+
+ IM_NDIM(imout) = 2
+ if (IS_INDEFI(dimen)) {
+ IM_LEN(im_out, 1) = psf_size
+ IM_LEN(im_out, 2) = psf_size
+ im_size = psf_size
+ } else {
+ IM_LEN(im_out, 1) = dimen
+ IM_LEN(im_out, 2) = dimen
+ im_size = dimen
+ }
+ IM_PIXTYPE(im_out) = TY_REAL
+
+ if (IS_INDEFR(xpsf)) {
+ dx = DP_PSFX(psffit)
+ dxfrom_psf = (DP_PSFX(psffit) - 1.0) / DP_PSFX(psffit) - 1.0
+ } else {
+ dx = xpsf
+ dxfrom_psf = (xpsf - 1.0) / DP_PSFX(psffit) - 1.0
+ }
+ if (IS_INDEFR(ypsf)) {
+ dy = DP_PSFY(psffit)
+ dyfrom_psf = (DP_PSFY(psffit) - 1.0) / DP_PSFY(psffit) - 1.0
+ } else {
+ dy = ypsf
+ dyfrom_psf = (ypsf - 1.0) / DP_PSFY(psffit) - 1.0
+ }
+
+ if (IS_INDEFR (magnitude)) {
+ scale = 1.0
+ } else {
+ scale = DAO_RELBRIGHT (psffit, magnitude)
+ }
+
+ call sprintf (IM_TITLE(im_out), SZ_IMTITLE,
+ "PSF evaluated at X: %.2f Y: %.2f Mag: %.3f")
+ call pargr (dx)
+ call pargr (dy)
+ if (IS_INDEFR(magnitude))
+ call pargr (DP_PSFMAG(psffit))
+ else
+ call pargr (magnitude)
+
+ # Get the image buffer and evaluate the PSF.
+ pixels = imps2r (im_out, 1, int (IM_LEN (im_out, 1)), 1,
+ int (IM_LEN (im_out, 2)))
+
+ # Get the starting coordinates and interpolation interval.
+ start = - (psf_size - 1) / 2.0
+ delta = real (psf_size - 1) / real (im_size - 1)
+
+ # Evaluate the pixels.
+ pixel = pixels
+ do j = 1, im_size {
+ dy = start + delta * (j - 1)
+ dysq = dy ** 2
+ do i = 1, im_size {
+ dx = start + delta * (i - 1)
+ drsq = dx ** 2 + dysq
+ if (drsq >= psfradsq)
+ Memr[pixel] = 0.0
+ else
+ Memr[pixel] = scale * dp_usepsf (DP_PSFUNCTION(psffit),
+ dx, dy, DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit), dxfrom_psf,
+ dyfrom_psf, dvdx, dvdy)
+ pixel = pixel + 1
+ }
+ }
+end
diff --git a/noao/digiphot/daophot/seepsf/mkpkg b/noao/digiphot/daophot/seepsf/mkpkg
new file mode 100644
index 00000000..f8f23f29
--- /dev/null
+++ b/noao/digiphot/daophot/seepsf/mkpkg
@@ -0,0 +1,11 @@
+# SEEPSF task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpmkimage.x <imhdr.h> ../lib/daophotdef.h
+ t_seepsf.x <fset.h>
+ ;
diff --git a/noao/digiphot/daophot/seepsf/t_seepsf.x b/noao/digiphot/daophot/seepsf/t_seepsf.x
new file mode 100644
index 00000000..e104121c
--- /dev/null
+++ b/noao/digiphot/daophot/seepsf/t_seepsf.x
@@ -0,0 +1,91 @@
+include <fset.h>
+
+# T_SEEPSF -- Produce the PSF in image scale coordinates.
+
+procedure t_seepsf ()
+
+pointer psfimage # name of the input PSF
+pointer image # name of the output image
+int dimen # size of the image
+real magnitude # magnitude of star
+
+int psffd, pimlist, lpimlist, imlist, limlist
+pointer im, sp, dao
+real xpsf, ypsf
+
+int clgeti(), fstati(), imtopen(), imtlen(), imtgetim()
+real clgetr()
+pointer immap()
+
+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 (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ dimen = clgeti ("dimension")
+ if (! IS_INDEFI(dimen)) {
+ if (mod (dimen, 2) == 0)
+ dimen = dimen + 1
+ }
+ xpsf = clgetr ("xpsf")
+ ypsf = clgetr ("ypsf")
+ magnitude = clgetr ("magnitude")
+
+ # Get the lists.
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+
+ # Check the list lengths for equality.
+ if (lpimlist != limlist) {
+ call imtclose (pimlist)
+ call imtclose (imlist)
+ call sfree (sp)
+ call error (0,
+ "The psf and output image lengths are imcompatibale")
+ }
+
+ # Initialize the daophot structure and get the pset parameters.
+ call dp_init (dao)
+ call dp_fitsetup (dao)
+
+ # Loop over the input images
+ while ((imtgetim (pimlist, Memc[psfimage], SZ_FNAME) != EOF) &&
+ (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF)) {
+
+ # Open the psfimage.
+ psffd = immap (Memc[psfimage], READ_ONLY, 0)
+
+ # Open the output image.
+ im = immap (Memc[image], NEW_COPY, psffd)
+
+ # Read the PSF.
+ call dp_readpsf (dao, psffd)
+
+ # Make PSF image.
+ call dp_mkimage (dao, psffd, im, dimen, xpsf, ypsf, magnitude)
+
+ # Close the PSF image and the output image.
+ call imunmap (psffd)
+ call imunmap (im)
+ }
+
+ # Close the daophot structure.
+ call dp_fitclose (dao)
+ call dp_free (dao)
+
+ # Close the lists
+ call imtclose (pimlist)
+ call imtclose (imlist)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/select/dpgwselect.x b/noao/digiphot/daophot/select/dpgwselect.x
new file mode 100644
index 00000000..dcaafece
--- /dev/null
+++ b/noao/digiphot/daophot/select/dpgwselect.x
@@ -0,0 +1,141 @@
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define NCOLUMN 6
+
+define GR_DATASTR "%-9d%10t%-6d%16t%-10.3f%26t%-10.3f%36t%-12.3f%48t%-15.7g%80t \n"
+
+# DP_XWRTSELECT -- Write out the groups into an ST Table.
+
+procedure dp_xwrtselect (dao, grp, ngroup, group_id)
+
+pointer dao # pointer to the daophot structure
+pointer grp # pointer to group output file
+int ngroup # number in the group
+int group_id # the id of the group
+
+int i
+pointer apsel
+
+begin
+ # Get the daophot pointer.
+ apsel = DP_APSEL(dao)
+
+ # Write out the data.
+ do i = 1, ngroup {
+ call fprintf (grp, GR_DATASTR)
+ call pargi (group_id)
+ call pargi (Memi[DP_APID(apsel)+i-1])
+ call pargr (Memr[DP_APXCEN(apsel)+i-1])
+ call pargr (Memr[DP_APYCEN(apsel)+i-1])
+ call pargr (Memr[DP_APMAG(apsel)+i-1])
+ call pargr (Memr[DP_APMSKY(apsel)+i-1])
+ }
+end
+
+
+# DP_TWRTSELECT -- Write out the groups into an ST Table.
+
+procedure dp_twrtselect (dao, grp, colpoint, ngroup, cur_group, row)
+
+pointer dao # pointer to the daophot structure
+pointer grp # pointer to group output file
+pointer colpoint[ARB] # column pointers
+int ngroup # number in group
+int cur_group # current group
+
+int i, row
+pointer apsel
+
+begin
+ # Get the daophot pointer.
+ apsel = DP_APSEL(dao)
+
+ # Write out the data.
+ do i = 1, ngroup {
+ row = row + 1
+ call tbrpti (grp, colpoint[1], Memi[DP_APID(apsel)+i-1], 1, row)
+ call tbrpti (grp, colpoint[2], cur_group, 1, row)
+ call tbrptr (grp, colpoint[3], Memr[DP_APXCEN(apsel)+i-1], 1, row)
+ call tbrptr (grp, colpoint[4], Memr[DP_APYCEN(apsel)+i-1], 1, row)
+ call tbrptr (grp, colpoint[5], Memr[DP_APMAG(apsel)+i-1], 1, row)
+ call tbrptr (grp, colpoint[6], Memr[DP_APMSKY(apsel)+i-1], 1, row)
+
+ }
+end
+
+
+# DP_XGSELPARS -- Add various parameters to the header of the group table.
+
+procedure dp_xgselpars (tp, min_group, max_group)
+
+pointer tp # pointer to the table
+int min_group # minimum group size
+int max_group # maximum group size
+
+begin
+ # Add the min_group and max_group parameters.
+ call dp_iparam (tp, "MINSZGROUP", min_group, "number", "")
+ call dp_iparam (tp, "MAXSZGROUP", max_group, "number", "")
+end
+
+
+# DP_TGSELCOL -- Set the column pointers for the output file.
+
+procedure dp_tgselcol (tp, colpoints)
+
+pointer tp # table pointer
+pointer colpoints[ARB] # column pointers
+
+begin
+ call tbcfnd (tp, ID, colpoints[1], 1)
+ if (colpoints[1] == NULL)
+ call tbcfnd (tp, "ID", colpoints[1], 1)
+ if (colpoints[1] == NULL)
+ call printf ("Error reading ID.\n")
+
+ call tbcfnd (tp, GROUP, colpoints[2], 1)
+ if (colpoints[2] == NULL)
+ call tbcfnd (tp, "GROUP", colpoints[2], 1)
+ if (colpoints[2] == NULL)
+ call printf ("Error reading GROUP.\n")
+
+ call tbcfnd (tp, XCENTER, colpoints[3], 1)
+ if (colpoints[3] == NULL)
+ call tbcfnd (tp, "XCENTER", colpoints[3], 1)
+ if (colpoints[3] == NULL)
+ call printf ("Error reading XCENTER.\n")
+
+ call tbcfnd (tp, YCENTER, colpoints[4], 1)
+ if (colpoints[4] == NULL)
+ call tbcfnd (tp, "YCENTER", colpoints[4], 1)
+ if (colpoints[4] == NULL)
+ call printf ("Error reading YCENTER.\n")
+
+ call tbcfnd (tp, MAG, colpoints[5], 1)
+ if (colpoints[5] == NULL)
+ call tbcfnd (tp, APMAG, colpoints[5], 1)
+ if (colpoints[5] == NULL)
+ call printf ("Error reading MAG.\n")
+
+ call tbcfnd (tp, SKY, colpoints[6], 1)
+ if (colpoints[6] == NULL)
+ call tbcfnd (tp, SKY, colpoints[6], 1)
+ if (colpoints[6] == NULL)
+ call printf ("Error reading SKY.\n")
+end
+
+
+# DP_TGSELPARS -- Add various parameters to the header of the group table.
+
+procedure dp_tgselpars (tp, min_group, max_group)
+
+pointer tp # pointer to the table
+int min_group # minimum group size
+int max_group # maximum group size
+
+begin
+ # Add the min_group and max_group parameters.
+ call tbhadi (tp, "MINSZGROUP", min_group)
+ call tbhadi (tp, "MAXSZGROUP", max_group)
+end
diff --git a/noao/digiphot/daophot/select/dppfmerge.x b/noao/digiphot/daophot/select/dppfmerge.x
new file mode 100644
index 00000000..1d48cfba
--- /dev/null
+++ b/noao/digiphot/daophot/select/dppfmerge.x
@@ -0,0 +1,81 @@
+include <tbset.h>
+include "../lib/apseldef.h"
+
+# DP_PFMERGE -- Read the input photometry file, extract the fields ID,
+# XCENTER, YCENTER, MAG, and MSKY from each input record and add these
+# records to the output file.
+
+define NCOLUMN 5
+
+procedure dp_pfmerge (infd, outfd, in_text, out_text, first_file)
+
+int infd # the input file descriptor
+int outfd # the output file descriptor
+int in_text # input text file ?
+int out_text # output text file ?
+int first_file # first file ?
+
+int nrow, instar, outstar, id
+pointer sp, indices, fields, ocolpoint, key
+real x, y, mag, sky
+int tbpsta(), dp_rrphot()
+
+begin
+ # Allocate some memory.
+ call smark (sp)
+ call salloc (indices, NAPPAR, TY_INT)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (ocolpoint, NCOLUMN, TY_POINTER)
+
+ # Initialize the output file.
+ if (first_file == YES) {
+ if (out_text == YES) {
+ call seek (infd, BOF)
+ call dp_apheader (infd, outfd)
+ call dp_xpbanner (outfd)
+ } else {
+ call dp_tpdefcol (outfd, Memi[ocolpoint])
+ call tbhcal (infd, outfd)
+ }
+ outstar = 0
+ }
+
+ # Initialize the input file
+ if (in_text == YES) {
+ call pt_kyinit (key)
+ Memi[indices] = DP_PAPID
+ Memi[indices+1] = DP_PAPXCEN
+ Memi[indices+2] = DP_PAPYCEN
+ Memi[indices+3] = DP_PAPMAG1
+ Memi[indices+4] = DP_PAPSKY
+ call dp_gappsf (Memi[indices], Memc[fields], NAPRESULT)
+ nrow = 0
+ } else {
+ call dp_tpkinit (infd, Memi[indices])
+ nrow = tbpsta (infd, TBL_NROWS)
+ }
+
+ # Loop over the stars.
+ instar = 0
+ repeat {
+
+ # Read the input record.
+ if (dp_rrphot (infd, key, Memc[fields], Memi[indices], id,
+ x, y, sky, mag, instar, nrow) == EOF)
+ break
+
+ # Write the output record.
+ outstar = outstar + 1
+ if (out_text == YES)
+ call dp_xpselmer (outfd, id, x, y, mag, sky)
+ else
+ call dp_tpselmer (outfd, id, x, y, mag, sky, Memi[ocolpoint],
+ outstar)
+ }
+
+
+ if (in_text == YES)
+ call pt_kyfree (key)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/select/dpsgroup.x b/noao/digiphot/daophot/select/dpsgroup.x
new file mode 100644
index 00000000..02b77ee7
--- /dev/null
+++ b/noao/digiphot/daophot/select/dpsgroup.x
@@ -0,0 +1,95 @@
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define NCOLUMN 6
+
+# DP_SGROUP -- Read in each group from the input file and write it to the
+# output file if its size is between min_group and max_group.
+
+procedure dp_sgroup (dao, tp_in, tp_out, text_file, min_group, max_group)
+
+pointer dao # pointer to the daophot structure
+pointer tp_in # the input file descriptor
+pointer tp_out # the output file descriptor
+bool text_file # text or table file
+int min_group # minimum sized group to extract
+int max_group # maximum sized group to extract
+
+int nrow_in_table, output_row, in_record, ngroup, cur_group
+pointer sp, indices, fields, key, icolpoint, ocolpoint
+int tbpsta(), dp_ggroup()
+
+begin
+ # Allocate some working memory.
+ call smark (sp)
+ call salloc (icolpoint, NAPGROUP, TY_POINTER)
+ call salloc (indices, NAPGROUP, TY_INT)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (ocolpoint, NCOLUMN, TY_POINTER)
+
+ # Allocate some memory for reading in the group.
+ call dp_gnindices (Memi[indices])
+ call dp_memapsel (dao, Memi[indices], NAPPAR, max_group + 1)
+
+ # Initialize the output file.
+ if (text_file) {
+ call dp_apheader (tp_in, tp_out)
+ call dp_xgselpars (tp_out, min_group, max_group)
+ call dp_apbanner (tp_in, tp_out)
+ } else {
+ call tbtcre (tp_out)
+ call tbhcal (tp_in, tp_out)
+ call dp_tgselcol (tp_out, Memi[ocolpoint])
+ call dp_tgselpars (tp_out, min_group, max_group)
+ }
+
+ # Initialize the input file.
+ if (text_file) {
+ call pt_kyinit (key)
+ call dp_gnstpsf (Memi[indices], Memc[fields], NAPGROUP)
+ nrow_in_table = 0
+ } else {
+ key = NULL
+ call dp_tnsinit (tp_in, Memi[icolpoint])
+ nrow_in_table = tbpsta (tp_in, TBL_NROWS)
+ }
+
+ # Initialize the output record counter.
+ output_row = 0
+
+ # Initialize the input record counter.
+ in_record = 1
+
+ repeat {
+
+ # Read in the group.
+ ngroup = dp_ggroup (dao, tp_in, key, Memc[fields], Memi[indices],
+ Memi[icolpoint], nrow_in_table, max_group, in_record,
+ cur_group)
+ if (ngroup <= 0)
+ break
+ if (ngroup < min_group || ngroup > max_group)
+ next
+
+ # Print a message to the terminal.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf ("Selecting group: %6d of %6d star(s)\n")
+ call pargi (cur_group)
+ call pargi (ngroup)
+ }
+
+ # Write the group to the output file.
+ if (text_file)
+ call dp_xwrtselect (dao, tp_out, ngroup, cur_group)
+ else
+ call dp_twrtselect (dao, tp_out, Memi[ocolpoint], ngroup,
+ cur_group, output_row)
+ }
+
+ if (text_file)
+ call pt_kyfree (key)
+
+ # Free memory.
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/select/mkpkg b/noao/digiphot/daophot/select/mkpkg
new file mode 100644
index 00000000..38c8bb67
--- /dev/null
+++ b/noao/digiphot/daophot/select/mkpkg
@@ -0,0 +1,15 @@
+# GRPSELECT and PFMERGE tasks
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dppfmerge.x <tbset.h> ../lib/apseldef.h
+ dpsgroup.x <tbset.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h
+ dpgwselect.x ../lib/apseldef.h ../lib/daophotdef.h
+ t_grpselect.x <fset.h> ../lib/daophotdef.h
+ t_pfmerge.x <fset.h>
+ ;
diff --git a/noao/digiphot/daophot/select/t_grpselect.x b/noao/digiphot/daophot/select/t_grpselect.x
new file mode 100644
index 00000000..89377270
--- /dev/null
+++ b/noao/digiphot/daophot/select/t_grpselect.x
@@ -0,0 +1,105 @@
+include <fset.h>
+include "../lib/daophotdef.h"
+
+# T_GRPSELECT -- Select groups from a GROUP file on the basis of the size
+# of the group. Only groups of the sizes specified are copied into the
+# output table.
+
+procedure t_grpselect ()
+
+pointer ingroup # the input GROUP file
+pointer outgroup # the output GROUP file
+int min_group # the minimum group size
+int max_group # the maximum group size
+
+bool gr_text
+int ilist, lilist, olist, lolist, verbose
+pointer sp, tp_in, tp_out, dao
+
+bool clgetb(), itob()
+int open(), tbtopn(), clgeti(), fstati(), btoi(), access()
+int fntopnb(), fntlenb(), fntgfnb()
+
+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 (ingroup, SZ_FNAME, TY_CHAR)
+ call salloc (outgroup, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("ingroupfile", Memc[ingroup], SZ_FNAME)
+ call clgstr ("outgroupfile", Memc[outgroup], SZ_FNAME)
+ min_group = clgeti ("min_group")
+ max_group = clgeti ("max_group")
+ verbose = btoi (clgetb ("verbose"))
+
+ # Open the daophot structure.
+ call dp_init (dao)
+
+ # Open the photometry structure.
+ call dp_apsetup (dao)
+
+ # Set some parameters.
+ call dp_seti (dao, VERBOSE, verbose)
+
+ # Get the lists.
+ ilist = fntopnb (Memc[ingroup], NO)
+ lilist = fntlenb (ilist)
+ olist = fntopnb (Memc[outgroup], NO)
+ lolist = fntlenb (olist)
+
+ # Check the list lengths.
+ if (lilist != lolist) {
+ call fntclsb (ilist)
+ call fntclsb (olist)
+ call sfree (sp)
+ call error (0,
+ "The input and output list lengths are not compatible")
+ }
+
+ # Loop over the files.
+ while ((fntgfnb (ilist, Memc[ingroup], SZ_FNAME) != EOF) &&
+ (fntgfnb (olist, Memc[outgroup], SZ_FNAME) != EOF)) {
+
+ # Open the input file.
+ gr_text = itob (access (Memc[ingroup], 0, TEXT_FILE))
+ if (gr_text)
+ tp_in = open (Memc[ingroup], READ_ONLY, TEXT_FILE)
+ else
+ tp_in = tbtopn (Memc[ingroup], READ_ONLY, 0)
+
+ # Open an output file of the same type as the input file.
+ if (gr_text)
+ tp_out = open (Memc[outgroup], NEW_FILE, TEXT_FILE)
+ else
+ tp_out = tbtopn (Memc[outgroup], NEW_COPY, tp_in)
+
+ # Read in the groups and select by group size.
+ call dp_sgroup (dao, tp_in, tp_out, gr_text, min_group, max_group)
+
+ # Close the input and output files.
+ if (gr_text) {
+ call close (tp_in)
+ call close (tp_out)
+ } else {
+ call tbtclo (tp_in)
+ call tbtclo (tp_out)
+ }
+ }
+
+ # Close the lists.
+ call fntclsb (ilist)
+ call fntclsb (olist)
+
+ # Free the photometry structure.
+ call dp_apclose (dao)
+
+ # Free the daophot structure.
+ call dp_free (dao)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/select/t_pfmerge.x b/noao/digiphot/daophot/select/t_pfmerge.x
new file mode 100644
index 00000000..f9f096e1
--- /dev/null
+++ b/noao/digiphot/daophot/select/t_pfmerge.x
@@ -0,0 +1,110 @@
+include <fset.h>
+
+# T_PFMERGE -- Merge photometry files written by PHOT, PSF, PEAK, GROUP,
+# NSTAR or ALLSTAR into one photometry file. The fields ID, XCENTER,
+# YCENTER, MAG, and MKSKY are read from each input file and written
+# without change to the output file. The input files may be text files or
+# binary ST tables files. The output file will have the same file type as the
+# the first input file. The header of the output file will be the header
+# of the first input file.
+
+procedure t_pfmerge ()
+
+pointer inphotfiles # the input photometry files
+pointer outphotfile # the output photometry file
+bool verbose # verbose output ?
+
+int plist, lplist, infd, outfd, first_file, in_text, out_text
+pointer sp, infname
+bool clgetb()
+int fstati(), fntopnb(), fntlenb(), fntgfnb(), access(), open()
+pointer tbtopn()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (inphotfiles, SZ_FNAME, TY_CHAR)
+ call salloc (outphotfile, SZ_FNAME, TY_CHAR)
+ call salloc (infname, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("inphotfiles", Memc[inphotfiles], SZ_FNAME)
+ call clgstr ("outphotfile", Memc[outphotfile], SZ_FNAME)
+ verbose = clgetb ("verbose")
+
+ # Open the input file list and determine the file type of the first
+ # file.
+ plist = fntopnb (Memc[inphotfiles], NO)
+ lplist = fntlenb (plist)
+ if (lplist <= 0) {
+ call fntclsb (plist)
+ call sfree (sp)
+ return
+ }
+ if (fntgfnb (plist, Memc[infname], SZ_FNAME) == EOF) {
+ call fntclsb (plist)
+ call sfree (sp)
+ return
+ } else {
+ out_text = access (Memc[infname], 0, TEXT_FILE)
+ call fntrewb (plist)
+ }
+
+ # Open the output file.
+ if (out_text == YES)
+ outfd = open (Memc[outphotfile], NEW_FILE, TEXT_FILE)
+ else
+ outfd = tbtopn (Memc[outphotfile], NEW_FILE, 0)
+
+ # Loop over the list of input files
+ first_file = YES
+ while (fntgfnb (plist, Memc[infname], SZ_FNAME) != EOF) {
+
+ # Print message.
+ if (verbose) {
+ call printf ("Merging photometry file %s into %s\n")
+ call pargstr (Memc[infname])
+ call pargstr (Memc[outphotfile])
+ }
+
+ # Open the input file.
+ in_text = access (Memc[infname], 0, TEXT_FILE)
+ if (verbose && (in_text != out_text)) {
+ if (in_text == YES)
+ call eprintf ("File %s is not an ST table file.\n")
+ else
+ call eprintf ("File %s is not a text file.\n")
+ call pargstr (Memc[infname])
+ }
+ if (in_text == YES)
+ infd = open (Memc[infname], READ_ONLY, TEXT_FILE)
+ else
+ infd = tbtopn (Memc[infname], READ_ONLY, 0)
+
+ # Now merge the files.
+ call dp_pfmerge (infd, outfd, in_text, out_text, first_file)
+
+ # Close the photometry file.
+ if (in_text == YES)
+ call close (infd)
+ else
+ call tbtclo (infd)
+
+ first_file = NO
+ }
+
+ # Close the output file.
+ if (out_text == YES)
+ call close (outfd)
+ else
+ call tbtclo (outfd)
+
+ # Close the input file list.
+ call fntclsb (plist)
+
+ call sfree(sp)
+end
diff --git a/noao/digiphot/daophot/setimpars.cl b/noao/digiphot/daophot/setimpars.cl
new file mode 100644
index 00000000..57b1c57b
--- /dev/null
+++ b/noao/digiphot/daophot/setimpars.cl
@@ -0,0 +1,276 @@
+# SETIMPARS -- Initialize the DAOPHOT task and pset parameters.
+
+procedure setimpars (image, restore, update)
+
+string image {prompt="Image name"}
+bool restore {yes, prompt="Restore the last saved parameter set ?"}
+bool update {yes, prompt="Update the last saved parameter set ?"}
+bool review {no,
+ prompt="Review the parameters before saving ?"}
+file parfile {"", prompt="Input algorithm parameters file"}
+file datapars {"", prompt="The input data dependent parameters file"}
+file findpars {"",
+ prompt="The input object detection parameters file"}
+file centerpars {"", prompt="The input centering parameters file"}
+file fitskypars {"", prompt="The input sky fitting parameters file"}
+file photpars {"",
+ prompt="The input aperture photometry parameters file"}
+file daopars {"", prompt="The input psf fitting parameters file"}
+bool unlearn {no,
+ prompt="Unlearn the current algorithm parameters ?"}
+
+begin
+ # Define some temporary variables.
+ bool trestore, tupdate
+ string timage, tinparfile, toutparfile, tpars, tfile1, tfile2
+
+ # Read in the image name.
+ timage = image
+ trestore = restore
+ tupdate = update
+ print ("Setting parameters for image ", timage, " ...")
+
+ # Set the input image name.
+ addstar.image = timage
+ allstar.image = timage
+ daoedit.image = timage
+ daofind.image = timage
+ group.image = timage
+ nstar.image = timage
+ peak.image = timage
+ pexamine.image = timage
+ phot.image = timage
+ psf.image = timage
+ pstselect.image = timage
+ substar.image = timage
+
+ # Set the input coordinate / sky files back to their defaults.
+ phot.skyfile = ""
+
+ # Set the input photometry files back to their defaults.
+ addstar.photfile = ""
+ addstar.simple_text = no
+ allstar.photfile = "default"
+ group.photfile = "default"
+ grpselect.ingroupfile = ""
+ nstar.groupfile = "default"
+ peak.photfile = "default"
+ phot.coords = "default"
+ psf.photfile = "default"
+ psf.pstfile = ""
+ pstselect.photfile = "default"
+ substar.photfile = "default"
+
+ # Set the psfimage back to the default.
+ addstar.psfimage = "default"
+ allstar.psfimage = "default"
+ group.psfimage = "default"
+ nstar.psfimage = "default"
+ peak.psfimage = "default"
+ seepsf.psfimage = ""
+ substar.psfimage = "default"
+
+ # Set the output photometry file names to the default.
+ allstar.allstarfile = "default"
+ allstar.rejfile = "default"
+ daofind.output = "default"
+ group.groupfile = "default"
+ grpselect.outgroupfile = ""
+ nstar.nstarfile = "default"
+ nstar.rejfile = "default"
+ peak.peakfile = "default"
+ peak.rejfile = "default"
+ phot.output = "default"
+ psf.groupfile = "default"
+ psf.opstfile = "default"
+ pstselect.pstfile = "default"
+
+ # Set the output images back to the default.
+ addstar.addimage = "default"
+ allstar.subimage = "default"
+ daofind.starmap = ""
+ daofind.skymap = ""
+ psf.psfimage = "default"
+ seepsf.image = ""
+ substar.subimage = "default"
+
+ # Set any output plot files back to the default.
+ phot.plotfile = ""
+ pstselect.plotfile = ""
+ psf.plotfile = ""
+
+ # Get the input parameter file name.
+ tinparfile = parfile
+ if (tinparfile == "") {
+ if (access (timage // ".pars") && trestore)
+ tinparfile = timage // ".pars"
+ } else if (! access (tinparfile)) {
+ print ("File ", tinparfile, " does not exist ...")
+ return
+ }
+
+ # Read in the input parameters.
+
+ if (tinparfile != "") {
+
+ print ("Reading algorithm parameters from file ",
+ tinparfile, " ...")
+ cl (< tinparfile)
+
+ } else {
+
+ tpars = datapars
+ if (access (tpars)) {
+ print ("Reading datapars parameters from file ", tpars, " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("datapars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ print ("Reading default datapars parameters from disk ...")
+ unlearn ("daophot.datapars")
+ } else {
+ print ("Reading current datapars parameters from disk ...")
+ }
+
+ tpars = findpars
+ if (access (tpars)) {
+ print ("Reading findpars parameters from file ", tpars, " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("findpars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ print ("Reading default findpars parameters from disk ...")
+ unlearn ("daophot.findpars")
+ } else {
+ print ("Reading current findpars parameters from disk ...")
+ }
+
+ tpars = centerpars
+ if (access (tpars)) {
+ print ("Reading centerpars parameters from file ", tpars,
+ " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("centerpars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ unlearn ("daophot.centerpars")
+ print ("Reading default centerpars parameters from disk ...")
+ } else {
+ print ("Reading current centerpars parameters from disk ...")
+ }
+
+ tpars = fitskypars
+ if (access (tpars)) {
+ print ("Reading fitskypars parameters from file ", tpars,
+ " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("fitskypars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ unlearn ("daophot.fitskypars")
+ print ("Reading default fitskypars parameters from disk ...")
+ } else {
+ print ("Reading current fitskypars parameters from disk ...")
+ }
+
+ tpars = photpars
+ if (access (tpars)) {
+ print ("Reading photpars parameters from file ", tpars,
+ " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("photpars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ unlearn ("daophot.photpars")
+ print ("Reading default photpars parameters from disk ...")
+ } else {
+ print ("Reading current photpars parameters from disk ...")
+ }
+
+ tpars = daopars
+ if (access (tpars)) {
+ print ("Reading psf fitting parameters from file ", tpars,
+ " ...")
+ tfile1 = mktemp ("tmp$pars")
+ tfile2 = mktemp ("tmp$pars")
+ dparam (tpars, > tfile1)
+ list = tfile1
+ while (fscan (list, line) != EOF) {
+ if (substr (line, 1, 5) != "# EOF")
+ print ("daopars.", line, >> tfile2)
+ }
+ cl (< tfile2)
+ delete (tfile1 // "," // tfile2, verify-, default_action+,
+ allversions+, subfiles+, go_ahead+, >& "dev$null")
+ } else if (unlearn) {
+ unlearn ("daophot.daopars")
+ print ("Reading default daopars parameters from disk ...")
+ } else {
+ print ("Reading current daopars parameters from disk ...")
+ }
+ }
+
+ # Review the current values for the algorithm parameters.
+ if (review) {
+ eparam ("datapars")
+ eparam ("findpars")
+ eparam ("centerpars")
+ eparam ("fitskypars")
+ eparam ("photpars")
+ eparam ("daopars")
+ }
+
+ # Update the output parameter file.
+ toutparfile = timage // ".pars"
+ if (tupdate) {
+ if (access (toutparfile)) {
+ print ("Updating image parameter file ", toutparfile, " ...")
+ delete (toutparfile, verify-, default_action+, allversions+,
+ subfiles+, go_ahead+, >& "dev$null")
+ } else {
+ print ("Creating image parameter file ", toutparfile, " ...")
+ }
+ dparam ("datapars", "findpars", "centerpars", "fitskypars",
+ "photpars", "daopars", > toutparfile)
+ }
+end
diff --git a/noao/digiphot/daophot/substar.par b/noao/digiphot/daophot/substar.par
new file mode 100644
index 00000000..db9947be
--- /dev/null
+++ b/noao/digiphot/daophot/substar.par
@@ -0,0 +1,17 @@
+# SUBSTAR Parameters
+
+image,f,a,,,,"Image corresponding to photometry file"
+photfile,f,a,default,,,"Input photometry file (default: image.nst.?)"
+exfile,f,a,,,,"Input exclude file (default: image.pst.?)"
+psfimage,f,a,default,,,"PSF image (default: image.psf.?)"
+subimage,f,a,"default",,,"Subtracted image (default: image.sub.?)"
+datapars,pset,h,"",,,Data dependent parameters
+daopars,pset,h,"",,,Psf fitting parameters
+wcsin,s,h,)_.wcsin,,,"The input coordinate system (logical,tv,physical,world)"
+wcsout,s,h,)_.wcsout,,,"The output coordinate system (logical,tv,physical)"
+wcspsf,s,h,)_.wcspsf,,,"The psf coordinate system (logical,tv,physical)"
+cache,b,h,)_.cache,,,"Cache the image pixels?"
+verify,b,h,)_.verify,,,Verify critical substar parameters?
+update,b,h,)_.update,,,Update critical substar parameters?
+verbose,b,h,)_.verbose,,,Print substar messages?
+mode,s,h,'ql'
diff --git a/noao/digiphot/daophot/substar/dpgimbufr.x b/noao/digiphot/daophot/substar/dpgimbufr.x
new file mode 100644
index 00000000..d4fac359
--- /dev/null
+++ b/noao/digiphot/daophot/substar/dpgimbufr.x
@@ -0,0 +1,137 @@
+include <imhdr.h>
+
+# DP_GIMBUFR -- Maintain buffer of image lines. A new buffer is created when
+# the buffer pointer is null. No changing of buffer size is allowed, although
+# this should be added. The minimum number of image reads is used.
+
+define flush_ 91
+
+procedure dp_gimbufr (inim, outim, line1, line2, buf, flush)
+
+pointer inim # input image pointer
+pointer outim # output image pointer
+int line1 # first image line of buffer
+int line2 # last image line of buffer
+pointer buf # buffer
+bool flush # flush the current contents of the buffer
+
+int i, ncols, nlines, llast1, llast2, nllast, lp, lout
+pointer buf1, buf2
+pointer imgl2r(), impl2r()
+
+begin
+ nlines = line2 - line1 + 1
+ ncols = IM_LEN (inim, 1)
+ lp = 0
+
+ if (flush)
+ goto flush_
+
+ # If the buffer pointer is undefined then allocate memory for the
+ # buffer. If the number of columns or lines requested changes
+ # reallocate the buffer. Initialize the last line values to force
+ # a full buffer image read.
+
+ if (buf == NULL) {
+ call malloc (buf, ncols * nlines, TY_REAL)
+ #llast1 = line1 - nlines
+ #llast2 = line2 - nlines
+ llast1 = 0
+ llast2 = 0
+ } else if ((nlines > nllast)) {
+ call eprintf ("Buffer requested is larger than previous one\n")
+ return
+ }
+
+ #call printf ("line1=%d line2=%d llast1=%d llast2=%d\n")
+ #call pargi (line1)
+ #call pargi (line2)
+ #call pargi (llast1)
+ #call pargi (llast2)
+
+ # Write out the lines that are not needed any more.
+ if (line1 > llast1 && llast1 > 0) {
+ buf2 = buf
+ lout = min (llast2, line1 - 1)
+ do i = llast1, lout{
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ #call printf ("Writing line: %d\n")
+ #call pargi (i)
+ buf2 = buf2 + ncols
+ }
+ }
+
+ # Write out any skipped image lines.
+ if (line1 > llast2) {
+ do i = llast2 + 1, line1 - 1 {
+ buf2 = imgl2r (inim, i)
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ #call printf ("Copying line: %d\n")
+ #call pargi (i)
+ }
+ }
+
+ # Now move the remaining lines to the begining of the buffer.
+ if (llast2 >= line1 ) {
+ buf2 = buf + ncols * (line1 - llast1)
+ buf1 = buf
+ do i = line1, llast2 {
+ lp = lp + 1
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ #call printf ("Moving line: %d\n")
+ #call pargi (i)
+ buf2 = buf2 + ncols
+ buf1 = buf1 + ncols
+ }
+ }
+
+ # Read only the image lines with are different from the last buffer.
+ buf1 = buf + ncols * lp
+ lout = max (line1, llast2 + 1)
+ do i = lout, line2 {
+ #call printf ("Reading line: %d\n")
+ #call pargi (i)
+ buf2 = imgl2r (inim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ buf1 = buf1 + ncols
+ }
+
+ # Save the buffer parameters.
+ llast1 = line1
+ llast2 = line2
+ nllast = nlines
+
+ # Quit
+ return
+
+flush_
+ # If requested to flush the current contents of the buffer we
+ # write out lines llast1 to llast2 and then set buf == NULL.
+
+ # Flush the data buffer.
+ if (buf != NULL) {
+ buf2 = buf
+ do i = llast1, llast2 {
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ #call printf ("Writing line: %d\n")
+ #call pargi (i)
+ buf2 = buf2 + ncols
+ }
+ }
+
+ # Copy any remaining image lines.
+ do i = llast2 + 1, IM_LEN(inim,2) {
+ buf2 = imgl2r (inim, i)
+ buf1 = impl2r (outim, i)
+ call amovr (Memr[buf2], Memr[buf1], ncols)
+ #call printf ("Copying line: %d\n")
+ #call pargi (i)
+ }
+
+ call mfree (buf, TY_REAL)
+ buf = NULL
+ nllast = 0
+end
diff --git a/noao/digiphot/daophot/substar/dprestars.x b/noao/digiphot/daophot/substar/dprestars.x
new file mode 100644
index 00000000..3b317960
--- /dev/null
+++ b/noao/digiphot/daophot/substar/dprestars.x
@@ -0,0 +1,116 @@
+include <tbset.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+
+# DP_RESTARS -- Read in the IDS of the stars to be excluded, find these stars
+# in the photometry list, and set their magnitudes to INDEF.
+
+int procedure dp_restars (dao, im, ext, text_file)
+
+pointer dao # pointer to the daophot structure
+pointer im # the input image descriptor
+int ext # the exclude list file descriptor
+bool text_file # text or table file ?
+
+real tx, ty, rjunk
+pointer apsel, sp, fields, indices, key
+int i, nrow, idno, nexcl, starno
+int tbpsta(), dp_apsel(), dp_exfind()
+
+begin
+ # Get some pointers.
+ apsel = DP_APSEL(dao)
+
+ # Get some working space.
+ call smark (sp)
+ call salloc (fields, SZ_LINE, TY_CHAR)
+ call salloc (indices, 1, TY_INT)
+
+ # Initialize the read.
+ if (text_file) {
+ call pt_kyinit (key)
+ Memi[indices] = DP_PAPID
+ call dp_gappsf (Memi[indices], Memc[fields], 1)
+ } else {
+ call dp_tptinit (ext, Memi[indices])
+ nrow = tbpsta (ext, TBL_NROWS)
+ }
+
+ i = 1
+ nexcl = 0
+ repeat {
+
+ # Read the next star.
+ if (text_file) {
+ if (dp_apsel (key, ext, Memc[fields], Memi[indices], idno,
+ rjunk, rjunk, rjunk, rjunk) == EOF)
+ break
+ } else {
+ if (i > nrow)
+ break
+ call dp_tptread (ext, Memi[indices], idno, rjunk, rjunk, rjunk,
+ i)
+ }
+
+ # Subtract star from the photometry list.
+ if (idno > 0) {
+ starno = dp_exfind (Memi[DP_APID(apsel)],
+ Memr[DP_APXCEN(apsel)], Memr[DP_APYCEN(apsel)],
+ Memr[DP_APMAG(apsel)], DP_APNUM(apsel), idno)
+ if (starno > 0) {
+ if (DP_VERBOSE(dao) == YES) {
+ call dp_wout (dao, im, Memr[DP_APXCEN(apsel)+starno-1],
+ Memr[DP_APYCEN(apsel)+starno-1], tx, ty, 1)
+ call printf (
+ "EXCLUDING - Star:%5d X =%8.2f Y =%8.2f Mag =%8.2f\n")
+ call pargi (Memi[DP_APID(apsel)+starno-1])
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (Memr[DP_APMAG(apsel)+starno-1])
+ }
+ nexcl = nexcl + 1
+ } else if (DP_VERBOSE(dao) == YES) {
+ call printf ("EXCLUDING - Star:%5d not found\n")
+ call pargi (idno)
+ }
+ }
+
+ i = i + 1
+ }
+
+ if (text_file)
+ call pt_kyfree (key)
+ call sfree (sp)
+
+ return (nexcl)
+end
+
+
+# DP_EXFIND -- Find the star to be exclude in the photometry list.
+
+int procedure dp_exfind (ids, xcen, ycen, mags, nstars, idex)
+
+int ids[ARB] # array of stellar ids
+real xcen[ARB] # array of x coordinates
+real ycen[ARB] # array of y coordinates
+real mags[ARB] # array of magnitudes
+int nstars # number of stars in photometry list
+int idex # id of star to be excluded
+
+int i, found
+
+begin
+ found = 0
+ do i = 1, nstars {
+ if (ids[i] != idex)
+ next
+ found = i
+ break
+ }
+
+ if (found > 0)
+ mags[i] = INDEFR
+
+ return (found)
+end
diff --git a/noao/digiphot/daophot/substar/dpsconfirm.x b/noao/digiphot/daophot/substar/dpsconfirm.x
new file mode 100644
index 00000000..3ed5bc27
--- /dev/null
+++ b/noao/digiphot/daophot/substar/dpsconfirm.x
@@ -0,0 +1,18 @@
+# DP_SCONFIRM -- Procedure to confirm the critical substar parameters.
+
+procedure dp_sconfirm (dao)
+
+pointer dao # pointer to the daophot structure
+
+begin
+ call printf ("\n")
+
+ # Confirm the psf radius.
+ call dp_vpsfrad (dao)
+
+ # Confirm the minimum and maximum good data values.
+ call dp_vdatamin (dao)
+ call dp_vdatamax (dao)
+
+ call printf ("\n")
+end
diff --git a/noao/digiphot/daophot/substar/dpsubstar.x b/noao/digiphot/daophot/substar/dpsubstar.x
new file mode 100644
index 00000000..b33358dc
--- /dev/null
+++ b/noao/digiphot/daophot/substar/dpsubstar.x
@@ -0,0 +1,200 @@
+include <mach.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+include "../lib/apseldef.h"
+
+define EXPAND 8
+
+# DP_SUBSTAR -- Subtract the scaled and shifted PSF from the data
+
+procedure dp_substar (dao, inim, exfd, ex_text, outim)
+
+pointer dao # pointer to the DAOPHOT structure
+pointer inim # pointer to the input image
+int exfd # exclude file descriptor
+bool ex_text # text or table exclude file
+pointer outim # pointer to the output image
+
+real pradius, psfradsq, x, y, dxfrom_psf, dyfrom_psf, mag, tx, ty
+real rel_bright, maxgdata
+pointer apsel, psffit, buf, sp, index
+int i, id, line1, line2, nline_buf, x1, x2, y1, y2
+int lowy, highy, offset, nstars, ier
+int dp_restars()
+
+begin
+ # Get the daophot pointers.
+ apsel = DP_APSEL (dao)
+ psffit = DP_PSFFIT (dao)
+
+ # Exit gracefully if there are no stars.
+ #if (DP_APNUM(apsel) <= 0) {
+ #call printf ("The number of stars in the photometry list is %d\n")
+ #call pargi (DP_APNUM(apsel))
+ #return
+ #}
+
+ # Check for stars to be excluded.
+ if (exfd != NULL) {
+ if (dp_restars (dao, inim, exfd, ex_text) <= 0)
+ ;
+ }
+
+ # Compute the size of subraster to read from the PSF image.
+ if (DP_PSFSIZE(dao) == 0)
+ pradius = DP_PSFRAD(dao)
+ else
+ pradius = (real (DP_PSFSIZE(psffit) - 1) / 2.0 - 1.0) / 2.0
+ psfradsq = pradius * pradius
+
+ # Set the maximum good bad limit.
+ if (IS_INDEFR (DP_MAXGDATA(dao)))
+ maxgdata = MAX_REAL
+ else
+ maxgdata = DP_MAXGDATA(dao)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (index, DP_APNUM (apsel), TY_INT)
+
+ # Sort the photometry on increasing Y.
+ if (DP_APNUM(apsel) > 0)
+ call quick (Memr[DP_APYCEN(apsel)], DP_APNUM(apsel), Memi[index],
+ ier)
+
+ # Initialize the boundary of the buffer.
+ buf = NULL
+ line1 = 0
+ line2 = 0
+ nline_buf = EXPAND * pradius
+
+ nstars = 0
+ do i = 1, DP_APNUM (apsel) {
+
+ # Get the data for the next star.
+ offset = Memi[index+i-1] - 1
+ x = Memr[DP_APXCEN(apsel)+offset]
+ y = Memr[DP_APYCEN(apsel)+i-1]
+ id = Memi[DP_APID(apsel)+offset]
+ mag = Memr[DP_APMAG (apsel)+offset]
+ call dp_wpsf (dao, inim, x, y, dxfrom_psf, dyfrom_psf, 1)
+ dxfrom_psf = (dxfrom_psf - 1.0) / DP_PSFX(psffit) - 1.0
+ dyfrom_psf = (dyfrom_psf - 1.0) / DP_PSFY(psffit) - 1.0
+
+ # Reject star is the magnitude is INDEF.
+ if (IS_INDEFR(x) || IS_INDEFR(y) || IS_INDEFR(mag)) {
+ if (DP_VERBOSE(dao) == YES) {
+ if (IS_INDEFR(x) || IS_INDEFR(y)) {
+ tx = x
+ ty = y
+ } else
+ call dp_wout (dao, inim, x, y, tx, ty, 1)
+ call printf (
+ "REJECTING - Star:%5d X =%8.2f Y =%8.2f Mag =%8.2f\n")
+ call pargi (id)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (mag)
+ }
+ next
+ }
+
+ # Print out the verbose message.
+ if (DP_VERBOSE(dao) == YES) {
+ call dp_wout (dao, inim, x, y, tx, ty, 1)
+ call printf (
+ "SUBTRACTING - Star:%5d X =%8.2f Y =%8.2f Mag =%8.2f\n")
+ call pargi (id)
+ call pargr (tx)
+ call pargr (ty)
+ call pargr (mag)
+ }
+
+ # Determine the range of lines required.
+ lowy = max (1, int (y - pradius) + 1)
+ highy = min (IM_LEN (inim, 2), int (y + pradius))
+ if (highy > line2) {
+ line1 = max (1, lowy)
+ line2 = min (line1 + nline_buf, IM_LEN (inim, 2))
+ call dp_gimbufr (inim, outim, line1, line2, buf, false)
+ }
+
+ # Change coordinates to reference frame of buffer.
+ y = y - line1 + 1.0
+ y1 = max (1, int (y - pradius) + 1)
+ y2 = min (line2 - line1 + 1, int (y + pradius))
+ x1 = max (1, int (x - pradius) + 1)
+ x2 = min (IM_LEN (inim, 1), int (x + pradius))
+
+ # Computee the relative brightness.
+ rel_bright = DAO_RELBRIGHT (psffit, mag)
+
+ # Subtract this star.
+ call dp_sstar (dao, Memr[buf], int (IM_LEN(inim,1)), nline_buf,
+ x1, x2, y1, y2, x, y, psfradsq, rel_bright, dxfrom_psf,
+ dyfrom_psf, maxgdata)
+
+ nstars = nstars + 1
+ }
+
+ # Flush the remaining lines in the image buffer.
+ call dp_gimbufr (inim, outim, y1, y2, buf, true)
+
+ # Summarize data on the number of stars subtracted.
+ if (DP_VERBOSE(dao) == YES) {
+ call printf (
+ "\nA total of %d stars were subtracted out of a possible %d\n")
+ call pargi (nstars)
+ call pargi (DP_APNUM(apsel))
+ }
+
+ # Free memory.
+ call sfree (sp)
+end
+
+
+# DP_SSTAR -- Subtract the star from the image.
+
+procedure dp_sstar (dao, data, nx, ny, x1, x2, y1, y2, xstar, ystar, psfradsq,
+ rel_bright, dxfrom_psf, dyfrom_psf, maxgdata)
+
+pointer dao # pointer to the daophot structure
+real data[nx,ny] # sata buffer
+int nx, ny # size of buffer
+int x1, x2, y1, y2 # area of interest
+real xstar, ystar # position of star to subtract
+real psfradsq # PSF radius ** 2
+real rel_bright # relative brightness of star
+real dxfrom_psf, dyfrom_psf # not currently used
+real maxgdata # maximum good data
+
+int ix, iy
+pointer psffit
+real dx, dy, dxsq, dysq, radsq, dvdx, dvdy
+real dp_usepsf()
+
+begin
+ psffit = DP_PSFFIT(dao)
+ do iy = y1, y2 {
+ dy = real (iy) - ystar
+ dysq = dy * dy
+ do ix = x1, x2 {
+ if (data[ix,iy] > maxgdata)
+ next
+ dx = real (ix) - xstar
+ dxsq = dx * dx
+ radsq = dxsq + dysq
+ if (radsq >= psfradsq) {
+ if (dx > 0.0)
+ break
+ next
+ }
+ data[ix,iy] = data[ix,iy] - rel_bright *
+ dp_usepsf (DP_PSFUNCTION(psffit), dx, dy,
+ DP_PSFHEIGHT(psffit), Memr[DP_PSFPARS(psffit)],
+ Memr[DP_PSFLUT(psffit)], DP_PSFSIZE(psffit),
+ DP_NVLTABLE(psffit), DP_NFEXTABLE(psffit),
+ dxfrom_psf, dyfrom_psf, dvdx, dvdy)
+ }
+ }
+end
diff --git a/noao/digiphot/daophot/substar/mkpkg b/noao/digiphot/daophot/substar/mkpkg
new file mode 100644
index 00000000..d51cf73e
--- /dev/null
+++ b/noao/digiphot/daophot/substar/mkpkg
@@ -0,0 +1,17 @@
+# SUBSTAR task
+
+$checkout libpkg.a ".."
+$update libpkg.a
+$checkin libpkg.a ".."
+$exit
+
+libpkg.a:
+ dpsconfirm.x
+ dpsubstar.x <mach.h> <imhdr.h> \
+ ../lib/daophotdef.h ../lib/apseldef.h
+ dpgimbufr.x <imhdr.h>
+ dprestars.x <tbset.h> ../lib/daophotdef.h \
+ ../lib/apseldef.h
+ t_substar.x <fset.h> <imhdr.h> \
+ ../lib/daophotdef.h
+ ;
diff --git a/noao/digiphot/daophot/substar/t_substar.x b/noao/digiphot/daophot/substar/t_substar.x
new file mode 100644
index 00000000..11ffc72b
--- /dev/null
+++ b/noao/digiphot/daophot/substar/t_substar.x
@@ -0,0 +1,286 @@
+include <fset.h>
+include <imhdr.h>
+include "../lib/daophotdef.h"
+
+# T_SUBSTAR -- Procedure to subtract DAOPHOT photometry from an image.
+
+procedure t_substar ()
+
+pointer image # name of the image
+pointer photfile # input photometry file
+pointer exfile # input exclude file
+pointer psfimage # name of the output PSF
+pointer subimage # subtracted image
+
+pointer sp, input, output, dao, outfname, str
+int psffd, photfd, root, verify, update, wcs
+int imlist, limlist, alist, lalist, pimlist, lpimlist, simlist, lsimlist
+int exfd, elist, lelist, cache, req_size, old_size, buf_size, memstat
+bool ap_text, ex_text
+
+pointer immap(), tbtopn()
+int open(), fnldir(), strlen(), strncmp(), access(), fstati(), btoi()
+int imtopen(), imtlen(), imtgetim(), fntopnb(), fntlenb(), fntgfnb()
+int clgwrd(), sizeof(), dp_memstat()
+bool clgetb(), itob()
+
+begin
+ # Set the standard output to flush on newline.
+ if (fstati (STDOUT, F_REDIR) == NO)
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Get some working memory.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (photfile, SZ_FNAME, TY_CHAR)
+ call salloc (exfile, SZ_FNAME, TY_CHAR)
+ call salloc (psfimage, SZ_FNAME, TY_CHAR)
+ call salloc (subimage, SZ_FNAME, TY_CHAR)
+ call salloc (outfname, SZ_FNAME, TY_CHAR)
+ call salloc (str, SZ_FNAME, TY_CHAR)
+
+ # Get the various task parameters.
+ call clgstr ("image", Memc[image], SZ_FNAME)
+ call clgstr ("photfile", Memc[photfile], SZ_FNAME)
+ call clgstr ("exfile", Memc[exfile], SZ_FNAME)
+ call clgstr ("psfimage", Memc[psfimage], SZ_FNAME)
+ call clgstr ("subimage", Memc[subimage], SZ_FNAME)
+ verify = btoi (clgetb ("verify"))
+ update = btoi (clgetb ("update"))
+ cache = btoi (clgetb ("cache"))
+
+ # Get the lists.
+ imlist = imtopen (Memc[image])
+ limlist = imtlen (imlist)
+ alist = fntopnb (Memc[photfile], NO)
+ lalist = fntlenb (alist)
+ elist = fntopnb (Memc[exfile], NO)
+ lelist = fntlenb (elist)
+ pimlist = imtopen (Memc[psfimage])
+ lpimlist = imtlen (pimlist)
+ simlist = imtopen (Memc[subimage])
+ lsimlist = imtlen (simlist)
+
+ # Test that the lengths of the photometry file, psf image and
+ # subtracted image lists are the same as the length of the input
+ # image list.
+
+ if ((limlist != lalist) && (strncmp (Memc[photfile], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (elist)
+ call imtclose (pimlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and photometry file list lengths")
+ }
+
+ if ((lelist != 0) && (limlist != lelist) && (strncmp (Memc[exfile],
+ DEF_DEFNAME, DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (elist)
+ call imtclose (pimlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and exclude file list lengths")
+ }
+
+ if ((limlist != lpimlist) && (strncmp (Memc[psfimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (elist)
+ call imtclose (pimlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and psf file list lengths")
+ }
+
+ if ((limlist != lsimlist) && (strncmp (Memc[subimage], DEF_DEFNAME,
+ DEF_LENDEFNAME) != 0)) {
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (elist)
+ call imtclose (pimlist)
+ call imtclose (simlist)
+ call sfree (sp)
+ call error (0,
+ "Incompatible image and subtracted image list lengths")
+ }
+
+ # Initialize the DAOPHOT structure and get the pset parameters.
+ call dp_gppars (dao)
+ call dp_seti (dao, VERBOSE, btoi (clgetb ("verbose")))
+
+ # Verify the critical parameters.
+ if (verify == YES) {
+ call dp_sconfirm (dao)
+ if (update == YES)
+ call dp_pppars (dao)
+ }
+
+ # Get the wcs information.
+ wcs = clgwrd ("wcsin", Memc[str], SZ_FNAME, WCSINSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the input coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSIN, wcs)
+ wcs = clgwrd ("wcsout", Memc[str], SZ_FNAME, WCSOUTSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the output coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSOUT, wcs)
+ wcs = clgwrd ("wcspsf", Memc[str], SZ_FNAME, WCSPSFSTR)
+ if (wcs <= 0) {
+ call eprintf (
+ "Warning: Setting the psf coordinate system to logical\n")
+ wcs = WCS_LOGICAL
+ }
+ call dp_seti (dao, WCSPSF, wcs)
+
+
+ # Initialize the PSF structure.
+ call dp_fitsetup (dao)
+
+ # Initialize the star list.
+ call dp_apselsetup (dao)
+
+ # Loop over the images
+ while (imtgetim (imlist, Memc[image], SZ_FNAME) != EOF) {
+
+ # Open input and output images
+ input = immap (Memc[image], READ_ONLY, 0)
+ call dp_sets (dao, INIMAGE, Memc[image])
+
+ # Cache the input image pixels.
+ req_size = MEMFUDGE * (2 * IM_LEN(input,1) * IM_LEN(input,2) *
+ sizeof (IM_PIXTYPE(input)))
+ memstat = dp_memstat (cache, req_size, old_size)
+ if (memstat == YES)
+ call dp_pcache (input, INDEFI, buf_size)
+
+ # If the output image name is DEF_DEFNAME, dir$default or a
+ # directory specification then the extension "sub" is added to
+ # the image name and a suitable version number is appended to the
+ # output name.
+
+ if (imtgetim (simlist, Memc[subimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[subimage], SZ_FNAME)
+ root = fnldir (Memc[subimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[subimage + root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[subimage])) {
+ call dp_oimname (Memc[image], Memc[outfname], "sub",
+ Memc[outfname], SZ_FNAME)
+ output = immap (Memc[outfname], NEW_COPY, input)
+ } else {
+ call strcpy (Memc[subimage], Memc[outfname], SZ_FNAME)
+ output = immap (Memc[outfname], NEW_COPY, input)
+ }
+ call dp_sets (dao, OUTIMAGE, Memc[outfname])
+ if (memstat == YES)
+ call dp_pcache (output, INDEFI, buf_size)
+
+ # Open input photometry table and read in the photometry.
+ if (fntgfnb (alist, Memc[photfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[photfile], SZ_FNAME)
+ root = fnldir (Memc[photfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[photfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[photfile]))
+ call dp_inname (Memc[image], Memc[outfname], "nst",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[photfile], Memc[outfname], SZ_FNAME)
+ ap_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ap_text)
+ photfd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ photfd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ call dp_wgetapert (dao, input, photfd, DP_MAXNSTAR(dao), ap_text)
+ call dp_sets (dao, INPHOTFILE, Memc[outfname])
+
+ # Open the input exclude file.
+ if (lelist == 0) {
+ exfd = NULL
+ Memc[outfname] = EOS
+ } else {
+ if (fntgfnb (elist, Memc[exfile], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[exfile], SZ_FNAME)
+ root = fnldir (Memc[exfile], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[exfile+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[exfile]))
+ call dp_inname (Memc[image], Memc[outfname], "pst",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[exfile], Memc[outfname], SZ_FNAME)
+ ex_text = itob (access (Memc[outfname], 0, TEXT_FILE))
+ if (ex_text)
+ exfd = open (Memc[outfname], READ_ONLY, TEXT_FILE)
+ else
+ exfd = tbtopn (Memc[outfname], READ_ONLY, 0)
+ }
+ call dp_sets (dao, COORDS, Memc[outfname])
+
+ # Read in the PSF
+ if (imtgetim (pimlist, Memc[psfimage], SZ_FNAME) == EOF)
+ call strcpy (DEF_DEFNAME, Memc[psfimage], SZ_FNAME)
+ root = fnldir (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ if (strncmp (DEF_DEFNAME, Memc[psfimage+root],
+ DEF_LENDEFNAME) == 0 || root == strlen (Memc[psfimage]))
+ call dp_iimname (Memc[image], Memc[outfname], "psf",
+ Memc[outfname], SZ_FNAME)
+ else
+ call strcpy (Memc[psfimage], Memc[outfname], SZ_FNAME)
+ psffd = immap (Memc[outfname], READ_ONLY, 0)
+ call dp_readpsf (dao, psffd)
+ call dp_sets (dao, PSFIMAGE, Memc[outfname])
+
+ # Now go and subtract those stars!
+ call dp_substar (dao, input, exfd, ex_text, output)
+
+ # Close the input and output images.
+ call imunmap (input)
+ call imunmap (output)
+
+ # Close the photometry file.
+ if (ap_text)
+ call close (photfd)
+ else
+ call tbtclo (photfd)
+
+ # Close the exclude file.
+ if (ex_text)
+ call close (exfd)
+ else
+ call tbtclo (exfd)
+
+ # Close the PSF image.
+ call imunmap (psffd)
+
+ # Uncache memory
+ call fixmem (old_size)
+
+ }
+
+ # Close the lists.
+ call imtclose (imlist)
+ call fntclsb (alist)
+ call fntclsb (elist)
+ call imtclose (pimlist)
+ call imtclose (simlist)
+
+ # Free the daophot structures.
+ call dp_apclose (dao)
+ call dp_fitclose (dao)
+ call dp_free (dao)
+
+ call sfree (sp)
+end
diff --git a/noao/digiphot/daophot/test/cmds.dat b/noao/digiphot/daophot/test/cmds.dat
new file mode 100644
index 00000000..2a4bbdbf
--- /dev/null
+++ b/noao/digiphot/daophot/test/cmds.dat
@@ -0,0 +1,4 @@
+:a 10
+f
+w
+q
diff --git a/noao/digiphot/daophot/test/fits3.fits b/noao/digiphot/daophot/test/fits3.fits
new file mode 100644
index 00000000..ff7938e7
--- /dev/null
+++ b/noao/digiphot/daophot/test/fits3.fits
Binary files differ
diff --git a/noao/digiphot/daophot/x_daophot.x b/noao/digiphot/daophot/x_daophot.x
new file mode 100644
index 00000000..b9c2c627
--- /dev/null
+++ b/noao/digiphot/daophot/x_daophot.x
@@ -0,0 +1,14 @@
+# Task statements for the daophot package
+
+task addstar = t_addstar,
+ allstar = t_allstar,
+ daoedit = t_daoedit,
+ group = t_group,
+ grpselect = t_grpselect,
+ nstar = t_nstar,
+ peak = t_peak,
+ pfmerge = t_pfmerge,
+ psf = t_psf,
+ pstselect = t_pstselect,
+ seepsf = t_seepsf,
+ substar = t_substar