Beispiel #1
0
# Import required tools/tasks
from casatools import simulator, image, table, coordsys, measures, componentlist, quanta, ctsys, ms
from casatasks.private import simutil

from IPython.display import Markdown as md

# Instantiate all the required tools
sm = simulator()
ia = image()
tb = table()
cs = coordsys()
me = measures()
qa = quanta()
cl = componentlist()
mysu = simutil.simutil()
myms = ms()

import warnings
warnings.simplefilter("ignore", category=RuntimeWarning)


def plotData(msname='sim_data.ms', myplot='uv'):
    """
    Options : myplot='uv'
              myplot='data_spectrum'
              myplot='data_time'
    """
    from matplotlib.collections import LineCollection
    tb.open(msname)
Beispiel #2
0
def get_sim_model(calms,
                  model_images,
                  freqs,
                  fwidths,
                  pa=0.0,
                  indirection='',
                  del_cross=False,
                  residuals=True):
    '''
    Function that simulates a radiointerferometric observation out of a
    model fits image. It will produce the visibilities of the model using
    the same uv coverage as the provided calibrated visibilities. It needs
    to simulate a model image for each spw of the observations. The visibilities
    will be averaged in time (limited by scans) and frequency (limited by spws).
    The calibrated visibilities should already be splitted, with no other
    sources, and with the calibrated data in the 'data' datacolumn.

    INPUT parameters:
    - calms: calibrated (observed) visibilities.
    - model_images: list of model images at different frequencies, in fits
    format. These frequencies should be the central frequencies of the spws in
    the observations. They need to be in the same order, so first check the
    listobs of the observations. It has to be a list, even if you are simulating
    just one frequency.
    - freqs: list of central frequencies of the spws and model_images. It has to
    be a list, even if you are simulating just one frequency. In GHz.
    - fwidths: width of the spws of the observations. It can be a list with an
    element for each spw (freqs), or it can be just one value, and it will be
    assumed that all spws have the same width. In MHz.
    OPTIONAL parameters:
    - pa: position angle of the disk (from north to east). Provide it just if
    the disk needs to be rotated (DIAD images need to be rotated).
    - indirection: coordinates of the center of the model image. If not
    provided, it will look for this information in the header of the fits files.
    - residuals: Calculate residual visibilities (observation - model)?
    - del_cross: If True, it will delete cross polarizations. Usually only used
    for VLA observations, not for ALMA.
    OUTPUT:
    A vis_obj object with the visiblities in it.
    It will also create a simulated measurement set.

    NOTE:
    For now, calms needs to have only one channel per spw.
    '''
    if len(model_images) != len(freqs):
        raise IOError(
            'GET_SIM_MODEL: Number of frequencies should be the same' +
            ' as the number of input model images.')
    # We get the spectral windows of calms
    # ms.open(calms)
    # ms.selectinit(reset=True)
    # ms.selectinit()
    # axis_info = ms.getspectralwindowinfo()
    # ms.close()
    tb.open(calms)
    spwids = np.unique(tb.getcol("DATA_DESC_ID"))
    tb.close()
    # Get the frequency information
    tb.open(calms + '/SPECTRAL_WINDOW')
    freqstb = tb.getcol("CHAN_FREQ")
    tb.close()

    obs_spwids = []
    RefFreqs = []
    for key in spwids:
        obs_spwids.append(int(key))
        # RefFreqs.append(round(axis_info[key]['RefFreq']/1e9,3)) # in GHz
        RefFreqs.append(round(freqstb[:, key] / 1e9, 6))  # in GHz
    obs_spwids = np.array(obs_spwids)
    RefFreqs = np.array(RefFreqs)

    mydat = []
    if residuals:
        resdat = []
    spwids = []
    for freqid, freq0 in enumerate(freqs):
        freq0 = round(freq0,
                      6)  # we round the frequency to have 6 decimal digits
        freq = str(freq0) + 'GHz'
        fitsimage = model_images[freqid]
        if type(fwidths) is list:
            widthf = str(fwidths[freqid]) + 'MHz'
        else:
            widthf = str(fwidths) + 'MHz'
        # We find the spwid for this frequency
        try:
            spwid = obs_spwids[RefFreqs == freq0][0]
            spwids.append(spwid)
        except:
            raise ValueError(
                'GET_SIM_MODEL: Frequency ' + freq + ' is not one of ' +
                'the reference frequencies of calms. It could be a rounding issue.'
            )

        # Rotating image
        imObj = pyfits.open(fitsimage)
        Header = imObj[0].header  # we keep the header
        mod_image = imObj[0].data[:, :]  # image in matrix
        imObj.close()
        if pa != 0.0:
            rotangle = -(pa)
            rotdisk = scipy.ndimage.interpolation.rotate(mod_image,
                                                         rotangle,
                                                         reshape=False)
            fitsimage = fitsimage[:-4] + 'rot.fits'  # Name of rotated image
            rotImObj = pyfits.writeto(fitsimage, rotdisk, Header, clobber=True)

        # We get the inbright and pixel size
        stats = imstat(fitsimage)
        if 'CUNIT1' in Header.keys():
            if Header['CUNIT1'] == 'deg':
                delt = Header['CDELT1'] * np.pi / 180.  # to radians
            elif Header['CUNIT1'] == 'rad':
                delt = Header['CDELT1']
            else:
                raise IOError('GET_SIM_MODEL: Potentially weird coordinate ' +
                              'units. Please use deg or rad.')
        else:
            print('WARNING: Assuming units of model coordinates are deg.')
            delt = Header['CDELT1'] * np.pi / 180.  # to radians

        if 'BUNIT' in Header.keys():
            if Header['BUNIT'] == 'Jy/pixel':
                inbright = str(stats['max'][0]) + 'Jy/pixel'
            elif Header['BUNIT'] == 'W.m-2.pixel-1':  # MCFOST format, nu*Fnu
                inbright = stats['max'][0] / (freq0 * 1e9) / 1e-26  # to Jy
                inbright = str(inbright) + 'Jy/pixel'
            elif Header['BUNIT'] == 'erg/s/cm2/Hz':
                inbright = str(stats['max'][0] *
                               (delt**2.) * 1.0e23) + 'Jy/pixel'
            else:
                raise IOError(
                    'GET_SIM_MODEL: Potentially weird intensity ' +
                    'units. Please use Jy/pixel, W.m-2.pixel-1, or erg/s/cm2/Hz.'
                )
        else:
            print('WARNING: Assuming units of model are erg s-1 cm-2 Hz-1.')
            inbright = str(stats['max'][0] * (delt**2.) * 1.0e23) + 'Jy/pixel'
        delta = np.abs(delt) * 180. / np.pi * 3600.  # to arcsec

        # We import the image into CASA format
        imname0 = fitsimage[:-4] + 'image'
        importfits(fitsimage=fitsimage,
                   imagename=imname0,
                   overwrite=True,
                   defaultaxes=False)
        # os.system('rm '+fitsimage)

        # We modify the image to include the stokes and frequency axis.
        util = simutil()
        imname = fitsimage[:-4] + 'fixed.image'
        util.modifymodel(inimage=imname0,
                         outimage=imname,
                         inbright=inbright,
                         indirection=indirection,
                         incell=str(delta) + 'arcsec',
                         incenter=freq,
                         inwidth=widthf,
                         innchan=1)
        os.system('rm -r ' + imname0)

        # We split the calibrated visibilities in spw
        modelms = fitsimage[:-4] + 'model_vis.spw' + str(
            spwid) + 'freq' + freq + '.ms'
        if os.path.isdir(modelms) == False:
            split(vis=calms,
                  outputvis=modelms,
                  spw=str(spwid),
                  keepflags=False,
                  datacolumn='data')
            # We remove the pointing table
            tb.open(modelms + '/POINTING', nomodify=False)
            tb.removerows(range(tb.nrows()))
            tb.done()
        if residuals:
            residualms = (fitsimage[:-4] + 'model_vis.spw' + str(spwid) +
                          'freq' + freq + '.residuals_ms')
            if os.path.isdir(residualms) == False:
                os.system('cp -r ' + modelms + ' ' + residualms)

        # We simulate the observation
        sm.openfromms(modelms)
        sm.setvp()
        #sm.summary()
        sm.predict(imagename=imname)
        sm.done()
        os.system('rm -r ' + imname)

        # Extract visibilities of the model
        ms.open(modelms, nomodify=(del_cross == False))
        ms.selectinit(reset=True)
        modeldata = ms.getdata(
            ['real', 'imaginary', 'u', 'v', 'weight', 'flag', 'data'])
        if del_cross:
            # If True, we flag the cross polarizations
            modeldata['real'][1, :, :] = modeldata['real'][0, :, :]
            modeldata['real'][2, :, :] = modeldata['real'][0, :, :]
            modeldata['imaginary'][1, :, :] = modeldata['imaginary'][0, :, :]
            modeldata['imaginary'][2, :, :] = modeldata['imaginary'][0, :, :]
            modeldata['data'][1, :, :] = modeldata['data'][0, :, :]
            modeldata['data'][2, :, :] = modeldata['data'][0, :, :]
            modeldata['flag'][1, :, :] = True
            modeldata['flag'][2, :, :] = True
            ms.putdata({'data': modeldata['data']})
        mydat.append(modeldata)
        ms.close()

        # Residuals
        if residuals:
            # Extract visibilities of observations
            ms.open(calms)
            ms.selectinit(reset=True)
            ms.selectinit(datadescid=spwid)
            resdata = ms.getdata(
                ['real', 'imaginary', 'u', 'v', 'weight', 'flag', 'data'])
            ms.close()
            # Subtract model from observations
            resdata['real'] = resdata['real'] - modeldata['real']
            resdata[
                'imaginary'] = resdata['imaginary'] - modeldata['imaginary']
            resdata['data'] = resdata['data'] - modeldata['data']
            if del_cross:
                resdata['flag'][1, :, :] = True
                resdata['flag'][2, :, :] = True
            resdat.append(resdata)
            # Save residuals to ms
            ms.open(residualms, nomodify=False)
            ms.selectinit(reset=True)
            ms.putdata({'data': resdata['data']})
            ms.close()

    model_vis = CASA_vis_obj(mydat,
                             np.array([freqs]).T * 1e9,
                             name='model',
                             spwids=spwids)

    if residuals:
        res_vis = CASA_vis_obj(resdat,
                               np.array([freqs]).T * 1e9,
                               name='residuals',
                               spwids=spwids)
        return model_vis, res_vis
    else:
        return model_vis
Beispiel #3
0
def create_model(snu_ff,
                 nu0,
                 dust_ff_ratio,
                 bandwidth=7.5,
                 startfreq=35.0,
                 offset_position=[0.0, 0.0],
                 direction="J2000 10h00m00.0s -30d00m00.0s",
                 modelname='skymodel_test'):
    '''

    create an ms with a point source with the given spectrum.

    '''

    from casatasks.private import simutil
    u = simutil.simutil()

    from casatools import quanta
    from casatools import componentlist
    from casatools import image
    from casatools import measures

    qa = quanta()
    cl = componentlist()
    me = measures()
    ia = image()

    obs_freq = np.linspace(startfreq, startfreq + bandwidth, 1000)

    ff_spect = calc_ff_spect(snu_ff, nu0, obs_freq)
    dust_spect = calc_dust_spect(snu_ff, nu0, dust_ff_ratio, obs_freq)

    comb_spect = ff_spect + dust_spect

    xx = u.direction_splitter(direction)
    qra = xx[1]
    qdec = xx[2]

    qra1 = qa.add(qra, str(offset_position[0]) + "arcsec")
    qdec1 = qa.add(qdec, str(offset_position[1]) + "arcsec")

    xx1 = xx[0] + " " + qa.formxxx(qra1, format='hms',
                                   prec=3) + " " + qa.formxxx(
                                       qdec1, format='dms', prec=4)

    cl.done()  #close any open component list

    cl.addcomponent(flux=1.0, dir=xx1, shape='point')

    # tabularfreq in Hz
    # tabularflux in Jy
    obs_freq_Hz = obs_freq * 1e9
    cl.setspectrum(which=0,
                   type='tabular',
                   tabularfreqs=obs_freq_Hz,
                   tabularflux=comb_spect)

    filename = modelname + '.cl'
    if os.path.exists(filename):
        shutil.rmtree(filename)
    cl.rename(filename)

    # make a skymodel from the component list since simobserve
    # doesn't handle the component lists with frequency dependence.
    # Don't need header info. can set that in simobserve
    ia.done()

    filename = modelname + ".image"
    if os.path.exists(filename):
        shutil.rmtree(filename)

    ia.fromshape(filename, [300, 300, 1, len(obs_freq)], overwrite=True)
    cs = ia.coordsys()

    cs.setunits(['deg', 'deg', '', 'GHz'])
    cell_rad = qa.convert(qa.quantity("0.1arcsec"), "deg")['value']
    cs.setincrement([-cell_rad, cell_rad], 'direction')

    cs.setreferencepixel(0, type='Spectral')
    cs.setreferencevalue(str(obs_freq[0]) + "GHz", 'Spectral')
    cs.setincrement("%.5fGHz" % np.diff(obs_freq)[0], 'spectral')

    tmp = cs.referencevalue(format='q')
    tmp['quantity']['*1'] = xx[1]
    tmp['quantity']['*2'] = xx[2]
    cs.setreferencevalue(value=tmp)

    ia.setcoordsys(cs.torecord())
    ia.setbrightnessunit("Jy/pixel")
    ia.modify(cl.torecord(), subtract=False)

    ia.done()
    cl.done()
Beispiel #4
0
    float(ra_src.split("h")[0]) +
    (float(ra_src.split("h")[1].split("m")[0]) / 60) +
    (float(ra_src.split("h")[1].split("m")[1][:-1]) / 3600))
hr_angle_src_end = lst_src_end - (
    float(ra_src.split("h")[0]) +
    (float(ra_src.split("h")[1].split("m")[0]) / 60) +
    (float(ra_src.split("h")[1].split("m")[1][:-1]) / 3600))
start_time = str(round(hr_angle_src, 2)) + "h"
stop_time = str(round(hr_angle_src_end, 2)) + "h"

freq_min = str(
    qa.convert(str(freq_centre_src) + 'MHz', 'MHz')['value'] -
    (float(nfft_src) / 2) *
    qa.convert(str(16.0 / nfft_src) + 'MHz', 'MHz')['value']) + 'MHz'
conf_file = 'gbd_src.cfg'
u = simutil.simutil()
xx, yy, zz, diam, padnames, padnames, telescope, posobs = u.readantenna(
    conf_file)
ms_name = 'gbd_src.ms'
sm.open(ms_name)
pos_gmrt = me.observatory('GMRT')
sm.setconfig(telescopename=telescope,
             x=xx,
             y=yy,
             z=zz,
             dishdiameter=diam.tolist(),
             mount='alt-az',
             antname=padnames,
             padname=padnames,
             coordsystem='global',
             referencelocation=pos_gmrt)