コード例 #1
0
def mfs_dirty_spws(img, spws, chans):
    """
    Dirty image each supplied spw (MFS)

    Inputs:
        img :: Imaging object
            The Imaging object
        spws, chans :: lists
            spectral windows and channels to image

    Returns: Nothing
    """
    for spw, chan in zip(spws, chans):
        imagename = "{0}.spw{1}.{2}.mfs".format(img.imfield, spw, img.stokes)
        if img.uvtaper:
            imagename = imagename + ".uvtaper"
        imagename = os.path.join(img.outdir, imagename)
        img.logger.info(
            "Generating dirty image of spw {0} (MFS)...".format(spw))
        cleanspw = spw
        if chan:
            cleanspw = "{0}:{1}".format(spw, chan)
        casa.tclean(
            vis=img.vis,
            imagename=imagename,
            phasecenter=img.cp["phasecenter"],
            field=img.field,
            spw=cleanspw,
            specmode="mfs",
            gridder=img.cp["gridder"],
            wprojplanes=img.cp["wprojplanes"],
            threshold="0mJy",
            niter=0,
            deconvolver="multiscale",
            scales=img.cp["scales"],
            gain=img.cp["gain"],
            cyclefactor=img.cp["cyclefactor"],
            imsize=img.cp["imsize"],
            pblimit=-1.0,
            cell=img.cp["cell"],
            weighting=img.cp["weighting"],
            robust=img.cp["robust"],
            uvtaper=img.outertaper,
            uvrange=img.uvrange,
            stokes=img.stokes,
            pbcor=False,
            parallel=img.parallel,
        )
        img.logger.info("Done.")

        # Generate primary beam image
        img.logger.info(
            "Generating primary beam image of spw {0} (MFS)...".format(spw))
        makePB(
            vis=img.vis,
            field=img.field,
            spw=spw,
            uvrange=img.uvrange,
            stokes=img.stokes,
            imtemplate="{0}.image".format(imagename),
            outimage="{0}.pb.image".format(imagename),
            pblimit=img.cp["pblimit"],
        )
        img.logger.info("Done.")

        # Primary beam correction
        img.logger.info("Performing primary beam correction...")
        casa.impbcor(
            imagename="{0}.image".format(imagename),
            pbimage="{0}.pb.image".format(imagename),
            outfile="{0}.pbcor.image".format(imagename),
            overwrite=True,
        )
        img.logger.info("Done.")

        # Export to fits
        img.logger.info("Exporting fits file...")
        casa.exportfits(
            imagename="{0}.pb.image".format(imagename),
            fitsimage="{0}.pb.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.image".format(imagename),
            fitsimage="{0}.dirty.image.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.residual".format(imagename),
            fitsimage="{0}.dirty.residual.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.pbcor.image".format(imagename),
            fitsimage="{0}.dirty.pbcor.image.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        img.logger.info("Done.")
コード例 #2
0
def mfs_clean_spws(img, spws, chans, spwtype):
    """
    Clean each supplied spw (MFS)

    Inputs:
        img :: Imaging object
            The Imaging object
        spws, chans :: lists
            spectral windows and channels to image
        spwtype :: string
            'line' or 'cont', to determine which clean params to use

    Returns: Nothing
    """
    for spw, chan in zip(spws, chans):
        # If not interactive, Lightly clean to get threshold
        imagename = "{0}.spw{1}.{2}.mfs".format(img.imfield, spw, img.stokes)
        if img.uvtaper:
            imagename = imagename + ".uvtaper"
        imagename = os.path.join(img.outdir, imagename)
        cleanspw = spw
        if chan:
            cleanspw = "{0}:{1}".format(spw, chan)
        if not img.interactive:
            # Save model if necessary
            savemodel = "none"
            if img.savemodel == "light":
                savemodel = "modelcolumn"
            img.logger.info("Lightly cleaning spw {0} (MFS)...".format(spw))
            casa.tclean(
                vis=img.vis,
                imagename=imagename,
                phasecenter=img.cp["phasecenter"],
                field=img.field,
                spw=cleanspw,
                specmode="mfs",
                gridder=img.cp["gridder"],
                wprojplanes=img.cp["wprojplanes"],
                threshold="0mJy",
                niter=img.cp["lightniter"] * len(img.stokes),
                usemask="auto-multithresh",
                pbmask=img.cp[spwtype + "pbmask"],
                sidelobethreshold=img.cp[spwtype + "sidelobethreshold"],
                noisethreshold=img.cp[spwtype + "noisethreshold"],
                lownoisethreshold=img.cp[spwtype + "lownoisethreshold"],
                negativethreshold=img.cp[spwtype + "negativethreshold"],
                smoothfactor=img.cp[spwtype + "smoothfactor"],
                minbeamfrac=img.cp[spwtype + "minbeamfrac"],
                cutthreshold=img.cp[spwtype + "cutthreshold"],
                growiterations=img.cp[spwtype + "growiterations"],
                deconvolver="multiscale",
                scales=img.cp["scales"],
                gain=img.cp["gain"],
                cyclefactor=img.cp["cyclefactor"],
                imsize=img.cp["imsize"],
                pblimit=-1.0,
                cell=img.cp["cell"],
                weighting=img.cp["weighting"],
                robust=img.cp["robust"],
                uvtaper=img.outertaper,
                uvrange=img.uvrange,
                stokes=img.stokes,
                savemodel=savemodel,
                pbcor=False,
                restart=True,
                calcres=False,
                calcpsf=False,
                parallel=img.parallel,
            )
            img.logger.info("Done.")

            # Get RMS of residuals
            dat = casa.imstat(
                imagename="{0}.residual".format(imagename),
                axes=[0, 1],
                mask="'{0}.mask' == 0".format(imagename),
            )
            img.logger.info("Max un-masked RMS: {0:.2f} mJy/beam".format(
                1000.0 * np.max(dat["rms"])))
            img.logger.info(
                "Max un-masked MAD*1.4826: {0:.2f} mJy/beam".format(
                    1000.0 * 1.4826 * np.max(dat["medabsdevmed"])))
            img.logger.info(
                "Using max(MAD) x 1.4826 x {0} as threshold".format(
                    img.cp["nrms"]))
            threshold = "{0:.2f}mJy".format(img.cp["nrms"] * 1000.0 * 1.4826 *
                                            np.max(dat["medabsdevmed"]))
        else:
            threshold = "0.0mJy"

        # Clean to threshold
        # Save model if necessary
        savemodel = "none"
        if img.savemodel == "clean":
            savemodel = "modelcolumn"
        img.logger.info("Cleaning spw {0} (MFS) to threshold: {1}...".format(
            spw, threshold))
        casa.tclean(
            vis=img.vis,
            imagename=imagename,
            field=img.field,
            phasecenter=img.cp["phasecenter"],
            spw=cleanspw,
            gridder=img.cp["gridder"],
            wprojplanes=img.cp["wprojplanes"],
            specmode="mfs",
            threshold=threshold,
            niter=img.cp["maxniter"] * len(img.stokes),
            usemask="auto-multithresh",
            pbmask=img.cp[spwtype + "pbmask"],
            sidelobethreshold=img.cp[spwtype + "sidelobethreshold"],
            noisethreshold=img.cp[spwtype + "noisethreshold"],
            lownoisethreshold=img.cp[spwtype + "lownoisethreshold"],
            negativethreshold=img.cp[spwtype + "negativethreshold"],
            smoothfactor=img.cp[spwtype + "smoothfactor"],
            minbeamfrac=img.cp[spwtype + "minbeamfrac"],
            cutthreshold=img.cp[spwtype + "cutthreshold"],
            growiterations=img.cp[spwtype + "growiterations"],
            deconvolver="multiscale",
            scales=img.cp["scales"],
            gain=img.cp["gain"],
            cyclefactor=img.cp["cyclefactor"],
            imsize=img.cp["imsize"],
            pblimit=-1.0,
            cell=img.cp["cell"],
            weighting=img.cp["weighting"],
            robust=img.cp["robust"],
            uvtaper=img.outertaper,
            uvrange=img.uvrange,
            pbcor=False,
            stokes=img.stokes,
            savemodel=savemodel,
            interactive=img.interactive,
            restart=True,
            calcres=False,
            calcpsf=False,
            parallel=img.parallel,
        )
        img.logger.info("Done.")

        # Primary beam correction
        img.logger.info("Performing primary beam correction...")
        casa.impbcor(
            imagename="{0}.image".format(imagename),
            pbimage="{0}.pb.image".format(imagename),
            outfile="{0}.pbcor.image".format(imagename),
            overwrite=True,
        )
        img.logger.info("Done.")

        # Export to fits
        img.logger.info("Exporting fits file...")
        casa.exportfits(
            imagename="{0}.image".format(imagename),
            fitsimage="{0}.clean.image.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.mask".format(imagename),
            fitsimage="{0}.clean.mask.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.residual".format(imagename),
            fitsimage="{0}.clean.residual.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.pbcor.image".format(imagename),
            fitsimage="{0}.clean.pbcor.image.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        img.logger.info("Done.")
コード例 #3
0
def mfs_clean_cont(img):
    """
    Clean combined spws using multi-frequency synthesis

    Inputs:
        img :: Imaging object
            The Imaging object

    Returns: Nothing
    """
    # If not cleaning interactively, lightly clean to get RMS
    # threshold
    imagename = "{0}.cont.{1}.mfs".format(img.imfield, img.stokes)
    if img.uvtaper:
        imagename = imagename + ".uvtaper"
    cleanspw = ",".join([
        "{0}:{1}".format(spw, chan) if chan else spw
        for spw, chan in zip(img.cont_spws, img.cont_chans)
    ])
    if not img.interactive:
        savemodel = "none"
        if img.savemodel == "light":
            savemodel = "modelcolumn"
        img.logger.info("Lightly cleaning continuum image (MFS)...")
        casa.tclean(
            vis=img.vis,
            imagename=os.path.join(img.outdir, imagename),
            phasecenter=img.cp["phasecenter"],
            field=img.field,
            spw=cleanspw,
            gridder=img.cp["gridder"],
            wprojplanes=img.cp["wprojplanes"],
            specmode="mfs",
            threshold="0mJy",
            niter=img.cp["lightniter"] * len(img.stokes),
            usemask="auto-multithresh",
            pbmask=img.cp["contpbmask"],
            sidelobethreshold=img.cp["contsidelobethreshold"],
            noisethreshold=img.cp["contnoisethreshold"],
            lownoisethreshold=img.cp["contlownoisethreshold"],
            negativethreshold=img.cp["contnegativethreshold"],
            smoothfactor=img.cp["contsmoothfactor"],
            minbeamfrac=img.cp["contminbeamfrac"],
            cutthreshold=img.cp["contcutthreshold"],
            growiterations=img.cp["contgrowiterations"],
            nterms=img.cp["nterms"],
            deconvolver="mtmfs",
            scales=img.cp["scales"],
            gain=img.cp["gain"],
            cyclefactor=img.cp["cyclefactor"],
            imsize=img.cp["imsize"],
            pblimit=-1.0,
            cell=img.cp["cell"],
            weighting=img.cp["weighting"],
            robust=img.cp["robust"],
            uvtaper=img.outertaper,
            uvrange=img.uvrange,
            stokes=img.stokes,
            pbcor=False,
            restart=True,
            calcres=False,
            calcpsf=False,
            savemodel=savemodel,
            parallel=img.parallel,
        )
        img.logger.info("Done.")

        # Get RMS of residuals outside of clean mask
        dat = casa.imstat(
            imagename="{0}.residual.tt0".format(
                os.path.join(img.outdir, imagename)),
            axes=[0, 1],
            mask="'{0}.mask' == 0".format(os.path.join(img.outdir, imagename)),
        )
        img.logger.info("Max un-masked RMS: {0:.2f} mJy/beam".format(
            1000.0 * np.max(dat["rms"])))
        img.logger.info("Max un-masked MAD*1.4826: {0:.2f} mJy/beam".format(
            1000.0 * 1.4826 * np.max(dat["medabsdevmed"])))
        img.logger.info("Using max(MAD) x 1.4826 x {0} as threshold".format(
            img.cp["nrms"]))
        threshold = "{0:.2f}mJy".format(img.cp["nrms"] * 1000.0 * 1.4826 *
                                        np.max(dat["medabsdevmed"]))
    else:
        # No threshold for interactive clean
        threshold = "0.0mJy"

    # Clean to threshold
    savemodel = "none"
    if img.savemodel == "clean":
        savemodel = "modelcolumn"
    img.logger.info(
        "Cleaning continuum image (MFS) to threshold: {0}...".format(
            threshold))
    casa.tclean(
        vis=img.vis,
        imagename=os.path.join(img.outdir, imagename),
        phasecenter=img.cp["phasecenter"],
        field=img.field,
        spw=cleanspw,
        gridder=img.cp["gridder"],
        wprojplanes=img.cp["wprojplanes"],
        specmode="mfs",
        threshold=threshold,
        niter=img.cp["maxniter"] * len(img.stokes),
        usemask="auto-multithresh",
        pbmask=img.cp["contpbmask"],
        sidelobethreshold=img.cp["contsidelobethreshold"],
        noisethreshold=img.cp["contnoisethreshold"],
        lownoisethreshold=img.cp["contlownoisethreshold"],
        negativethreshold=img.cp["contnegativethreshold"],
        smoothfactor=img.cp["contsmoothfactor"],
        minbeamfrac=img.cp["contminbeamfrac"],
        cutthreshold=img.cp["contcutthreshold"],
        growiterations=img.cp["contgrowiterations"],
        nterms=img.cp["nterms"],
        deconvolver="mtmfs",
        scales=img.cp["scales"],
        gain=img.cp["gain"],
        cyclefactor=img.cp["cyclefactor"],
        imsize=img.cp["imsize"],
        pblimit=-1.0,
        cell=img.cp["cell"],
        weighting=img.cp["weighting"],
        robust=img.cp["robust"],
        uvtaper=img.outertaper,
        uvrange=img.uvrange,
        pbcor=False,
        stokes=img.stokes,
        interactive=img.interactive,
        restart=True,
        calcres=False,
        calcpsf=False,
        savemodel=savemodel,
        parallel=img.parallel,
    )
    img.logger.info("Done.")

    # Primary beam correction using PB of center channel
    img.logger.info("Performing primary beam correction...")
    # Due to widebandpbcor limitiations, need to go into outdir
    os.chdir(img.outdir)
    spwlist = [
        int(spw) for chan in img.cp["contpbchan"].split(",")
        for spw in img.cont_spws
    ]
    chanlist = [
        int(chan) for chan in img.cp["contpbchan"].split(",")
        for spw in img.cont_spws
    ]
    weightlist = [1.0 for _ in spwlist]
    casa.widebandpbcor(
        vis=os.path.join("..", img.vis),
        imagename=imagename,
        nterms=img.cp["nterms"],
        pbmin=img.cp["pblimit"],
        threshold="0.1mJy",
        spwlist=spwlist,
        weightlist=weightlist,
        chanlist=chanlist,
    )
    img.logger.info("Done.")
    os.chdir("..")

    # Export to fits
    img.logger.info("Exporting fits file...")
    imagename = os.path.join(img.outdir, imagename)
    casa.exportfits(
        imagename="{0}.image.tt0".format(imagename),
        fitsimage="{0}.clean.image.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.mask".format(imagename),
        fitsimage="{0}.clean.mask.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.residual.tt0".format(imagename),
        fitsimage="{0}.clean.residual.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.tt0".format(imagename),
        fitsimage="{0}.clean.pbcor.image.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.alpha".format(imagename),
        fitsimage="{0}.clean.pbcor.image.alpha.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.alpha.error".format(imagename),
        fitsimage="{0}.clean.pbcor.image.alpha.error.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    img.logger.info("Done.")
コード例 #4
0
def mfs_dirty_cont(img):
    """
    Dirty image combined spws using multi-frequency synthesis

    Inputs:
        img :: Imaging object
            The Imaging object

    Returns: Nothing
    """
    imagename = "{0}.cont.{1}.mfs".format(img.imfield, img.stokes)
    if img.uvtaper:
        imagename = imagename + ".uvtaper"
    img.logger.info("Generating dirty continuum image (MFS)...")
    cleanspw = ",".join([
        "{0}:{1}".format(spw, chan) if chan else spw
        for spw, chan in zip(img.cont_spws, img.cont_chans)
    ])
    casa.tclean(
        vis=img.vis,
        imagename=os.path.join(img.outdir, imagename),
        phasecenter=img.cp["phasecenter"],
        field=img.field,
        spw=cleanspw,
        gridder=img.cp["gridder"],
        wprojplanes=img.cp["wprojplanes"],
        specmode="mfs",
        threshold="0mJy",
        niter=0,
        nterms=img.cp["nterms"],
        deconvolver="mtmfs",
        scales=img.cp["scales"],
        gain=img.cp["gain"],
        cyclefactor=img.cp["cyclefactor"],
        imsize=img.cp["imsize"],
        pblimit=-1.0,
        cell=img.cp["cell"],
        weighting=img.cp["weighting"],
        robust=img.cp["robust"],
        uvtaper=img.outertaper,
        uvrange=img.uvrange,
        stokes=img.stokes,
        pbcor=False,
        parallel=img.parallel,
    )
    img.logger.info("Done.")

    # Primary beam correction
    img.logger.info("Performing primary beam correction...")
    # Due to widebandpbcor limitiations, need to go into outdir
    os.chdir(img.outdir)
    spwlist = [
        int(spw) for chan in img.cp["contpbchan"].split(",")
        for spw in img.cont_spws
    ]
    chanlist = [
        int(chan) for chan in img.cp["contpbchan"].split(",")
        for spw in img.cont_spws
    ]
    weightlist = [1.0 for _ in spwlist]
    casa.widebandpbcor(
        vis=os.path.join("..", img.vis),
        imagename=imagename,
        nterms=img.cp["nterms"],
        pbmin=img.cp["pblimit"],
        threshold="0.1mJy",
        spwlist=spwlist,
        weightlist=weightlist,
        chanlist=chanlist,
    )
    img.logger.info("Done.")
    os.chdir("..")

    # Export to fits
    img.logger.info("Exporting fits file...")
    casa.exportfits(
        imagename="{0}/{1}.pbcor.workdirectory/{1}.pb.tt0".format(
            img.outdir, imagename),
        fitsimage="{0}/{1}.pb.fits".format(img.outdir, imagename),
        overwrite=True,
        history=False,
    )
    imagename = os.path.join(img.outdir, imagename)
    casa.exportfits(
        imagename="{0}.image.tt0".format(imagename),
        fitsimage="{0}.dirty.image.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.residual.tt0".format(imagename),
        fitsimage="{0}.dirty.residual.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.tt0".format(imagename),
        fitsimage="{0}.dirty.pbcor.image.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.alpha".format(imagename),
        fitsimage="{0}.dirty.pbcor.image.alpha.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    casa.exportfits(
        imagename="{0}.pbcor.image.alpha.error".format(imagename),
        fitsimage="{0}.dirty.pbcor.image.alpha.error.fits".format(imagename),
        overwrite=True,
        history=False,
    )
    img.logger.info("Done.")
コード例 #5
0
ファイル: smooth.py プロジェクト: tvwenger/casa_pipeline
def smooth_all(field,my_line_spws='',config=None,overwrite=False,
               linetype='clean',conttype='clean'):
    """
    Smooth all line and continuum images to worst resolution of
    any individual image

    Inputs:
      field        = field to analyze
      my_line_spws = comma separated string of line spws
      config       = ConfigParser object for this project
      overwrite    = if True, overwrite steps as necessary
                     if False, skip steps if output already exists
      linetype = 'clean' or 'dirty', etc.
      conttype = 'clean' or 'dirty', etc.

    Returns:
      Nothing
    """
    #
    # start logger
    #
    logger = logging.getLogger("main")
    #
    # check config
    #
    if config is None:
        logger.critical("Error: Need to supply a config")
        raise ValueError("Config is None") 
    #
    # Find beam major axes, minor axes, and position angles for all
    # available images
    #
    logger.info("Finding largest synthesized beam")
    bmajs = []
    bmins = []
    bpas = []
    contimage = '{0}.cont.mfs.{1}.image.tt0'.format(field,conttype)
    contpbimage = '{0}.cont.mfs.{1}.pbcor.image.tt0'.format(field,conttype)
    contresimage = '{0}.cont.mfs.{1}.residual.tt0'.format(field,conttype)
    if not os.path.isdir(contimage):
        logger.warn("{0} not found!".format(contimage))
    else:
        bmajs.append(casa.imhead(imagename=contimage,mode='get',
                                 hdkey='beammajor')['value'])
        bmins.append(casa.imhead(imagename=contimage,mode='get',
                                 hdkey='beamminor')['value'])
        bpas.append(casa.imhead(imagename=contimage,mode='get',
                                hdkey='beampa')['value'])
    for spw in my_line_spws.split(','):
        lineimage = '{0}.spw{1}.channel.{2}.combeam.pbcor'.format(field,spw,linetype)
        if not os.path.isdir(lineimage):
            logger.warn("{0} not found!".format(lineimage))
            continue
        bmajs.append(casa.imhead(imagename=lineimage,mode='get',
                                hdkey='beammajor')['value'])
        bmins.append(casa.imhead(imagename=lineimage,mode='get',
                                hdkey='beamminor')['value'])
        bpas.append(casa.imhead(imagename=lineimage,mode='get',
                                hdkey='beampa')['value'])
    #
    # Smooth available images to maximum (circular) beam size
    # + 0.1 pixel size (otherwise imsmooth will complain)
    #
    cell_size = float(config.get("Clean","cell").replace('arcsec',''))
    bmaj_target = np.max(bmajs)+0.1*cell_size
    bmin_target = np.max(bmajs)+0.1*cell_size
    bpa_target = 0.
    logger.info("Smoothing all images to")
    logger.info("Major axis: {0} arcsec".format(bmaj_target))
    logger.info("Minor axis: {0} arcsec".format(bmin_target))
    logger.info("Position angle: {0} degs".format(bpa_target))
    bmaj_target = {'unit':'arcsec','value':bmaj_target}
    bmin_target = {'unit':'arcsec','value':bmin_target}
    bpa_target = {'unit':'deg','value':bpa_target}
    # Smooth continuum
    if os.path.isdir(contimage):
        logger.info("Working on continuum image")
        outfile='{0}.cont.mfs.{1}.imsmooth'.format(field,conttype)
        casa.imsmooth(imagename=contimage,kernel='gauss',
                      targetres=True,major=bmaj_target,minor=bmin_target,
                      pa=bpa_target,outfile=outfile,overwrite=overwrite)
        casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,history=False)
        logger.info("Done!")
    if os.path.isdir(contpbimage):
        logger.info("Working on continuum PBCorr image")
        outfile='{0}.cont.mfs.{1}.imsmooth.pbcor'.format(field,conttype)
        casa.imsmooth(imagename=contpbimage,kernel='gauss',
                      targetres=True,major=bmaj_target,minor=bmin_target,
                      pa=bpa_target,outfile=outfile,overwrite=overwrite)
        casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,history=False)
        logger.info("Done!")
    if os.path.isdir(contresimage):
        logger.info("Working on continuum residual image")
        outfile='{0}.cont.mfs.{1}.imsmooth.residual'.format(field,conttype)
        casa.imsmooth(imagename=contresimage,kernel='gauss',
                      targetres=True,major=bmaj_target,minor=bmin_target,
                      pa=bpa_target,outfile=outfile,overwrite=overwrite)
        casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,history=False)
        logger.info("Done!")
    # Smooth lines
    for spw in my_line_spws.split(','):
        lineimage = '{0}.spw{1}.channel.{2}.combeam.pbcor'.format(field,spw,linetype)
        if os.path.isdir(lineimage):
            logger.info("Working on spw {0}".format(spw))
            outfile = '{0}.spw{1}.channel.{2}.imsmooth.pbcor'.format(field,spw,linetype)
            casa.imsmooth(imagename=lineimage,kernel='gauss',
                        targetres=True,major=bmaj_target,minor=bmin_target,
                        pa=bpa_target,outfile=outfile,overwrite=overwrite)
            casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                            overwrite=True,history=False,velocity=True)
            logger.info("Done!")
    logger.info("Done!")
コード例 #6
0
ファイル: smooth.py プロジェクト: tvwenger/casa_pipeline
def smooth_all(field,
               my_line_spws='',
               config=None,
               overwrite=False,
               linetype='clean',
               conttype='clean'):
    """
    Smooth all line and continuum images to worst resolution of
    any individual image

    Inputs:
      field        = field to analyze
      my_line_spws = comma separated string of line spws
      config       = ConfigParser object for this project
      overwrite    = if True, overwrite steps as necessary
                     if False, skip steps if output already exists
      linetype = 'clean' or 'dirty', etc.
      conttype = 'clean' or 'dirty', etc.

    Returns:
      Nothing
    """
    #
    # start logger
    #
    logger = logging.getLogger("main")
    #
    # check config
    #
    if config is None:
        logger.critical("Error: Need to supply a config")
        raise ValueError("Config is None")
    #
    # Find beam major axes, minor axes, and position angles for all
    # available images
    #
    logger.info("Finding largest synthesized beam")
    bmajs = []
    bmins = []
    bpas = []
    contimage = '{0}.cont.mfs.{1}.image.tt0'.format(field, conttype)
    contpbimage = '{0}.cont.mfs.{1}.pbcor.image.tt0'.format(field, conttype)
    contresimage = '{0}.cont.mfs.{1}.residual.tt0'.format(field, conttype)
    if not os.path.isdir(contimage):
        logger.warn("{0} not found!".format(contimage))
    else:
        bmajs.append(
            casa.imhead(imagename=contimage, mode='get',
                        hdkey='beammajor')['value'])
        bmins.append(
            casa.imhead(imagename=contimage, mode='get',
                        hdkey='beamminor')['value'])
        bpas.append(
            casa.imhead(imagename=contimage, mode='get',
                        hdkey='beampa')['value'])
    for spw in my_line_spws.split(','):
        lineimage = '{0}.spw{1}.channel.{2}.combeam.pbcor'.format(
            field, spw, linetype)
        if not os.path.isdir(lineimage):
            logger.warn("{0} not found!".format(lineimage))
            continue
        bmajs.append(
            casa.imhead(imagename=lineimage, mode='get',
                        hdkey='beammajor')['value'])
        bmins.append(
            casa.imhead(imagename=lineimage, mode='get',
                        hdkey='beamminor')['value'])
        bpas.append(
            casa.imhead(imagename=lineimage, mode='get',
                        hdkey='beampa')['value'])
    #
    # Smooth available images to maximum (circular) beam size
    # + 0.1 pixel size (otherwise imsmooth will complain)
    #
    cell_size = float(config.get("Clean", "cell").replace('arcsec', ''))
    bmaj_target = np.max(bmajs) + 0.1 * cell_size
    bmin_target = np.max(bmajs) + 0.1 * cell_size
    bpa_target = 0.
    logger.info("Smoothing all images to")
    logger.info("Major axis: {0} arcsec".format(bmaj_target))
    logger.info("Minor axis: {0} arcsec".format(bmin_target))
    logger.info("Position angle: {0} degs".format(bpa_target))
    bmaj_target = {'unit': 'arcsec', 'value': bmaj_target}
    bmin_target = {'unit': 'arcsec', 'value': bmin_target}
    bpa_target = {'unit': 'deg', 'value': bpa_target}
    # Smooth continuum
    if os.path.isdir(contimage):
        logger.info("Working on continuum image")
        outfile = '{0}.cont.mfs.{1}.imsmooth'.format(field, conttype)
        casa.imsmooth(imagename=contimage,
                      kernel='gauss',
                      targetres=True,
                      major=bmaj_target,
                      minor=bmin_target,
                      pa=bpa_target,
                      outfile=outfile,
                      overwrite=overwrite)
        casa.exportfits(imagename=outfile,
                        fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,
                        history=False)
        logger.info("Done!")
    if os.path.isdir(contpbimage):
        logger.info("Working on continuum PBCorr image")
        outfile = '{0}.cont.mfs.{1}.imsmooth.pbcor'.format(field, conttype)
        casa.imsmooth(imagename=contpbimage,
                      kernel='gauss',
                      targetres=True,
                      major=bmaj_target,
                      minor=bmin_target,
                      pa=bpa_target,
                      outfile=outfile,
                      overwrite=overwrite)
        casa.exportfits(imagename=outfile,
                        fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,
                        history=False)
        logger.info("Done!")
    if os.path.isdir(contresimage):
        logger.info("Working on continuum residual image")
        outfile = '{0}.cont.mfs.{1}.imsmooth.residual'.format(field, conttype)
        casa.imsmooth(imagename=contresimage,
                      kernel='gauss',
                      targetres=True,
                      major=bmaj_target,
                      minor=bmin_target,
                      pa=bpa_target,
                      outfile=outfile,
                      overwrite=overwrite)
        casa.exportfits(imagename=outfile,
                        fitsimage='{0}.fits'.format(outfile),
                        overwrite=True,
                        history=False)
        logger.info("Done!")
    # Smooth lines
    for spw in my_line_spws.split(','):
        lineimage = '{0}.spw{1}.channel.{2}.combeam.pbcor'.format(
            field, spw, linetype)
        if os.path.isdir(lineimage):
            logger.info("Working on spw {0}".format(spw))
            outfile = '{0}.spw{1}.channel.{2}.imsmooth.pbcor'.format(
                field, spw, linetype)
            casa.imsmooth(imagename=lineimage,
                          kernel='gauss',
                          targetres=True,
                          major=bmaj_target,
                          minor=bmin_target,
                          pa=bpa_target,
                          outfile=outfile,
                          overwrite=overwrite)
            casa.exportfits(imagename=outfile,
                            fitsimage='{0}.fits'.format(outfile),
                            overwrite=True,
                            history=False,
                            velocity=True)
            logger.info("Done!")
    logger.info("Done!")
コード例 #7
0
def channel_clean_spws(img, spws, spwtype):
    """
    Clean all supplied spws by channel using clean mask from MFS
    images.

    Inputs:
        img :: Imaging object
            The imaging object
        spws :: string
            comma-separated string of spws to image
        spwtype :: string
            'line' or 'cont', to determine which clean params to use

    Returns: Nothing
    """
    #
    # Set channel parameters
    #
    if spwtype == "cont":
        restfreqs = [None for spw in spws]
        start = None
        width = img.cp["contwidth"]
        nchans = [None for spw in spws]
        outframe = img.cp["contoutframe"]
        veltype = None
        interpolation = None
    elif spwtype == "line":
        spw_inds = [
            img.config.get("Spectral Windows", "Line").split(",").index(spw)
            for spw in spws
        ]
        restfreqs = [
            img.config.get("Clean", "restfreqs").split(",")[spw_ind]
            for spw_ind in spw_inds
        ]
        outframe = img.cp["lineoutframe"]
        veltype = img.cp["veltype"]
        interpolation = img.cp["interpolation"]

        # Determine velocity-gridding parameter
        start, width, nchans = grid_parameters(img, spws)
    else:
        img.logger.critical("Error: spwtype {0} not supported".format(spwtype))
        raise ValueError("Invalid spwtype")

    # Loop over spws
    for spw, restfreq, nchan in zip(spws, restfreqs, nchans):
        # Get niters
        if nchan is None:
            # get number of channels from dirty image
            imagename = "{0}.spw{1}.{2}.channel".format(img.imfield, spw, img.stokes)
            if img.uvtaper:
                imagename = imagename + ".uvtaper"
            imagename = os.path.join(img.outdir, imagename)
            imagename = imagename + ".dirty.image.fits"
            if not os.path.exists(imagename):
                raise ValueError(
                    "Must create dirty channel cube first: {0}".format(imagename)
                )
            dirty_hdr = fits.getheader(imagename)
            lightniter = img.cp["lightniter"] * dirty_hdr["NAXIS3"] * len(img.stokes)
            niter = img.cp["maxniter"] * dirty_hdr["NAXIS3"] * len(img.stokes)
        else:
            lightniter = img.cp["lightniter"] * nchan * len(img.stokes)
            niter = img.cp["maxniter"] * nchan * len(img.stokes)

        # If not interactive, Lightly clean spw
        imagename = "{0}.spw{1}.{2}.channel".format(img.imfield, spw, img.stokes)
        if img.uvtaper:
            imagename = imagename + ".uvtaper"
            mask = "{0}.spw{1}.{2}.mfs.uvtaper.mask".format(
                img.imfield, spw, img.stokes
            )
        else:
            mask = "{0}.spw{1}.{2}.mfs.mask".format(img.imfield, spw, img.stokes)
        imagename = os.path.join(img.outdir, imagename)
        mask = os.path.join(img.outdir, mask)
        if not os.path.isdir(mask):
            img.logger.critical("Error: {0} does not exist".format(mask))
            raise ValueError("{0} does not exist".format(mask))
        if not img.interactive:
            img.logger.info(
                "Lightly cleaning spw {0} (restfreq: {1})...".format(spw, restfreq)
            )
            img.logger.info("Using mask: {0}".format(mask))
            casa.tclean(
                vis=img.vis,
                imagename=imagename,
                phasecenter=img.cp["phasecenter"],
                field=img.field,
                spw=spw,
                gridder=img.cp["gridder"],
                wprojplanes=img.cp["wprojplanes"],
                specmode="cube",
                threshold="0mJy",
                niter=lightniter,
                mask=mask,
                deconvolver="multiscale",
                scales=img.cp["scales"],
                gain=img.cp["gain"],
                cyclefactor=img.cp["cyclefactor"],
                imsize=img.cp["imsize"],
                pblimit=-1.0,
                cell=img.cp["cell"],
                weighting=img.cp["weighting"],
                robust=img.cp["robust"],
                restfreq=restfreq,
                start=start,
                width=width,
                nchan=nchan,
                outframe=outframe,
                veltype=veltype,
                interpolation=interpolation,
                uvtaper=img.outertaper,
                uvrange=img.uvrange,
                stokes=img.stokes,
                pbcor=False,
                restart=True,
                calcres=False,
                calcpsf=False,
                parallel=img.parallel,
            )

            # This generates a channel mask, so next clean can't
            # have mfs mask
            mask = ""

            # Get RMS of residuals
            dat = casa.imstat(
                imagename="{0}.residual".format(imagename),
                axes=[0, 1],
                mask="'{0}.mask' == 0".format(imagename),
            )
            img.logger.info(
                "Max un-masked RMS: {0:.2f} mJy/beam".format(
                    1000.0 * np.max(dat["rms"])
                )
            )
            img.logger.info(
                "Max un-masked MAD*1.4826: {0:.2f} mJy/beam".format(
                    1000.0 * 1.4826 * np.max(dat["medabsdevmed"])
                )
            )
            img.logger.info(
                "Using max(MAD) x 1.4826 x {0} as threshold".format(img.cp["nrms"])
            )
            threshold = "{0:.2f}mJy".format(
                img.cp["nrms"] * 1000.0 * 1.4826 * np.max(dat["medabsdevmed"])
            )
        else:
            threshold = "0.0mJy"

        # Deep clean to threshold
        img.logger.info(
            "Cleaning spw {0} (restfreq: {1}) to threshold: {2}...".format(
                spw, restfreq, threshold
            )
        )
        if mask:
            img.logger.info("Using mask: {0}".format(mask))
        casa.tclean(
            vis=img.vis,
            imagename=imagename,
            phasecenter=img.cp["phasecenter"],
            field=img.field,
            spw=spw,
            specmode="cube",
            gridder=img.cp["gridder"],
            wprojplanes=img.cp["wprojplanes"],
            threshold=threshold,
            niter=niter,
            mask=mask,
            deconvolver="multiscale",
            scales=img.cp["scales"],
            gain=img.cp["gain"],
            cyclefactor=img.cp["cyclefactor"],
            imsize=img.cp["imsize"],
            pblimit=-1.0,
            cell=img.cp["cell"],
            weighting=img.cp["weighting"],
            robust=img.cp["robust"],
            restfreq=restfreq,
            start=start,
            width=width,
            nchan=nchan,
            outframe=outframe,
            veltype=veltype,
            interpolation=interpolation,
            uvtaper=img.outertaper,
            uvrange=img.uvrange,
            pbcor=False,
            stokes=img.stokes,
            interactive=img.interactive,
            restart=True,
            calcres=False,
            calcpsf=False,
            parallel=img.parallel,
        )
        img.logger.info("Done.")

        # Primary beam correction
        pbimage = "{0}.pb.image".format(imagename)
        img.logger.info("Performing primary beam correction...")
        if not os.path.exists(pbimage):
            raise ValueError(
                "Could not find {0}. Did you dirty MFS first?".format(pbimage)
            )
        casa.impbcor(
            imagename="{0}.image".format(imagename),
            pbimage=pbimage,
            outfile="{0}.pbcor.image".format(imagename),
            overwrite=True,
        )
        img.logger.info("Done.")

        # Export to fits
        img.logger.info("Exporting fits file...")
        velocity = spwtype == "line"
        casa.exportfits(
            imagename="{0}.image".format(imagename),
            fitsimage="{0}.clean.image.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.mask".format(imagename),
            fitsimage="{0}.clean.mask.fits".format(imagename),
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.residual".format(imagename),
            fitsimage="{0}.clean.residual.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.pbcor.image".format(imagename),
            fitsimage="{0}.clean.pbcor.image.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        img.logger.info("Done.")
コード例 #8
0
def channel_dirty_spws(img, spws, spwtype):
    """
    Dirty image each supplied spectral window (channel cube)

    Inputs:
        img :: Imaging object
            The Imaging object
        spws :: string
            comma-separated string of spws to image
        spwtype :: string
            'line' or 'cont', to determine which clean params to use

    Returns: Nothing
    """
    # Set channel parameters
    if spwtype == "cont":
        restfreqs = [None for spw in spws]
        start = None
        width = img.cp["contwidth"]
        nchans = [None for spw in spws]
        outframe = img.cp["contoutframe"]
        veltype = None
        interpolation = None
    elif spwtype == "line":
        spw_inds = [
            img.config.get("Spectral Windows", "Line").split(",").index(spw)
            for spw in spws
        ]
        restfreqs = [
            img.config.get("Clean", "restfreqs").split(",")[spw_ind]
            for spw_ind in spw_inds
        ]
        outframe = img.cp["lineoutframe"]
        veltype = img.cp["veltype"]
        interpolation = img.cp["interpolation"]

        # Determine velocity-gridding parameter
        start, width, nchans = grid_parameters(img, spws)
    else:
        img.logger.critical("Error: spwtype {0} not supported".format(spwtype))
        raise ValueError("Invalid spwtype")

    # Loop over spws
    for spw, restfreq, nchan in zip(spws, restfreqs, nchans):
        imagename = "{0}.spw{1}.{2}.channel".format(img.imfield, spw, img.stokes)
        if img.uvtaper:
            imagename = imagename + ".uvtaper"
        imagename = os.path.join(img.outdir, imagename)
        img.logger.info(
            "Dirty imaging spw {0} (restfreq: {1})...".format(spw, restfreq)
        )
        casa.tclean(
            vis=img.vis,
            imagename=imagename,
            phasecenter=img.cp["phasecenter"],
            field=img.field,
            spw=spw,
            specmode="cube",
            gridder=img.cp["gridder"],
            wprojplanes=img.cp["wprojplanes"],
            threshold="0mJy",
            niter=0,
            deconvolver="multiscale",
            scales=img.cp["scales"],
            gain=img.cp["gain"],
            cyclefactor=img.cp["cyclefactor"],
            imsize=img.cp["imsize"],
            pblimit=-1.0,
            cell=img.cp["cell"],
            weighting=img.cp["weighting"],
            robust=img.cp["robust"],
            restfreq=restfreq,
            start=start,
            width=width,
            nchan=nchan,
            outframe=outframe,
            veltype=veltype,
            interpolation=interpolation,
            uvtaper=img.outertaper,
            uvrange=img.uvrange,
            stokes=img.stokes,
            pbcor=False,
            parallel=img.parallel,
        )
        img.logger.info("Done.")

        # Generate primary beam image
        img.logger.info(
            "Generating primary beam image of spw {0} (channel)...".format(spw)
        )
        makePB(
            vis=img.vis,
            field=img.field,
            spw=spw,
            uvrange=img.uvrange,
            stokes=img.stokes,
            imtemplate="{0}.image".format(imagename),
            outimage="{0}.pb.image".format(imagename),
            pblimit=img.cp["pblimit"],
        )

        # Primary beam correction
        pbimage = "{0}.pb.image".format(imagename)
        img.logger.info("Performing primary beam correction...")
        if not os.path.exists(pbimage):
            raise ValueError(
                "Could not find {0}. Did you dirty MFS first?".format(pbimage)
            )
        casa.impbcor(
            imagename="{0}.image".format(imagename),
            pbimage=pbimage,
            outfile="{0}.pbcor.image".format(imagename),
            overwrite=True,
        )
        img.logger.info("Done.")

        # Export to fits
        img.logger.info("Exporting fits file...")
        velocity = spwtype == "line"
        casa.exportfits(
            imagename="{0}.pb.image".format(imagename),
            fitsimage="{0}.pb.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.image".format(imagename),
            fitsimage="{0}.dirty.image.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.residual".format(imagename),
            fitsimage="{0}.dirty.residual.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        casa.exportfits(
            imagename="{0}.pbcor.image".format(imagename),
            fitsimage="{0}.dirty.pbcor.image.fits".format(imagename),
            velocity=velocity,
            overwrite=True,
            history=False,
        )
        img.logger.info("Done.")
コード例 #9
0
ファイル: smooth.py プロジェクト: tvwenger/WANA
def smooth_all(field, spws='', stokes='', imagetype='clean',
               mosaic=False, overwrite=False):
    """
    Smooth all line and continuum images/cubes to largest 
    beam size of any individual image/cube.

    Inputs: 
      field :: string
        The field to analyze
      spws :: string
        comma separated string of spws to smooth
      stokes :: string
        The Stokes parameters in the image
      imagetype :: string
        What images to process. For example,
        'dirty', 'clean', 'dirty.uvtaper', or 'clean.uvtaper'
      mosaic :: boolean
        if True, these are mosaic images (.linmos.fits)
      overwrite :: boolean
        if True, overwrite existing images

    Returns: Nothing
    """
    myspws = ['spw{0}'.format(spw) if spw != 'cont' else spw
              for spw in spws.split(',')]
    #
    # Find beam major axes, minor axes, and position angles for all
    # available images
    #
    print("Finding largest synthesized beam")
    bmajs = []
    bmins = []
    # images
    imname = '{0}.{1}.{2}.mfs.{3}.image.fits'
    if mosaic:
        imname = '{0}.{1}.{2}.mfs.{3}.image.linmos.fits'
    images = [imname.format(field, spw, stokes, imagetype)
              for spw in myspws
              if os.path.exists(imname.format(field,spw,stokes,imagetype))]
    # residual images
    resimages = [image.replace('.image.', '.residual.') for image in images]
    # cubes
    imname = '{0}.{1}.{2}.channel.{3}.image.fits'
    if mosaic:
        imname = '{0}.{1}.{2}.channel.{3}.image.linmos.fits'
    cubes = [imname.format(field, spw, stokes, imagetype)
             for spw in myspws
             if os.path.exists(imname.format(field,spw,stokes,imagetype))]
    # residual cubes
    rescubes = [image.replace('.image.', '.residual.') for image in cubes]
    for imagename, resimagename in zip(images+cubes, resimages+rescubes):
        with fits.open(imagename) as imhdulist:
            bunit = imhdulist[0].header['BUNIT']
            if len(imhdulist) > 1:
                bmaj = imhdulist[1].data['BMAJ'][0] # arcsec
                bmin = imhdulist[1].data['BMIN'][0] # arcsec
                bpa = imhdulist[1].data['BPA'][0]
            else:
                bmaj = imhdulist[0].header['BMAJ'] * 3600. # arcsec
                bmin = imhdulist[0].header['BMIN'] * 3600. # arcsec
                bpa = imhdulist[0].header['BPA']
            # check that residual images have beams and units
            with fits.open(resimagename, 'update') as reshdulist:
                if 'BMIN' not in reshdulist[0].header:
                    reshdulist[0].header['BMIN'] = bmin/3600. # deg
                    reshdulist[0].header['BMAJ'] = bmaj/3600. # deg
                    reshdulist[0].header['BPA'] = bpa
                if not reshdulist[0].header['BUNIT']:
                    reshdulist[0].header['BUNIT'] = bunit
            # check that residual images have units
            # append
            bmajs.append(bmaj)
            bmins.append(bmin)
    #
    # Smooth available images to maximum (circular) beam size
    # + pixel diagonal size (otherwise imsmooth will complain)
    #
    cell_size = abs(casa.imhead(imagename)['incr'][0]) * 206265.
    bmaj_target = np.max(bmajs)+1.42*cell_size
    bmin_target = np.max(bmajs)+1.42*cell_size
    bpa_target = 0.
    print("Smoothing all images to")
    print("Major axis: {0:.2f} arcsec".format(bmaj_target))
    print("Minor axis: {0:.2f} arcsec".format(bmin_target))
    print("Position angle: {0:.2f} degs".format(bpa_target))
    bmaj_target = {'unit':'arcsec','value':bmaj_target}
    bmin_target = {'unit':'arcsec','value':bmin_target}
    bpa_target = {'unit':'deg','value':bpa_target}
    for imagename, resimagename in zip(images+cubes, resimages+rescubes):
        # export velocity axis if this is a cube
        velocity = 'channel' in imagename
        # smooth image
        outfile = imagename.replace('.image.fits','.imsmooth.image')
        if mosaic:
            outfile = imagename.replace('.image.linmos.fits', '.imsmooth.image.linmos')
        casa.imsmooth(imagename=imagename,kernel='gauss',
                      targetres=True,major=bmaj_target,minor=bmin_target,
                      pa=bpa_target,outfile=outfile,overwrite=overwrite)
        casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                        velocity=velocity,overwrite=True,history=False)
        # primary beam correct
        if not mosaic:
            smoimagename = outfile
            pbimage = imagename.replace('.{0}.image.fits'.format(imagetype), '.pb.fits')
            outfile = imagename.replace('.image.fits', '.pbcor.imsmooth.image')
            casa.impbcor(imagename=smoimagename, pbimage=pbimage,
                        outfile=outfile, overwrite=True)
            casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                            velocity=velocity,overwrite=True,history=False)
        # check that residual image has beam size, if not add it
        with fits.open(resimagename, 'update') as hdulist:
            hdu = hdulist[0]
            if 'BMIN' not in hdu.header:
                hdu.header['BMIN'] = bmin_target['value']/3600.
                hdu.header['BMAJ'] = bmaj_target['value']/3600.
                hdu.header['BPA'] = bpa_target['value']
        # smooth residual image
        outfile = resimagename.replace('.residual.fits','.imsmooth.residual')
        if mosaic:
            outfile = resimagename.replace('.residual.linmos.fits', '.imsmooth.residual.linmos')
        casa.imsmooth(imagename=resimagename,kernel='gauss',
                      targetres=True,major=bmaj_target,minor=bmin_target,
                      pa=bpa_target,outfile=outfile,overwrite=overwrite)
        casa.exportfits(imagename=outfile,fitsimage='{0}.fits'.format(outfile),
                        velocity=velocity,overwrite=True,history=False)
    print("Done!")