diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 89d7412fb..586de0348 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,7 +27,7 @@ number of the code change for that issue. These PRs can be viewed at: - Deprecated the TEAL helper "run" functions as well as the editpars parameters in base drizzlepac functions. [#2152] -- Added code to handle deprecations in photutils v3.0.0. [#2089] +- Added code to handle deprecations in photutils v3.0.0. [#2089, #2153] 3.11.0 (28-Apr-2026) diff --git a/drizzlepac/haputils/_detection_utils.py b/drizzlepac/haputils/_detection_utils.py index c7db307f1..d1a368759 100644 --- a/drizzlepac/haputils/_detection_utils.py +++ b/drizzlepac/haputils/_detection_utils.py @@ -17,6 +17,7 @@ import numpy as np from photutils.detection import find_peaks from photutils.utils.exceptions import NoDetectionsWarning +from photutils import use_future_column_names def _filter_data(data, kernel, mode='constant', fill_value=0.0, @@ -339,8 +340,9 @@ def _find_stars(data, kernel, threshold_eff, min_separation=None, with warnings.catch_warnings(): # suppress any NoDetectionsWarning from find_peaks warnings.filterwarnings('ignore', category=NoDetectionsWarning) - tbl = find_peaks(convolved_data, threshold_eff, footprint=footprint, - mask=mask) + with use_future_column_names(): + tbl = find_peaks(convolved_data, threshold_eff, footprint=footprint, + mask=mask) if tbl is None: return None diff --git a/drizzlepac/haputils/align_utils.py b/drizzlepac/haputils/align_utils.py index e180457c1..a8e5b5588 100755 --- a/drizzlepac/haputils/align_utils.py +++ b/drizzlepac/haputils/align_utils.py @@ -26,6 +26,7 @@ from photutils.background import Background2D from photutils.detection import DAOStarFinder from photutils.utils import NoDetectionsWarning +from photutils import use_future_column_names import stwcs from stwcs.wcsutil import HSTWCS @@ -60,8 +61,7 @@ log = logutil.create_logger(__name__, level=logutil.logging.NOTSET, stream=sys.stdout, format=SPLUNK_MSG_FORMAT, datefmt=MSG_DATEFMT) -PHOTUTILS_GE_3 = minversion(photutils, "2.3.1.dev") -photutils.future_column_names = True +PHOTUTILS_GE_3 = minversion(photutils, "3.0.0") if PHOTUTILS_GE_3: X_CENTROID = 'x_centroid' Y_CENTROID = 'y_centroid' @@ -803,7 +803,8 @@ def find_alignment_sources(self, output=True, dqname='DQ', crclean=False, daofind = DAOStarFinder(fwhm=self.kernel_fwhm, threshold=1.0e-10) log.debug("Determining source properties as src_table...") - src_table = daofind(sciarr, mask=bkg_mask) + with use_future_column_names(): + src_table = daofind(sciarr, mask=bkg_mask) del sci_bkgsub, bkg_mask, sci_gauss # explicitly clean up memory if src_table is not None: log.info("Total Number of detected sources: {}".format(len(src_table))) diff --git a/drizzlepac/haputils/analyze.py b/drizzlepac/haputils/analyze.py index 25685edea..c152d3648 100644 --- a/drizzlepac/haputils/analyze.py +++ b/drizzlepac/haputils/analyze.py @@ -42,8 +42,7 @@ log = logutil.create_logger(__name__, level=logutil.logging.INFO, stream=sys.stdout, format=SPLUNK_MSG_FORMAT, datefmt=MSG_DATEFMT) -PHOTUTILS_GE_3 = minversion(photutils, "2.3.1.dev") -photutils.future_column_names = True +PHOTUTILS_GE_3 = minversion(photutils, "3.0.0") __all__ = ['analyze_data', 'analyze_wrapper', 'mvm_analyze_wrapper'] diff --git a/drizzlepac/haputils/astrometric_utils.py b/drizzlepac/haputils/astrometric_utils.py index 2bbc2cc4a..86f985151 100644 --- a/drizzlepac/haputils/astrometric_utils.py +++ b/drizzlepac/haputils/astrometric_utils.py @@ -49,6 +49,7 @@ from astropy.utils.decorators import deprecated import photutils +from photutils import use_future_column_names from photutils.segmentation import (detect_sources, SourceCatalog, detect_threshold, deblend_sources, SegmentationImage) @@ -86,8 +87,7 @@ ASTROMETRIC_CAT_ENVVAR = "ASTROMETRIC_CATALOG_URL" DEF_CAT_URL = 'http://gsss.stsci.edu/webservices' -PHOTUTILS_GE_3 = minversion(photutils, "2.3.1.dev") -photutils.future_column_names = True +PHOTUTILS_GE_3 = minversion(photutils, "3.0.0") if PHOTUTILS_GE_3: X_CENTROID = 'x_centroid' Y_CENTROID = 'y_centroid' @@ -816,13 +816,15 @@ def build_auto_kernel(imgarr, whtarr, fwhm=3.0, threshold=None, source_box=7, kern_img[:, -edge:] = 0.0 kernel_psf = False - peaks = find_peaks(kern_img, threshold=threshold * 5, box_size=isolation_size) + with use_future_column_names(): + peaks = find_peaks(kern_img, threshold=threshold * 5, box_size=isolation_size) if peaks is None or (peaks is not None and len(peaks) == 0): tmean = threshold.mean() if isinstance(threshold, np.ndarray) else threshold if tmean > kern_img.mean(): kern_stats = sigma_clipped_stats(kern_img) threshold = kern_stats[2] - peaks = find_peaks(kern_img, threshold=threshold, box_size=isolation_size) + with use_future_column_names(): + peaks = find_peaks(kern_img, threshold=threshold, box_size=isolation_size) if peaks is not None: # Sort based on peak_value to identify brightest sources for use as a kernel @@ -929,7 +931,8 @@ def find_fwhm(psf, default_fwhm, log_level=logutil.logging.INFO): sub_shape=(11, 11), maxiters=2) - phot_results = itr_phot_obj(psf) + with use_future_column_names(): + phot_results = itr_phot_obj(psf) except Exception as x_cept: log.warning(f"The find_fwhm() failed due to problem with fitting. Trying again. Exception: {x_cept}") return None @@ -1206,7 +1209,8 @@ def extract_sources(img, dqmask=None, fwhm=3.0, kernel=None, photmode=None, detection_img[segm.data[seg_slice] == 0] = 0 # Detect sources in this specific segment - seg_table = daofind.find_stars(detection_img) + with use_future_column_names(): + seg_table = daofind.find_stars(detection_img) # Pick out brightest source only if src_table is None and seg_table: @@ -1229,7 +1233,8 @@ def extract_sources(img, dqmask=None, fwhm=3.0, kernel=None, photmode=None, segimg = SegmentationImage(segment.data) segment_properties = SourceCatalog(detection_img, segimg) - sat_table = segment_properties.to_table() + with use_future_column_names(): + sat_table = segment_properties.to_table() seg_table['flux'][max_row] = sat_table[flux_colname][0] seg_table['peak'][max_row] = sat_table['max_value'][0] xcentroid = sat_table[X_CENTROID][0] @@ -1251,7 +1256,8 @@ def extract_sources(img, dqmask=None, fwhm=3.0, kernel=None, photmode=None, else: log.debug("Determining source properties as src_table...") cat = SourceCatalog(img, segm) - src_table = cat.to_table() + with use_future_column_names(): + src_table = cat.to_table() # Make column names consistent with IRAFStarFinder column names src_table.rename_column(flux_colname, 'flux') src_table.rename_column(FERR_COLNAME, 'flux_err') diff --git a/drizzlepac/haputils/catalog_utils.py b/drizzlepac/haputils/catalog_utils.py index d91de54f7..276050e7b 100755 --- a/drizzlepac/haputils/catalog_utils.py +++ b/drizzlepac/haputils/catalog_utils.py @@ -23,6 +23,7 @@ StdBackgroundRMS) from photutils.detection import DAOStarFinder, IRAFStarFinder from photutils.utils import calc_total_error +from photutils import use_future_column_names from stsci.tools import logutil from stwcs.wcsutil import HSTWCS @@ -55,8 +56,7 @@ log = logutil.create_logger(__name__, level=logutil.logging.NOTSET, stream=sys.stdout, format=SPLUNK_MSG_FORMAT, datefmt=MSG_DATEFMT) -PHOTUTILS_GE_3 = minversion(photutils, "2.3.1.dev") -photutils.future_column_names = True +PHOTUTILS_GE_3 = minversion(photutils, "3.0.0") if PHOTUTILS_GE_3: X_CENTROID = 'x_centroid' Y_CENTROID = 'y_centroid' @@ -1125,12 +1125,14 @@ def identify_sources(self, **pars): reg_rms_median)) daofind = DAOStarFinder(fwhm=source_fwhm, threshold=self.param_dict['nsigma'] * reg_rms_median) - reg_sources = daofind(region, mask=self.image.inv_footprint_mask) + with use_future_column_names(): + reg_sources = daofind(region, mask=self.image.inv_footprint_mask) elif self.param_dict["starfinder_algorithm"] == "iraf": log.info("IRAFStarFinder(fwhm={}, threshold={}*{})".format(source_fwhm, self.param_dict['nsigma'], reg_rms_median)) isf = IRAFStarFinder(fwhm=source_fwhm, threshold=self.param_dict['nsigma'] * reg_rms_median) - reg_sources = isf(region, mask=self.image.inv_footprint_mask) + with use_future_column_names(): + reg_sources = isf(region, mask=self.image.inv_footprint_mask) elif self.param_dict["starfinder_algorithm"] == "psf": log.info("UserStarFinder(fwhm={}, threshold={}*{})".format(source_fwhm, self.param_dict['nsigma'], reg_rms_median)) @@ -1179,8 +1181,9 @@ def identify_sources(self, **pars): if self.diagnostic_mode: fits.PrimaryHDU(data=region).writeto(_region_name, overwrite=True) - reg_sources = daofind(region, - mask=self.image.inv_footprint_mask) + with use_future_column_names(): + reg_sources = daofind(region, + mask=self.image.inv_footprint_mask) _region_name = self.image.imgname.replace(reg_suffix, 'starfind_sources{}.ecsv'.format(masknum)) if self.diagnostic_mode: @@ -1200,7 +1203,8 @@ def identify_sources(self, **pars): daofind = DAOStarFinder( fwhm=source_fwhm, threshold=self.param_dict['nsigma'] * reg_rms_median) - reg_sources = daofind(region, mask=self.image.inv_footprint_mask) + with use_future_column_names(): + reg_sources = daofind(region, mask=self.image.inv_footprint_mask) else: err_msg = "'{}' is not a valid 'starfinder_algorithm' parameter input in the catalog_generation parameters json file. Valid options are 'dao' for photutils.detection.DAOStarFinder() or 'iraf' for photutils.detection.IRAFStarFinder().".format(self.param_dict["starfinder_algorithm"]) log.error(err_msg) @@ -2008,7 +2012,8 @@ def identify_sources(self, **pars): enforce_icrs_compatibility(self.source_cat) # Convert source_cat which is a SourceCatalog to an Astropy Table - need the data in tabular # form to filter out bad rows and correspondingly bad segments before the filter images are processed. - total_measurements_table = Table(self.source_cat.to_table(columns=['label', 'xcentroid', 'ycentroid', 'sky_centroid_icrs'])) + with use_future_column_names(): + total_measurements_table = Table(self.source_cat.to_table(columns=['label', 'xcentroid', 'ycentroid', 'sky_centroid_icrs'])) # Filter the table to eliminate nans or inf based on the coordinates, then remove these segments from # the segmentation image too @@ -2424,7 +2429,8 @@ def measure_sources(self, filter_name): enforce_icrs_compatibility(self.source_cat) - filter_measurements_table = Table(self.source_cat.to_table(columns=include_filter_cols)) + with use_future_column_names(): + filter_measurements_table = Table(self.source_cat.to_table(columns=include_filter_cols)) # Compute aperture photometry measurements and append the columns to the measurements table self.do_aperture_photometry(imgarr, filter_measurements_table, self.imgname, filter_name) diff --git a/drizzlepac/haputils/deconvolve_utils.py b/drizzlepac/haputils/deconvolve_utils.py index 7e1b737d3..87b5d0c59 100644 --- a/drizzlepac/haputils/deconvolve_utils.py +++ b/drizzlepac/haputils/deconvolve_utils.py @@ -13,6 +13,7 @@ from photutils.detection import StarFinderBase, find_peaks from photutils.utils import NoDetectionsWarning +from photutils import use_future_column_names from stsci.tools import fileutil as fu @@ -965,8 +966,9 @@ def find_point_sources(drzname, data=None, mask=None, fits.PrimaryHDU(data=decmask.astype(np.uint16)).writeto(drzname.replace('.fits', '_deconv_mask.fits'), overwrite=True) # find sources in deconvolved image - dec_peaks = find_peaks(decdrz, threshold=0.0, - mask=invmask, box_size=box_size) + with use_future_column_names(): + dec_peaks = find_peaks(decdrz, threshold=0.0, + mask=invmask, box_size=box_size) # Use these positions as an initial guess for the final position peak_mask = (drz * 0.).astype(np.uint8) @@ -983,7 +985,8 @@ def find_point_sources(drzname, data=None, mask=None, # Use this new mask to find the actual peaks in the original input # but only to integer pixel precision. - peaks = find_peaks(drz, threshold=0., box_size=box_size // 2) + with use_future_column_names(): + peaks = find_peaks(drz, threshold=0., box_size=box_size // 2) if len(peaks) == 0: peaks = None diff --git a/drizzlepac/haputils/photometry_tools.py b/drizzlepac/haputils/photometry_tools.py index 674839ac0..f6ceea8d2 100755 --- a/drizzlepac/haputils/photometry_tools.py +++ b/drizzlepac/haputils/photometry_tools.py @@ -64,6 +64,7 @@ from drizzlepac.haputils import constants from drizzlepac.haputils.background_median import aperture_stats_tbl from photutils.aperture import aperture_photometry +from photutils import use_future_column_names def iraf_style_photometry(phot_apertures, bg_apertures, data, photflam, photplam, error_array=None, bg_method='mode', epadu=1.0): @@ -107,7 +108,8 @@ def iraf_style_photometry(phot_apertures, bg_apertures, data, photflam, photplam if bg_method not in ['mean', 'median', 'mode']: raise ValueError('Invalid background method, choose either \ mean, median, or mode') - phot = aperture_photometry(data, phot_apertures, error=error_array) + with use_future_column_names(): + phot = aperture_photometry(data, phot_apertures, error=error_array) bg_phot = aperture_stats_tbl(data, bg_apertures, sigma_clip=True) names = ['X-Center', 'Y-Center', 'ID'] x, y = phot_apertures[0].positions.T diff --git a/drizzlepac/haputils/svm_quality_analysis.py b/drizzlepac/haputils/svm_quality_analysis.py index 9628c0f8e..6afa96ecc 100755 --- a/drizzlepac/haputils/svm_quality_analysis.py +++ b/drizzlepac/haputils/svm_quality_analysis.py @@ -49,6 +49,7 @@ from itertools import chain import numpy as np from photutils.detection import DAOStarFinder +from photutils import use_future_column_names from scipy import ndimage from scipy.spatial import KDTree @@ -1057,7 +1058,8 @@ def find_hap_point_sources(filt_obj, log_level=logutil.logging.NOTSET): log.info("DAOStarFinder(fwhm={}, threshold={}*{})".format(img_obj.kernel_fwhm, nsigma, img_obj.bkg_rms_median)) daofind = DAOStarFinder(fwhm=img_obj.kernel_fwhm, threshold=nsigma * img_obj.bkg_rms_median) - sources = Table(daofind(image, mask=exclusion_mask)) + with use_future_column_names(): + sources = Table(daofind(image, mask=exclusion_mask)) cat_name = filt_obj.product_basename + "_point-cat-fxm.ecsv" return {"filt_obj": filt_obj, "sources": sources, "cat_name": cat_name}