From 496db58f2cd1d9a5830d10d5db33dfa4e5e524a9 Mon Sep 17 00:00:00 2001 From: mdlpstsci Date: Thu, 21 Nov 2024 14:59:48 -0500 Subject: [PATCH] =?UTF-8?q?HLA-1362:=20Modified=20the=20minimum=20RMS=20co?= =?UTF-8?q?mputation=20used=20as=20a=20discriminant=20for=20choos=E2=80=A6?= =?UTF-8?q?=20(#1908)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.rst | 4 ++++ drizzlepac/haputils/catalog_utils.py | 33 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a05f2a94a..9fb956ce3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,10 @@ number of the code change for that issue. These PRs can be viewed at: 3.7.2 (unreleased) ================== +- Include a minimum RMS value for the SBC detector, as is done for the other + detectors, as there seems to be a lot of noise in the source catalogs due to + a low detection threshold. [#1908] + - Force an exit with a return code, KEYWORD_UPDATE_PROBLEM, in try/exception block when invoking refine_product_headers in hapsequencer.py and hapmultisequencer.py. If the FITS header keywords are not properly updated, this can cause errors during diff --git a/drizzlepac/haputils/catalog_utils.py b/drizzlepac/haputils/catalog_utils.py index ffef2e5e8..7374e2de3 100755 --- a/drizzlepac/haputils/catalog_utils.py +++ b/drizzlepac/haputils/catalog_utils.py @@ -289,6 +289,15 @@ def compute_background(self, box_size, win_size, is_zero_background_defined = True log.info(f"Input image contains excessive zero values in the background. Median: {self.bkg_median:.6f} RMS: {self.bkg_rms_median:.6f}") + # Compute a minimum rms value based upon information directly from the data + minimum_rms = 1.0 / self.keyword_dict['texpo_time'] + if np.nan_to_num(self.bkg_rms_median) < minimum_rms: + self.bkg_rms_median = minimum_rms + log.info("") + log.info(f"Minimum RMS of input based upon the total exposure time: {minimum_rms:.6f}") + log.info(f"Median RMS has been updated - Median: {self.bkg_median:.6f} RMS: {self.bkg_rms_median:.6f}") + log.info("") + # BACKGROUND COMPUTATION 2 (sigma_clipped_stats) # If the input data is not the unusual case of SBC "excessive zero background", compute # a sigma-clipped background which returns only single values for mean, @@ -343,17 +352,18 @@ def compute_background(self, box_size, win_size, log.info("") # Compute a minimum rms value based upon information directly from the data - 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'] - - # Compare a minimum rms based upon input characteristics versus the one computed and use - # the larger of the two values. - if (bkg_rms < minimum_rms): - bkg_rms = minimum_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("") + if self.keyword_dict['detector'].upper() != 'SBC': + minimum_rms = np.sqrt(self.keyword_dict['numexp']) * self.keyword_dict['readnse'] / self.keyword_dict['texpo_time'] + else: + minimum_rms = np.sqrt(np.clip(bkg_median * self.keyword_dict['texpo_time'], a_min=1.0, a_max=None)) / self.keyword_dict['texpo_time'] + + # Compare a minimum rms based upon input characteristics versus the rms computed and use + # the larger of the two values. + if (bkg_rms < minimum_rms): + bkg_rms = minimum_rms + log.info(f"Minimum RMS of input based upon the readnoise, 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 # the input data, but the content based on the sigma-clipped statistics. @@ -490,6 +500,7 @@ def _get_header_data(self): keyword_dict["texpo_time"] = self.imghdu[0].header["TEXPTIME"] keyword_dict["exptime"] = self.imghdu[0].header["EXPTIME"] keyword_dict["ndrizim"] = self.imghdu[0].header["NDRIZIM"] + keyword_dict["numexp"] = self.imghdu[0].header["NUMEXP"] if keyword_dict["detector"].upper() != "SBC": if keyword_dict["instrument"].upper() == 'WFPC2': atodgn = self._get_max_key_value(self.imghdu[0].header, 'ATODGAIN')