From a63b5bcefcd59fa188386b9a047c5240a7ad50d4 Mon Sep 17 00:00:00 2001 From: Mihir Patankar Date: Sat, 7 Oct 2023 22:21:21 -0400 Subject: [PATCH] change the padding strategy --- lightcurve_processing.py | 20 ++++++-------------- postage_stamp_plotter.py | 40 +++++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/lightcurve_processing.py b/lightcurve_processing.py index 541a23f..4f9c0a9 100644 --- a/lightcurve_processing.py +++ b/lightcurve_processing.py @@ -97,17 +97,9 @@ def get_images(self, region_event_list): dealing with hundreds of thousands of blank pixels. The cropping bounds are written to the FITS file for later use in plotting.""" - def convert_bounds_object_to_hdu(bounds: CropBounds): - hdu = io.fits.table_to_hdu( - table.Table({field: [(getattr(bounds, field))] for field in bounds._fields}) - ) - hdu.header["EXTNAME"] = "BOUNDS" - return hdu - dmstat(infile=f"{region_event_list}[cols x,y]") - sky_bounds = CropBounds.from_source_region_bounds( - *dmstat.out_min.split(","), *dmstat.out_max.split(",") - ) + sky_bounds = CropBounds.from_strings(*dmstat.out_min.split(","), *dmstat.out_max.split(",")) + sky_bounds.double() dmcopy( infile=f"{self.event_list}" f"[bin x={sky_bounds.x_min}:{sky_bounds.x_max}:0.5," @@ -115,10 +107,10 @@ def convert_bounds_object_to_hdu(bounds: CropBounds): outfile=(sky_coords_image := f"{region_event_list}.skyimg.fits"), ) with io.fits.open(sky_coords_image, mode="append") as hdu_list: - hdu_list.append(convert_bounds_object_to_hdu(sky_bounds)) - dmstat(infile=f"{region_event_list}[cols detx,dety]") + hdu_list.append(sky_bounds.to_hdu()) - detector_bounds = CropBounds.from_source_region_bounds( + dmstat(infile=f"{region_event_list}[cols detx,dety]") + detector_bounds = CropBounds.from_strings( *dmstat.out_min.split(","), *dmstat.out_max.split(",") ) dmcopy( @@ -128,7 +120,7 @@ def convert_bounds_object_to_hdu(bounds: CropBounds): outfile=(detector_coords_image := f"{region_event_list}.detimg.fits"), ) with io.fits.open(detector_coords_image, mode="append") as hdu_list: - hdu_list.append(convert_bounds_object_to_hdu(detector_bounds)) + hdu_list.append(detector_bounds.to_hdu()) self.sky_coords_image, self.detector_coords_image = sky_coords_image, detector_coords_image def get_observation_details(self): diff --git a/postage_stamp_plotter.py b/postage_stamp_plotter.py index d2dfff2..3bae50b 100644 --- a/postage_stamp_plotter.py +++ b/postage_stamp_plotter.py @@ -1,6 +1,6 @@ """Mihir Patankar [mpatankar06@gmail.com]""" +from dataclasses import dataclass, fields from io import BytesIO -from typing import NamedTuple import matplotlib import numpy @@ -36,7 +36,7 @@ def plot_postagestamps(sky_image, detector_image): table (BINTABLE). The detector image is done on a square root scale to give the image more contrast. The PNG data is returned in a BytesIO object.""" matplotlib.use("agg") - sky_image_data = io.fits.getdata(sky_image, ext=0) + sky_image_data = numpy.sqrt(io.fits.getdata(sky_image, ext=0)) detector_image_data = numpy.sqrt(io.fits.getdata(detector_image, ext=0)) figure, (sky_image_plot, detector_image_plot) = pyplot.subplots(nrows=1, ncols=2) figure.set_figwidth(10) @@ -62,7 +62,7 @@ def plot_postagestamps(sky_image, detector_image): sky_image_plot.get_xlim(), ) sky_image_plot.set_xticks(*sky_x_ticks, rotation=90) - detector_image_plot.set_title("Detector-Coordinates Postage Stamp (sqrt Scale)", y=1.05) + detector_image_plot.set_title("Detector-Coordinates Postage Stamp", y=1.05) detector_image_plot.set_xlabel("Detector-Coordinates X Pixel") detector_image_plot.set_ylabel("Detector-Coordinates Y Pixel") detector_image_plot.grid(True, linestyle="-", color="gray") @@ -88,7 +88,8 @@ def plot_postagestamps(sky_image, detector_image): return png_data -class CropBounds(NamedTuple): +@dataclass +class CropBounds: """Holds the bounding box of our postage stamp images.""" x_min: float @@ -96,18 +97,27 @@ class CropBounds(NamedTuple): x_max: float y_max: float - @classmethod - def from_source_region_bounds(cls, x_min, y_min, x_max, y_max): - """Gives the image some padding so the background region can be observed. This should be - immune to edge cases where the source region plus padding exceeds the dimensions of the - whole image.""" - padding = 20 # In chandra pixels - return cls( - float(x_min) - padding, - float(y_min) - padding, - float(x_max) + padding, - float(y_max) + padding, + def double(self): + """Double the bounds, useful for including background in the image.""" + x_range = self.x_max - self.x_min + self.x_min -= x_range + self.x_max += x_range + y_range = self.y_max - self.y_min + self.y_min -= y_range + self.y_max += y_range + + def to_hdu(self): + """Convert the dataclass to a Header Data Unit for FITS files.""" + hdu = io.fits.table_to_hdu( + table.Table({field.name: [(getattr(self, field.name))] for field in fields(self)}) ) + hdu.header["EXTNAME"] = "BOUNDS" + return hdu + + @classmethod + def from_strings(cls, x_min, y_min, x_max, y_max): + """Casts a set of string values to floats.""" + return cls(float(x_min), float(y_min), float(x_max), float(y_max)) @classmethod def from_hdu_list(cls, hdu_list):