Example #1
0
def get_uvw_segment(d, segment=-1):
    """ Calculates uvw for each baseline at mid time of a given segment.
    d defines pipeline state. assumes segmenttimes defined by RT.set_pipeline.
    """

    # define times to read
    if segment != -1:
        assert d.has_key('segmenttimes'), 'd must have segmenttimes defined'

        t0 = d['segmenttimes'][segment][0]
        t1 = d['segmenttimes'][segment][1]
        datetime = qa.time(qa.quantity((t1+t0)/2,'d'),form=['ymdhms'], prec=9)[0]
        logger.info('Calculating uvw for segment %d' % (segment))
    else:
        datetime = 0

    (u, v, w) = sdmreader.calc_uvw(d['filename'], d['scan'], datetime=datetime)

    # cast to units of lambda at first channel. -1 keeps consistent with ms reading convention
    u = u * d['freq_orig'][0] * (1e9/3e8) * (-1)     
    v = v * d['freq_orig'][0] * (1e9/3e8) * (-1)
    w = w * d['freq_orig'][0] * (1e9/3e8) * (-1)

    return u.astype('float32'), v.astype('float32'), w.astype('float32')
Example #2
0
def get_metadata(filename, scan, paramfile='', **kwargs):
    """ Parses sdm file to define metadata for observation, including scan info, image grid parameters, pipeline memory usage, etc.
    Mirrors parsems.get_metadata().
    If paramfile defined, it will use it (filename or RT.Params instance ok).
    """

    # create primary state dictionary
    d = {}

    # set workdir
    d['filename'] = os.path.abspath(filename)
    d['workdir'] = os.path.dirname(d['filename'])

    # define parameters of pipeline via Params object
    params = pp.Params(paramfile)
    for k in params.defined:   # fill in default params
        d[k] = params[k]

    # overload with provided kwargs
    for key in kwargs.keys():
        logger.info('Setting %s to %s' % (key, kwargs[key]))
        d[key] = kwargs[key]

    if 'silent' in kwargs.keys():
        loglevel = logging.ERROR
    else:
        loglevel = logging.INFO
    logger.setLevel(loglevel)

    # define scan list
    if d.has_key('bdfdir'):   # only needed on cbe
        bdfdir = d['bdfdir']
    else:
        bdfdir = None
    scans, sources = sdmreader.read_metadata(d['filename'], scan, bdfdir=bdfdir)

    # define source props
    d['source'] = scans[scan]['source']
    d['radec'] = [(prop['ra'], prop['dec']) for (sr,prop) in sources.iteritems() if prop['source'] == d['source']][0]

    # define spectral info
    sdm = sdmpy.SDM(d['filename'])
    d['spw_orig'] = [int(row.spectralWindowId.split('_')[1]) for row in sdm['SpectralWindow']]
    d['spw_nchan'] = [int(row.numChan) for row in sdm['SpectralWindow']]

    try:
        d['spw_reffreq'] = [float(row.chanFreqStart) for row in sdm['SpectralWindow']]   # nominal
    except:
        d['spw_reffreq'] = [float(row.chanFreqArray.strip().split(' ')[2]) for row in sdm['SpectralWindow']]  # GMRT uses array of all channel starts
    try:
        d['spw_chansize'] = [float(row.chanFreqStep) for row in sdm['SpectralWindow']]   # nominal
    except:
        d['spw_chansize'] = [float(row.chanWidthArray.strip().split(' ')[2]) for row in sdm['SpectralWindow']]   # GMRT uses array of all channel starts

    # select spw. note that spw selection not fully supported yet.
    if not len(d['spw']):
        d['spw'] = d['spw_orig']

    spwch = []
    reffreq = d['spw_reffreq']; spectralwindow = d['spw_orig']; numchan = d['spw_nchan']; chansize = d['spw_chansize']
    for freq in sorted(d['spw_reffreq']):
        ii = reffreq.index(freq)
        if spectralwindow[ii] in d['spw']:
            spwch.extend(list(n.linspace(reffreq[ii], reffreq[ii]+(numchan[ii]-1)*chansize[ii], numchan[ii])))  # spacing of channel *centers*

    d['freq_orig'] = n.array([n.mean(spwch[i:i+d['read_fdownsample']]) for i in range(0, len(spwch), d['read_fdownsample'])], dtype='float32')/1e9
#    d['freq_orig'] = n.array(spwch, dtype='float32')/1e9  # without downsample

    # select subset of channels
    if not len(d['chans']):
        d['chans'] = range(len(d['freq_orig']))

    d['nspw'] = len(d['spw'])
    d['freq'] = d['freq_orig'][d['chans']]
    d['nchan'] = len(d['chans'])

    # define chan ranges per spw (before selecting subset)
    spw_chanr = []; i0=0
    for nch in d['spw_nchan']:
        spw_chanr.append((i0, i0+nch))
        i0 = nch
    d['spw_chanr'] = spw_chanr

    # define nchan per spw after selecting subset
    d['spw_nchan_select'] = [len([ch for ch in range(d['spw_chanr'][i][0], d['spw_chanr'][i][1]) if ch in d['chans']]) for i in range(len(d['spw_chanr']))]
    spw_chanr_select = []; i0=0
    for nch in d['spw_nchan_select']:
        spw_chanr_select.append((i0, i0+nch))
        i0 = nch
    d['spw_chanr_select'] = spw_chanr_select

    # define image params
    d['urange'] = {}; d['vrange'] = {}
    d['scan'] = scan
    (u, v, w) = sdmreader.calc_uvw(d['filename'], d['scan'])  # default uses time at start
    u = u * d['freq_orig'][0] * (1e9/3e8) * (-1)     
    v = v * d['freq_orig'][0] * (1e9/3e8) * (-1)     
    d['urange'][d['scan']] = u.max() - u.min()
    d['vrange'][d['scan']] = v.max() - v.min()
    d['dishdiameter'] = float(sdm['Antenna'][0].dishDiameter.strip())  # should be in meters
    d['uvres_full'] = n.round(d['dishdiameter']/(3e-1/d['freq'].min())/2).astype('int')    # delay beam larger than VLA field of view at all freqs. assumes freq in GHz.
    # **this may let vis slip out of bounds. should really define grid out to 2*max(abs(u)) and 2*max(abs(v)). in practice, very few are lost.**

    if not all([d.has_key('npixx_full'), d.has_key('npixy_full')]):
        urange = d['urange'][d['scan']]*(d['freq'].max()/d['freq_orig'][0])   # uvw from get_uvw already in lambda at ch0
        vrange = d['vrange'][d['scan']]*(d['freq'].max()/d['freq_orig'][0])
        powers = n.fromfunction(lambda i,j: 2**i*3**j, (14,10), dtype='int')   # power array for 2**i * 3**j
        rangex = n.round(d['uvoversample']*urange).astype('int')
        rangey = n.round(d['uvoversample']*vrange).astype('int')
        largerx = n.where(powers-rangex/d['uvres_full'] > 0, powers, powers[-1,-1])
        p2x, p3x = n.where(largerx == largerx.min())
        largery = n.where(powers-rangey/d['uvres_full'] > 0, powers, powers[-1,-1])
        p2y, p3y = n.where(largery == largery.min())
        d['npixx_full'] = (2**p2x * 3**p3x)[0]
        d['npixy_full'] = (2**p2y * 3**p3y)[0]

    # define ants/bls
    # hacking here to fit observatory-specific use of antenna names
    if 'VLA' in sdm['ExecBlock'][0]['telescopeName']:
        d['ants'] = [int(ant.name.lstrip('ea')) for ant in sdm['Antenna']]
    elif 'GMRT' in sdm['ExecBlock'][0]['telescopeName']:        
        d['ants'] = [int(ant.antennaId.split('_')[1]) for ant in sdm['Antenna']]

   # remove unwanted ants
    for ant in d['excludeants']:
        d['ants'].remove(ant)
    d['nants'] = len(d['ants'])
#    d['blarr'] = n.array([[d['ants'][i],d['ants'][j]] for j in range(d['nants']) for i in range(0,j)])
    d['nbl'] = d['nants']*(d['nants']-1)/2

    # define times
    d['starttime_mjd'] = scans[d['scan']]['startmjd']
    # assume inttime same for all scans

    for scan in sdm['Main']:
        interval = int(scan.interval)
        nints = int(scan.numIntegration)
        # get inttime in seconds
        if 'VLA' in sdm['ExecBlock'][0]['telescopeName']:
            inttime = 1e-9*interval/nints          # VLA uses interval as scan duration
            scannum = int(scan.scanNumber)
        elif 'GMRT' in sdm['ExecBlock'][0]['telescopeName']:        
            inttime = 1e-9*interval                # GMRT uses interval as the integration duration
            scannum = int(scan.subscanNumber)
        if scannum == d['scan']:
            d['inttime'] = inttime
            d['nints'] = nints

    # define pols
    d['pols_orig'] = [pol for pol in sdm['Polarization'][0].corrType.strip().split(' ') if pol in ['XX', 'YY', 'XY', 'YX', 'RR', 'LL', 'RL', 'LR']]
    d['npol_orig'] = int(sdm['Polarization'][0].numCorr)

    # summarize metadata
    logger.info('\n')
    logger.info('Metadata summary:')
    logger.info('\t Working directory and data at %s, %s' % (d['workdir'], os.path.basename(d['filename'])))
    logger.info('\t Using scan %d, source %s' % (int(d['scan']), d['source']))
    logger.info('\t nants, nbl: %d, %d' % (d['nants'], d['nbl']))
    logger.info('\t Freq range (%.3f -- %.3f). %d spw with %d chans.' % (d['freq'].min(), d['freq'].max(), d['nspw'], d['nchan']))
    logger.info('\t Scan has %d ints (%.1f s) and inttime %.3f s' % (d['nints'], d['nints']*d['inttime'], d['inttime']))
    logger.info('\t %d polarizations: %s' % (d['npol_orig'], d['pols_orig']))
    logger.info('\t Ideal uvgrid npix=(%d,%d) and res=%d (oversample %.1f)' % (d['npixx_full'], d['npixy_full'], d['uvres_full'], d['uvoversample']))

    return d