From 2767e85b6b3fc84d2ac927b8f34eb95f5306c53a Mon Sep 17 00:00:00 2001 From: Frits Sweijen Date: Sun, 17 Mar 2024 22:18:13 +0100 Subject: [PATCH 1/5] Script to blank images based on primary beam --- .../wsclean_trim_image_to_primary_beam.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 fits_helpers/wsclean_trim_image_to_primary_beam.py diff --git a/fits_helpers/wsclean_trim_image_to_primary_beam.py b/fits_helpers/wsclean_trim_image_to_primary_beam.py new file mode 100644 index 00000000..3aab6138 --- /dev/null +++ b/fits_helpers/wsclean_trim_image_to_primary_beam.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +import argparse +import os + +from astropy.io import fits # type: ignore +import numpy as np + +def trim_image(imname: str, beamlvl: float, MFS: bool) -> str: + """ Blanks images created by WSClean beyond a specified level of the primary beam. + + Args: + imname : str + Name of the images to blank as passed to WSClean's -name option. + beamlvl : float + Level of the primary beam to blank below. + MFS : bool + + Returns: + imname_trimmed : str + Base name of the blanked images. + """ + if MFS: + im_app = imname + '-MFS-image.fits' + im_pb = imname + '-MFS-image-pb.fits' + im_beam = imname + '-MFS-beam-0.fits' + else: + im_app = imname + '-image.fits' + im_pb = imname + '-image-pb.fits' + im_beam = imname + '-beam-0.fits' + + if not os.path.isfile(im_app): + raise FileNotFoundError(f"Image {im_app} does not exist.") + if not os.path.isfile(im_pb): + raise FileNotFoundError(f"Image {im_pb} does not exist.") + if not os.path.isfile(im_beam): + raise FileNotFoundError(f"Image {im_beam} does not exist.") + beam = fits.getdata(im_beam) + mask = beam > beamlvl + + data_app = fits.getdata(im_app) + data_pb = fits.getdata(im_pb) + + im_app_masked = np.where(mask, data_app, np.nan) + im_pb_masked = np.where(mask, data_pb, np.nan) + + print(f'Writing primary-beam-trimmed images for {imname}...') + fits.writeto(f"{imname}.pbtrimmed-MFS-image.fits", data=im_app_masked, header=fits.getheader(im_app)) + fits.writeto(f"{imname}.pbtrimmed-MFS-image-pb.fits", data=im_pb_masked, header=fits.getheader(im_pb)) + print('Done') + return imname + ".pbtrimmed" + + +if __name__ == '__main__': + parser = argparse.ArgumentParser("Trim a WSClean image to a certain value of the primary beam.") + parser.add_argument("--imagename", type=str, help="Image name as passed to WSClean.") + parser.add_argument("--beam_cut", type=float, help="Fractional value of the primary beam to trim to relative to the centre of the image.") + parser.add_argument("--no-MFS", action="store_true", required=False, help="Set if image was made using a single output channel (i.e. -channels-out=1 or not given).") + args = parser.parse_args() + + trim_image(args.imagename, args.beam_cut, not args.no_MFS) From 89722722364bbb0f5ddffebf4ff6c09db2483a22 Mon Sep 17 00:00:00 2001 From: Frits Sweijen Date: Sun, 17 Mar 2024 22:20:09 +0100 Subject: [PATCH 2/5] Execute permissions --- fits_helpers/wsclean_trim_image_to_primary_beam.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 fits_helpers/wsclean_trim_image_to_primary_beam.py diff --git a/fits_helpers/wsclean_trim_image_to_primary_beam.py b/fits_helpers/wsclean_trim_image_to_primary_beam.py old mode 100644 new mode 100755 From 5441a5dbc39eaabf88e04b335ec81a6ee6911c6e Mon Sep 17 00:00:00 2001 From: Frits Sweijen Date: Sun, 17 Mar 2024 22:25:14 +0100 Subject: [PATCH 3/5] Rename trim to blank --- .../wsclean_trim_image_to_primary_beam.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fits_helpers/wsclean_trim_image_to_primary_beam.py b/fits_helpers/wsclean_trim_image_to_primary_beam.py index 3aab6138..3ac5840b 100755 --- a/fits_helpers/wsclean_trim_image_to_primary_beam.py +++ b/fits_helpers/wsclean_trim_image_to_primary_beam.py @@ -5,7 +5,7 @@ from astropy.io import fits # type: ignore import numpy as np -def trim_image(imname: str, beamlvl: float, MFS: bool) -> str: +def blank_image(imname: str, beamlvl: float, MFS: bool) -> str: """ Blanks images created by WSClean beyond a specified level of the primary beam. Args: @@ -16,7 +16,7 @@ def trim_image(imname: str, beamlvl: float, MFS: bool) -> str: MFS : bool Returns: - imname_trimmed : str + imname_blanked : str Base name of the blanked images. """ if MFS: @@ -43,18 +43,18 @@ def trim_image(imname: str, beamlvl: float, MFS: bool) -> str: im_app_masked = np.where(mask, data_app, np.nan) im_pb_masked = np.where(mask, data_pb, np.nan) - print(f'Writing primary-beam-trimmed images for {imname}...') - fits.writeto(f"{imname}.pbtrimmed-MFS-image.fits", data=im_app_masked, header=fits.getheader(im_app)) - fits.writeto(f"{imname}.pbtrimmed-MFS-image-pb.fits", data=im_pb_masked, header=fits.getheader(im_pb)) + print(f'Writing primary-beam-blanked images for {imname}...') + fits.writeto(f"{imname}.pbblanked-MFS-image.fits", data=im_app_masked, header=fits.getheader(im_app)) + fits.writeto(f"{imname}.pbblanked-MFS-image-pb.fits", data=im_pb_masked, header=fits.getheader(im_pb)) print('Done') - return imname + ".pbtrimmed" + return imname + ".pbblanked" if __name__ == '__main__': - parser = argparse.ArgumentParser("Trim a WSClean image to a certain value of the primary beam.") + parser = argparse.ArgumentParser("Blank a WSClean image to a certain value of the primary beam.") parser.add_argument("--imagename", type=str, help="Image name as passed to WSClean.") - parser.add_argument("--beam_cut", type=float, help="Fractional value of the primary beam to trim to relative to the centre of the image.") + parser.add_argument("--beam_cut", type=float, help="Fractional value of the primary beam to blank to relative to the centre of the image.") parser.add_argument("--no-MFS", action="store_true", required=False, help="Set if image was made using a single output channel (i.e. -channels-out=1 or not given).") args = parser.parse_args() - trim_image(args.imagename, args.beam_cut, not args.no_MFS) + blank_image(args.imagename, args.beam_cut, not args.no_MFS) From 673b832e2312787d0caaa068d1de9b9fd60c87ae Mon Sep 17 00:00:00 2001 From: Frits Sweijen Date: Sun, 17 Mar 2024 22:26:59 +0100 Subject: [PATCH 4/5] Finish docstring --- fits_helpers/wsclean_trim_image_to_primary_beam.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fits_helpers/wsclean_trim_image_to_primary_beam.py b/fits_helpers/wsclean_trim_image_to_primary_beam.py index 3ac5840b..30a117d5 100755 --- a/fits_helpers/wsclean_trim_image_to_primary_beam.py +++ b/fits_helpers/wsclean_trim_image_to_primary_beam.py @@ -14,6 +14,7 @@ def blank_image(imname: str, beamlvl: float, MFS: bool) -> str: beamlvl : float Level of the primary beam to blank below. MFS : bool + Set to True if the image was made in MFS mode (i.e. channels-out > 1). Returns: imname_blanked : str From 9662370eb372abbe7b27b0092dab0ba3ec80795d Mon Sep 17 00:00:00 2001 From: Frits Sweijen Date: Mon, 18 Mar 2024 08:53:19 +0100 Subject: [PATCH 5/5] Name more appropriately --- ...primary_beam.py => wsclean_blank_image_beyond_primary_beam.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename fits_helpers/{wsclean_trim_image_to_primary_beam.py => wsclean_blank_image_beyond_primary_beam.py} (100%) diff --git a/fits_helpers/wsclean_trim_image_to_primary_beam.py b/fits_helpers/wsclean_blank_image_beyond_primary_beam.py similarity index 100% rename from fits_helpers/wsclean_trim_image_to_primary_beam.py rename to fits_helpers/wsclean_blank_image_beyond_primary_beam.py