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

Fix all warnings #203

Merged
merged 12 commits into from
Dec 12, 2023
11 changes: 11 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,14 @@ addopts = [
]
log_cli_level = "info"
xfail_strict = true
filterwarnings = [
"error",
# Apparently bqplot is using deprecated traitlets APIs
'ignore:\s+Sentinel is not a public part of the traitlets API:DeprecationWarning',
# ginga is using something from asdf that has been deprecated
'ignore:AsdfInFits has been deprecated:DeprecationWarning',
# ipyautoui generates this warning...
'ignore:metadata \{.+\} was set from the constructor:DeprecationWarning',
# Generated from batman
'ignore:Conversion of an array with ndim > 0 to a scalar:DeprecationWarning',
]
22 changes: 0 additions & 22 deletions stellarphot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,4 @@
from ._astropy_init import * # noqa
# ----------------------------------------------------------------------------

# Enforce Python version check during package import.
# This is the same check as the one at the top of setup.py
import sys
from distutils.version import LooseVersion

__minimum_python_version__ = "3.10"

__all__ = []


class UnsupportedPythonError(Exception):
"""
Wraps an exception to raise if a user tries to use stellarphot
with an unsupported version of Python.
"""
pass


if LooseVersion(sys.version) < LooseVersion(__minimum_python_version__):
raise UnsupportedPythonError("stellarphot does not support Python < {}"
.format(__minimum_python_version__))

from .core import *
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ def test_bad_comp_star(bad_thing):

if bad_thing == 'RA':
# "Jiggle" one of the stars by moving it by a few arcsec in one image.
coord_inp = SkyCoord(ra=last_one['ra'], dec=last_one['dec'],
coord_inp = SkyCoord(ra=last_one['ra'][0], dec=last_one['dec'][0],
unit=u.degree)
coord_bad_ra = coord_inp.ra + 3 * u.arcsecond
print(len(last_one), coord_inp)
input_table['ra'][-1] = coord_bad_ra.degree
elif bad_thing == 'NaN':
input_table['aperture_net_cnts'][-1] = np.nan
Expand Down
4 changes: 3 additions & 1 deletion stellarphot/differential_photometry/tests/test_vsx_mags.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def test_multi_vmag():

vmag, error = calc_vmag(var_stars, star_data, comp_stars, band='Rc', star_data_mag_column='mag_inst_R')
del var_stars['coords']
v_data = vstack([var_stars, var_stars])

# We really don't care about the metadata here, so silently accept one
v_data = vstack([var_stars, var_stars], metadata_conflicts='silent')
v_data['coords'] = SkyCoord(ra=v_data['RAJ2000'],
dec=v_data['DEJ2000'], unit='degree')
v_table = calc_multi_vmag(v_data, star_data, comp_stars, band='Rc', star_data_mag_column='mag_inst_R')
Expand Down
24 changes: 21 additions & 3 deletions stellarphot/io/tests/test_tess_submission.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
import warnings

import pytest

Expand Down Expand Up @@ -78,10 +79,27 @@ def test_target_file():
# object

tic_742648307 = SkyCoord(ra=104.733225, dec=49.968739, unit='degree')

tess_target = TessTargetFile(tic_742648307, magnitude=12, depth=10)

# Check that the first thing in the list is the tick object
check_coords = SkyCoord(ra=tess_target.table['RA'][0],
dec=tess_target.table['Dec'][0],
unit=('hour', 'degree'))
check_coords = SkyCoord(
ra=tess_target.table['RA'][0],
dec=tess_target.table['Dec'][0],
unit=('hour', 'degree')
)
assert tic_742648307.separation(check_coords).arcsecond < 1

# On windows the temporary file cannot be deleted because if it is
# then the file immediately vanished. That means we get a warning
# about having an open file handle. We can ignore that warning
# because we don't care about it here.

# The warning doesn't get generated until the last reference to
# the object is deleted, so we need to do that here instead of
# letting it happen at the end of the test.
with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message="unclosed file",
category=ResourceWarning)
del tess_target
5 changes: 2 additions & 3 deletions stellarphot/photometry/photometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ def multi_image_photometry(directory_with_images,
reject_unmatched : bool, optional (Default: True)
If ``True``, any sources that are not detected on all the images are
rejected. If you are interested in a source that can intermittently
fall below your detection limits, we suggest setting this to ``False``
fall below your detection limits, we suggest setting this to ``False``
so that all sources detected on each image are reported.

include_dig_noise : bool, optional (Default: True)
Expand Down Expand Up @@ -973,7 +973,7 @@ def calculate_noise(camera=None, counts=0.0, sky_per_pix=0.0,

\\sigma = \\sqrt{G \\cdot N_C + A \\cdot \\left(1 + \\frac{A}{B}\\right)\\cdot \\left[ G\\cdot S + D \\cdot t + R^2 + (0.289 G)^2\\right]}

where :math:`\sigma` is the noise, :math:`G` is the gain,
where :math:`\\sigma` is the noise, :math:`G` is the gain,
:math:`N_C` is the source counts (which is photon/electron counts divided by gain),
:math:`A` is the aperture area in pixels,
:math:`B` is the annulus area in pixels,
Expand Down Expand Up @@ -1053,4 +1053,3 @@ def calculate_noise(camera=None, counts=0.0, sky_per_pix=0.0,
digitization = area_ratio * (gain * 0.289) ** 2

return np.sqrt(poisson_source + sky + dark + rn_error + digitization)

20 changes: 15 additions & 5 deletions stellarphot/photometry/tests/fake_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ class FakeImage:

noise_dev : float, optional
The standard deviation of the noise in the image.

seed : int, optional
The seed to use for the random number generator. If not specified,
the seed will be randomly generated.
"""
def __init__(self, noise_dev=1.0):
def __init__(self, noise_dev=1.0, seed=None):
self.image_shape = [400, 500]
data_file = get_pkg_data_filename('data/test_sources.csv')
self._sources = Table.read(data_file)
Expand All @@ -29,7 +33,8 @@ def __init__(self, noise_dev=1.0):
self.sources)
self._noise = make_noise_image(self._stars.shape,
mean=self.mean_noise,
stddev=noise_dev)
stddev=noise_dev,
seed=seed)
# Sky background per pixel should be the mean level of the noise.
self._sources['sky_per_pix_avg'] = self.mean_noise

Expand All @@ -51,11 +56,16 @@ def image(self):
class FakeCCDImage(CCDData):
# Generates a fake CCDData object for testing purposes.
def __init__(self, *args, **kwargs):
# Pull off the seed argument if it exists.
seed = kwargs.pop('seed', None)

# If no arguments are passed, use the default FakeImage.
# This dodge is necessary because otherwise we can't copy the CCDData
# object apparently.
if (len(args) == 0) and (len(kwargs) == 0):
base_data = FakeImage()
base_data = FakeImage(seed=seed)
super().__init__(base_data.image.copy(), unit='adu')

# Append attributes from the base data object.
self.sources = base_data.sources.copy()
self.noise_dev = base_data.noise_dev
Expand Down Expand Up @@ -162,4 +172,4 @@ def shift_FakeCCDImage(ccd_data, x_shift, y_shift):
stddev=shifted_ccd_data.noise_dev)
shifted_ccd_data.data = srcs + background

return shifted_ccd_data
return shifted_ccd_data
24 changes: 18 additions & 6 deletions stellarphot/photometry/tests/test_detection.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import warnings

import numpy as np
import pytest

from astropy.table import QTable
from astropy.stats import gaussian_sigma_to_fwhm
from astropy import units as u
from astropy.utils.exceptions import AstropyUserWarning

from stellarphot.photometry import (source_detection, compute_fwhm)

from fake_image import FakeImage

# Make sure the tests are deterministic by using a random seed
SEED = 5432985


@pytest.mark.parametrize('units', [u.pixel, None])
def test_compute_fwhm(units):
fake_image = FakeImage()
fake_image = FakeImage(seed=SEED)
sources = fake_image.sources
if units is not None:
# It turns out having a unit on a column is not the same as
Expand All @@ -32,7 +39,7 @@ def test_compute_fwhm(units):
def test_compute_fwhm_with_NaNs():
# Regression test for https://github.com/feder-observatory/stellarphot/issues/161
# We should be able to find FWHM for a source even with NaNs in the image.
fake_image = FakeImage()
fake_image = FakeImage(seed=SEED)
sources = fake_image.sources
x, y = sources['x_mean'].astype(int)[0], sources['y_mean'].astype(int)[0]
image = fake_image.image.copy()
Expand All @@ -41,8 +48,13 @@ def test_compute_fwhm_with_NaNs():
# usual row/column swap when going to x/y coordinates.
image[y, x] = np.nan

fwhm_x, fwhm_y = compute_fwhm(image, sources,
x_column='x_mean', y_column='y_mean', fit=True)
# We expect a warning about NaNs in the image, so catch it
with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message="Non-Finite input data has been removed",
category=AstropyUserWarning)
fwhm_x, fwhm_y = compute_fwhm(image, sources,
x_column='x_mean', y_column='y_mean', fit=True)

expected_fwhm = np.array(sources['x_stddev'] * gaussian_sigma_to_fwhm)
assert np.allclose(fwhm_x, expected_fwhm, rtol=1e-2)
Expand All @@ -52,7 +64,7 @@ def test_detect_source_number_location():
"""
Make sure we detect the sources in the input table....
"""
fake_image = FakeImage()
fake_image = FakeImage(seed=SEED)
sources = QTable(fake_image.sources, units={'x_mean':u.pixel, 'y_mean':u.pixel,
'x_stddev':u.pixel, 'y_stddev':u.pixel})
# print(sources)
Expand Down Expand Up @@ -85,7 +97,7 @@ def test_detect_source_with_padding():
"""
Make sure we detect the sources in the input table....
"""
fake_image = FakeImage()
fake_image = FakeImage(seed=SEED)
sources = QTable(fake_image.sources, units={'x_mean':u.pixel, 'y_mean':u.pixel,
'x_stddev':u.pixel, 'y_stddev':u.pixel})
# Pass only one value for the sky background for source detection
Expand Down
43 changes: 28 additions & 15 deletions stellarphot/photometry/tests/test_photometry.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import tempfile
from pathlib import Path
import warnings

import numpy as np
import pytest
from astropy import units as u
from astropy.coordinates import EarthLocation
from astropy.io import ascii
from astropy.utils.data import get_pkg_data_filename
from astropy.utils.metadata.exceptions import MergeConflictWarning

from fake_image import FakeCCDImage, shift_FakeCCDImage

from stellarphot.core import Camera, SourceListData
Expand All @@ -16,6 +19,9 @@
from stellarphot.settings import ApertureSettings

GAINS = [1.0, 1.5, 2.0]
# Make sure the tests are deterministic by using a random seed
SEED = 5432985


def test_calc_noise_defaults():
# If we put in nothing we should get an error about is missing camera
Expand Down Expand Up @@ -224,7 +230,7 @@ def test_find_too_close():
# The True case below is a regression test for #157
@pytest.mark.parametrize('int_data', [True, False])
def test_aperture_photometry_no_outlier_rejection(int_data):
fake_CCDimage = FakeCCDImage()
fake_CCDimage = FakeCCDImage(seed=SEED)

sources = fake_CCDimage.sources
aperture = sources['aperture'][0]
Expand Down Expand Up @@ -293,7 +299,7 @@ def test_aperture_photometry_with_outlier_rejection(reject):
the photometry is correct when outliers are rejected and is
incorrect when outliers are not rejected.
"""
fake_CCDimage = FakeCCDImage()
fake_CCDimage = FakeCCDImage(seed=SEED)
sources = fake_CCDimage.sources
aperture = sources['aperture'][0]
inner_annulus = 2 * aperture
Expand All @@ -305,6 +311,8 @@ def test_aperture_photometry_with_outlier_rejection(reject):

image = fake_CCDimage.data

print(f'{fake_CCDimage=}')
print(f"{sources['x_stddev'].mean()}")
found_sources = source_detection(fake_CCDimage,
fwhm=sources['x_stddev'].mean(),
threshold=10)
Expand Down Expand Up @@ -363,7 +371,7 @@ def test_aperture_photometry_with_outlier_rejection(reject):

def list_of_fakes(num_files):
# Generate fake CCDData objects for use in photometry_on_directory tests
fake_images = [FakeCCDImage()]
fake_images = [FakeCCDImage(seed=SEED)]

# Create additional images, each in a different position.
for i in range(num_files-1):
Expand Down Expand Up @@ -397,6 +405,7 @@ def test_photometry_on_directory():
f"tempfile_{i:02d}.fit" for i in range(1, num_files + 1)]
# Write the CCDData objects to files
for i, image in enumerate(fake_images):
from time import sleep; sleep(1)
image.write(temp_file_names[i])

object_name = fake_images[0].header['OBJECT']
Expand All @@ -413,18 +422,22 @@ def test_photometry_on_directory():
fwhm=fake_images[0].sources['x_stddev'].mean(),
threshold=10)

phot_data = multi_image_photometry(temp_dir,
object_name,
found_sources,
fake_camera,
fake_obs,
aperture_settings,
shift_tolerance, max_adu, fwhm_estimate,
include_dig_noise=True,
reject_too_close=True,
reject_background_outliers=True,
passband_map=None,
fwhm_by_fit=True)
with warnings.catch_warnings():
warnings.filterwarnings("ignore",
message="Cannot merge meta key",
category=MergeConflictWarning)
phot_data = multi_image_photometry(temp_dir,
object_name,
found_sources,
fake_camera,
fake_obs,
aperture_settings,
shift_tolerance, max_adu, fwhm_estimate,
include_dig_noise=True,
reject_too_close=True,
reject_background_outliers=True,
passband_map=None,
fwhm_by_fit=True)

# For following assertion to be true, rad must be small enough that
# no source lies within outer_annulus of the edge of an image.
Expand Down
Loading