Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Allow a 2D threshold in StarFinder classes #1293

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion photutils/detection/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def _find_stars(convolved_data, kernel, threshold, *, min_separation=0.0,
kernel : `_StarFinderKernel`
The convolution kernel.

threshold : float
threshold : float or 2D array-like
The absolute image value above which to select sources. This
threshold should be the threshold input to the star finder class
multiplied by the kernel relerr.
Expand Down Expand Up @@ -96,6 +96,9 @@ def _find_stars(convolved_data, kernel, threshold, *, min_separation=0.0,
pad_mode = 'constant'
convolved_data = np.pad(convolved_data, pad, mode=pad_mode,
constant_values=0.0)
if not np.isscalar(threshold):
threshold = np.pad(threshold, pad, mode=pad_mode,
constant_values=0.0)
if mask is not None:
mask = np.pad(mask, pad, mode=pad_mode, constant_values=False)

Expand Down
18 changes: 13 additions & 5 deletions photutils/detection/daofinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ class DAOStarFinder(StarFinderBase):

Parameters
----------
threshold : float

threshold : float or array-like
The absolute image value above which to select sources.
A non-scalar ``threshold`` must have the same shape
as ``data``. See `~photutils.segmentation.detect_threshold` for
one way to create a ``threshold`` image.

fwhm : float
The full-width half-maximum (FWHM) of the major axis of the
Expand Down Expand Up @@ -158,9 +162,6 @@ def __init__(self, threshold, fwhm, ratio=1.0, theta=0.0,
roundhi=1.0, sky=0.0, exclude_border=False,
brightest=None, peakmax=None, xycoords=None):

if not np.isscalar(threshold):
raise TypeError('threshold must be a scalar value.')

if not np.isscalar(fwhm):
raise TypeError('fwhm must be a scalar value.')

Expand Down Expand Up @@ -411,6 +412,13 @@ def data_peak(self):
def convdata_peak(self):
return self.cutout_convdata[:, self.cutout_center[0],
self.cutout_center[1]]
@lazyproperty
def threshold_peak(self):
if np.isscalar(self.threshold_eff):
return np.repeat(self.threshold_eff, len(self.xypos))
else:
return self.make_cutouts(
self.threshold_eff)[:, self.cutout_center[0], self.cutout_center[1]]

@lazyproperty
def roundness1(self):
Expand Down Expand Up @@ -622,7 +630,7 @@ def peak(self):

@lazyproperty
def flux(self):
return ((self.convdata_peak / self.threshold_eff)
return ((self.convdata_peak / self.threshold_peak)
- (self.sky * self.npix))

@lazyproperty
Expand Down
9 changes: 5 additions & 4 deletions photutils/detection/irafstarfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ class IRAFStarFinder(StarFinderBase):

Parameters
----------
threshold : float

threshold : float or 2D array-like
The absolute image value above which to select sources.
A non-scalar ``threshold`` must have the same shape
as ``data``. See `~photutils.segmentation.detect_threshold` for
one way to create a ``threshold`` image.

fwhm : float
The full-width half-maximum (FWHM) of the 2D circular Gaussian
Expand Down Expand Up @@ -132,9 +136,6 @@ def __init__(self, threshold, fwhm, sigma_radius=1.5, minsep_fwhm=2.5,
exclude_border=False, brightest=None, peakmax=None,
xycoords=None):

if not np.isscalar(threshold):
raise TypeError('threshold must be a scalar value.')

if not np.isscalar(fwhm):
raise TypeError('fwhm must be a scalar value.')

Expand Down
2 changes: 1 addition & 1 deletion photutils/detection/peakfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def find_peaks(data, threshold, box_size=3, footprint=None, mask=None,
data : array_like
The 2D array of the image.

threshold : float or array-like
threshold : float or 2D array-like
The data value or pixel-wise data values to be used for the
detection threshold. A 2D ``threshold`` must have the same shape
as ``data``. See `~photutils.segmentation.detect_threshold` for
Expand Down
2 changes: 1 addition & 1 deletion photutils/detection/starfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class StarFinder(StarFinderBase):

Parameters
----------
threshold : float
threshold : float or 2D array-like
The absolute image value above which to select sources.

kernel : `numpy.ndarray`
Expand Down
9 changes: 4 additions & 5 deletions photutils/detection/tests/test_daofinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


DATA = make_100gaussians_image()
THRESHOLDS = [8.0, 10.0]
THRESHOLDS = [8.0, 10.0, 8.*np.ones_like(DATA)]
FWHMS = [1.0, 1.5, 2.0]


Expand All @@ -29,6 +29,8 @@ class TestDAOStarFinder:
def test_daofind(self, threshold, fwhm):
starfinder = DAOStarFinder(threshold, fwhm, sigma_radius=1.5)
tbl = starfinder(DATA)
if not np.isscalar(threshold):
threshold = threshold.flatten()[0]
datafn = f'daofind_test_thresh{threshold:04.1f}_fwhm{fwhm:04.1f}.txt'
datafn = op.join(op.dirname(op.abspath(__file__)), 'data', datafn)
tbl_ref = Table.read(datafn, format='ascii')
Expand All @@ -37,10 +39,7 @@ def test_daofind(self, threshold, fwhm):
for col in tbl.colnames:
assert_allclose(tbl[col], tbl_ref[col])

def test_daofind_threshold_fwhm_inputs(self):
with pytest.raises(TypeError):
DAOStarFinder(threshold=np.ones((2, 2)), fwhm=3.)

def test_daofind_fwhm_input(self):
with pytest.raises(TypeError):
DAOStarFinder(threshold=3., fwhm=np.ones((2, 2)))

Expand Down
9 changes: 4 additions & 5 deletions photutils/detection/tests/test_irafstarfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


DATA = make_100gaussians_image()
THRESHOLDS = [8.0, 10.0]
THRESHOLDS = [8.0, 10.0, 8.*np.ones_like(DATA)]
FWHMS = [1.0, 1.5, 2.0]


Expand All @@ -29,6 +29,8 @@ class TestIRAFStarFinder:
def test_irafstarfind(self, threshold, fwhm):
starfinder = IRAFStarFinder(threshold, fwhm, sigma_radius=1.5)
tbl = starfinder(DATA)
if not np.isscalar(threshold):
threshold = threshold.flatten()[0]
datafn = (f'irafstarfind_test_thresh{threshold:04.1f}_'
f'fwhm{fwhm:04.1f}.txt')
datafn = op.join(op.dirname(op.abspath(__file__)), 'data', datafn)
Expand All @@ -38,10 +40,7 @@ def test_irafstarfind(self, threshold, fwhm):
for col in tbl.colnames:
assert_allclose(tbl[col], tbl_ref[col])

def test_irafstarfind_threshold_fwhm_inputs(self):
with pytest.raises(TypeError):
IRAFStarFinder(threshold=np.ones((2, 2)), fwhm=3.)

def test_irafstarfind_fwhm_input(self):
with pytest.raises(TypeError):
IRAFStarFinder(threshold=3., fwhm=np.ones((2, 2)))

Expand Down