PRO select_psf_stars_from_star_list, xc, yc, flux, corr, range, imxsize, imysize, bpmdata, flux_thresh, corr_thresh, psf_companion_distance_limit, $
; Description: This module selects a set of suitable PSF stars from an input star list containing pixel coordinates
; "xc" and "yc", flux estimates "flux", and correlation coefficients with the image PSF "corr". Suitable
; PSF stars are chosen using the following selection criteria:
;
; (i) The pixel in which the pixel coordinates of a PSF star lie must not be within a distance of
; "ceil(range)" pixels along each coordinate axis from the image edge.
;
; (ii) A PSF star must have no bad pixels within a distance of "ceil(range)" pixels from the centre of
; the pixel in which its pixel coordinates lie. Bad pixels are flagged in the bad pixel mask array
; "bpmdata" of size "imxsize" by "imysize" pixels.
;
; (iii) A PSF star must have a flux value "flux" that is greater than or equal to the flux threhsold
; "flux_thresh".
;
; (iv) A PSF star must have a correlation coefficient with the image PSF "corr" that is greater than or
; equal to the correlation coefficient threshold "corr_thresh".
;
; (v) A PSF star must not have a brighter star within a distance of "range" from its own pixel
; coordinates.
;
; (vi) A PSF star must not have a companion star with a flux greater than "psf_companion_flux_limit"
; times its own flux that is within a distance of "psf_companion_distance_limit*range" pixels from
; its own pixel coordinates.
;
; The selected PSF stars are returned to the user via a set of subscripts "psf_star_subs" corresponding
; to the star list, along with the number of selected PSF stars "npsf_stars".
; The input star list should contain all non-saturated stars down to a detection threshold that is
; less than or equal to "psf_companion_flux_limit" times the flux threshold "flux_thresh" in order to
; properly reject candidate PSF stars based on the companion star selection criteria (v) and (vi).
;
; Input Parameters:
;
; xc - FLOAT/DOUBLE SCALAR/VECTOR/ARRAY - A scalar/vector/array of x coordinates for the stars in the input star
; list (pix).
; yc - FLOAT/DOUBLE SCALAR/VECTOR/ARRAY - A scalar/vector/array with the same number of elements as "xc" which
; contains the y coordinates for the stars in the input star list (pix).
; flux - FLOAT/DOUBLE SCALAR/VECTOR/ARRAY - A scalar/vector/array with the same number of elements as "xc" which
; contains the flux estimates for the stars in the input star list.
; The units of the values in this input parameter are usually ADU,
; ADU/s, or sigma (i.e. flux normalised by flux uncertainty), and they
; should match the units of the flux threshold "flux_thresh". The
; values supplied in this input parameter may represent any quantity
; that is associated with the brightness of an object, and they need
; not necessarily represent true fluxes. For instance, the values in
; this parameter could represent the pixel values for the peak pixel
; in each object.
; corr - FLOAT/DOUBLE SCALAR/VECTOR/ARRAY - A scalar/vector/array with the same number of elements as "xc" which
; contains the correlation coefficients between each star in the input
; star list and the image PSF. Stars with correlation coefficients that
; do not lie in the range "0.0 <= corr <= 1.0" will not be considered
; as candidate PSF stars. If this parameter does not have the correct
; number type, or the same number of elements as "xc", then the module
; will not apply the selection criterion (iv) described above.
; range - FLOAT/DOUBLE - The distance to be used to test for proximity to the image edges, the presence of bad
; pixels, brighter stars, and companion stars. If this parameter does not have the correct
; number type, or it is zero or negative, then the module will not apply the selection
; criteria (i), (ii), (v), and (vi) described above.
; imxsize - INTEGER/LONG - The image size along the x-axis (pix). If this parameter does not have the correct
; number type, or it is zero or negative, then the module will not apply the selection
; criteria (i) and (ii) described above.
; imysize - INTEGER/LONG - The image size along the y-axis (pix). If this parameter does not have the correct
; number type, or it is zero or negative, then the module will not apply the selection
; criteria (i) and (ii) described above.
; bpmdata - BYTE/INTEGER/LONG ARRAY - A two-dimensional bad pixel mask array of size "imxsize" by "imysize"
; pixels which flags good pixels with a value of "1" and bad pixels with
; any other value. If this array does not have the correct number type, or
; the correct dimensions and size, then the module will consider all image
; pixels to be good, which means that all stars will automatically pass the
; selection criterion (ii) described above.
; flux_thresh - FLOAT/DOUBLE - The flux threshold to be used to select PSF stars as described in the selection
; criterion (iii) above. The units of this input parameter are usually ADU, ADU/s,
; or sigma (i.e. flux normalised by flux uncertainty), and they should match the
; units of the values in the input parameter "flux".
; corr_thresh - FLOAT/DOUBLE - The correlation coefficient threshold to be used to select PSF stars as described
; in the selection criterion (iv) above. If this parameter does not have the correct
; number type, or it does not lie in the range "0.0 <= corr_thresh <= 1.0", then the
; module will assume that the correlation coefficient threshold is "0.0".
; psf_companion_distance_limit - FLOAT/DOUBLE - The distance, as a multiple of the parameter "range", within
; which a star is considered to be a companion star for use in the
; PSF selection criterion (vi) described above. If this parameter
; does not have the correct number type, or it is zero or negative,
; then the module will not apply the selection criterion (vi)
; described above.
; psf_companion_flux_limit - FLOAT/DOUBLE - The fractional flux above which a companion star will discount a
; candidate PSF star as described in the selection criterion (vi)
; above. If this parameter does not have the correct number type, or
; it is negative, then the module will not apply the selection
; criterion (vi) described above.
;
; Output Parameters:
;
; psf_star_subs - LONG VECTOR - A one-dimensional vector of length "npsf_stars" containing the subscripts of
; the selected PSF stars from the input star list. If the keyword SORT_BY_FLUX is
; set, then the subscripts are ordered such that the selected PSF stars are
; ordered from the brightest to the faintest based on the flux values provided in
; the input parameter "flux". If no PSF stars are selected from the star list,
; then this parameter is returned as the single-element vector "[-1L]".
; npsf_stars - LONG - The number of selected PSF stars.
; status - INTEGER - If the module successfully executed the selection algorithm for PSF stars, then "status"
; is returned with a value of "1", otherwise it is returned with a value of "0".
;
; Keywords:
;
; If the keyword SORT_BY_FLUX is set (as "/SORT_BY_FLUX"), then the module will sort the subscripts
; "psf_star_subs" such that the selected PSF stars are ordered from the brightest to the faintest based on the
; flux values provided in the input parameter "flux".
;
; N.B: In DanIDL, I adopt a pixel coordinate system such that the origin of the coordinate system is at the
; bottom left hand corner of the bottom left hand pixel in an image. Therefore, the centre of the bottom
; left hand pixel in an image has coordinates (0.5,0.5) in this coordinate system. For each full pixel
; moved to the right in the image, the x pixel coordinate increments by 1, and similarly for each full
; pixel moved up in the image, the y pixel coordinate increments by 1.
;
; Author: Dan Bramich (dan.bramich@hotmail.co.uk)
;
; History:
;
; 01/02/2012 - Module created (dmb).
;Set the default output parameter values
;Check that "xc" is of the correct number type
;Check that "yc" is of the correct number type and that it has the same number of elements as "xc"
;Check that "flux" is of the correct number type and that it has the same number of elements as "xc"
;Check that "corr" is of the correct number type and that it has the same number of elements as "xc"
;Check that "range" is a positive number of the correct type
;Check that "imxsize" and "imysize" are both positive numbers of the correct type
;If "bpmdata" is not of the correct number type or it is not an image array of size "imxsize" by "imysize"
;pixels, then assume that all of the image pixels are good
;Check that "flux_thresh" is a number of the correct type
;Check that "corr_thresh" is a number of the correct type and that it lies in the range "0.0 <= corr_thresh <= 1.0"
;Check that "psf_companion_distance_limit" is a positive number of the correct type
;Check that "psf_companion_flux_limit" is a non-negative number of the correct type
;Set "status" to "1"
;Remove candidate PSF stars whose flux estimates "flux" are less than the flux threshold "flux_thresh" or whose
;correlation coefficients with the image PSF "corr" are not in the range "corr_thresh <= corr <= 1.0"
;If the distance "range" has an acceptable value, then continue to apply the criteria (i), (ii), (v), and (vi)
;described above
;If the image dimensions "imxsize" and "imysize" have acceptable values, then continue to apply the criterion
;(i) described above
;Remove candidate PSF stars that are within a distance of "ceil(range)" along each coordinate axis from the
;image edge
;If the bad pixel mask array "bpmdata" is an image of size "imxsize" by "imysize" pixels, then continue to apply
;the criterion (ii) described above
;Remove candidate PSF stars that have at least one bad pixel within a distance of "ceil(range)" from the centre
;of the pixel in which their coordinates lie
;For each candidate PSF star, use a fast binary search to find the subset of stars from the input star list that
;have x coordinates within a distance D along the x axis of the x coordinate of the current candidate PSF star,
;where D is the larger of "range" and "psf_companion_distance_limit*range"
;Remove candidate PSF stars that have a brighter companion star within a distance of "range" from the candidate PSF
;star centre. If required, then also remove candidate PSF stars that have a companion star with a flux greater than
;"psf_companion_flux_limit" times the candidate PSF star flux that is within a distance of
;"psf_companion_distance_limit*range" from the candidate PSF star centre.
;Calculate the square of the distance between the current candidate PSF star and each of the stars in the subset
;of stars from the input star list that have x coordinates within a distance D along the x axis of the x coordinate
;of the current candidate PSF star, where D is the larger of "range" and "psf_companion_distance_limit*range"
;Determine the number of stars in the subset of stars from the input star list that are brighter than the current
;candidate PSF star and that are within a distance of "range" from the centre of the current candidate PSF star
;If required, then determine the number of stars in the subset of stars from the input star list that are brighter
;than a factor of "psf_companion_flux_limit" times the star flux of the current candidate PSF star and that are
;within a distance of "psf_companion_distance_limit*range" from the centre of the current candidate PSF star
;Save the subscript and flux of the current candidate PSF star
;If there are no candidate PSF stars left, then return with an empty list of PSF stars, otherwise update the
;subscripts and fluxes of the list of candidate PSF stars
;If the keyword SORT_BY_FLUX is set, then sort the final list of suitable PSF stars such that they are ordered
;from the brightest to the faintest based on the flux values provided in the input parameter "flux"
;Save the subscripts of the final list of suitable PSF stars