def __init__(self, sdmfile, fileroot='', workdir=''): self.sdmfile = os.path.abspath(sdmfile) if not fileroot: self.fileroot = os.path.split(os.path.abspath(sdmfile))[1] else: self.fileroot = fileroot if not workdir: self.workdir = os.path.split(self.sdmfile)[0] else: self.workdir = workdir self.scans, self.sources = sdmreader.read_metadata(sdmfile) self.gainscans = [sc for sc in self.scans.keys() if 'PHASE' in self.scans[sc]['intent']] # get all cal fields self.bpscans = [sc for sc in self.scans.keys() if 'BANDPASS' in self.scans[sc]['intent']] # get all cal fields self.sdm = sdmpy.SDM(self.sdmfile) if len(self.gainstr) or len(self.bpstr): print 'Found gaincal scans %s and bpcal scans %s.' % (self.gainstr, self.bpstr) self.set_fluxinfo()
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
def read_metadata(sdmname): """ Read scan and source metadata """ sc,sr = sdmreader.read_metadata(sdmname) return sc, sr