示例#1
0
    def test40(self):
        '''cvel2 40: test effect of sign of width parameter: radio velocity mode, width negative'''
        self.setUp_vis_b()
        myvis = vis_b
        os.system('ln -sf ' + myvis + ' myinput.ms')
        mytb.open('myinput.ms/SPECTRAL_WINDOW')
        a = mytb.getcell('CHAN_FREQ')
        c = qa.constants('c')['value']
        mytb.close()

        restf = a[0]
        bv1 = c * (restf - a[3]) / restf
        bv2 = c * (restf - a[4]) / restf
        wv = abs(bv2 - bv1)
        b = numpy.array([a[3], a[4], a[5]])
        rval = cvel2(vis='myinput.ms',
                     outputvis=outfile,
                     mode='velocity',
                     veltype='radio',
                     nchan=3,
                     start=str(bv1) + 'm/s',
                     width="-" + str(wv) + 'm/s',
                     restfreq=str(restf) + 'Hz')
        self.assertNotEqual(rval, False)
        ret = verify_ms(outfile, 1, 3, 0, b)
        self.assertTrue(ret[0], ret[1])
示例#2
0
    def test42(self):
        '''cvel2 42: test effect of sign of width parameter: optical velocity mode, width negative'''
        self.setUp_vis_b()
        myvis = vis_b
        os.system('ln -sf ' + myvis + ' myinput.ms')
        mytb.open('myinput.ms/SPECTRAL_WINDOW')
        a = mytb.getcell('CHAN_FREQ')
        c = qa.constants('c')['value']
        mytb.close()

        restf = a[0]
        bv1 = c * (restf - a[5]) / a[5]
        bv2 = c * (restf - a[4]) / a[4]
        wv = abs(bv2 - bv1 + 1.)
        bv2 = bv1 + wv
        bv3 = bv2 + wv
        a4 = restf / (bv2 / c + 1.)
        a3 = restf / (bv3 / c + 1.)
        b = numpy.array([a3, a4, a[5]])
        rval = cvel2(vis='myinput.ms',
                     outputvis=outfile,
                     mode='velocity',
                     veltype='optical',
                     nchan=3,
                     start=str(bv3) + 'm/s',
                     width='-' + str(wv) + 'm/s',
                     restfreq=str(restf) + 'Hz')
        self.assertNotEqual(rval, False)
        ret = verify_ms(outfile, 1, 3, 0, b)
        self.assertTrue(ret[0], ret[1])
示例#3
0
 def test41(self):
     '''cvel2 41: test effect of sign of width parameter: optical velocity mode, width positive'''
     self.setUp_vis_b()
     myvis = vis_b
     os.system('ln -sf ' + myvis + ' myinput.ms')
     mytb.open('myinput.ms/SPECTRAL_WINDOW')
     a = mytb.getcell('CHAN_FREQ')
     c =  qa.constants('c')['value']
     mytb.close()
     
     restf = a[0] 
     bv1 = c * (restf-a[5])/a[5] 
     bv2 = c * (restf-a[4])/a[4] 
     wv = abs(bv2-bv1+1.)
     bv2 = bv1 + wv
     bv3 = bv2 + wv
     a4 = restf/(bv2/c+1.)        
     a3 = restf/(bv3/c+1.)
     b = numpy.array([a3, a4, a[5]])
     rval = cvel2(
         vis = 'myinput.ms',
         outputvis = outfile,
         mode = 'velocity',
         veltype = 'optical',
         nchan = 3,
         start = str(bv1)+'m/s',
         width=str(wv)+'m/s',
         restfreq=str(restf)+'Hz'
         )
     self.assertNotEqual(rval,False)
     ret = verify_ms(outfile, 1, 3, 0, b)
     self.assertTrue(ret[0],ret[1])
示例#4
0
    def test40(self):
        '''cvel2 40: test effect of sign of width parameter: radio velocity mode, width negative'''
        self.setUp_vis_b()
        myvis = vis_b
        os.system('ln -sf ' + myvis + ' myinput.ms')
        mytb.open('myinput.ms/SPECTRAL_WINDOW')
        a = mytb.getcell('CHAN_FREQ')
        c =  qa.constants('c')['value']
        mytb.close()

        restf = a[0] 
        bv1 = c * (restf-a[3])/restf 
        bv2 = c * (restf-a[4])/restf 
        wv = abs(bv2-bv1)
        b = numpy.array([a[3], a[4], a[5]])
        rval = cvel2(
            vis = 'myinput.ms',
            outputvis = outfile,
            mode = 'velocity',
            veltype = 'radio',
            nchan = 3,
            start = str(bv1)+'m/s',
            width="-"+str(wv)+'m/s',
            restfreq=str(restf)+'Hz'
            )
        self.assertNotEqual(rval,False)
        ret = verify_ms(outfile, 1, 3, 0, b)
        self.assertTrue(ret[0],ret[1])
示例#5
0
            restfreq = None 
        plot_profile_map(image, figfile, pol, spectralaxis, restfreq, title, linecolor, linestyle, linewidth,
                         separatepanel, plotmasked, maskedcolor,
                         showaxislabel, showtick, showticklabel, parsed_size,
                         nx, ny, transparent, plotrange)
    except Exception, e:
        casalog.post('Error: %s'%(str(e)), priority='SEVERE')
        import traceback
        casalog.post(traceback.format_exc(), priority='DEBUG')
        raise e
    finally:
        pass
    
NoData = -32767.0
NoDataThreshold = NoData + 10000.0
LightSpeedQuantity = qa.constants('c')
LightSpeed = qa.convert(LightSpeedQuantity, 'km/s')['value'] # speed of light in km/s
DPIDetail = 130

dsyb = '$^\circ$'
hsyb = ':'
msyb = ':'

def Deg2HMS(x, arrowance):
    # Transform degree to HHMMSS.sss format
    xx = x % 360 + arrowance
    h = int(xx / 15)
    m = int((xx % 15) * 4)
    s = ((xx % 15) * 4 - m) * 60.0
    return (h, m, s)
示例#6
0
def imreg(vis=None,
          ephem=None,
          msinfo=None,
          imagefile=None,
          timerange=None,
          reftime=None,
          fitsfile=None,
          beamfile=None,
          offsetfile=None,
          toTb=None,
          sclfactor=1.0,
          verbose=False,
          p_ang=False,
          overwrite=True,
          usephacenter=True,
          deletehistory=False,
          subregion=[],
          docompress=False):
    ''' 
    main routine to register CASA images
           Required Inputs:
               vis: STRING. CASA measurement set from which the image is derived
               imagefile: STRING or LIST. name of the input CASA image
               timerange: STRING or LIST. timerange used to generate the CASA image, must have the same length as the input images. 
                          Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00~2012/03/03/13:00:00'
           Optional Inputs:
               msinfo: DICTIONARY. CASA MS information, output from read_msinfo. If not provided, generate one from the supplied vis
               ephem: DICTIONARY. solar ephem, output from read_horizons. 
                      If not provided, query JPL Horizons based on time info of the vis (internet connection required)
               fitsfile: STRING or LIST. name of the output registered fits files
               reftime: STRING or LIST. Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00'
               offsetfile: optionally provide an offset with a series of solar x and y offsets with timestamps 
               toTb: Bool. Convert the default Jy/beam to brightness temperature?
               sclfactor: scale the image values up by its value (to compensate VLA 20 dB attenuator)
               verbose: Bool. Show more diagnostic info if True.
               usephacenter: Bool -- if True, correct for the RA and DEC in the ms file based on solar empheris.
                                     Otherwise assume the phasecenter is correctly pointed to the solar disk center
                                     (EOVSA case)
               subregion: Region selection. See 'help par.region' for details.
    Usage:
    >>> from suncasa.utils import helioimage2fits as hf
    >>> hf.imreg(vis='mydata.ms', imagefile='myimage.image', fitsfile='myimage.fits',
                 timerange='2017/08/21/20:21:10~2017/08/21/20:21:18')
    The output fits file is 'myimage.fits'

    History:
    BC (sometime in 2014): function was first wrote, followed by a number of edits by BC and SY
    BC (2019-07-16): Added checks for stokes parameter. Verified that for converting from Jy/beam to brightness temperature,
                     the convention of 2*k_b*T should always be used. I.e., for unpolarized source, stokes I, RR, LL, XX, YY, 
                     etc. in the output CASA images from (t)clean should all have same values of radio intensity 
                     (in Jy/beam) and brightness temperature (in K).

    '''

    if deletehistory:
        ms_clearhistory(vis)

    if not imagefile:
        raise ValueError('Please specify input image')
    if not timerange:
        raise ValueError('Please specify timerange of the input image')
    if type(imagefile) == str:
        imagefile = [imagefile]
    if type(timerange) == str:
        timerange = [timerange]
    if not fitsfile:
        fitsfile = [img + '.fits' for img in imagefile]
    if type(fitsfile) == str:
        fitsfile = [fitsfile]
    nimg = len(imagefile)
    if len(timerange) != nimg:
        raise ValueError(
            'Number of input images does not equal to number of timeranges!')
    if len(fitsfile) != nimg:
        raise ValueError(
            'Number of input images does not equal to number of output fits files!'
        )
    nimg = len(imagefile)
    if verbose:
        print(str(nimg) + ' images to process...')

    if reftime:  # use as reference time to find solar disk RA and DEC to register the image, but not the actual timerange associated with the image
        if type(reftime) == str:
            reftime = [reftime] * nimg
        if len(reftime) != nimg:
            raise ValueError(
                'Number of reference times does not match that of input images!'
            )
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=reftime,
                               usephacenter=usephacenter)
    else:
        # use the supplied timerange to register the image
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=timerange,
                               usephacenter=usephacenter)

    if toTb:
        (bmajs, bmins, bpas, beamunits,
         bpaunits) = getbeam(imagefile=imagefile, beamfile=beamfile)

    for n, img in enumerate(imagefile):
        if verbose:
            print('processing image #' + str(n) + ' ' + img)
        fitsf = fitsfile[n]
        timeran = timerange[n]
        # obtain duration of the image as FITS header exptime
        try:
            [tbg0, tend0] = timeran.split('~')
            tbg_d = qa.getvalue(qa.convert(qa.totime(tbg0), 'd'))[0]
            tend_d = qa.getvalue(qa.convert(qa.totime(tend0), 'd'))[0]
            tdur_s = (tend_d - tbg_d) * 3600. * 24.
            dateobs = qa.time(qa.quantity(tbg_d, 'd'), form='fits', prec=10)[0]
        except:
            print('Error in converting the input timerange: ' + str(timeran) +
                  '. Proceeding to the next image...')
            continue

        hel = helio[n]
        if not os.path.exists(img):
            warnings.warn('{} does not existed!'.format(img))
        else:
            if os.path.exists(fitsf) and not overwrite:
                raise ValueError(
                    'Specified fits file already exists and overwrite is set to False. Aborting...'
                )
            else:
                p0 = hel['p0']
                tb.open(img + '/logtable', nomodify=False)
                nobs = tb.nrows()
                tb.removerows([i + 1 for i in range(nobs - 1)])
                tb.close()
                ia.open(img)
                imr = ia.rotate(pa=str(-p0) + 'deg')
                if subregion is not []:
                    imr = imr.subimage(region=subregion)
                imr.tofits(fitsf, history=False, overwrite=overwrite)
                imr.close()
                imsum = ia.summary()
                ia.close()
                ia.done()

            # construct the standard fits header
            # RA and DEC of the reference pixel crpix1 and crpix2
            (imra, imdec) = (imsum['refval'][0], imsum['refval'][1])
            # find out the difference of the image center to the CASA phase center
            # RA and DEC difference in arcseconds
            ddec = degrees((imdec - hel['dec_fld'])) * 3600.
            dra = degrees((imra - hel['ra_fld']) * cos(hel['dec_fld'])) * 3600.
            # Convert into image heliocentric offsets
            prad = -radians(hel['p0'])
            dx = (-dra) * cos(prad) - ddec * sin(prad)
            dy = (-dra) * sin(prad) + ddec * cos(prad)
            if offsetfile:
                try:
                    offset = np.load(offsetfile)
                except:
                    raise ValueError(
                        'The specified offsetfile does not exist!')
                reftimes_d = offset['reftimes_d']
                xoffs = offset['xoffs']
                yoffs = offset['yoffs']
                timg_d = hel['reftime']
                ind = bisect.bisect_left(reftimes_d, timg_d)
                xoff = xoffs[ind - 1]
                yoff = yoffs[ind - 1]
            else:
                xoff = hel['refx']
                yoff = hel['refy']
            if verbose:
                print(
                    'offset of image phase center to visibility phase center (arcsec): dx={0:.2f}, dy={1:.2f}'
                    .format(dx, dy))
                print(
                    'offset of visibility phase center to solar disk center (arcsec): dx={0:.2f}, dy={1:.2f}'
                    .format(xoff, yoff))
            (crval1, crval2) = (xoff + dx, yoff + dy)
            # update the fits header to heliocentric coordinates

            hdu = pyfits.open(fitsf, mode='update')
            hdu[0].verify('fix')
            header = hdu[0].header
            dshape = hdu[0].data.shape
            ndim = hdu[0].data.ndim
            (cdelt1,
             cdelt2) = (-header['cdelt1'] * 3600., header['cdelt2'] * 3600.
                        )  # Original CDELT1, 2 are for RA and DEC in degrees
            header['cdelt1'] = cdelt1
            header['cdelt2'] = cdelt2
            header['cunit1'] = 'arcsec'
            header['cunit2'] = 'arcsec'
            header['crval1'] = crval1
            header['crval2'] = crval2
            header['ctype1'] = 'HPLN-TAN'
            header['ctype2'] = 'HPLT-TAN'
            header['date-obs'] = dateobs  # begin time of the image
            if not p_ang:
                hel['p0'] = 0
            try:
                # this works for pyfits version of CASA 4.7.0 but not CASA 4.6.0
                if tdur_s:
                    header.set('exptime', tdur_s)
                else:
                    header.set('exptime', 1.)
                header.set('p_angle', hel['p0'])
                header.set('hgln_obs', 0.)
                header.set('rsun_ref', sun.constants.radius.value)
                if sunpyver <= 1:
                    header.set(
                        'dsun_obs',
                        sun.sunearth_distance(Time(dateobs)).to(u.meter).value)
                    header.set(
                        'rsun_obs',
                        sun.solar_semidiameter_angular_size(
                            Time(dateobs)).value)
                    header.set(
                        'hglt_obs',
                        sun.heliographic_solar_center(Time(dateobs))[1].value)
                else:
                    header.set(
                        'dsun_obs',
                        sun.earth_distance(Time(dateobs)).to(u.meter).value)
                    header.set('rsun_obs',
                               sun.angular_radius(Time(dateobs)).value)
                    header.set('hglt_obs', sun.L0(Time(dateobs)).value)
            except:
                # this works for astropy.io.fits
                if tdur_s:
                    header.append(('exptime', tdur_s))
                else:
                    header.append(('exptime', 1.))
                header.append(('p_angle', hel['p0']))
                header.append(('hgln_obs', 0.))
                header.append(('rsun_ref', sun.constants.radius.value))
                if sunpyver <= 1:
                    header.append(
                        ('dsun_obs', sun.sunearth_distance(Time(dateobs)).to(
                            u.meter).value))
                    header.append(('rsun_obs',
                                   sun.solar_semidiameter_angular_size(
                                       Time(dateobs)).value))
                    header.append(('hglt_obs',
                                   sun.heliographic_solar_center(
                                       Time(dateobs))[1].value))
                else:
                    header.append(
                        ('dsun_obs',
                         sun.earth_distance(Time(dateobs)).to(u.meter).value))
                    header.append(
                        ('rsun_obs', sun.angular_radius(Time(dateobs)).value))
                    header.append(('hglt_obs', sun.L0(Time(dateobs)).value))

            # check if stokes parameter exist
            exist_stokes = False
            stokes_mapper = {
                'I': 1,
                'Q': 2,
                'U': 3,
                'V': 4,
                'RR': -1,
                'LL': -2,
                'RL': -3,
                'LR': -4,
                'XX': -5,
                'YY': -6,
                'XY': -7,
                'YX': -8
            }
            if 'CRVAL3' in header.keys():
                if header['CTYPE3'] == 'STOKES':
                    stokenum = header['CRVAL3']
                    exist_stokes = True
            if 'CRVAL4' in header.keys():
                if header['CTYPE4'] == 'STOKES':
                    stokenum = header['CRVAL4']
                    exist_stokes = True
            if exist_stokes:
                if stokenum in stokes_mapper.values():
                    stokesstr = list(stokes_mapper.keys())[list(
                        stokes_mapper.values()).index(stokenum)]
                else:
                    print('Stokes parameter {0:d} not recognized'.format(
                        stokenum))
                if verbose:
                    print('This image is in Stokes ' + stokesstr)
            else:
                print(
                    'STOKES Information does not seem to exist! Assuming Stokes I'
                )
                stokenum = 1

            # intensity units to brightness temperature
            if toTb:
                # get restoring beam info
                bmaj = bmajs[n]
                bmin = bmins[n]
                beamunit = beamunits[n]
                data = hdu[
                    0].data  # remember the data order is reversed due to the FITS convension
                keys = list(header.keys())
                values = list(header.values())
                # which axis is frequency?
                faxis = keys[values.index('FREQ')][-1]
                faxis_ind = ndim - int(faxis)
                # find out the polarization of this image
                k_b = qa.constants('k')['value']
                c_l = qa.constants('c')['value']
                # Always use 2*kb for all polarizations
                const = 2. * k_b / c_l**2
                if header['BUNIT'].lower() == 'jy/beam':
                    header['BUNIT'] = 'K'
                    header['BTYPE'] = 'Brightness Temperature'
                    for i in range(dshape[faxis_ind]):
                        nu = header['CRVAL' +
                                    faxis] + header['CDELT' + faxis] * (
                                        i + 1 - header['CRPIX' + faxis])
                        if header['CUNIT' + faxis] == 'KHz':
                            nu *= 1e3
                        if header['CUNIT' + faxis] == 'MHz':
                            nu *= 1e6
                        if header['CUNIT' + faxis] == 'GHz':
                            nu *= 1e9
                        if len(bmaj) > 1:  # multiple (per-plane) beams
                            bmajtmp = bmaj[i]
                            bmintmp = bmin[i]
                        else:  # one single beam
                            bmajtmp = bmaj[0]
                            bmintmp = bmin[0]
                        if beamunit == 'arcsec':
                            bmaj0 = np.radians(bmajtmp / 3600.)
                            bmin0 = np.radians(bmintmp / 3600.)
                        if beamunit == 'arcmin':
                            bmaj0 = np.radians(bmajtmp / 60.)
                            bmin0 = np.radians(bmintmp / 60.)
                        if beamunit == 'deg':
                            bmaj0 = np.radians(bmajtmp)
                            bmin0 = np.radians(bmintmp)
                        if beamunit == 'rad':
                            bmaj0 = bmajtmp
                            bmin0 = bmintmp
                        beam_area = bmaj0 * bmin0 * np.pi / (4. * log(2.))
                        factor = const * nu**2  # SI unit
                        jy_to_si = 1e-26
                        # print(nu/1e9, beam_area, factor)
                        factor2 = sclfactor
                        # if sclfactor:
                        #     factor2 = 100.
                        if faxis == '3':
                            data[:,
                                 i, :, :] *= jy_to_si / beam_area / factor * factor2
                        if faxis == '4':
                            data[
                                i, :, :, :] *= jy_to_si / beam_area / factor * factor2

            header = fu.headerfix(header)
            hdu.flush()
            hdu.close()

            if ndim - np.count_nonzero(np.array(dshape) == 1) > 3:
                docompress = False
                '''
                    Caveat: only 1D, 2D, or 3D images are currently supported by
                    the astropy fits compression. If a n-dimensional image data array
                    does not have at least n-3 single-dimensional entries,
                    force docompress to be False
                '''

                print(
                    'warning: The fits data contains more than 3 non squeezable dimensions. Skipping fits compression..'
                )
            if docompress:
                fitsftmp = fitsf + ".tmp.fits"
                os.system("mv {} {}".format(fitsf, fitsftmp))
                hdu = pyfits.open(fitsftmp)
                hdu[0].verify('fix')
                header = hdu[0].header
                data = hdu[0].data
                fu.write_compressed_image_fits(fitsf,
                                               data,
                                               header,
                                               compression_type='RICE_1',
                                               quantize_level=4.0)
                os.system("rm -rf {}".format(fitsftmp))
    if deletehistory:
        ms_restorehistory(vis)
    return fitsfile
示例#7
0
def imreg(vis=None, ephem=None, msinfo=None, reftime=None, imagefile=None, fitsfile=None, beamfile=None, \
          offsetfile=None, toTb=None, scl100=None, verbose=False, p_ang = False, overwrite = True, usephacenter=False):
    ia = iatool()
    if not imagefile:
        raise ValueError, 'Please specify input image'
    if not reftime:
        raise ValueError, 'Please specify reference time corresponding to the input image'
    if not fitsfile:
        fitsfile = [img + '.fits' for img in imagefile]
    if len(imagefile) != len(reftime):
        raise ValueError, 'Number of input images does not equal to number of helio coord headers!'
    if len(imagefile) != len(fitsfile):
        raise ValueError, 'Number of input images does not equal to number of output fits files!'
    nimg = len(imagefile)
    if verbose:
        print str(nimg) + ' images to process...'
    helio = ephem_to_helio(vis,
                           ephem=ephem,
                           msinfo=msinfo,
                           reftime=reftime,
                           usephacenter=usephacenter)
    for n, img in enumerate(imagefile):
        if verbose:
            print 'processing image #' + str(n)
        fitsf = fitsfile[n]
        hel = helio[n]
        if not os.path.exists(img):
            raise ValueError, 'Please specify input image'
        if os.path.exists(fitsf) and not overwrite:
            raise ValueError, 'Specified fits file already exists and overwrite is set to False. Aborting...'
        else:
            p0 = hel['p0']
            ia.open(img)
            imr = ia.rotate(pa=str(-p0) + 'deg')
            imr.tofits(fitsf, history=False, overwrite=overwrite)
            imr.close()
            sum = ia.summary()
            ia.close()
        # construct the standard fits header
        # RA and DEC of the reference pixel crpix1 and crpix2
        (imra, imdec) = (sum['refval'][0], sum['refval'][1])
        # find out the difference of the image center to the CASA phase center
        # RA and DEC difference in arcseconds
        ddec = degrees((imdec - hel['dec_fld'])) * 3600.
        dra = degrees((imra - hel['ra_fld']) * cos(hel['dec_fld'])) * 3600.
        # Convert into image heliocentric offsets
        prad = -radians(hel['p0'])
        dx = (-dra) * cos(prad) - ddec * sin(prad)
        dy = (-dra) * sin(prad) + ddec * cos(prad)
        if offsetfile:
            try:
                offset = np.load(offsetfile)
            except:
                raise ValueError, 'The specified offsetfile does not exist!'
            reftimes_d = offset['reftimes_d']
            xoffs = offset['xoffs']
            yoffs = offset['yoffs']
            timg_d = hel['reftime']
            ind = bisect.bisect_left(reftimes_d, timg_d)
            xoff = xoffs[ind - 1]
            yoff = yoffs[ind - 1]
        else:
            xoff = hel['refx']
            yoff = hel['refy']
        if verbose:
            print 'offset of image phase center to visibility phase center (arcsec): ', dx, dy
            print 'offset of visibility phase center to solar disk center (arcsec): ', xoff, yoff
        (crval1, crval2) = (xoff + dx, yoff + dy)
        # update the fits header to heliocentric coordinates

        hdu = pyfits.open(fitsf, mode='update')
        header = hdu[0].header
        (cdelt1,
         cdelt2) = (-header['cdelt1'] * 3600., header['cdelt2'] * 3600.
                    )  # Original CDELT1, 2 are for RA and DEC in degrees
        header['cdelt1'] = cdelt1
        header['cdelt2'] = cdelt2
        header['cunit1'] = 'arcsec'
        header['cunit2'] = 'arcsec'
        header['crval1'] = crval1
        header['crval2'] = crval2
        header['ctype1'] = 'HPLN-TAN'
        header['ctype2'] = 'HPLT-TAN'
        header['date-obs'] = hel['date-obs']  #begin time of the image
        if not p_ang:
            hel['p0'] = 0
        try:
            # this works for pyfits version of CASA 4.7.0 but not CASA 4.6.0
            header.update('exptime', hel['exptime'])
            header.update('p_angle', hel['p0'])
            header.update(
                'dsun_obs',
                sun.sunearth_distance(Time(hel['date-obs'])).to(u.meter).value)
            header.update(
                'rsun_obs',
                sun.solar_semidiameter_angular_size(Time(
                    hel['date-obs'])).value)
            header.update('rsun_ref', sun.constants.radius.value)
            header.update('hgln_obs', 0.)
            header.update(
                'hglt_obs',
                sun.heliographic_solar_center(Time(hel['date-obs']))[1].value)
        except:
            # this works for astropy.io.fits
            header.append(('exptime', hel['exptime']))
            header.append(('p_angle', hel['p0']))
            header.append(
                ('dsun_obs', sun.sunearth_distance(Time(hel['date-obs'])).to(
                    u.meter).value))
            header.append(('rsun_obs',
                           sun.solar_semidiameter_angular_size(
                               Time(hel['date-obs'])).value))
            header.append(('rsun_ref', sun.constants.radius.value))
            header.append(('hgln_obs', 0.))
            header.append(('hglt_obs',
                           sun.heliographic_solar_center(Time(
                               hel['date-obs']))[1].value))

        # header.update('comment', 'Fits header updated to heliocentric coordinates by Bin Chen')

        # update intensity units, i.e. to brightness temperature?
        if toTb:
            # get restoring beam info
            (bmajs, bmins, bpas, beamunits,
             bpaunits) = getbeam(imagefile=imagefile, beamfile=beamfile)
            bmaj = bmajs[n]
            bmin = bmins[n]
            beamunit = beamunits[n]
            data = hdu[
                0].data  # remember the data order is reversed due to the FITS convension
            dim = data.ndim
            sz = data.shape
            keys = header.keys()
            values = header.values()
            # which axis is frequency?
            faxis = keys[values.index('FREQ')][-1]
            faxis_ind = dim - int(faxis)
            if header['BUNIT'].lower() == 'jy/beam':
                header['BUNIT'] = 'K'
                for i in range(sz[faxis_ind]):
                    nu = header['CRVAL' + faxis] + header['CDELT' + faxis] * \
                                                   (i + 1 - header['CRPIX' + faxis])
                    if header['CUNIT' + faxis] == 'KHz':
                        nu *= 1e3
                    if header['CUNIT' + faxis] == 'MHz':
                        nu *= 1e6
                    if header['CUNIT' + faxis] == 'GHz':
                        nu *= 1e9
                    if len(bmaj) > 1:  # multiple (per-plane) beams
                        bmajtmp = bmaj[i]
                        bmintmp = bmin[i]
                    else:  # one single beam
                        bmajtmp = bmaj[0]
                        bmintmp = bmin[0]
                    if beamunit == 'arcsec':
                        bmaj0 = np.radians(bmajtmp / 3600.)
                        bmin0 = np.radians(bmajtmp / 3600.)
                    if beamunit == 'arcmin':
                        bmaj0 = np.radians(bmajtmp / 60.)
                        bmin0 = np.radians(bmintmp / 60.)
                    if beamunit == 'deg':
                        bmaj0 = np.radians(bmajtmp)
                        bmin0 = np.radians(bmintmp)
                    if beamunit == 'rad':
                        bmaj0 = bmajtmp
                        bmin0 = bmintmp
                    beam_area = bmaj0 * bmin0 * np.pi / (4. * log(2.))
                    k_b = qa.constants('k')['value']
                    c_l = qa.constants('c')['value']
                    factor = 2. * k_b * nu**2 / c_l**2  # SI unit
                    jy_to_si = 1e-26
                    # print nu/1e9, beam_area, factor
                    factor2 = 1.
                    if scl100:
                        factor2 = 100.
                    if faxis == '3':
                        data[:,
                             i, :, :] *= jy_to_si / beam_area / factor * factor2
                    if faxis == '4':
                        data[
                            i, :, :, :] *= jy_to_si / beam_area / factor * factor2

        hdu.flush()
        hdu.close()
示例#8
0
def plotcomp(compdict, showplot=True, wantdict=False, symb=',',
             include0amp=False, include0bl=False, blunit='', bl0flux=0.0):

    """
    Given a dict including
    
    {'clist': component list,
     'objname': objname,
     'epoch': epoch,
     'shape': component shape dict, including direction.
     'freqs (GHz)': pl.array of frequencies,
     'antennalist': An array configuration file as used by simdata,
     'savedfig': False or, if specified, the filename to save the plot to,
     'standard': setjy fluxstandard type},

    and symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: ',':  The smallest points I could find,

    make a plot of visibility amplitude vs. baseline length for clist at epoch.

    If antennalist is not found as is, it will look for antennalist in
    os.getenv('CASAPATH').split(' ')[0] + '/data/alma/simmos/'.
    
    showplot: Whether or not to show the plot on screen.

    If wantdict is True, it returns a dictionary with the amplitudes and
    baselines on success.  Otherwise, it returns True or False as its estimated
    success value.

    include0amp: Force the lower limit of the amplitude axis to 0.
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: unit of the baseline length (='' used the unit in the data or klambda)
    bl0flux: Zero baseline flux
    """
    def failval():
        """
        Returns an appropriate failure value.
        Note that mydict.update(plotcomp(wantdict=True, ...)) would give a
        confusing error message if plotcomp returned False.
        """
        retval = False
        if wantdict:
            retval = {}
        return retval
    retval = failval()  # Default
    try:
        clist = compdict['clist']
        objname = compdict['objname']
        epoch = compdict['epoch']
        epstr = mepoch_to_str(epoch)
        antennalist = compdict['antennalist']

        # Read the configuration info.
        if not antennalist:
            print "compdict['antennalist'] must be set!"
            print "Try something in", os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/"
            return failval()
        # Try repodir if raw antennalist doesn't work.
        if not os.path.exists(antennalist):
            repodir = os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/"
            antennalist = repodir + antennalist

        su = simutil("")
        stnx, stny, stnz, diam, padnames, telescopename, obsmeas = su.readantenna(antennalist)
        #print "telescopename:", telescopename

        # Check that the source is up.
        myme = metool()
        posobs = myme.observatory(telescopename)
        #print "posobs:", posobs
        myme.doframe(epoch)
        myme.doframe(posobs)
        azel = myme.measure(compdict['shape']['direction'], 'azel')
        azeldegs = tuple([qa.convert(azel[m], 'deg')['value'] for m in ('m0', 'm1')])
        casalog.post("(az, el): (%.2f, %.2f) degrees" % azeldegs)
        # riseset blabs to the logger, so introduce it now.
        casalog.post('Rise and set times of ' + objname + " from " + telescopename + ':')
        approx = ''
        if 'JPL' in compdict.get('standard', 'JPL'):
            # The object is in the Solar System or not known to be extragalactic.
            approx = "APPROXIMATE.  The times do not account for the apparent motion of "\
                     + objname + "."
            casalog.post("  (" + approx + ")")
        riset = myme.riseset(compdict['shape']['direction'])
        msg = ''
        if riset['rise'] == 'above':
            msg = objname + " is circumpolar"
        elif riset['rise'] == 'below':
            msg = objname + ' is not visible from ' + telescopename
        if msg:
            if approx:
                msg += ' around ' + mepoch_to_str(epoch)
            casalog.post(msg)
        else:
            for t in riset:
                riset[t]['str'] = mepoch_to_str(riset[t]['utc'])
            casalog.post(objname + " rises at %s and sets at %s." % (riset['rise']['str'],
                                                                     riset['set']['str']))
            tmeridian=(riset['rise']['utc']['m0']['value']+riset['set']['utc']['m0']['value'])/2.
            casalog.post(objname + ': meridian passage at ' + qa.time(str(tmeridian)+'d')[0])

        if approx:
            riset['NOTE'] = approx
        if not azel['m1']['value'] > 0.0:
            casalog.post(objname + " is not visible from " + telescopename + " at " + epstr,
                         'SEVERE')
            if wantdict:
                return riset
            else:
                return False

        # Start a temp MS.
        workingdir = os.path.abspath(os.path.dirname(clist.rstrip('/')))
        tempms = tempfile.mkdtemp(prefix=objname, dir=workingdir)

        mysm = smtool()
        mysm.open(tempms)

        su.setcfg(mysm, telescopename, stnx, stny, stnz, diam,
                  padnames, posobs)

        #print "cfg set"

        # Only 1 polarization is wanted for now.
        stokes, feeds = su.polsettings(telescopename, 'RR')
        
        casalog.post("stokes, feeds: %s, %s" % (stokes, feeds))
        fband = su.bandname(compdict['freqs (GHz)'][0])
        chaninc = 1.0
        nchan = len(compdict['freqs (GHz)'])
        if nchan > 1:
            chaninc = (compdict['freqs (GHz)'][-1] - compdict['freqs (GHz)'][0]) / (nchan - 1)
        mysm.setspwindow(spwname=fband,
                         freq=str(compdict['freqs (GHz)'][0]) + 'GHz', 
                         deltafreq=str(chaninc) + 'GHz', 
                         freqresolution='1Hz', 
                         nchannels=nchan, refcode="LSRK",
                         stokes=stokes)
        mysm.setfeed(mode=feeds, pol=[''])
        mysm.setlimits(shadowlimit=0.01, elevationlimit='10deg')
        mysm.setauto(0.0)
        mysm.setfield(sourcename=objname,
                      sourcedirection=compdict['shape']['direction'],
                      calcode="OBJ", distance='0m')
        mysm.settimes(integrationtime="1s", usehourangle=False,
                      referencetime=epoch)
        
        # this only creates blank uv entries
        mysm.observe(sourcename=objname, spwname=fband,
                   starttime="-0.5s", stoptime="0.5s", project=objname)

        mysm.setdata(fieldid=[0])
        mysm.setvp()
        casalog.post("done setting up simulation parameters")

        mysm.predict(complist=clist)        # do actual calculation of visibilities:

        mysm.close()
        casalog.post("Simulation finished.")

        mytb = tbtool()
        mytb.open(tempms)
        data = mytb.getcol('DATA')[0]       # Again, only 1 polarization for now. 
        data = abs(data)
        baselines = mytb.getcol('UVW')[:2,:]  # Drop w.
        datablunit = mytb.getcolkeywords('UVW')['QuantumUnits']
        mytb.close()
        #print "Got the data and baselines"
        shutil.rmtree(tempms)

        if datablunit[1] != datablunit[0]:
            casalog.post('The baseline units are mismatched!: %s' % datablunit,
                         'SEVERE')
            return failval()
        datablunit = datablunit[0]
        # uv dist unit in klambda or m
        if datablunit == 'm' and blunit=='klambda':
            kl = qa.constants('C')['value']/(compdict['freqs (GHz)'][0]*1e6)
            blunit = 'k$\lambda$'
        else:
            blunit = datablunit
            kl = 1.0
        pl.ioff()
        #baselines = pl.hypot(baselines[0]/kl, baselines[1]/kl)
        baselines = pl.hypot(baselines[0], baselines[1])

        #if not showplot:
        #    casalog.post('Sorry, not showing the plot is not yet implemented',
        #                 'WARN')

        if showplot: 
          pl.ion()
        pl.clf()
        pl.ioff() 
        nfreqs = len(compdict['freqs (GHz)'])
        for freqnum in xrange(nfreqs):
            freq = compdict['freqs (GHz)'][freqnum]
            casalog.post("Plotting " + str(freq) + " GHz.")
            pl.plot(baselines/kl, data[freqnum], symb, label="%.3g GHz" % freq)
            #pl.plot(baselines, data[freqnum], symb, label="%.3g GHz" % freq)
        pl.xlabel("Baseline length (" + blunit + ")")
        pl.ylabel("Visibility amplitude (Jy)")
        if include0amp:
            pl.ylim(ymin=0.0)
        if include0bl:
            pl.xlim(xmin=0.0)
        pl.suptitle(objname + " (predicted by %s)" % compdict['standard'], fontsize=14)
        #pl.suptitle(objname + " (predicted)", fontsize=14)

        # Unlike compdict['antennalist'], antennalist might have had repodir
        # prefixed to it.
        pl.title('at ' + epstr + ' for ' + os.path.basename(compdict['antennalist']), fontsize=10)
        titletxt='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs
        # for comparison of old and new models - omit azeldegs as all in az~0
        if bl0flux > 0.0:
            if len(compdict['freqs (GHz)']) == 1:
                titletxt+='\n bl0 flux:%.3f Jy' % bl0flux
            else:
                titletxt+='\n bl0 flux:%.3f Jy @ %s GHz' % (bl0flux, compdict['freqs (GHz)'][0]) 
        pl.legend(loc='best', title=titletxt)
        #pl.legend(loc='best', title='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs)
        y_formatter=matplotlib.ticker.ScalarFormatter(useOffset=False)
        pl.axes().yaxis.set_major_formatter(y_formatter) 
        if showplot:
          pl.ion()
          pl.draw()
        if compdict.get('savedfig'):
            pl.savefig(compdict.get('savedfig'))
            casalog.post("Saved plot to " + str(compdict.get('savedfig')))

        if wantdict:
            retval = {'amps': data,
                      'antennalist': antennalist,  # Absolute path, now.
                      'azel': azel,
                      'baselines': baselines,
                      'blunit': blunit,
                      'riseset': riset,
                      'savedfig': compdict.get('savedfig')}
        else:
            retval = True
    except Exception, instance:
        casalog.post(str(instance), 'SEVERE')
        if os.path.isdir(tempms):
            shutil.rmtree(tempms)
示例#9
0
def imreg(vis=None,
          ephem=None,
          msinfo=None,
          imagefile=None,
          timerange=None,
          reftime=None,
          fitsfile=None,
          beamfile=None,
          offsetfile=None,
          toTb=None,
          scl100=None,
          verbose=False,
          p_ang=False,
          overwrite=True,
          usephacenter=True,
          deletehistory=False):
    ''' 
    main routine to register CASA images
           Required Inputs:
               vis: STRING. CASA measurement set from which the image is derived
               imagefile: STRING or LIST. name of the input CASA image
               timerange: STRING or LIST. timerange used to generate the CASA image, must have the same length as the input images. 
                          Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00~2012/03/03/13:00:00'
           Optional Inputs:
               msinfo: DICTIONARY. CASA MS information, output from read_msinfo. If not provided, generate one from the supplied vis
               ephem: DICTIONARY. solar ephem, output from read_horizons. 
                      If not provided, query JPL Horizons based on time info of the vis (internet connection required)
               fitsfile: STRING or LIST. name of the output registered fits files
               reftime: STRING or LIST. Each element should be in CASA standard time format, e.g., '2012/03/03/12:00:00'
               offsetfile: optionally provide an offset with a series of solar x and y offsets with timestamps 
               toTb: Bool. Convert the default Jy/beam to brightness temperature?
               scl100: Bool. If True, scale the image values up by 100 (to compensate VLA 20 dB attenuator)
               verbose: Bool. Show more diagnostic info if True.
               usephacenter: Bool -- if True, correct for the RA and DEC in the ms file based on solar empheris.
                                     Otherwise assume the phasecenter is correctly pointed to the solar disk center
                                     (EOVSA case)
    '''
    ia = iatool()

    if deletehistory:
        msclearhistory(vis)
    if verbose:
        import time
        t0 = time.time()
        prtidx = 1
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    if not imagefile:
        raise ValueError, 'Please specify input image'
    if not timerange:
        raise ValueError, 'Please specify timerange of the input image'
    if type(imagefile) == str:
        imagefile = [imagefile]
    if type(timerange) == str:
        timerange = [timerange]
    if not fitsfile:
        fitsfile = [img + '.fits' for img in imagefile]
    if type(fitsfile) == str:
        fitsfile = [fitsfile]
    nimg = len(imagefile)
    if len(timerange) != nimg:
        raise ValueError, 'Number of input images does not equal to number of timeranges!'
    if len(fitsfile) != nimg:
        raise ValueError, 'Number of input images does not equal to number of output fits files!'
    nimg = len(imagefile)
    if verbose:
        print str(nimg) + ' images to process...'

    if verbose:
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    if reftime:  # use as reference time to find solar disk RA and DEC to register the image, but not the actual timerange associated with the image
        if type(reftime) == str:
            reftime = [reftime] * nimg
        if len(reftime) != nimg:
            raise ValueError, 'Number of reference times does not match that of input images!'
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=reftime,
                               usephacenter=usephacenter)
    else:
        # use the supplied timerange to register the image
        helio = ephem_to_helio(vis,
                               ephem=ephem,
                               msinfo=msinfo,
                               reftime=timerange,
                               usephacenter=usephacenter)

    if verbose:
        print('point {}: {}'.format(prtidx, time.time() - t0))
        prtidx += 1

    for n, img in enumerate(imagefile):
        if verbose:
            print 'processing image #' + str(n)
        fitsf = fitsfile[n]
        timeran = timerange[n]
        # obtain duration of the image as FITS header exptime
        try:
            [tbg0, tend0] = timeran.split('~')
            tbg_d = qa.getvalue(qa.convert(qa.totime(tbg0), 'd'))[0]
            tend_d = qa.getvalue(qa.convert(qa.totime(tend0), 'd'))[0]
            tdur_s = (tend_d - tbg_d) * 3600. * 24.
            dateobs = qa.time(qa.quantity(tbg_d, 'd'), form='fits', prec=10)[0]
        except:
            print 'Error in converting the input timerange: ' + str(
                timeran) + '. Proceeding to the next image...'
            continue

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hel = helio[n]
        if not os.path.exists(img):
            raise ValueError, 'Please specify input image'
        if os.path.exists(fitsf) and not overwrite:
            raise ValueError, 'Specified fits file already exists and overwrite is set to False. Aborting...'
        else:
            p0 = hel['p0']
            ia.open(img)
            imr = ia.rotate(pa=str(-p0) + 'deg')
            imr.tofits(fitsf, history=False, overwrite=overwrite)
            imr.close()
            imsum = ia.summary()
            ia.close()

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        # construct the standard fits header
        # RA and DEC of the reference pixel crpix1 and crpix2
        (imra, imdec) = (imsum['refval'][0], imsum['refval'][1])
        # find out the difference of the image center to the CASA phase center
        # RA and DEC difference in arcseconds
        ddec = degrees((imdec - hel['dec_fld'])) * 3600.
        dra = degrees((imra - hel['ra_fld']) * cos(hel['dec_fld'])) * 3600.
        # Convert into image heliocentric offsets
        prad = -radians(hel['p0'])
        dx = (-dra) * cos(prad) - ddec * sin(prad)
        dy = (-dra) * sin(prad) + ddec * cos(prad)
        if offsetfile:
            try:
                offset = np.load(offsetfile)
            except:
                raise ValueError, 'The specified offsetfile does not exist!'
            reftimes_d = offset['reftimes_d']
            xoffs = offset['xoffs']
            yoffs = offset['yoffs']
            timg_d = hel['reftime']
            ind = bisect.bisect_left(reftimes_d, timg_d)
            xoff = xoffs[ind - 1]
            yoff = yoffs[ind - 1]
        else:
            xoff = hel['refx']
            yoff = hel['refy']
        if verbose:
            print 'offset of image phase center to visibility phase center (arcsec): ', dx, dy
            print 'offset of visibility phase center to solar disk center (arcsec): ', xoff, yoff
        (crval1, crval2) = (xoff + dx, yoff + dy)
        # update the fits header to heliocentric coordinates

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hdu = pyfits.open(fitsf, mode='update')

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        header = hdu[0].header
        (cdelt1,
         cdelt2) = (-header['cdelt1'] * 3600., header['cdelt2'] * 3600.
                    )  # Original CDELT1, 2 are for RA and DEC in degrees
        header['cdelt1'] = cdelt1
        header['cdelt2'] = cdelt2
        header['cunit1'] = 'arcsec'
        header['cunit2'] = 'arcsec'
        header['crval1'] = crval1
        header['crval2'] = crval2
        header['ctype1'] = 'HPLN-TAN'
        header['ctype2'] = 'HPLT-TAN'
        header['date-obs'] = dateobs  # begin time of the image
        if not p_ang:
            hel['p0'] = 0
        try:
            # this works for pyfits version of CASA 4.7.0 but not CASA 4.6.0
            if tdur_s:
                header.set('exptime', tdur_s)
            else:
                header.set('exptime', 1.)
            header.set('p_angle', hel['p0'])
            header.set('dsun_obs',
                       sun.sunearth_distance(Time(dateobs)).to(u.meter).value)
            header.set(
                'rsun_obs',
                sun.solar_semidiameter_angular_size(Time(dateobs)).value)
            header.set('rsun_ref', sun.constants.radius.value)
            header.set('hgln_obs', 0.)
            header.set('hglt_obs',
                       sun.heliographic_solar_center(Time(dateobs))[1].value)
        except:
            # this works for astropy.io.fits
            if tdur_s:
                header.append(('exptime', tdur_s))
            else:
                header.append(('exptime', 1.))
            header.append(('p_angle', hel['p0']))
            header.append(
                ('dsun_obs',
                 sun.sunearth_distance(Time(dateobs)).to(u.meter).value))
            header.append(
                ('rsun_obs',
                 sun.solar_semidiameter_angular_size(Time(dateobs)).value))
            header.append(('rsun_ref', sun.constants.radius.value))
            header.append(('hgln_obs', 0.))
            header.append(
                ('hglt_obs',
                 sun.heliographic_solar_center(Time(dateobs))[1].value))

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        # update intensity units, i.e. to brightness temperature?
        if toTb:
            # get restoring beam info
            (bmajs, bmins, bpas, beamunits,
             bpaunits) = getbeam(imagefile=imagefile, beamfile=beamfile)
            bmaj = bmajs[n]
            bmin = bmins[n]
            beamunit = beamunits[n]
            data = hdu[
                0].data  # remember the data order is reversed due to the FITS convension
            dim = data.ndim
            sz = data.shape
            keys = header.keys()
            values = header.values()
            # which axis is frequency?
            faxis = keys[values.index('FREQ')][-1]
            faxis_ind = dim - int(faxis)
            if header['BUNIT'].lower() == 'jy/beam':
                header['BUNIT'] = 'K'
                header['BTYPE'] = 'Brightness Temperature'
                for i in range(sz[faxis_ind]):
                    nu = header['CRVAL' + faxis] + header['CDELT' + faxis] * (
                        i + 1 - header['CRPIX' + faxis])
                    if header['CUNIT' + faxis] == 'KHz':
                        nu *= 1e3
                    if header['CUNIT' + faxis] == 'MHz':
                        nu *= 1e6
                    if header['CUNIT' + faxis] == 'GHz':
                        nu *= 1e9
                    if len(bmaj) > 1:  # multiple (per-plane) beams
                        bmajtmp = bmaj[i]
                        bmintmp = bmin[i]
                    else:  # one single beam
                        bmajtmp = bmaj[0]
                        bmintmp = bmin[0]
                    if beamunit == 'arcsec':
                        bmaj0 = np.radians(bmajtmp / 3600.)
                        bmin0 = np.radians(bmajtmp / 3600.)
                    if beamunit == 'arcmin':
                        bmaj0 = np.radians(bmajtmp / 60.)
                        bmin0 = np.radians(bmintmp / 60.)
                    if beamunit == 'deg':
                        bmaj0 = np.radians(bmajtmp)
                        bmin0 = np.radians(bmintmp)
                    if beamunit == 'rad':
                        bmaj0 = bmajtmp
                        bmin0 = bmintmp
                    beam_area = bmaj0 * bmin0 * np.pi / (4. * log(2.))
                    k_b = qa.constants('k')['value']
                    c_l = qa.constants('c')['value']
                    factor = 2. * k_b * nu**2 / c_l**2  # SI unit
                    jy_to_si = 1e-26
                    # print nu/1e9, beam_area, factor
                    factor2 = 1.
                    if scl100:
                        factor2 = 100.
                    if faxis == '3':
                        data[:,
                             i, :, :] *= jy_to_si / beam_area / factor * factor2
                    if faxis == '4':
                        data[
                            i, :, :, :] *= jy_to_si / beam_area / factor * factor2

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1

        hdu.flush()
        hdu.close()

        if verbose:
            print('point {}: {}'.format(prtidx, time.time() - t0))
            prtidx += 1
示例#10
0
def plotcomp(compdict, showplot=True, wantdict=False, symb=',',
             include0amp=False, include0bl=False, blunit='', bl0flux=0.0):

    """
    Given a dict including
    
    {'clist': component list,
     'objname': objname,
     'epoch': epoch,
     'shape': component shape dict, including direction.
     'freqs (GHz)': pl.array of frequencies,
     'antennalist': An array configuration file as used by simdata,
     'savedfig': False or, if specified, the filename to save the plot to,
     'standard': setjy fluxstandard type},

    and symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: ',':  The smallest points I could find,

    make a plot of visibility amplitude vs. baseline length for clist at epoch.

    If antennalist is not found as is, it will look for antennalist in
    os.getenv('CASAPATH').split(' ')[0] + '/data/alma/simmos/'.
    
    showplot: Whether or not to show the plot on screen.

    If wantdict is True, it returns a dictionary with the amplitudes and
    baselines on success.  Otherwise, it returns True or False as its estimated
    success value.

    include0amp: Force the lower limit of the amplitude axis to 0.
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: unit of the baseline length (='' used the unit in the data or klambda)
    bl0flux: Zero baseline flux
    """
    def failval():
        """
        Returns an appropriate failure value.
        Note that mydict.update(plotcomp(wantdict=True, ...)) would give a
        confusing error message if plotcomp returned False.
        """
        retval = False
        if wantdict:
            retval = {}
        return retval
    retval = failval()  # Default
    try:
        clist = compdict['clist']
        objname = compdict['objname']
        epoch = compdict['epoch']
        epstr = mepoch_to_str(epoch)
        antennalist = compdict['antennalist']

        # Read the configuration info.
        if not antennalist:
            print "compdict['antennalist'] must be set!"
            print "Try something in", os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/"
            return failval()
        # Try repodir if raw antennalist doesn't work.
        if not os.path.exists(antennalist):
            repodir = os.getenv("CASAPATH").split(' ')[0] + "/data/alma/simmos/"
            antennalist = repodir + antennalist

        su = simutil("")
        stnx, stny, stnz, diam, padnames, nant, telescopename = su.readantenna(antennalist)
        #print "telescopename:", telescopename

        # Check that the source is up.
        myme = metool()
        posobs = myme.observatory(telescopename)
        #print "posobs:", posobs
        myme.doframe(epoch)
        myme.doframe(posobs)
        azel = myme.measure(compdict['shape']['direction'], 'azel')
        azeldegs = tuple([qa.convert(azel[m], 'deg')['value'] for m in ('m0', 'm1')])
        casalog.post("(az, el): (%.2f, %.2f) degrees" % azeldegs)
        # riseset blabs to the logger, so introduce it now.
        casalog.post('Rise and set times of ' + objname + " from " + telescopename + ':')
        approx = ''
        if 'JPL' in compdict.get('standard', 'JPL'):
            # The object is in the Solar System or not known to be extragalactic.
            approx = "APPROXIMATE.  The times do not account for the apparent motion of "\
                     + objname + "."
            casalog.post("  (" + approx + ")")
        riset = myme.riseset(compdict['shape']['direction'])
        msg = ''
        if riset['rise'] == 'above':
            msg = objname + " is circumpolar"
        elif riset['rise'] == 'below':
            msg = objname + ' is not visible from ' + telescopename
        if msg:
            if approx:
                msg += ' around ' + mepoch_to_str(epoch)
            casalog.post(msg)
        else:
            for t in riset:
                riset[t]['str'] = mepoch_to_str(riset[t]['utc'])
            casalog.post(objname + " rises at %s and sets at %s." % (riset['rise']['str'],
                                                                     riset['set']['str']))
            tmeridian=(riset['rise']['utc']['m0']['value']+riset['set']['utc']['m0']['value'])/2.
            casalog.post(objname + ': meridian passage at ' + qa.time(str(tmeridian)+'d')[0])

        if approx:
            riset['NOTE'] = approx
        if not azel['m1']['value'] > 0.0:
            casalog.post(objname + " is not visible from " + telescopename + " at " + epstr,
                         'SEVERE')
            if wantdict:
                return riset
            else:
                return False

        # Start a temp MS.
        workingdir = os.path.abspath(os.path.dirname(clist.rstrip('/')))
        tempms = tempfile.mkdtemp(prefix=objname, dir=workingdir)

        mysm = smtool()
        mysm.open(tempms)

        su.setcfg(mysm, telescopename, stnx, stny, stnz, diam,
                  padnames, posobs)

        #print "cfg set"

        # Only 1 polarization is wanted for now.
        stokes, feeds = su.polsettings(telescopename, 'RR')
        
        casalog.post("stokes, feeds: %s, %s" % (stokes, feeds))
        fband = su.bandname(compdict['freqs (GHz)'][0])
        chaninc = 1.0
        nchan = len(compdict['freqs (GHz)'])
        if nchan > 1:
            chaninc = (compdict['freqs (GHz)'][-1] - compdict['freqs (GHz)'][0]) / (nchan - 1)
        mysm.setspwindow(spwname=fband,
                         freq=str(compdict['freqs (GHz)'][0]) + 'GHz', 
                         deltafreq=str(chaninc) + 'GHz', 
                         freqresolution='1Hz', 
                         nchannels=nchan, refcode="LSRK",
                         stokes=stokes)
        mysm.setfeed(mode=feeds, pol=[''])
        mysm.setlimits(shadowlimit=0.01, elevationlimit='10deg')
        mysm.setauto(0.0)
        mysm.setfield(sourcename=objname,
                      sourcedirection=compdict['shape']['direction'],
                      calcode="OBJ", distance='0m')
        mysm.settimes(integrationtime="1s", usehourangle=False,
                      referencetime=epoch)
        
        # this only creates blank uv entries
        mysm.observe(sourcename=objname, spwname=fband,
                   starttime="-0.5s", stoptime="0.5s", project=objname)

        mysm.setdata(fieldid=[0])
        mysm.setvp()
        casalog.post("done setting up simulation parameters")

        mysm.predict(complist=clist)        # do actual calculation of visibilities:

        mysm.close()
        casalog.post("Simulation finished.")

        mytb = tbtool()
        mytb.open(tempms)
        data = mytb.getcol('DATA')[0]       # Again, only 1 polarization for now. 
        data = abs(data)
        baselines = mytb.getcol('UVW')[:2,:]  # Drop w.
        datablunit = mytb.getcolkeywords('UVW')['QuantumUnits']
        mytb.close()
        #print "Got the data and baselines"
        shutil.rmtree(tempms)

        if datablunit[1] != datablunit[0]:
            casalog.post('The baseline units are mismatched!: %s' % datablunit,
                         'SEVERE')
            return failval()
        datablunit = datablunit[0]
        # uv dist unit in klambda or m
        if datablunit == 'm' and blunit=='klambda':
            kl = qa.constants('C')['value']/(compdict['freqs (GHz)'][0]*1e6)
            blunit = 'k$\lambda$'
        else:
            blunit = datablunit
            kl = 1.0
        pl.ioff()
        #baselines = pl.hypot(baselines[0]/kl, baselines[1]/kl)
        baselines = pl.hypot(baselines[0], baselines[1])

        #if not showplot:
        #    casalog.post('Sorry, not showing the plot is not yet implemented',
        #                 'WARN')

        if showplot: 
          pl.ion()
        pl.clf()
        pl.ioff() 
        nfreqs = len(compdict['freqs (GHz)'])
        for freqnum in xrange(nfreqs):
            freq = compdict['freqs (GHz)'][freqnum]
            casalog.post("Plotting " + str(freq) + " GHz.")
            pl.plot(baselines/kl, data[freqnum], symb, label="%.3g GHz" % freq)
            #pl.plot(baselines, data[freqnum], symb, label="%.3g GHz" % freq)
        pl.xlabel("Baseline length (" + blunit + ")")
        pl.ylabel("Visibility amplitude (Jy)")
        if include0amp:
            pl.ylim(ymin=0.0)
        if include0bl:
            pl.xlim(xmin=0.0)
        pl.suptitle(objname + " (predicted by %s)" % compdict['standard'], fontsize=14)
        #pl.suptitle(objname + " (predicted)", fontsize=14)

        # Unlike compdict['antennalist'], antennalist might have had repodir
        # prefixed to it.
        pl.title('at ' + epstr + ' for ' + os.path.basename(compdict['antennalist']), fontsize=10)
        titletxt='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs
        # for comparison of old and new models - omit azeldegs as all in az~0
        if bl0flux > 0.0:
            if len(compdict['freqs (GHz)']) == 1:
                titletxt+='\n bl0 flux:%.3f Jy' % bl0flux
            else:
                titletxt+='\n bl0 flux:%.3f Jy @ %s GHz' % (bl0flux, compdict['freqs (GHz)'][0]) 
        pl.legend(loc='best', title=titletxt)
        #pl.legend(loc='best', title='($%.0f^\circ$ az, $%.0f^\circ$ el)' % azeldegs)
        y_formatter=matplotlib.ticker.ScalarFormatter(useOffset=False)
        pl.axes().yaxis.set_major_formatter(y_formatter) 
        if showplot:
          pl.ion()
          pl.draw()
        if compdict.get('savedfig'):
            pl.savefig(compdict.get('savedfig'))
            casalog.post("Saved plot to " + str(compdict.get('savedfig')))

        if wantdict:
            retval = {'amps': data,
                      'antennalist': antennalist,  # Absolute path, now.
                      'azel': azel,
                      'baselines': baselines,
                      'blunit': blunit,
                      'riseset': riset,
                      'savedfig': compdict.get('savedfig')}
        else:
            retval = True
    except Exception, instance:
        casalog.post(str(instance), 'SEVERE')
        if os.path.isdir(tempms):
            shutil.rmtree(tempms)
示例#11
0
                         linecolor, linestyle, linewidth, separatepanel,
                         plotmasked, maskedcolor, showaxislabel, showtick,
                         showticklabel, parsed_size, nx, ny, transparent,
                         plotrange)
    except Exception, e:
        casalog.post('Error: %s' % (str(e)), priority='SEVERE')
        import traceback
        casalog.post(traceback.format_exc(), priority='DEBUG')
        raise e
    finally:
        pass


NoData = -32767.0
NoDataThreshold = NoData + 10000.0
LightSpeedQuantity = qa.constants('c')
LightSpeed = qa.convert(LightSpeedQuantity,
                        'km/s')['value']  # speed of light in km/s
DPIDetail = 130

dsyb = '$^\circ$'
hsyb = ':'
msyb = ':'


def Deg2HMS(x, arrowance):
    # Transform degree to HHMMSS.sss format
    xx = x % 360 + arrowance
    h = int(xx / 15)
    m = int((xx % 15) * 4)
    s = ((xx % 15) * 4 - m) * 60.0