diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /noao/digiphot/daophot | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'noao/digiphot/daophot')
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 Binary files differnew file mode 100644 index 00000000..ff7938e7 --- /dev/null +++ b/noao/digiphot/daophot/test/fits3.fits 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 |