########################################################################3 # task_imsmooth.py # # Copyright (C) 2008, 2009 # Associated Universities, Inc. Washington DC, USA. # # This script is free software; you can redistribute it and/or modify it # under the terms of the GNU Library General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public # License for more details. # # You should have received a copy of the GNU Library General Public License # along with this library; if not, write to the Free Software Foundation, # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. # # Correspondence concerning AIPS++ should be adressed as follows: # Internet email: aips2-request@nrao.edu. # Postal address: AIPS++ Project Office # National Radio Astronomy Observatory # 520 Edgemont Road # Charlottesville, VA 22903-2475 USA # # <summary> # CASA task for smoothing an image, by doing Forier-based convolution # on a CASA image file. # </summary> # # <reviewed reviwer="" date="" tests="" demos=""> # </reviewed # # <author> # Shannon Jaeger (University of Calgary) # </author> # # <etymology> # imsmooth stands for image smoothing # </etymology> # # <synopsis> # task_imsmooth.py is a Python script providing an easy to use task # for smoothing an image. # # The convolv2d function of the image tool is used to do the work, # a description of this function can be found at # http://casa.nrao.edu/docs/casaref/image.convolve2d.html#x27-270001.1.1 # # </synopsis> # # <example> # <srcblock> # # The following code snippet find the 1-moments, intensity-weighted # # coordinate, often used for finding velocity fields. # imsmooth( imagename='myimage', kernel='gaussian', outfile='myimage.smooth' ) # # # </example> # # <motivation> # To provide a user-friendly method to smooth images. # </motivation> # # <todo> # </todo> from __future__ import absolute_import import inspect import os import sys import numpy # get is_CASA6 and is_python3 from casatasks.private.casa_transition import * if is_CASA6: from casatools import image, regionmanager, quanta from casatasks import casalog from .ialib import write_image_history _qa = quanta( ) else: from taskinit import * from ialib import write_image_history image = iatool regionmanager = rgtool # not a local tool _qa = qa from casatasks.private.callabletask import log_origin_setter @log_origin_setter def imsmooth( imagename, kernel, major, minor, pa, targetres, kimage, scale, region, box, chans, stokes, mask, outfile, stretch, overwrite, beam ): ikernel = kernel.startswith('i') ckernel = kernel.startswith('c') bkernel = kernel.startswith('b') gkernel = kernel.startswith('g') if ( not ( gkernel or bkernel or ckernel or ikernel ) ): raise ValueError('Unsupported kernel, ' + kernel) if (not ikernel and type(beam) == str): if len(beam) != 0: err = "beam cannot be a non-empty string" casalog.post(err, "SEVERE") raise Exception(err) beam = {} # First check to see if the output file exists. If it # does then we abort. CASA doesn't allow files to be # over-written, just a policy. if ( len( outfile ) < 1 ): outfile = 'imsmooth_results.im' casalog.post( "The outfile paramter is empty, consequently the" \ +" smoothed image will be\nsaved on disk in file, " \ + outfile, 'WARN') _myia = image() _myia.dohistory(False) retia = image() _myia.open(imagename) mycsys = _myia.coordsys() myrg = regionmanager() reg = myrg.frombcs( mycsys.torecord(), _myia.shape(), box, chans, stokes, "a", region ) myrg.done() mycsys.done() _myia.done() # If the values given are integers we assume they are given in # arcsecs and alter appropriately if not ikernel: if isinstance(major, (int, float)): major=str(major)+'arcsec' if isinstance(minor, (int, float)): minor=str(minor)+'arcsec' if isinstance(pa, (int, float)): pa=str(pa)+'deg' try: outia = None if ( gkernel or ckernel): _myia.open(imagename) if ckernel: beam = _myia.commonbeam() # add a small epsilon to avoid convolving with a null beam to reach # a target resolution that already exists beam['major'] = _qa.mul(beam['major'], 1 + 1e-10) beam['minor'] = _qa.mul(beam['minor'], 1 + 1e-10) major = "" minor = "" pa = "" targetres = True if (beam and (major or minor or pa)): raise ValueError("You may specify only beam or the set of major/minor/pa") if not beam: if not major: raise ValueError("Major axis must be specified") if not minor: raise ValueError("Minor axis must be specified") if not pa: raise ValueError("Position angle must be specified") outia = _myia.convolve2d( axes=[0,1], region=reg, major=major, minor=minor, pa=pa, outfile=outfile, mask=mask, stretch=stretch, targetres=targetres, overwrite=overwrite, beam=beam ) elif (bkernel ): if not major or not minor: raise ValueError("Both major and minor must be specified.") # BOXCAR KERNEL # # Until convolve2d supports boxcar we will need to # use sepconvolve to do this. # # BIG NOTE!!!!! # According to Gaussian2D documentation the default position # angle aligns the major axis along the y-axis, which typically # be lat. So this means that we need to use the major quantity # on the y axis (or 1) for sepconvolve. _myia.open( imagename ) casalog.post( "ia.sepconvolve( axes=[0,1],"+\ "types=['boxcar','boxcar' ],"+\ "widths=[ "+str(minor)+", "+str(major)+" ],"+ \ "region="+str(reg)+",outfile="+outfile+" )",\ 'DEBUG2' ) #retValue = ia.sepconvolve( axes=[0,1], types=['box','box' ],\ # widths=[ minor, major ], \ # region=reg,outfile=outfile ) outia = _myia.sepconvolve( axes=[0,1], types=['box','box' ], widths=[ minor, major ], region=reg,outfile=outfile, mask=mask, stretch=stretch, overwrite=overwrite ) elif ikernel: _myia.open(imagename) outia = _myia.convolve( outfile=outfile, kernel=kimage, scale=scale, region=reg, mask=mask, overwrite=overwrite, stretch=stretch ) else: raise ValueError('Unrecognized kernel type: ' + kernel) try: param_names = imsmooth.__code__.co_varnames[:imsmooth.__code__.co_argcount] if is_python3: vars = locals( ) param_vals = [vars[p] for p in param_names] else: param_vals = [eval(p) for p in param_names] write_image_history( outia, sys._getframe().f_code.co_name, param_names, param_vals, casalog ) except Exception as instance: casalog.post("*** Error \'%s\' updating HISTORY" % (instance), 'WARN') finally: _myia.done() if outia: outia.done()