def write_flag(msfile, elevation_limit, elevation, baseline_dict): """ flag data if below user-specified elevation limit """ tb = casatools.table() qa = casatools.quanta() me = casatools.measures() tb.open(msfile, nomodify=True) flag = tb.getcol('FLAG').T tb.close() tb.open(msfile + '/ANTENNA', nomodify=True) station_names = tb.getcol('NAME') pos = tb.getcol('POSITION') mount = tb.getcol('MOUNT') Nant = pos.shape[0] tb.close() for a0 in range(Nant): for a1 in range(Nant): if a1 > a0: flag_mask = np.invert( ((elevation[a1] > elevation_limit) & (elevation[a0] > elevation_limit)) > 0) #print(flag_mask.reshape((flag[:,:,baseline_dict[(a0, a1)]].shape, 1, 1))) print(flag_mask.reshape((flag_mask.shape[0], 1, 1)).shape) flag[baseline_dict[(a0, a1)]] = flag_mask.reshape( (flag_mask.shape[0], 1, 1)) if ("JB" in station_names) & ("M2" in station_names): flagdata(vis=msfile, mode='manual', antenna="JB&M2") tb.open(msfile, nomodify=False) tb.putcol("FLAG", flag.T) tb.close()
def make_baseline_dictionary(msfile): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() tb.open(msfile, nomodify=True) A0 = tb.getcol('ANTENNA1') A1 = tb.getcol("ANTENNA2") ant_unique = np.unique(np.hstack((A0, A1))) tb.close() return dict([((x, y), np.where((A0 == x) & (A1 == y))[0]) for x in ant_unique for y in ant_unique if y > x])
def parallacticAngle(msfile, times): #measure = pm.measures() #tab = pt.table(msfile, readonly=True,ack=False) #field_tab = pt.table(tab.getkeyword('FIELD'),ack=False) #direction = np.squeeze(field_tab.getcol('PHASE_DIR')) tb = casatools.table() qa = casatools.quanta() me = casatools.measures() time_unique = times tb.open(msfile + '/FIELD', nomodify=True) direction = np.squeeze(tb.getcol('PHASE_DIR')) tb.close() tb.open(msfile + '/ANTENNA', nomodify=True) station_names = tb.getcol('NAME') pos = tb.getcol('POSITION').T mount = tb.getcol('MOUNT') Nant = pos.shape[0] N = range(Nant) nbl = (Nant * (Nant - 1)) / 2 tb.close() ra = qa.quantity(direction[0], 'rad') dec = qa.quantity(direction[1], 'rad') pointing = me.direction('j2000', ra, dec) start_time = me.epoch('utc', qa.quantity(time_unique[0], 's')) me.doframe(start_time) parallactic_ant_matrix = np.zeros((Nant, time_unique.shape[0])) def antenna_para(antenna): x = qa.quantity(pos[antenna, 0], 'm') y = qa.quantity(pos[antenna, 1], 'm') z = qa.quantity(pos[antenna, 2], 'm') position = me.position('wgs84', x, y, z) me.doframe(position) sec2rad = 2 * np.pi / (24 * 3600.) hour_angle = me.measure(pointing, 'HADEC')['m0']['value'] +\ (time_unique-time_unique.min()) * sec2rad earth_radius = 6371000.0 latitude = np.arcsin(pos[antenna, 2] / earth_radius) return np.arctan2( np.sin(hour_angle) * np.cos(latitude), (np.cos(direction[1]) * np.sin(latitude) - np.cos(hour_angle) * np.cos(latitude) * np.sin(direction[1]))) for i in range(Nant): if mount[i] == 'EQUATORIAL': parallactic_ant_matrix[i] = np.zeros(time_unique.shape) else: parallactic_ant_matrix[i] = antenna_para(i) * (180. / np.pi) return parallactic_ant_matrix
def match_to_antenna_nos(evn_SEFD, msfile): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() evn_SEFD_2 = {} evn_diams = {} tb.open('%s/ANTENNA' % msfile) x = tb.getcol('NAME') tb.close() print(evn_SEFD) for i, j in enumerate(x): evn_SEFD_2[i] = evn_SEFD[j][0] evn_diams[i] = evn_SEFD[j][1] return evn_SEFD_2, evn_diams
def uvw(mjd, direction, antpos): """Return an Nbaseline-x-3 array giving U,V,W in meters for the given MJD, sky direction, and antenna positions. direction is (ra,dec) in radians antpos is Nant-by-3 array of antenna positions in meters. This can be called on an sdmpy Scan object like: uvw = sdmpy.calib.uvw(scan.startMJD, scan.coordinates, scan.positions) """ if casatools is None: raise RuntimeError("") me = casatools.measures() qa = casatools.quanta() qq = qa.quantity s = me.direction('J2000', qq(direction[0],'rad'), qq(direction[1],'rad')) e = me.epoch('UTC', qq(mjd,'d')) o = me.observatory('VLA') me.doframe(o) me.doframe(e) me.doframe(s) pos = np.array(antpos) casapos = me.position('ITRF', qq(pos[:,0],'m'), qq(pos[:,1],'m'), qq(pos[:,2],'m')) bls = me.expand(me.touvw(me.asbaseline(casapos))[0])[1]['value'] bls = bls.reshape((-1,3)) # Original code from rfpipe: #ord1 = [(i,j) for i in range(nants) for j in range(i+1, nants)] # CASA order #ord2 = [(i,j) for j in range(nants) for i in range(j)] # BDF order nant = pos.shape[0] nbl = bls.shape[0] # Index into the output (BDF-style) array for each value # in the input (CASA-style) array. oidx = [ant2bl((i,j)) for i in range(nant) for j in range(i+1,nant)] uvw = 0.0*bls for i in range(nbl): uvw[oidx[i],:] = bls[i,:] return uvw
def add_pt_src(msfile, pt_flux): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() cl = casatools.componentlist() tb.open(msfile + '/SOURCE') direc = tb.getcol('DIRECTION') direc = direc.T[0] tb.close() print('J2000 %srad %srad' % (direc[0], direc[1])) cl.addcomponent(flux=pt_flux, fluxunit='Jy', shape='point', dir='J2000 %srad %srad' % (direc[0], direc[1])) os.system('rm -r %s.cl' % msfile) cl.rename('%s.cl' % msfile) cl.close() ft(vis=msfile, complist='%s.cl' % msfile, usescratch=True) #uvsub(vis=msfile,reverse=True) os.system('rm -r %s.cl' % msfile)
def calc_pb_corr(msfile, diam_ants, single_freq): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() arcmin_off = float(msfile.split('_')[1]) + ( float(msfile.split('_')[2].split('.ms')[0]) / 60.) tb.open('%s/SPECTRAL_WINDOW' % msfile) nspw = len(tb.getcol("MEAS_FREQ_REF")) chan_freqs = tb.getcol('CHAN_FREQ').T if single_freq != False: freq = np.mean(chan_freqs) chan_freqs = [freq] * nspw diams_ants2 = {} for i in diams_ants.keys(): pb_freq = {} for j in range(nspw): pb_freq[str(j)] = np.sqrt( calc_hpbw(x=arcmin_off, diam=diam_ants[i], freq=chan_freqs[j])) print(pb_freq) diams_ants2[i] = pb_freq datacolumn = 'MODEL_DATA' tb.open('%s' % msfile, nomodify=True) data = tb.getcol('%s' % datacolumn) antenna1 = tb.getcol('ANTENNA1') antenna2 = tb.getcol('ANTENNA2') spw_id = tb.getcol('DATA_DESC_ID') tint = np.average(tb.getcol('EXPOSURE')) tb.close() for i in range(len(antenna1)): amps, phase = R2P(data[:, :, i]) amps = amps * (diams_ants2[antenna1[i]][str(spw_id[i])] * diams_ants2[antenna2[i]][str(spw_id[i])]) data[:, :, i] = P2R(amps, phase) tb.open('%s' % msfile, nomodify=False) tb.putcol('%s' % datacolumn, data) tb.close() return
def add_noise(msfile, datacolumn, evn_SEFD, adjust_time=1.0): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() tb.open('%s' % msfile, nomodify=True) data = tb.getcol('%s' % datacolumn) if datacolumn == 'CORRECTED_DATA': weightnames = 'WEIGHT' elif datacolumn == 'DATA': weightnames = 'SIGMA' else: raise TypeError weights = tb.getcol('%s' % weightnames) antenna1 = tb.getcol('ANTENNA1') antenna2 = tb.getcol('ANTENNA2') tint = np.average(tb.getcol('EXPOSURE')) tb.close() if adjust_time != 1.0: tint = tint * adjust_time tb.open('%s/SPECTRAL_WINDOW' % msfile, nomodify=True) chan_width = np.average(tb.getcol('CHAN_WIDTH')) print(chan_width, tint) tb.close() for i in range(len(antenna1)): sefd = calc_sefd(evn_SEFD[antenna1[i]], evn_SEFD[antenna2[i]], tint, chan_width, 0.88) amps = np.random.normal(0., sefd, np.shape(data[:, :, i])) phase = ((np.pi + np.pi) * np.random.random_sample(np.shape(data[:, :, i]))) - np.pi data[:, :, i] = P2R(amps, phase) weights[:, i] = np.ones(weights[:, i].shape) / (sefd**2) tb.open('%s' % msfile, nomodify=False) tb.putcol('%s' % datacolumn, data) tb.putcol('%s' % weightnames, weights) tb.close()
def get_lst_range(obs_date='21-Sep-09 18:50:25'): from casatools import measures, quanta me = measures() qa = quanta() t1 = me.epoch('utc', obs_date) me.doframe(me.observatory('VLA')) me.doframe(t1) t2 = me.measure(t1, 'LAST') d1 = me.riseset(me.direction('sun')) t_rise = d1['rise']['last'] t_set = d1['set']['last'] print('LST now: ' + str(qa.time(qa.sub(t2['m0'], qa.floor(t2['m0']))))) print('LST sunrise: ' + str(qa.time(qa.sub(t_rise['m0'], qa.floor(t_rise['m0']))))) print('LST sunset: ' + str(qa.time(qa.sub(t_set['m0'], qa.floor(t_set['m0']))))) lst_sunrise = qa.time(qa.sub(t_rise['m0'], qa.floor(t_rise['m0']))) lst_sunset = qa.time(qa.sub(t_set['m0'], qa.floor(t_set['m0']))) return lst_sunrise, lst_sunset
tb.fromascii(tabname, conf_file, firstline=3, sep=' ', columnnames=['X', 'Y', 'Z', 'DIAM', 'NAME'], datatypes=['D', 'D', 'D', 'D', 'A']) xx = tb.getcol('X') yy = tb.getcol('Y') zz = tb.getcol('Z') diam = tb.getcol('DIAM') anames = tb.getcol('NAME') tb.close() # simulate setup sm = casatools.simulator() me = casatools.measures() sm.open(msname) sm.setconfig(telescopename='ovro_mma', x=xx, y=yy, z=zz, dishdiameter=diam, mount='alt-az', antname=list(anames), padname=list(anames), coordsystem='global') sm.setspwindow(spwname='LWABand', freq='35MHz', deltafreq='21kHz', freqresolution='21kHz', nchannels=2398,
def calc_uvw_blt(blen, tobs, src_epoch, src_lon, src_lat, obs='OVRO_MMA'): """Calculates uvw coordinates. Uses CASA to calculate the u,v,w coordinates of the baselines `b` towards a source or phase center (specified by `src_epoch`, `src_lon` and `src_lat`) at the specified time and observatory. Parameters ---------- blen : ndarray The ITRF coordinates of the baselines. Type float, shape (nblt, 3), units of meters. tobs : ndarray An array of floats, the times in MJD for which to calculate the uvw coordinates, shape (nblt). src_epoch : str The epoch of the source or phase-center, as a CASA-recognized string e.g. ``'J2000'`` or ``'HADEC'`` src_lon : astropy quantity The longitude of the source or phase-center, in degrees or an equivalent unit. src_lat : astropy quantity The latitude of the source or phase-center, in degrees or an equivalent unit. Returns ------- bu : ndarray The u-value for each time and baseline, in meters. Shape is ``(len(b), len(tobs))``. bv : ndarray The v-value for each time and baseline, in meters. Shape is ``(len(b), len(tobs))``. bw : ndarray The w-value for each time and baseline, in meters. Shape is ``(len(b), len(tobs))``. """ nblt = tobs.shape[0] buvw = np.zeros((nblt, 3)) # Define the reference frame me = cc.measures() qa = cc.quanta() if obs is not None: me.doframe(me.observatory(obs)) if not isinstance(src_lon.ndim, float) and src_lon.ndim > 0: assert src_lon.ndim == 1 assert src_lon.shape[0] == nblt assert src_lat.shape[0] == nblt direction_set = False else: if (src_epoch == 'HADEC') and (nblt > 1): raise TypeError('HA and DEC must be specified at each ' 'baseline-time in tobs.') me.doframe( me.direction(src_epoch, qa.quantity(src_lon.to_value(u.deg), 'deg'), qa.quantity(src_lat.to_value(u.deg), 'deg'))) direction_set = True contains_nans = False for i in range(nblt): me.doframe(me.epoch('UTC', qa.quantity(tobs[i], 'd'))) if not direction_set: me.doframe( me.direction(src_epoch, qa.quantity(src_lon[i].to_value(u.deg), 'deg'), qa.quantity(src_lat[i].to_value(u.deg), 'deg'))) bl = me.baseline('itrf', qa.quantity(blen[i, 0], 'm'), qa.quantity(blen[i, 1], 'm'), qa.quantity(blen[i, 2], 'm')) # Get the uvw coordinates try: buvw[i, :] = me.touvw(bl)[1]['value'] except KeyError: contains_nans = True buvw[i, :] = np.ones(3) * np.nan if contains_nans: print('Warning: some solutions not found for u, v, w coordinates') return buvw
def check_elevation(msfile, custom_xyz=False): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() #measure = pm.measures() #tab = pt.table(msfile, readonly=True,ack=False) #field_tab = pt.table(tab.getkeyword('FIELD'),ack=False) #direction = np.squeeze(field_tab.getcol('PHASE_DIR')) tb.open(msfile, nomodify=True) time_unique = np.unique(tb.getcol('TIME')) tb.close() tb.open(msfile + '/FIELD', nomodify=True) direction = np.squeeze(tb.getcol('PHASE_DIR')) tb.close() tb.open(msfile + '/ANTENNA', nomodify=True) station_names = tb.getcol('NAME') if custom_xyz == True: if 'mosaic' in msfile: df = pd.read_csv( 'sims.itrf', delimiter=" ", header=None, names=['X', 'Y', 'Z', 'dish_diam', 'station', 'mount'], index_col=False) else: df = pd.read_csv( 'sims.itrf', delimiter=" ", header=None, names=['X', 'Y', 'Z', 'dish_diam', 'station', 'mount'], index_col=False) pos = np.vstack( [df['X'].to_numpy(), df['Y'].to_numpy(), df['Z'].to_numpy()]) else: pos = tb.getcol('POSITION') mount = tb.getcol('MOUNT') Nant = pos.shape[0] N = range(Nant) nbl = (Nant * (Nant - 1)) / 2 tb.close() ra = qa.quantity(direction[0], 'rad') dec = qa.quantity(direction[1], 'rad') pointing = me.direction('j2000', ra, dec) start_time = me.epoch('utc', qa.quantity(time_unique[0], 's')) me.doframe(start_time) elevation_ant_matrix = np.zeros((Nant, time_unique.shape[0])) def antenna_elevation(antenna): x = qa.quantity(pos[antenna, 0], 'm') y = qa.quantity(pos[antenna, 1], 'm') z = qa.quantity(pos[antenna, 2], 'm') position = me.position('wgs84', x, y, z) me.doframe(position) sec2rad = 2 * np.pi / (24 * 3600.) hour_angle = me.measure(pointing, 'HADEC')['m0']['value'] +\ (time_unique-time_unique.min()) * sec2rad earth_radius = 6371000.0 latitude = np.arcsin(pos[antenna, 2] / earth_radius) return np.arcsin( np.sin(latitude) * np.sin(direction[1]) + np.cos(latitude) * np.cos(direction[1]) * np.cos(hour_angle)) for i in range(Nant): elevation_ant_matrix[i] = antenna_elevation(i) return elevation_ant_matrix
import numpy as np from astropy.io import fits from astropy.wcs import WCS # Import required tools/tasks from casatools import simulator, image, table, coordsys, measures, componentlist, quanta, ctsys, ms from casatasks.private import simutil from IPython.display import Markdown as md # Instantiate all the required tools sm = simulator() ia = image() tb = table() cs = coordsys() me = measures() qa = quanta() cl = componentlist() mysu = simutil.simutil() myms = ms() import warnings warnings.simplefilter("ignore", category=RuntimeWarning) def plotData(msname='sim_data.ms', myplot='uv'): """ Options : myplot='uv' myplot='data_spectrum' myplot='data_time' """
def getPlotantsAntennaInfo(msname, log, exclude, checkbaselines): tb = table( ) me = measures( ) qa = quanta( ) telescope, arrayPos = getPlotantsObservatoryInfo(msname) arrayWgs84 = me.measure(arrayPos, 'WGS84') arrayLon, arrayLat, arrayAlt = [arrayWgs84[i]['value'] for i in ['m0','m1','m2']] # Open the ANTENNA subtable to get the names of the antennas in this MS and # their positions. Note that the entries in the ANTENNA subtable are pretty # much in random order, so antNames translates between their index and name # (e.g., index 11 = STD155). We'll need these indices for later, since the # main data table refers to the antennas by their indices, not names. anttabname = msname + '/ANTENNA' tb.open(anttabname) # Get antenna names from antenna table antNames = np.array(tb.getcol("NAME")).tolist() stationNames = np.array(tb.getcol("STATION")).tolist() if telescope == 'VLBA': # names = ant@station antNames = ['@'.join(antsta) for antsta in zip(antNames,stationNames)] # Get antenna positions from antenna table antPositions = np.array([me.position('ITRF', qa.quantity(x, 'm'), qa.quantity(y, 'm'), qa.quantity(z, 'm')) for (x, y, z) in tb.getcol('POSITION').transpose()]) tb.close() allAntIds = range(len(antNames)) if checkbaselines: # Get antenna ids from main table; this will add to runtime tb.open(msname) ants1 = tb.getcol('ANTENNA1') ants2 = tb.getcol('ANTENNA2') tb.close() antIdsUsed = list(set(np.append(ants1, ants2))) else: # use them all! antIdsUsed = allAntIds # handle exclude -- remove from antIdsUsed for antId in exclude: try: antNameId = antNames[antId] + " (id " + str(antId) + ")" antIdsUsed.remove(antId) casalog.post("Exclude antenna " + antNameId) except ValueError: casalog.post("Cannot exclude antenna " + antNameId + ": not in main table", "WARN") # apply antIdsUsed mask antNames = [antNames[i] for i in antIdsUsed] antPositions = [antPositions[i] for i in antIdsUsed] stationNames = [stationNames[i] for i in antIdsUsed] nAnts = len(antIdsUsed) print("Number of points being plotted:", nAnts) casalog.post("Number of points being plotted: " + str(nAnts)) if nAnts == 0: # excluded all antennas return telescope, antNames, [], [], [] # Get the names, indices, and lat/lon/alt coords of "good" antennas. antWgs84s = np.array([me.measure(pos, 'WGS84') for pos in antPositions]) # Convert from lat, lon, alt to X, Y, Z (unless VLBA) # where X is east, Y is north, Z is up, # and 0, 0, 0 is the center # Note: this conversion is NOT exact, since it doesn't take into account # Earth's ellipticity! But it's close enough. if telescope == 'VLBA' and not log: antLons, antLats = [[pos[i] for pos in antWgs84s] for i in ['m0','m1']] antXs = [qa.convert(lon, 'deg')['value'] for lon in antLons] antYs = [qa.convert(lat, 'deg')['value'] for lat in antLats] else: antLons, antLats = [np.array( [pos[i]['value'] for pos in antWgs84s]) for i in ['m0','m1']] radE = 6370000. antXs = (antLons - arrayLon) * radE * np.cos(arrayLat) antYs = (antLats - arrayLat) * radE return telescope, antNames, antIdsUsed, antXs, antYs, stationNames
def simulate(imagename='', complist='', msname='dsa110-calsrc.ms', freq='1.4GHz', integrationtime='10s', diameter=5.0, noise='0Jy', gainnoise=0., nchan=1, calobsdir="J2000 12h00m00.0s 50d00m00.0s", srcobsdir="J2000 12h30m00.0s 50d00m00.0s"): """ Use source model to generate simulated ms for a few DSA antennas. If imagename and complist both provided, then complist will be added to image. """ # outriggers x = [ 0, 400, 380, 370, 410, 420, 200, -200, -400, -980, -550, -1250, -1200, -1200, -1350 ] y = [ -1050, -500, 350, 800, 975, 1120, 1100, 1050, 950, 775, 1000, 1120, 575, -800, -900 ] names = [ 'DSA-101', 'DSA-102', 'DSA-103', 'DSA-104', 'DSA-105', 'DSA-106', 'DSA-107', 'DSA-108', 'DSA-109', 'DSA-110', 'DSA-111', 'DSA-112', 'DSA-113', 'DSA-114', 'DSA-115' ] if os.path.exists(msname): logger.info("Removing existing file, {0}".format(msname)) shutil.rmtree(msname) sm = tools.simulator() sm.open(msname) me = tools.measures() refpos = me.observatory('OVRO_MMA') # TODO: confirm coordinates and set offsets from OVRO_MMA sm.setconfig(telescopename='DSA-110', x=x, y=y, dishdiameter=[diameter] * len(x), z=[0.] * len(x), offset=[0.0], mount=['ALT-AZ'], antname=names, padname=names, coordsystem='local', referencelocation=refpos) sm.setspwindow(spwname='LBand', freq=freq, deltafreq='0.5MHz', freqresolution='0.5MHz', nchannels=nchan, stokes='XX YY') sm.settimes(integrationtime=integrationtime, usehourangle=True, referencetime=58722) sm.setfeed(mode='perfect X Y') sm.setauto(autocorrwt=0.0) vp = tools.vpmanager() vp.reset() vp.setpbairy(telescope="DSA-110", dishdiam="{0}m".format(diameter), maxrad="10deg", blockagediam="1m") sm.setvp(dovp=True, usedefaultvp=False) if calobsdir is not None: sm.setfield(sourcename='cal', sourcedirection=me.direction(*calobsdir.split())) if srcobsdir is not None: sm.setfield(sourcename='src', sourcedirection=me.direction(*srcobsdir.split())) if calobsdir is not None: # sm.observe(sourcename='cal', spwname='LBand', starttime='-450s', stoptime='450s') # times are in HA referenced to first source sm.observemany(sourcenames=5 * ['src'], spwname='LBand', starttimes=5 * ['-5s'], stoptimes=5 * ['5s'], directions=list(transit( calobsdir, 5., 5))) # times are in HA referenced to first source if srcobsdir is not None: sm.observe(sourcename='src', spwname='LBand', starttime='1350s', stoptime='2250s') # 30min later if len(imagename) and len(complist): sm.predict(imagename=imagename) if len(complist): sm.predict(complist=complist, incremental=True) elif len(complist): sm.predict(complist=complist) if noise != '0Jy': sm.setnoise(mode='simplenoise', simplenoise=noise) if gainnoise: sm.setgain(mode='fbm', amplitude=gainnoise) if (noise != '0Jy') or gainnoise: sm.corrupt() sm.summary() sm.done()
def rescale_synthetic_HPBW(header, c_freq, diameter, vmodel, a_term_upscale, phase_centre, para_angle): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() try: ### Set sizes size = np.array([header['NAXIS1'], header['NAXIS2']]) cdelt = np.array([ header['CDELT1'] * a_term_upscale, header['CDELT2'] * a_term_upscale ]) centre = np.array([header['CRVAL1'], header['CRVAL2']]) total_size = size * cdelt #print('Header found') ret_singular = False except: #print('No header found reverting to some default values') size = [512, 512] cdelt = [1.388888888889e-07, 1.388888888889e-07] centre = [header[0], header[1]] ret_singular = True ### Open voltage model #print('open fits') hdu = fits.open(vmodel) vhead = hdu[0].header #print('reorder fits') vdata = hdu[0].data.squeeze() vdata = vdata.byteswap().newbyteorder() hdu.close() ### Rotate data #try: #print('sklearn rotate') ct = np.where(vdata == vdata.max()) #print('rotate') #print(vdata.shape,para_angle,ct[0][0],ct[1][0]) vdata = rotate(image=vdata, angle=para_angle, center=[ct[0][0], ct[1][0]]) #except: #from scipy.ndimage import rotate #print('scipy rotate') #vdata = rotate(input=vdata,angle=para_angle,reshape=False) ### Rescale model to diameter vhead['CDELT1'] = vhead['CDELT1'] * (vhead['DIAMETER'] / diameter) vhead['CDELT2'] = vhead['CDELT2'] * (vhead['DIAMETER'] / diameter) ### Rescale model to frequency vhead['CDELT1'] = vhead['CDELT1'] * (vhead['CRVAL3'] / c_freq) vhead['CDELT2'] = vhead['CDELT2'] * (vhead['CRVAL3'] / c_freq) ### Set phase centres vhead['CRVAL1'] = phase_centre[0] vhead['CRVAL2'] = phase_centre[1] #print('wcs') ### Set cutout re-sampling wcs = WCS(vhead, naxis=2) #print('wcs convert') centre_p = wcs.all_world2pix(centre[0] * u.deg, centre[1] * u.deg, 0) scale = vhead['CDELT1'] / np.abs(cdelt[0]) ## Add hard total pixel scaling factor # (bigger machines can have > 2e4 but probably overkill) sz = 2000 while scale * sz > 2e4: sz = int(sz - 2) if sz < 2: print("error size less than 2") sys.exit() hdu_cut = Cutout2D(data=vdata,wcs=wcs,\ position=[centre_p[0],centre_p[1]],\ size=[sz,sz]) ## Adjust scales to take this into account vhead = hdu_cut.wcs.to_header() vhead['CDELT1'] = vhead['CDELT1'] / scale vhead['CDELT2'] = vhead['CDELT2'] / scale vhead['CRPIX1'] = vhead['CRPIX1'] * scale vhead['CRPIX2'] = vhead['CRPIX2'] * scale data = rescale(hdu_cut.data, scale) wcs = WCS(vhead, naxis=2) centre_p = wcs.all_world2pix(centre[0] * u.deg, centre[1] * u.deg, 0) hdu_cut = Cutout2D(data=data, wcs=wcs,\ position=[centre_p[0],centre_p[1]],\ size=size) if ret_singular == False: return hdu_cut.data else: hc = hdu_cut.data.shape return hdu_cut.data[int(hc[0] / 2), int(hc[1] / 2)]
def calc_pb_synthetic(msfile, diam_ants, single_freq, array): tb = casatools.table() qa = casatools.quanta() me = casatools.measures() degree_off = float(msfile.split('_')[1]) + ( float(msfile.split('_')[2].split('.ms')[0]) / 60.) degree_off = degree_off / 60. print('times') tb.open('%s' % msfile) t = tb.getcol('TIME') t = [np.min(t), np.max(t)] t = np.arange(t[0], t[1], 3600) print(len(t)) tb.close() print('parang') para_angle = parallacticAngle(msfile, t) print(np.max(para_angle), np.min(para_angle), np.shape(para_angle)) if os.path.exists('../random_feed_rotation_%s.npy' % array): angle = np.load('../random_feed_rotation_%s.npy' % array) for i in range(np.shape(para_angle)[0]): para_angle[ i, :] = (angle[i] + para_angle[i, :] + 180) % (2 * 180) - 180 else: angle = np.random.default_rng().uniform(low=-180, high=180, size=(np.shape(para_angle)[0])) np.save('../random_feed_rotation_%s.npy' % array, angle) for i in range(np.shape(para_angle)[0]): para_angle[ i, :] = (angle[i] + para_angle[i, :] + 180) % (2 * 180) - 180 tb.open('%s/SPECTRAL_WINDOW' % msfile) nspw = len(tb.getcol("MEAS_FREQ_REF")) chan_freqs = tb.getcol('CHAN_FREQ').T tb.close() if single_freq != False: freq = np.mean(chan_freqs) chan_freqs = [freq] * nspw datacolumn = 'MODEL_DATA' tb.open('%s' % msfile, nomodify=True) data = tb.getcol('%s' % datacolumn) times = tb.getcol('TIME') antenna1 = tb.getcol('ANTENNA1') antenna2 = tb.getcol('ANTENNA2') spw_id = tb.getcol('DATA_DESC_ID') tint = np.average(tb.getcol('EXPOSURE')) tb.close() print('rescale') for k in range(len(t)): diams_ants2 = {} for o, i in enumerate(diams_ants.keys()): pb_freq = {} for j in range(nspw): print(k, o, j) pb_freq[str(j)] = rescale_synthetic_HPBW( header=[180., 60 + degree_off], c_freq=chan_freqs[j], diameter=diam_ants[i], vmodel='%s_voltage_response_100.0m.fits' % msfile, a_term_upscale=8, phase_centre=[180., 60.], para_angle=para_angle[o, k]) print('Ant %d (%s), time %.10e, freq %d, pbcor %.5f' % (o, i, t[k], chan_freqs[j], pb_freq[str(j)])) #pb_freq[str(j)] = np.sqrt(calc_hpbw(x=degree_off,diam=diam_ants[i],freq=chan_freqs[j])) diams_ants2[i] = pb_freq if k == (len(t) - 1): sub_ant1 = antenna1[(times >= t[k])] sub_ant2 = antenna2[(times >= t[k])] sub_data = data[:, :, (times >= t[k])] else: sub_ant1 = antenna1[((times >= t[k]) & (times < t[k + 1]))] sub_ant2 = antenna2[((times >= t[k]) & (times < t[k + 1]))] sub_data = data[:, :, ((times >= t[k]) & (times < t[k + 1]))] for i in range(len(sub_ant1)): amps, phase = R2P(sub_data[:, :, i]) amps = amps * (diams_ants2[sub_ant1[i]][str(spw_id[i])] * diams_ants2[sub_ant2[i]][str(spw_id[i])]) sub_data[:, :, i] = P2R(amps, phase) if k == (len(t) - 1): data[:, :, (times >= t[k])] = sub_data else: data[:, :, ((times >= t[k]) & (times < t[k + 1]))] = sub_data tb.open('%s' % msfile, nomodify=False) tb.putcol('%s' % datacolumn, data) tb.close() return
def create_model(snu_ff, nu0, dust_ff_ratio, bandwidth=7.5, startfreq=35.0, offset_position=[0.0, 0.0], direction="J2000 10h00m00.0s -30d00m00.0s", modelname='skymodel_test'): ''' create an ms with a point source with the given spectrum. ''' from casatasks.private import simutil u = simutil.simutil() from casatools import quanta from casatools import componentlist from casatools import image from casatools import measures qa = quanta() cl = componentlist() me = measures() ia = image() obs_freq = np.linspace(startfreq, startfreq + bandwidth, 1000) ff_spect = calc_ff_spect(snu_ff, nu0, obs_freq) dust_spect = calc_dust_spect(snu_ff, nu0, dust_ff_ratio, obs_freq) comb_spect = ff_spect + dust_spect xx = u.direction_splitter(direction) qra = xx[1] qdec = xx[2] qra1 = qa.add(qra, str(offset_position[0]) + "arcsec") qdec1 = qa.add(qdec, str(offset_position[1]) + "arcsec") xx1 = xx[0] + " " + qa.formxxx(qra1, format='hms', prec=3) + " " + qa.formxxx( qdec1, format='dms', prec=4) cl.done() #close any open component list cl.addcomponent(flux=1.0, dir=xx1, shape='point') # tabularfreq in Hz # tabularflux in Jy obs_freq_Hz = obs_freq * 1e9 cl.setspectrum(which=0, type='tabular', tabularfreqs=obs_freq_Hz, tabularflux=comb_spect) filename = modelname + '.cl' if os.path.exists(filename): shutil.rmtree(filename) cl.rename(filename) # make a skymodel from the component list since simobserve # doesn't handle the component lists with frequency dependence. # Don't need header info. can set that in simobserve ia.done() filename = modelname + ".image" if os.path.exists(filename): shutil.rmtree(filename) ia.fromshape(filename, [300, 300, 1, len(obs_freq)], overwrite=True) cs = ia.coordsys() cs.setunits(['deg', 'deg', '', 'GHz']) cell_rad = qa.convert(qa.quantity("0.1arcsec"), "deg")['value'] cs.setincrement([-cell_rad, cell_rad], 'direction') cs.setreferencepixel(0, type='Spectral') cs.setreferencevalue(str(obs_freq[0]) + "GHz", 'Spectral') cs.setincrement("%.5fGHz" % np.diff(obs_freq)[0], 'spectral') tmp = cs.referencevalue(format='q') tmp['quantity']['*1'] = xx[1] tmp['quantity']['*2'] = xx[2] cs.setreferencevalue(value=tmp) ia.setcoordsys(cs.torecord()) ia.setbrightnessunit("Jy/pixel") ia.modify(cl.torecord(), subtract=False) ia.done() cl.done()
import casatasks as tasks import casatools as tools qa = tools.quanta() me = tools.measures() from astropy import coordinates, units, io import numpy as np import pylab as plt import os, glob, shutil def applycal(msfile, gaintables, gainfield=None, targetfield=None, interp=None, spw=None, spwmap=None): """ Apply CASA calibration using calibration tables Example Usage: applycal(msfile0, gaintables, targetfield=targetfield, gainfield=['', '', '', '', '', '', '', ''], interp=['linear', 'linear', 'linear', 'linear', 'linear,linearflag', 'linear', 'linear', 'linear']) """ if not gainfield: gainfield = ['' for _ in range(len(gaintables))] if not interp:
def makePB( vis="", field="", spw="", timerange="", uvrange="", antenna="", observation="", intent="", scan="", imtemplate="", outimage="", pblimit=0.2, stokes="", ): """ (modified from casarecipes.makepb to support multiple stokes) Make a PB image using the imager tool, onto a specified image coordinate system This function can be used along with tclean to make .pb images for gridders that do not already do it (i.e. other than mosaic, awproject) This script takes an image to use as a template coordinate system, attempts to set up an identical coordinate system with the old imager tool, makes a PB for the telescope listed in the MS observation subtable, and regrids it (just in case) to the target coordinate system). This can be used for single fields and mosaics. """ tb = casatools.table() im = casatools.imager() ia = casatools.image() me = casatools.measures() qa = casatools.quanta() print("MAKEPB : Making a PB image using the imager tool") tb.open(vis + "/OBSERVATION") tel = tb.getcol("TELESCOPE_NAME")[0] tb.close() tb.open(vis + "/SPECTRAL_WINDOW") mfreqref = tb.getcol("MEAS_FREQ_REF")[0] tb.close() if mfreqref == 64: print( "MAKEPB : This function is using old imager tool, Undefined frame may not be handled properly." ) print("MAKEPB : Making PB for ", tel) ia.open(imtemplate) csysa = ia.coordsys() csys = csysa.torecord() shp = ia.shape() ia.close() dirs = csys["direction0"] phasecenter = me.direction( dirs["system"], qa.quantity(dirs["crval"][0], dirs["units"][0]), qa.quantity(dirs["crval"][1], dirs["units"][1]), ) cellx = qa.quantity(fabs(dirs["cdelt"][0]), dirs["units"][0]) celly = qa.quantity(fabs(dirs["cdelt"][1]), dirs["units"][1]) nchan = shp[3] start = qa.quantity(csysa.referencevalue()["numeric"][3], csysa.units()[3]) # assumes refpix is zero mestart = me.frequency("LSRK", start) step = qa.quantity(csysa.increment()["numeric"][3], csysa.units()[3]) smode = "mfs" if nchan > 1: smode = "frequency" print("MAKEPB : Starting imager tool") im.open(vis) im.selectvis( field=field, spw=spw, time=timerange, intent=intent, scan=scan, uvrange=uvrange, baseline=antenna, observation=observation, ) im.defineimage( nx=shp[0], ny=shp[0], phasecenter=phasecenter, cellx=qa.tos(cellx), celly=qa.tos(celly), nchan=nchan, start=mestart, step=step, mode=smode, stokes=stokes, ) im.setvp(dovp=True, telescope=tel) im.makeimage(type="pb", image=outimage + ".tmp") im.close() if mfreqref == 64: # skip this step if the frame is 'Undefined' shutil.copytree(outimage + ".tmp", outimage) else: print("MAKEPB : Regrid to desired coordinate system") imregrid( imagename=outimage + ".tmp", template=imtemplate, output=outimage, overwrite=True, asvelocity=False, ) shutil.rmtree(outimage + ".tmp") print("MAKEPB : Set mask to pblimit") ia.open(outimage) ia.calcmask("'" + outimage + "'>" + str(pblimit)) ia.close()