import ast
import glob
import math
import os
import pipeline.infrastructure as infrastructure
import pipeline.infrastructure.basetask as basetask
import pipeline.infrastructure.imagelibrary as imagelibrary
import pipeline.infrastructure.vdp as vdp
from pipeline.infrastructure import casa_tasks
from pipeline.infrastructure import task_registry
import pipeline.infrastructure.utils as utils
LOG = infrastructure.get_logger(__name__)
[docs]class MakecutoutimagesResults(basetask.Results):
def __init__(self, final=None, pool=None, preceding=None,
subimagelist=None, subimagenames=None, image_size=None):
super(MakecutoutimagesResults, self).__init__()
if final is None:
final = []
if pool is None:
pool = []
if preceding is None:
preceding = []
if subimagelist is None:
subimagelist = []
if subimagenames is None:
subimagenames = []
self.pool = pool[:]
self.final = final[:]
self.preceding = preceding[:]
self.error = set()
self.subimagelist = subimagelist[:]
self.subimagenames = subimagenames[:]
self.image_size = image_size
[docs] def merge_with_context(self, context):
"""
See :method:`~pipeline.infrastructure.api.Results.merge_with_context`
"""
# subimagelist is a list of dictionaries
# Use the same format and information from sciimlist, save for the image name and image plot
for subitem in self.subimagelist:
try:
imageitem = imagelibrary.ImageItem(
imagename=subitem['imagename'] + '.subim', sourcename=subitem['sourcename'],
spwlist=subitem['spwlist'], specmode=subitem['specmode'],
sourcetype=subitem['sourcetype'],
multiterm=subitem['multiterm'],
imageplot=subitem['imageplot'])
if 'TARGET' in subitem['sourcetype']:
context.subimlist.add_item(imageitem)
except:
pass
def __repr__(self):
return 'MakecutoutimagesResults:'
[docs]@task_registry.set_equivalent_casa_task('hif_makecutoutimages')
class Makecutoutimages(basetask.StandardTaskTemplate):
Inputs = MakecutoutimagesInputs
[docs] def prepare(self):
# PIPE-631: make alpha image cutouts in VLASS-SE-CONT mode
if hasattr(self.inputs.context, 'imaging_mode'):
img_mode = self.inputs.context.imaging_mode
else:
img_mode = None
imlist = self.inputs.context.sciimlist.get_imlist()
imagenames = []
# Per VLASS Tech Specs page 22
for imageitem in imlist:
if imageitem['multiterm']:
imagenames.extend(glob.glob(imageitem['imagename'] + '.tt0')) # non-pbcor
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.residual') + '*.tt0')) # non-pbcor
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.pbcor') + '*.tt0'))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.pbcor') + '*.tt0.rms'))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.psf') + '*.tt0'))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.residual.pbcor') + '*.tt0'))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.pb') + '*.tt0'))
if img_mode == 'VLASS-SE-CONT':
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.alpha')))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.alpha.error')))
else:
imagenames.extend(glob.glob(imageitem['imagename'])) # non-pbcor
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.residual'))) # non-pbcor
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.pbcor')))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.pbcor.rms')))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.psf')))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.image.residual.pbcor')))
imagenames.extend(glob.glob(imageitem['imagename'].replace('.image', '.pb')))
subimagenames = []
subimage_size = None
for imagename in imagenames:
if not os.path.exists(imagename + '.subim'):
subimagename = imagename + '.subim'
LOG.info("SubImagename: " + subimagename)
_, subimage_size = self._do_subim(imagename)
subimagenames.append(subimagename)
imlist.sort()
subimagenames.sort()
return MakecutoutimagesResults(subimagelist=imlist, subimagenames=subimagenames, image_size=subimage_size)
[docs] def analyse(self, results):
return results
def _do_imstat(self, imagename):
task = casa_tasks.imstat(imagename=imagename)
return self._executor.execute(task)
def _do_imhead(self, imagename):
task = casa_tasks.imhead(imagename=imagename)
return self._executor.execute(task)
def _do_subim(self, imagename):
inputs = self.inputs
# Get image parameters
# imstat_dict = self._do_imstat(imagename)
# Get image header
imhead_dict = self._do_imhead(imagename)
# Read in image size from header
imsizex = math.fabs(imhead_dict['refpix'][0]*imhead_dict['incr'][0]*(180.0/math.pi)*2) # degrees
imsizey = math.fabs(imhead_dict['refpix'][1]*imhead_dict['incr'][1]*(180.0/math.pi)*2) # degrees
image_size_x = 1.0 # degrees: size of cutout
image_size_y = 1.0 # degrees: size of cutout
# If less than or equal to 1 deg + 2 arcminute buffer, use the image size and no buffer
buffer_deg = 2.0 / 60.0 # Units of degrees
if imsizex <= (1.0 + buffer_deg):
image_size_x = imsizex
image_size_y = imsizey
buffer_deg = 0.0
imsize = [imhead_dict['shape'][0], imhead_dict['shape'][1]] # pixels
xcellsize = 3600.0 * (180.0 / math.pi) * math.fabs(imhead_dict['incr'][0])
ycellsize = 3600.0 * (180.0 / math.pi) * math.fabs(imhead_dict['incr'][1])
fld_subim_size_x = utils.round_half_up(3600.0 * (image_size_x + buffer_deg) / xcellsize) # Cutout size with buffer in pixels
fld_subim_size_y = utils.round_half_up(3600.0 * (image_size_y + buffer_deg) / ycellsize) # Cutout size with buffer in pixels
# equivalent blc,trc for extracting requested field, in pixels:
blcx = imsize[0] // 2 - (fld_subim_size_x / 2)
blcy = imsize[1] // 2 - (fld_subim_size_y / 2)
trcx = imsize[0] // 2 + (fld_subim_size_x / 2) + 1
trcy = imsize[1] // 2 + (fld_subim_size_y / 2) + 1
if blcx < 0.0:
blcx = 0
if blcy < 0.0:
blcy = 0
if trcx > imsize[0]:
trcx = imsize[0] - 1
if trcy > imsize[1]:
trcy = imsize[1] - 1
if inputs.offsetblc and inputs.offsettrc:
offsetblc = inputs.offsetblc
offsettrc = inputs.offsettrc
buffer_deg = 0.0
if isinstance(offsetblc, str):
offsetblc = ast.literal_eval(offsetblc)
if isinstance(offsettrc, str):
offsettrc = ast.literal_eval(offsettrc)
fld_subim_size_x_blc = utils.round_half_up(3600.0 * (offsetblc[0] / 3600.0 + buffer_deg / 2.0) / xcellsize)
fld_subim_size_y_blc = utils.round_half_up(3600.0 * (offsetblc[1] / 3600.0 + buffer_deg / 2.0) / ycellsize)
fld_subim_size_x_trc = utils.round_half_up(3600.0 * (offsettrc[0] / 3600.0 + buffer_deg / 2.0) / xcellsize)
fld_subim_size_y_trc = utils.round_half_up(3600.0 * (offsettrc[1] / 3600.0 + buffer_deg / 2.0) / ycellsize)
blcx = imsize[0] // 2 - fld_subim_size_x_blc
blcy = imsize[1] // 2 - fld_subim_size_y_blc
trcx = imsize[0] // 2 + fld_subim_size_x_trc + 1
trcy = imsize[1] // 2 + fld_subim_size_y_trc + 1
if blcx < 0.0:
blcx = 0
if blcy < 0.0:
blcy = 0
if trcx > imsize[0]:
trcx = imsize[0] - 1
if trcy > imsize[1]:
trcy = imsize[1] - 1
LOG.info("Using user defined offsets in arcseconds of: blc:({!s}), trc:({!s})".format(
','.join([str(i) for i in offsetblc]), ','.join([str(i) for i in offsettrc])))
fld_subim = str(blcx) + ',' + str(blcy) + ',' + str(trcx) + ',' + str(trcy)
LOG.info('Using field subimage blc,trc of {!s},{!s}, {!s},{!s}, which includes a buffer '
'of {!s} arcminutes.'.format(blcx, blcy, trcx, trcy, buffer_deg*60))
# imsubimage(imagename=clnpbcor, outfile=clnpbcor + '.subim', box=fld_subim)
# Quicklook parameters
imsubimageparams = {'imagename': imagename,
'outfile': imagename + '.subim',
'box': fld_subim}
task = casa_tasks.imsubimage(**imsubimageparams)
px = (trcx - blcx) + 1
py = (trcy - blcy) + 1
subimage_size = {'pixels_x': px,
'pixels_y': py,
'arcsec_x': px * xcellsize,
'arcsec_y': py * ycellsize}
return self._executor.execute(task), subimage_size