Пример #1
0
def ssobjangdiam(srcName, epoch, ephemdata="",unit=""):
    """
    srcName: solar system object name (case insensitive)
    epoch: in string format (e.g. "2015/09/01:12:00:00")
    ephemdata: ephemeris data (default = "", look up the standard ~/alma/JPL_Horizons in the data repo
    unit: unit for the output ang. diam.
    """
  
    defaultDataPath = os.getenv("CASAPATH").split()[0] + "/data/ephemerides/JPL-Horizons/"
    me = taskinit.metool()
    qa = taskinit.qatool()
    if ephemdata!="":
       datapath = ephemdata
    else:
       mjd = me.epoch("utc",epoch)['m0']['value'] 
       datapath = findEphemTable(defaultDataPath, srcName, mjd)

    me.framecomet(datapath)
    me.doframe(me.epoch("utc", epoch))
    me.doframe(me.observatory("ALMA"))
   
    angdiamrad= me.cometangdiam()
    if unit=="" or unit=="rad":
        angdiam = angdiamrad
    else:
        angdiam = qa.convert(qa.quantity(angdiamrad), unit)

    return angdiam
Пример #2
0
def qufromgain(caltable, badspw=[], paoffset=0.0):

    mytb = taskinit.tbtool()
    myme = taskinit.metool()

    mytb.open(caltable + '/ANTENNA')
    pos = mytb.getcol('POSITION')
    meanpos = pl.mean(pos, 1)
    frame = mytb.getcolkeyword('POSITION', 'MEASINFO')['Ref']
    units = mytb.getcolkeyword('POSITION', 'QuantumUnits')
    mpos = myme.position(frame,
                         str(meanpos[0]) + units[0],
                         str(meanpos[1]) + units[1],
                         str(meanpos[2]) + units[2])
    myme.doframe(mpos)

    # _geodetic_ latitude
    latr = myme.measure(mpos, 'WGS84')['m1']['value']

    print 'Latitude = ', latr * 180 / pi

    mytb.open(caltable + '/FIELD')
    nfld = mytb.nrows()
    dirs = mytb.getcol('DELAY_DIR')[:, 0, :]
    mytb.close()
    print 'Found as many as ' + str(nfld) + ' fields.'

    mytb.open(caltable + '/SPECTRAL_WINDOW')
    nspw = mytb.nrows()
    bandnames = [x.split('#')[0].split('_')[-1] for x in mytb.getcol('NAME')]
    mytb.close()
    print 'Found as many as ' + str(nspw) + ' spws.'

    R = pl.zeros((nspw, nfld))
    Q = pl.zeros((nspw, nfld))
    U = pl.zeros((nspw, nfld))
    mask = pl.ones((nspw, nfld), dtype=bool)

    if (len(badspw) > 0):
        mask[badspw, :] = False

    QU = {}
    mytb.open(caltable)
    for ifld in range(nfld):
        for ispw in range(nspw):
            st = mytb.query('FIELD_ID==' + str(ifld) +
                            ' && SPECTRAL_WINDOW_ID==' + str(ispw))
            nrows = st.nrows()
            if nrows > 0:

                rah = dirs[0, ifld] * 12.0 / pi
                decr = dirs[1, ifld]
                times = st.getcol('TIME')
                gains = st.getcol('CPARAM')
                ants = st.getcol('ANTENNA1')

                nants = ants.max() + 1

                # times
                time0 = 86400.0 * floor(times[0] / 86400.0)
                rtimes = times - time0

                # amplitude ratio
                amps = pl.absolute(gains)
                amps[amps == 0.0] = 1.0
                ratio = amps[0, 0, :] / amps[1, 0, :]

                ratio.resize(nrows / nants, nants)

                # parang
                parang = pl.zeros(len(times))

                for itim in range(len(times)):
                    tm = myme.epoch('UTC', str(times[itim]) + 's')
                    last = myme.measure(tm, 'LAST')['m0']['value']
                    last -= floor(last)  # days
                    last *= 24.0  # hours
                    ha = last - rah  # hours
                    har = ha * 2.0 * pi / 24.0

                    parang[itim] = atan2((cos(latr) * sin(har)),
                                         (sin(latr) * cos(decr) -
                                          cos(latr) * sin(decr) * cos(har)))

                parang.resize(nrows / nants, nants)
                parang += bandpa(bandnames[ispw])  # feed pos ang offset
                parang += (paoffset * pi / 180.)  # manual feed pa offset
                parangd = parang * (180.0 / pi)

                A = pl.ones((nrows / nants, 3))
                A[:, 1] = pl.cos(2 * parang[:, 0])
                A[:, 2] = pl.sin(2 * parang[:, 0])

                fit = pl.lstsq(A, pl.square(ratio))

                ants0 = range(nants)
                rsum = pl.sum(ratio[:, ants0], 1)
                rsum /= len(ants0)

                fit = pl.lstsq(A, pl.square(rsum))
                R[ispw, ifld] = fit[0][0]
                Q[ispw, ifld] = fit[0][1] / R[ispw, ifld] / 2.0
                U[ispw, ifld] = fit[0][2] / R[ispw, ifld] / 2.0
                P = sqrt(Q[ispw, ifld]**2 + U[ispw, ifld]**2)
                X = 0.5 * atan2(U[ispw, ifld], Q[ispw, ifld]) * 180 / pi

                print 'Fld=', ifld, 'Spw=', ispw, '(B=' + str(
                    bandnames[ispw]) + ', PA offset=' + str(
                        bandpa(bandnames[ispw]) * 180. /
                        pi) + 'deg)', 'Gx/Gy=', R[ispw, ifld], 'Q=', Q[
                            ispw, ifld], 'U=', U[ispw, ifld], 'P=', P, 'X=', X

            else:
                mask[ispw, ifld] = False

            st.close()

        if sum(mask[:, ifld]) > 0:
            print 'For field id = ', ifld, ' there are ', sum(
                mask[:, ifld]), 'good spws.'

            Qm = pl.mean(Q[mask[:, ifld], ifld])
            Um = pl.mean(U[mask[:, ifld], ifld])
            QU[ifld] = (Qm, Um)
            Qe = pl.std(Q[mask[:, ifld], ifld])
            Ue = pl.std(U[mask[:, ifld], ifld])
            Pm = sqrt(Qm**2 + Um**2)
            Xm = 0.5 * atan2(Um, Qm) * 180 / pi
            print 'Spw mean: Fld=', ifld, 'Q=', Qm, 'U=', Um, '(rms=', Qe, Ue, ')', 'P=', Pm, 'X=', Xm

    mytb.close()

    return QU
Пример #3
0
def qufromgain(caltable,badspw=[],paoffset=0.0):

    mytb=taskinit.tbtool()
    myme=taskinit.metool()

    mytb.open(caltable+'/ANTENNA')
    pos=mytb.getcol('POSITION')
    meanpos=pl.mean(pos,1)
    frame=mytb.getcolkeyword('POSITION','MEASINFO')['Ref']
    units=mytb.getcolkeyword('POSITION','QuantumUnits')
    mpos=myme.position(frame,
                     str(meanpos[0])+units[0],
                     str(meanpos[1])+units[1],
                     str(meanpos[2])+units[2])
    myme.doframe(mpos)

    # _geodetic_ latitude
    latr=myme.measure(mpos,'WGS84')['m1']['value']

    print 'Latitude = ',latr*180/pi

    mytb.open(caltable+'/FIELD')
    nfld=mytb.nrows()
    dirs=mytb.getcol('DELAY_DIR')[:,0,:]
    mytb.close()
    print 'Found as many as '+str(nfld)+' fields.'

    mytb.open(caltable+'/SPECTRAL_WINDOW')
    nspw=mytb.nrows()
    bandnames=[x.split('#')[0].split('_')[-1] for x in mytb.getcol('NAME')]
    mytb.close()
    print 'Found as many as '+str(nspw)+' spws.'

    R=pl.zeros((nspw,nfld))
    Q=pl.zeros((nspw,nfld))
    U=pl.zeros((nspw,nfld))
    mask=pl.ones((nspw,nfld),dtype=bool)

    if (len(badspw)>0):
        mask[badspw,:]=False

    QU={}
    mytb.open(caltable)
    for ifld in range(nfld):
        for ispw in range(nspw):
            st=mytb.query('FIELD_ID=='+str(ifld)+' && SPECTRAL_WINDOW_ID=='+str(ispw))
            nrows=st.nrows()
            if nrows > 0:


                rah=dirs[0,ifld]*12.0/pi
                decr=dirs[1,ifld]
                times=st.getcol('TIME')
                gains=st.getcol('CPARAM')
                ants=st.getcol('ANTENNA1')

                nants=ants.max()+1
                    
                # times
                time0=86400.0*floor(times[0]/86400.0)
                rtimes=times-time0

                # amplitude ratio
                amps=pl.absolute(gains)
                amps[amps==0.0]=1.0
                ratio=amps[0,0,:]/amps[1,0,:]
                
                ratio.resize(nrows/nants,nants)
                
                # parang
                parang=pl.zeros(len(times))
                
                for itim in range(len(times)):
                    tm=myme.epoch('UTC',str(times[itim])+'s')
                    last=myme.measure(tm,'LAST')['m0']['value']
                    last-=floor(last)  # days
                    last*=24.0  # hours
                    ha=last-rah  # hours
                    har=ha*2.0*pi/24.0
                    
                    parang[itim]=atan2( (cos(latr)*sin(har)),
                                        (sin(latr)*cos(decr)-cos(latr)*sin(decr)*cos(har)) )

                parang.resize(nrows/nants,nants)
                parang+=bandpa(bandnames[ispw])  # feed pos ang offset
                parang+=(paoffset*pi/180.)       # manual feed pa offset
                parangd=parang*(180.0/pi)

                A=pl.ones((nrows/nants,3))
                A[:,1]=pl.cos(2*parang[:,0])
                A[:,2]=pl.sin(2*parang[:,0])

                fit=pl.lstsq(A,pl.square(ratio))

                ants0=range(nants)
                rsum=pl.sum(ratio[:,ants0],1)
                rsum/=len(ants0)
                
                fit=pl.lstsq(A,pl.square(rsum))
                R[ispw,ifld]=fit[0][0]
                Q[ispw,ifld]=fit[0][1]/R[ispw,ifld]/2.0
                U[ispw,ifld]=fit[0][2]/R[ispw,ifld]/2.0
                P=sqrt(Q[ispw,ifld]**2+U[ispw,ifld]**2)
                X=0.5*atan2(U[ispw,ifld],Q[ispw,ifld])*180/pi

                print 'Fld=',ifld,'Spw=',ispw,'(B='+str(bandnames[ispw])+', PA offset='+str(bandpa(bandnames[ispw])*180./pi)+'deg)','Gx/Gy=',R[ispw,ifld],'Q=',Q[ispw,ifld],'U=',U[ispw,ifld],'P=',P,'X=',X
                
            else:
                mask[ispw,ifld]=False

            st.close()

        if sum(mask[:,ifld])>0:
            print 'For field id = ',ifld,' there are ',sum(mask[:,ifld]),'good spws.'

            Qm=pl.mean(Q[mask[:,ifld],ifld])
            Um=pl.mean(U[mask[:,ifld],ifld])
            QU[ifld]=(Qm,Um)
            Qe=pl.std(Q[mask[:,ifld],ifld])
            Ue=pl.std(U[mask[:,ifld],ifld])
            Pm=sqrt(Qm**2+Um**2)
            Xm=0.5*atan2(Um,Qm)*180/pi
            print 'Spw mean: Fld=', ifld,'Q=',Qm,'U=',Um,'(rms=',Qe,Ue,')','P=',Pm,'X=',Xm

    mytb.close()

    return QU
Пример #4
0
def predictcomp(objname=None,
                standard=None,
                epoch=None,
                minfreq=None,
                maxfreq=None,
                nfreqs=None,
                prefix=None,
                antennalist=None,
                showplot=None,
                savefig=None,
                symb=None,
                include0amp=None,
                include0bl=None,
                blunit=None,
                bl0flux=None):
    """
    Writes a component list named clist to disk and returns a dict of
    {'clist': clist,
     'objname': objname,
     'angdiam': angular diameter in radians (if used in clist),
     'standard': standard,
     'epoch': epoch,
     'freqs': pl.array of frequencies, in GHz,
     'uvrange': pl.array of baseline lengths, in m,
     'amps':  pl.array of predicted visibility amplitudes, in Jy,
     'savedfig': False or, if made, the filename of a plot.}
    or False on error.

    objname: An object supported by standard.
    standard: A standard for calculating flux densities, as in setjy.
              Default: 'Butler-JPL-Horizons 2010'
    epoch: The epoch to use for the calculations.   Irrelevant for
           extrasolar standards.
    minfreq: The minimum frequency to use.
             Example: '342.0GHz'
    maxfreq: The maximum frequency to use.
             Default: minfreq
             Example: '346.0GHz'
             Example: '', anything <= 0, or None: use minfreq.
    nfreqs:  The number of frequencies to use.
             Default: 1 if minfreq == maxfreq,
                      2 otherwise.
    prefix: The component list will be saved to
              prefix + '<objname>_spw0_<minfreq><epoch>.cl'
            Default: ''
    antennalist: An array configuration file as used by simdata.
                 If given, a plot of S vs. |u| will be made.
                 Default: '' (None, just make clist.)
    showplot: Whether or not to show the plot on screen.
              Subparameter of antennalist.
              Default: Necessarily False if antennalist is not specified.
                       True otherwise.
    savefig: Filename for saving a plot of S vs. |u|.
             Subparameter of antennalist.
             Default: False (necessarily if antennalist is not specified)
             Examples: True (save to prefix + '.png')
                       'myplot.png' (save to myplot.png) 
    symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: '.'
    include0amp: Force the lower limit of the amplitude axis to 0.
                 Default: False
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: Unit of the baseline length 
    bl0flux: show zero baseline flux
    """
    retval = False
    try:
        casalog.origin('predictcomp')
        # some parameter minimally required
        if objname == '':
            raise Exception, "Error, objname is undefined"
        if minfreq == '':
            raise Exception, "Error, minfreq is undefined"
        minfreqq = qa.quantity(minfreq)
        minfreqHz = qa.convert(minfreqq, 'Hz')['value']
        try:
            maxfreqq = qa.quantity(maxfreq)
        except Exception, instance:
            maxfreqq = minfreqq
        frequnit = maxfreqq['unit']
        maxfreqHz = qa.convert(maxfreqq, 'Hz')['value']
        if maxfreqHz <= 0.0:
            maxfreqq = minfreqq
            maxfreqHz = minfreqHz
        if minfreqHz != maxfreqHz:
            if nfreqs < 2:
                nfreqs = 2
        else:
            nfreqs = 1
        freqs = pl.linspace(minfreqHz, maxfreqHz, nfreqs)

        myme = metool()
        mepoch = myme.epoch('UTC', epoch)
        #if not prefix:
        ## meanfreq = {'value': 0.5 * (minfreqHz + maxfreqHz),
        ##             'unit': frequnit}
        ## prefix = "%s%s_%.7g" % (objname, epoch.replace('/', '-'),
        ##                         minfreqq['value'])
        ## if minfreqHz != maxfreqHz:
        ##     prefix += "to" + maxfreq
        ## else:
        ##     prefix += minfreqq['unit']
        ## prefix += "_"
        #    prefix = ''

        #
        if not prefix:
            if not os.access("./", os.W_OK):
                casalog.post(
                    "No write access in the current directory, trying to write cl to /tmp...",
                    "WARN")
                prefix = "/tmp/"
                if not os.access(prefix, os.W_OK):
                    casalog.post("No write access to /tmp to write cl file",
                                 "SEVERE")
                    return False
        else:
            prefixdir = os.path.dirname(prefix)
            if prefixdir == '/' and len(prefix) > 1:
                prefix = prefix + '/'
                prefixdir = os.path.dirname(prefix)
            if not os.path.exists(prefixdir):
                prefixdirs = prefixdir.split('/')
                if prefixdirs[0] == "" and len(prefixdirs) > 1:
                    rootdir = "/" + prefixdirs[1]
                else:
                    rootdir = "./"
                if os.access(rootdir, os.W_OK):
                    if prefixdir != '':
                        os.makedirs(prefixdir)
                else:
                    casalog.post(
                        "No write access to " + rootdir + " to write cl file",
                        "SEVERE")
                    return False

        # Get clist
        myim = imtool()
        if hasattr(myim, 'predictcomp'):
            casalog.post('local im instance created', 'DEBUG1')
        else:
            casalog.post('Error creating a local im instance.', 'SEVERE')
            return False
        #print "FREQS=",freqs
        # output CL file name is fixed : prefix+"spw0_"+minfreq+mepoch.cl
        minfreqGHz = qa.convert(qa.quantity(minfreq), 'GHz')['value']
        decimalfreq = minfreqGHz - int(minfreqGHz)
        decimalepoch = mepoch['m0']['value'] - int(mepoch['m0']['value'])
        if decimalfreq == 0.0:
            minfreqGHzStr = str(int(minfreqGHz)) + 'GHz'
        else:
            minfreqGHzStr = str(minfreqGHz) + 'GHz'

        if decimalepoch == 0.0:
            epochStr = str(int(mepoch['m0']['value'])) + 'd'
        else:
            epochStr = str(mepoch['m0']['value']) + 'd'
        outfilename = "spw0_" + objname + "_" + minfreqGHzStr + epochStr + '.cl'
        outfilename = prefix + outfilename
        if (os.path.exists(outfilename) and os.path.isdir(outfilename)):

            shutil.rmtree(outfilename)
            casalog.post("Removing the existing componentlist, " + outfilename)

        if standard == 'Butler-JPL-Horizons 2012':
            clist = predictSolarObjectCompList(objname, mepoch, freqs.tolist(),
                                               prefix)
        else:
            clist = myim.predictcomp(objname, standard, mepoch, freqs.tolist(),
                                     prefix)
        #print "created componentlist =",clist
        if os.path.isdir(clist):
            # The spw0 is useless here, but it is added by FluxStandard for the sake of setjy.
            casalog.post('The component list was saved to ' + clist)

            retval = {
                'clist': clist,
                'objname': objname,
                'standard': standard,
                'epoch': mepoch,
                'freqs (GHz)': 1.0e-9 * freqs,
                'antennalist': antennalist
            }
            mycl = cltool()
            mycl.open(clist)
            comp = mycl.getcomponent(0)
            zeroblf = comp['flux']['value']
            if standard == 'Butler-JPL-Horizons 2012':
                f0 = comp['spectrum']['frequency']['m0']['value']
            else:
                f0 = retval['freqs (GHz)'][0]
            casalog.post("Zero baseline flux %s @ %sGHz " % (zeroblf, f0),
                         'INFO')
            mycl.close(False)  # False prevents the stupid warning.
            for k in ('shape', 'spectrum'):
                retval[k] = comp[k]
            if antennalist:
                retval['spectrum']['bl0flux'] = {}
                retval['spectrum']['bl0flux']['value'] = zeroblf[0]
                retval['spectrum']['bl0flux']['unit'] = 'Jy'
                retval['savedfig'] = savefig
                if not bl0flux:
                    zeroblf = [0.0]
                retval.update(
                    plotcomp(retval,
                             showplot,
                             wantdict=True,
                             symb=symb,
                             include0amp=include0amp,
                             include0bl=include0bl,
                             blunit=blunit,
                             bl0flux=zeroblf[0]))
            else:
                retval['savedfig'] = None
        else:
            casalog.post("There was an error in making the component list.",
                         'SEVERE')
Пример #5
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)
Пример #6
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)
Пример #7
0
def predictcomp(objname=None, standard=None, epoch=None,
                minfreq=None, maxfreq=None, nfreqs=None, prefix=None,
                antennalist=None, showplot=None, savefig=None, symb=None,
                include0amp=None, include0bl=None, blunit=None, bl0flux=None):
    """
    Writes a component list named clist to disk and returns a dict of
    {'clist': clist,
     'objname': objname,
     'angdiam': angular diameter in radians (if used in clist),
     'standard': standard,
     'epoch': epoch,
     'freqs': pl.array of frequencies, in GHz,
     'uvrange': pl.array of baseline lengths, in m,
     'amps':  pl.array of predicted visibility amplitudes, in Jy,
     'savedfig': False or, if made, the filename of a plot.}
    or False on error.

    objname: An object supported by standard.
    standard: A standard for calculating flux densities, as in setjy.
              Default: 'Butler-JPL-Horizons 2010'
    epoch: The epoch to use for the calculations.   Irrelevant for
           extrasolar standards.
    minfreq: The minimum frequency to use.
             Example: '342.0GHz'
    maxfreq: The maximum frequency to use.
             Default: minfreq
             Example: '346.0GHz'
             Example: '', anything <= 0, or None: use minfreq.
    nfreqs:  The number of frequencies to use.
             Default: 1 if minfreq == maxfreq,
                      2 otherwise.
    prefix: The component list will be saved to
              prefix + 'spw0_<objname>_<minfreq><epoch>.cl'
            Default: ''
    antennalist: An array configuration file as used by simdata.
                 If given, a plot of S vs. |u| will be made.
                 Default: '' (None, just make clist.)
    showplot: Whether or not to show the plot on screen.
              Subparameter of antennalist.
              Default: Necessarily False if antennalist is not specified.
                       True otherwise.
    savefig: Filename for saving a plot of S vs. |u|.
             Subparameter of antennalist.
             Default: False (necessarily if antennalist is not specified)
             Examples: True (save to prefix + '.png')
                       'myplot.png' (save to myplot.png) 
    symb: One of matplotlib's codes for plot symbols: .:,o^v<>s+xDd234hH|_
          default: '.'
    include0amp: Force the lower limit of the amplitude axis to 0.
                 Default: False
    include0bl: Force the lower limit of the baseline length axis to 0.
    blunit: Unit of the baseline length 
    bl0flux: show zero baseline flux
    """
    retval = False
    try:
        casalog.origin('predictcomp')
        # some parameter minimally required
        if objname=='':
          raise Exception, "Error, objname is undefined"
        if minfreq=='':
          raise Exception, "Error, minfreq is undefined" 
        minfreqq = qa.quantity(minfreq)
        minfreqHz = qa.convert(minfreqq, 'Hz')['value']
        try:
            maxfreqq = qa.quantity(maxfreq)
        except Exception, instance:
            maxfreqq = minfreqq
        frequnit = maxfreqq['unit']
        maxfreqHz = qa.convert(maxfreqq, 'Hz')['value']
        if maxfreqHz <= 0.0:
            maxfreqq = minfreqq
            maxfreqHz = minfreqHz
        if minfreqHz != maxfreqHz:
            if nfreqs < 2:
                nfreqs = 2
        else:
            nfreqs = 1
        freqs = pl.linspace(minfreqHz, maxfreqHz, nfreqs)

        myme = metool()
        mepoch = myme.epoch('UTC', epoch)
        #if not prefix:
            ## meanfreq = {'value': 0.5 * (minfreqHz + maxfreqHz),
            ##             'unit': frequnit}
            ## prefix = "%s%s_%.7g" % (objname, epoch.replace('/', '-'),
            ##                         minfreqq['value'])
            ## if minfreqHz != maxfreqHz:
            ##     prefix += "to" + maxfreq
            ## else:
            ##     prefix += minfreqq['unit']
            ## prefix += "_"
        #    prefix = ''
        
        #
        if not prefix:
          if not os.access("./",os.W_OK):
            casalog.post("No write access in the current directory, trying to write cl to /tmp...","WARN")
            prefix="/tmp/"
            if not os.access(prefix, os.W_OK):
              casalog.post("No write access to /tmp to write cl file", "SEVERE")
              return False
        else:
          prefixdir=os.path.dirname(prefix)
          if not os.path.exists(prefixdir):
            prefixdirs = prefixdir.split('/')
            if prefixdirs[0]=="":
              rootdir = "/" + prefixdirs[1]
            else:
              rootdir = "./"
            if os.access(rootdir,os.W_OK):
              os.makedirs(prefixdir) 
            else:
              casalog.post("No write access to "+rootdir+" to write cl file", "SEVERE")
              return False
       
        # Get clist
        myim = imtool()
        if hasattr(myim, 'predictcomp'):
            casalog.post('local im instance created', 'DEBUG1')
        else:
            casalog.post('Error creating a local im instance.', 'SEVERE')
            return False
        #print "FREQS=",freqs
        if standard=='Butler-JPL-Horizons 2012':
            clist = predictSolarObjectCompList(objname, mepoch, freqs.tolist(), prefix)
        else:
            clist = myim.predictcomp(objname, standard, mepoch, freqs.tolist(), prefix)
        #print "created componentlist =",clist
        if os.path.isdir(clist):
            # The spw0 is useless here, but it is added by FluxStandard for the sake of setjy.
            casalog.post('The component list was saved to ' + clist)
            
            retval = {'clist': clist,
                      'objname': objname,
                      'standard': standard,
                      'epoch': mepoch,
                      'freqs (GHz)': 1.0e-9 * freqs,
                      'antennalist': antennalist}
            mycl = cltool()
            mycl.open(clist)
            comp = mycl.getcomponent(0)
            zeroblf=comp['flux']['value']
            if standard=='Butler-JPL-Horizons 2012':
              f0=comp['spectrum']['frequency']['m0']['value']
            else:
              f0=retval['freqs (GHz)'][0]
            casalog.post("Zero baseline flux %s @ %sGHz " % (zeroblf, f0),'INFO')
            mycl.close(False)               # False prevents the stupid warning.
            for k in ('shape', 'spectrum'):
                retval[k] = comp[k]
            if antennalist:
                retval['spectrum']['bl0flux']={}
                retval['spectrum']['bl0flux']['value']=zeroblf[0]
                retval['spectrum']['bl0flux']['unit']='Jy'
                retval['savedfig'] = savefig
                if not bl0flux:
                  zeroblf=[0.0]
                retval.update(plotcomp(retval, showplot, wantdict=True, symb=symb,
                                       include0amp=include0amp, include0bl=include0bl, blunit=blunit, bl0flux=zeroblf[0]))
            else:
                retval['savedfig'] = None
        else:
            casalog.post("There was an error in making the component list.",
                         'SEVERE')
Пример #8
0
def qufromgain(caltable,badspw=[],badant=[],fieldids=[],paoffset=None):

    mytb=taskinit.tbtool()
    myme=taskinit.metool()

    pos=myme.observatory('atca')
    myme.doframe(pos)

    # _geodetic_ latitude
    latr=myme.measure(pos,'WGS84')['m1']['value']
    #print 'latitude: ',latr*180/pi

    mytb.open(caltable+'/FIELD')
    nfld=mytb.nrows()
    dirs=mytb.getcol('DELAY_DIR')[:,0,:]
    mytb.close()
    print 'Found '+str(nfld)+' fields.'

    mytb.open(caltable+'/SPECTRAL_WINDOW')
    freq=mytb.getcol('REF_FREQUENCY')
    nspw=mytb.nrows()
    mytb.close()
    print 'Found '+str(nspw)+' spws.'

    #sort out pa offset to apply
    paoff=pl.zeros(nspw)
    if paoffset==None:
        # use defaults for ATCA
        # (should get these from Feed subtable, but cal table doesn't have one)
        for ispw in range(nspw):
            if freq[ispw]<30e9 or freq[ispw]>50e9:
                paoff[ispw]=45.
            else:
                paoff[ispw]=135.
    else:
        paoff=paoffset
    
    R=pl.zeros((nspw,nfld))
    Q=pl.zeros((nspw,nfld))
    U=pl.zeros((nspw,nfld))
    mask=pl.ones((nspw,nfld),dtype=bool)

    if (len(badspw)>0):
        mask[badspw,:]=False

    if (len(fieldids)==0):
        fieldids=range(nfld)

    QU={}
    mytb.open(caltable)
    for ifld in fieldids:
        for ispw in range(nspw):
            if not mask[ispw,ifld]:
                continue
            st=mytb.query('FIELD_ID=='+str(ifld)+' && SPECTRAL_WINDOW_ID=='+str(ispw))
            nrows=st.nrows()
            if nrows > 0:
                rah=dirs[0,ifld]*12.0/pi
                decr=dirs[1,ifld]
                times=st.getcol('TIME')
                gains=st.getcol('CPARAM')
                ants=st.getcol('ANTENNA1')

                ntimes=len(pl.unique(times))
                nants=ants.max()+1

                #print nrows, ntimes, nants

                # times
                time0=86400.0*floor(times[0]/86400.0)
                rtimes=times-time0

                # amplitude ratio
                amps=pl.absolute(gains)
                amps[amps==0.0]=1.0
                ratio=amps[0,0,:]/amps[1,0,:]
                
                
                # parang
                parang=pl.zeros(len(times))
                
                for itim in range(len(times)):
                    tm=myme.epoch('UTC',str(times[itim])+'s')
                    last=myme.measure(tm,'LAST')['m0']['value']
                    last-=floor(last)  # days
                    last*=24.0  # hours
                    ha=last-rah  # hours
                    har=ha*2.0*pi/24.0
                    
                    parang[itim]=atan2( (cos(latr)*sin(har)),
                                        (sin(latr)*cos(decr)-cos(latr)*sin(decr)*cos(har)) )

                ratio.resize(nrows/nants,nants)
                parang.resize(nrows/nants,nants)
                parang+=paoff[ispw]*pi/180.
                parangd=parang*(180.0/pi)

                A=pl.ones((nrows/nants,3))
                A[:,1]=pl.cos(2*parang[:,0])
                A[:,2]=pl.sin(2*parang[:,0])

                fit=pl.lstsq(A,pl.square(ratio))
               
                amask=pl.ones(nants,dtype=bool)
                if len(badant)>0:
                    amask[badant]=False
                rsum=pl.sum(ratio[:,amask],1)
                rsum/=pl.sum(amask)
                
                fit=pl.lstsq(A,pl.square(rsum))

                R[ispw,ifld]=fit[0][0]
                Q[ispw,ifld]=fit[0][1]/R[ispw,ifld]/2.0
                U[ispw,ifld]=fit[0][2]/R[ispw,ifld]/2.0
                P=sqrt(Q[ispw,ifld]**2+U[ispw,ifld]**2)
                X=0.5*atan2(U[ispw,ifld],Q[ispw,ifld])*180/pi

                print 'Fld=%i, Spw=%i, PA Offset=%5.1f, Gx/Gy=%5.3f, Q=%5.3f, U=%5.3f, P=%5.3f, X=%5.1f' % (ifld,ispw,paoff[ispw],R[ispw,ifld],Q[ispw,ifld],U[ispw,ifld],P,X)

            else:
                mask[ispw,ifld]=False

            st.close()

        if (sum(mask[:,ifld]))>0:
            print 'For field id = ',ifld,' there are ',sum(mask[:,ifld]),'good spws.'

            Qm=pl.mean(Q[mask[:,ifld],ifld])
            Um=pl.mean(U[mask[:,ifld],ifld])
            QU[ifld]=(Qm,Um)
            Qe=pl.std(Q[mask[:,ifld],ifld])
            Ue=pl.std(U[mask[:,ifld],ifld])
            Pm=sqrt(Qm**2+Um**2)
            Xm=0.5*atan2(Um,Qm)*180/pi
            print 'Spw mean: Fld=%i Fractional: Q=%5.3f, U=%5.3f, (rms= %5.3f,%5.3f), P=%5.3f, X=%5.1f' % (ifld,Qm,Um,Qe,Ue,Pm,Xm)
    mytb.close()

    return QU