Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion piff/basis_interp.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ def initialize(self, stars, logger=None):

:returns: A new list of Stars which have their parameters initialized.
"""
c = np.mean([s.fit.get_params(self._num) for s in stars], axis=0)
params = [s.fit.get_params(self._num) for s in stars if not s.is_flagged]
if len(params) == 0:
raise RuntimeError("All stars are flagged. Cannot initialize BasisPolynomial.")
c = np.mean(params, axis=0)
self.q = c[:,np.newaxis] * self.constant(1.)[np.newaxis,:]
stars = self.interpolateList(stars)
return stars
Expand Down
9 changes: 9 additions & 0 deletions piff/pixelgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ def initialize(self, star, logger=None, default_init=None):
if init is None: init = 'hsm'
logger.debug("initializing PixelGrid with method %s",init)

# Check if the star's image data is large enough to adequately fit the PixelGrid.
ny, nx = star.image.array.shape
pixel_scale = star.image.wcs.maxLinearScale(star.image.center)
min_xy_size = self.size * self.scale / pixel_scale
if max(nx,ny) < min_xy_size:
logger.warning(f"Image size ({nx},{ny}) is too small to constrain this PixelGrid. "
f"Minimum size required for this grid is {min_xy_size} pixels.")
raise RuntimeError("Star's image is too small.")

if init == 'hsm' or init == 'zero':
# Calculate the second moment to initialize an initial Gaussian profile.
# hsm returns: flux, x, y, sigma, g1, g2, flag
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
[build-system]
requires = ["setuptools>=38", "wheel", "pybind11>=2.2"]

[tool.pytest.ini_options]
testpaths = [
"tests",
]
10 changes: 10 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import pytest

def pytest_collectstart(collector):
if hasattr(collector, 'skip_compare'):
collector.skip_compare += 'stderr',

# cf. https://stackoverflow.com/questions/62044541/change-pytest-working-directory-to-test-case-directory
@pytest.fixture(autouse=True)
def change_test_dir(request, monkeypatch):
monkeypatch.chdir(request.fspath.dirname)
Binary file added tests/input/stars_131.pickle
Binary file not shown.
57 changes: 55 additions & 2 deletions tests/test_pixel.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def test_center():
du = 0.7
s = make_gaussian_data(2.0, x0, y0, influx, du=du)

mod = piff.PixelGrid(0.8, 29, centered=True)
mod = piff.PixelGrid(0.8, 27, centered=True)
star = mod.initialize(s)
psf = piff.SimplePSF(mod, None)
print('Flux, ctr after reflux:',star.fit.flux,star.fit.center)
Expand Down Expand Up @@ -617,7 +617,7 @@ def test_undersamp():
print('nominal chisq = ',s1.fit.chisq)
if __name__ == '__main__':
assert chisq1 > 1.e3
else:
else:
assert chisq1 > 5.e5 # Pretty large at the start before fitting.

s2 = mod.fit(s0)
Expand Down Expand Up @@ -1867,6 +1867,58 @@ def test_convergence_centering_failed():
assert piffResult.niter == 6, 'Maximum number of iterations in this example must be 6.'
assert np.shape(piffResult.stars[28].fit.A) == (0, 625), 'Centroid failed for this star, expected shape of A is (0,625)'


@timer
def test_too_small():
"""Test that PixelGrid fails gracefully if the data images are too small to constrain
the full extent of the pixel grid."""

# This test comes directly from the bug report in issue #131
import pickle
stars = pickle.load(open("input/stars_131.pickle", "rb"))

piffConfig = {
'type': "Simple",
'model': {
'type': 'PixelGrid',
'scale': 1.0,
# The input data images are 21x21.
# NOTE: size <= 23 worked here in Piff 1.5.
# But now requires size <= 21 to avoid exatrapolation around the edges.
'size': 25
},
'interp': {
'type': 'BasisPolynomial',
'order': 1
},
'outliers': {
'type': 'Chisq',
'nsigma': 4,
'max_remove': 0.05
}
}

piffResult = piff.PSF.process(piffConfig)
# Run on a single CCD, and in image coords rather than sky coords.
wcs = {0: galsim.PixelScale(1.0)}
pointing = None

# The original behavior was to complete successfully, but the model had crazy values
# off the edge of the constrained region.
with CaptureLog(2) as cl:
with np.testing.assert_raises(RuntimeError):
piffResult.fit(stars, wcs, pointing, logger=cl.logger)
assert "Image size (21,21) is too small to constrain this PixelGrid." in cl.output
assert "Removed 12 stars in initialize" in cl.output

# This configuration works.
piffConfig['model']['size'] = 21
piffResult = piff.PSF.process(piffConfig)
piffResult.fit(stars, wcs, pointing)
im = piffResult.draw(10, 10)
assert im(10,10) > 0


if __name__ == '__main__':
#import cProfile, pstats
#pr = cProfile.Profile()
Expand All @@ -1887,6 +1939,7 @@ def test_convergence_centering_failed():
test_var()
test_color()
test_convert_func()
test_too_small()
#pr.disable()
#ps = pstats.Stats(pr).sort_stats('tottime')
#ps.print_stats(20)