From 52f14a7eae0ccbfc0827f891153c9a0ccced4a83 Mon Sep 17 00:00:00 2001 From: mdlpstsci Date: Mon, 28 Oct 2024 11:29:14 -0400 Subject: [PATCH] HLA-1350/1240: Update background determination algorithm used for producing output source catalogs (#1904) --- CHANGELOG.rst | 16 ++++++++++++-- drizzlepac/haputils/catalog_utils.py | 33 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7c7c57f80..eb2f70037 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,18 @@ number of the code change for that issue. These PRs can be viewed at: 3.7.2 (unreleased) ================== +- Change to the algorithm which chooses which background determination algorithm to + use for processing when working on the output source catalogs. If the RMS from + the Photutils Background2D is greater than the RMS from the astropy.stats + sigma_clipped_stats, then the background algorithm is now set to use the + sigma_clipped_stats. [#1904] + +- Properly account for illuminated and non-illuminated pixels through the use + of masks when determining the background algorithm to use when working on the + output source catalogs. Use of the proper masks is particularly important for + the ACS/SBC data where the pixel is in the illuminated zone, but its value may + be zero. SBC is a MAMA photo-counting detector. (#1894) + - Modifications to support an upgrade to Photutils v1.13.0. Changes were made to accommodate new APIs, modified low-level functionality, and address columns of a table in get_cutouts() by name rather than position to ensure the correct @@ -40,8 +52,8 @@ number of the code change for that issue. These PRs can be viewed at: defined by full paths rather than being in the current working directory. [#1835] -3.7.1 (1-Oct-2024) -=================== +3.7.1.1 (1-Oct-2024) +==================== - Improved S_REGION using simplify-polygon, eorions, and dilation. [#1323] diff --git a/drizzlepac/haputils/catalog_utils.py b/drizzlepac/haputils/catalog_utils.py index b6b39c9b8..54016f766 100755 --- a/drizzlepac/haputils/catalog_utils.py +++ b/drizzlepac/haputils/catalog_utils.py @@ -288,7 +288,7 @@ def compute_background(self, box_size, win_size, self.bkg_type = 'zero_background' is_zero_background_defined = True - log.info("Input image contains excessive zero values in the background. Median: {} RMS: {}".format(self.bkg_median, self.bkg_rms_median)) + log.info(f"Input image contains excessive zero values in the background. Median: {self.bkg_median:.6f} RMS: {self.bkg_rms_median:.6f}") # BACKGROUND COMPUTATION 2 (sigma_clipped_stats) # If the input data is not the unusual case of SBC "excessive zero background", compute @@ -319,7 +319,7 @@ def compute_background(self, box_size, win_size, # Use the "raw" values generated by sigma_clipped_stats() # based on full unmasked image bkg_skew = np.abs(3.0 * (bkg_mean_full - bkg_median_full) / bkg_rms_full) - log.info("Sigma-clipped computed skewness: {0:.2f}".format(bkg_skew)) + log.info(f"Sigma-clipped computed skewness: {bkg_skew:.2f}") # Refine background to better compute the median value @@ -332,7 +332,7 @@ def compute_background(self, box_size, win_size, sigma=nsigma_clip, cenfunc='median') - log.info("Sigma-clipped Statistics - Background mean: {} median: {} rms: {}".format(bkg_mean, bkg_median, bkg_rms)) + log.info(f"Sigma-clipped Statistics - Background mean: {bkg_mean:.6f} median: {bkg_median:.6f} rms: {bkg_rms:.6f}") log.info("") # Ensure the computed values are not negative @@ -340,11 +340,11 @@ def compute_background(self, box_size, win_size, bkg_mean = max(0, bkg_mean) bkg_median = max(0, bkg_median) bkg_rms = max(0, bkg_rms) - log.info("UPDATED Sigma-clipped Statistics - Background mean: {} median: {} rms: {}".format(bkg_mean, bkg_median, bkg_rms)) + log.info(f"UPDATED Sigma-clipped Statistics - Background mean: {bkg_mean:.6f} median: {bkg_median:.6f} rms: {bkg_rms:.6f}") log.info("") # Compute a minimum rms value based upon information directly from the data - if self.keyword_dict["detector"].upper() not in ['IR', 'SBC']: + if self.keyword_dict["detector"].upper() != 'SBC': minimum_rms = self.keyword_dict['atodgn'] * self.keyword_dict['readnse'] \ * self.keyword_dict['ndrizim'] / self.keyword_dict['texpo_time'] @@ -352,8 +352,8 @@ def compute_background(self, box_size, win_size, # the larger of the two values. if (bkg_rms < minimum_rms): bkg_rms = minimum_rms - log.info("Mimimum RMS of input based upon the readnoise, gain, number of exposures, and total exposure time: {}".format(minimum_rms)) - log.info("Sigma-clipped RMS has been updated - Background mean: {} median: {} rms: {}".format(bkg_mean, bkg_median, bkg_rms)) + log.info(f"Mimimum RMS of input based upon the readnoise, gain, number of exposures, and total exposure time: {minimum_rms:.6f}") + log.info(f"Sigma-clipped RMS has been updated - Background mean: {bkg_mean:.6f} median: {bkg_median:.6f} rms: {bkg_rms:.6f}") log.info("") # Generate two-dimensional background and rms images with the attributes of @@ -400,6 +400,9 @@ def compute_background(self, box_size, win_size, negative_threshold = negative_sigma * bkg.background_rms_median break + log.info(f"Background2D - Background median: {bkg_median:.6f} rms: {bkg_rms_median:.6f}") + log.info("") + # If computation of a two-dimensional background image were successful, compute the # background-subtracted image and evaluate it for the number of negative values. # @@ -416,16 +419,24 @@ def compute_background(self, box_size, win_size, del imgdata_bkgsub # Report this information so the relative percentage and the threshold are known - log.info("Percentage of negative values in the background subtracted image {0:.2f} vs low threshold of {1:.2f}.".format(100.0 * negative_ratio, negative_percent)) + log.info(f"Percentage of negative values in the background subtracted image {100.0*negative_ratio:.2f} vs low threshold of {negative_percent:.2f}.") # If the background subtracted image has too many negative values which may be # indicative of large negative regions, the two-dimensional computed background # fit image should NOT be used. Use the sigma-clipped data instead. if negative_ratio * 100.0 > negative_percent: - log.info("Percentage of negative values {0:.2f} in the background subtracted image exceeds the threshold of {1:.2f}.".format(100.0 * negative_ratio, negative_percent)) + log.info(f"Percentage of negative values {100.0*negative_ratio:.2f} in the background subtracted image exceeds the threshold of {negative_percent:.2f}.") log.info("") log.info("*** Use the background image determined from the sigma_clip algorithm. ***") + # If the rms computed for the Background2D is larger than the rms computed + # for the sigma-clipped algorithm, use the sigma-clipped algorithm instead. + # The sigma-clipped values have already been set in BACKGROUND COMPUTATION 2 + # as the class attributes. + elif bkg_rms_median > self.bkg_rms_median: + log.info(f"Background2D rms, {bkg_rms_median:.6f}, is greater than sigma-clipped rms, {self.bkg_rms_median:.6f}.") + log.info("*** Use the background image determined from the sigma_clip algorithm. ***") + # Update the class variables with the background fit data else: self.bkg_background_ra = bkg_background_ra.copy() @@ -449,8 +460,8 @@ def compute_background(self, box_size, win_size, log.info("") log.info("Computation of image background complete") log.info("Found: ") - log.info(" Median background: {}".format(self.bkg_median)) - log.info(" Median RMS background: {}".format(self.bkg_rms_median)) + log.info(f" Median background: {self.bkg_median:.6f}") + log.info(f" Median RMS background: {self.bkg_rms_median:.6f}") log.info("") del bkg, imgdata