# 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' """ from matplotlib.collections import LineCollection tb.open(msname)
def get_sim_model(calms, model_images, freqs, fwidths, pa=0.0, indirection='', del_cross=False, residuals=True): ''' Function that simulates a radiointerferometric observation out of a model fits image. It will produce the visibilities of the model using the same uv coverage as the provided calibrated visibilities. It needs to simulate a model image for each spw of the observations. The visibilities will be averaged in time (limited by scans) and frequency (limited by spws). The calibrated visibilities should already be splitted, with no other sources, and with the calibrated data in the 'data' datacolumn. INPUT parameters: - calms: calibrated (observed) visibilities. - model_images: list of model images at different frequencies, in fits format. These frequencies should be the central frequencies of the spws in the observations. They need to be in the same order, so first check the listobs of the observations. It has to be a list, even if you are simulating just one frequency. - freqs: list of central frequencies of the spws and model_images. It has to be a list, even if you are simulating just one frequency. In GHz. - fwidths: width of the spws of the observations. It can be a list with an element for each spw (freqs), or it can be just one value, and it will be assumed that all spws have the same width. In MHz. OPTIONAL parameters: - pa: position angle of the disk (from north to east). Provide it just if the disk needs to be rotated (DIAD images need to be rotated). - indirection: coordinates of the center of the model image. If not provided, it will look for this information in the header of the fits files. - residuals: Calculate residual visibilities (observation - model)? - del_cross: If True, it will delete cross polarizations. Usually only used for VLA observations, not for ALMA. OUTPUT: A vis_obj object with the visiblities in it. It will also create a simulated measurement set. NOTE: For now, calms needs to have only one channel per spw. ''' if len(model_images) != len(freqs): raise IOError( 'GET_SIM_MODEL: Number of frequencies should be the same' + ' as the number of input model images.') # We get the spectral windows of calms # ms.open(calms) # ms.selectinit(reset=True) # ms.selectinit() # axis_info = ms.getspectralwindowinfo() # ms.close() tb.open(calms) spwids = np.unique(tb.getcol("DATA_DESC_ID")) tb.close() # Get the frequency information tb.open(calms + '/SPECTRAL_WINDOW') freqstb = tb.getcol("CHAN_FREQ") tb.close() obs_spwids = [] RefFreqs = [] for key in spwids: obs_spwids.append(int(key)) # RefFreqs.append(round(axis_info[key]['RefFreq']/1e9,3)) # in GHz RefFreqs.append(round(freqstb[:, key] / 1e9, 6)) # in GHz obs_spwids = np.array(obs_spwids) RefFreqs = np.array(RefFreqs) mydat = [] if residuals: resdat = [] spwids = [] for freqid, freq0 in enumerate(freqs): freq0 = round(freq0, 6) # we round the frequency to have 6 decimal digits freq = str(freq0) + 'GHz' fitsimage = model_images[freqid] if type(fwidths) is list: widthf = str(fwidths[freqid]) + 'MHz' else: widthf = str(fwidths) + 'MHz' # We find the spwid for this frequency try: spwid = obs_spwids[RefFreqs == freq0][0] spwids.append(spwid) except: raise ValueError( 'GET_SIM_MODEL: Frequency ' + freq + ' is not one of ' + 'the reference frequencies of calms. It could be a rounding issue.' ) # Rotating image imObj = pyfits.open(fitsimage) Header = imObj[0].header # we keep the header mod_image = imObj[0].data[:, :] # image in matrix imObj.close() if pa != 0.0: rotangle = -(pa) rotdisk = scipy.ndimage.interpolation.rotate(mod_image, rotangle, reshape=False) fitsimage = fitsimage[:-4] + 'rot.fits' # Name of rotated image rotImObj = pyfits.writeto(fitsimage, rotdisk, Header, clobber=True) # We get the inbright and pixel size stats = imstat(fitsimage) if 'CUNIT1' in Header.keys(): if Header['CUNIT1'] == 'deg': delt = Header['CDELT1'] * np.pi / 180. # to radians elif Header['CUNIT1'] == 'rad': delt = Header['CDELT1'] else: raise IOError('GET_SIM_MODEL: Potentially weird coordinate ' + 'units. Please use deg or rad.') else: print('WARNING: Assuming units of model coordinates are deg.') delt = Header['CDELT1'] * np.pi / 180. # to radians if 'BUNIT' in Header.keys(): if Header['BUNIT'] == 'Jy/pixel': inbright = str(stats['max'][0]) + 'Jy/pixel' elif Header['BUNIT'] == 'W.m-2.pixel-1': # MCFOST format, nu*Fnu inbright = stats['max'][0] / (freq0 * 1e9) / 1e-26 # to Jy inbright = str(inbright) + 'Jy/pixel' elif Header['BUNIT'] == 'erg/s/cm2/Hz': inbright = str(stats['max'][0] * (delt**2.) * 1.0e23) + 'Jy/pixel' else: raise IOError( 'GET_SIM_MODEL: Potentially weird intensity ' + 'units. Please use Jy/pixel, W.m-2.pixel-1, or erg/s/cm2/Hz.' ) else: print('WARNING: Assuming units of model are erg s-1 cm-2 Hz-1.') inbright = str(stats['max'][0] * (delt**2.) * 1.0e23) + 'Jy/pixel' delta = np.abs(delt) * 180. / np.pi * 3600. # to arcsec # We import the image into CASA format imname0 = fitsimage[:-4] + 'image' importfits(fitsimage=fitsimage, imagename=imname0, overwrite=True, defaultaxes=False) # os.system('rm '+fitsimage) # We modify the image to include the stokes and frequency axis. util = simutil() imname = fitsimage[:-4] + 'fixed.image' util.modifymodel(inimage=imname0, outimage=imname, inbright=inbright, indirection=indirection, incell=str(delta) + 'arcsec', incenter=freq, inwidth=widthf, innchan=1) os.system('rm -r ' + imname0) # We split the calibrated visibilities in spw modelms = fitsimage[:-4] + 'model_vis.spw' + str( spwid) + 'freq' + freq + '.ms' if os.path.isdir(modelms) == False: split(vis=calms, outputvis=modelms, spw=str(spwid), keepflags=False, datacolumn='data') # We remove the pointing table tb.open(modelms + '/POINTING', nomodify=False) tb.removerows(range(tb.nrows())) tb.done() if residuals: residualms = (fitsimage[:-4] + 'model_vis.spw' + str(spwid) + 'freq' + freq + '.residuals_ms') if os.path.isdir(residualms) == False: os.system('cp -r ' + modelms + ' ' + residualms) # We simulate the observation sm.openfromms(modelms) sm.setvp() #sm.summary() sm.predict(imagename=imname) sm.done() os.system('rm -r ' + imname) # Extract visibilities of the model ms.open(modelms, nomodify=(del_cross == False)) ms.selectinit(reset=True) modeldata = ms.getdata( ['real', 'imaginary', 'u', 'v', 'weight', 'flag', 'data']) if del_cross: # If True, we flag the cross polarizations modeldata['real'][1, :, :] = modeldata['real'][0, :, :] modeldata['real'][2, :, :] = modeldata['real'][0, :, :] modeldata['imaginary'][1, :, :] = modeldata['imaginary'][0, :, :] modeldata['imaginary'][2, :, :] = modeldata['imaginary'][0, :, :] modeldata['data'][1, :, :] = modeldata['data'][0, :, :] modeldata['data'][2, :, :] = modeldata['data'][0, :, :] modeldata['flag'][1, :, :] = True modeldata['flag'][2, :, :] = True ms.putdata({'data': modeldata['data']}) mydat.append(modeldata) ms.close() # Residuals if residuals: # Extract visibilities of observations ms.open(calms) ms.selectinit(reset=True) ms.selectinit(datadescid=spwid) resdata = ms.getdata( ['real', 'imaginary', 'u', 'v', 'weight', 'flag', 'data']) ms.close() # Subtract model from observations resdata['real'] = resdata['real'] - modeldata['real'] resdata[ 'imaginary'] = resdata['imaginary'] - modeldata['imaginary'] resdata['data'] = resdata['data'] - modeldata['data'] if del_cross: resdata['flag'][1, :, :] = True resdata['flag'][2, :, :] = True resdat.append(resdata) # Save residuals to ms ms.open(residualms, nomodify=False) ms.selectinit(reset=True) ms.putdata({'data': resdata['data']}) ms.close() model_vis = CASA_vis_obj(mydat, np.array([freqs]).T * 1e9, name='model', spwids=spwids) if residuals: res_vis = CASA_vis_obj(resdat, np.array([freqs]).T * 1e9, name='residuals', spwids=spwids) return model_vis, res_vis else: return model_vis
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()
float(ra_src.split("h")[0]) + (float(ra_src.split("h")[1].split("m")[0]) / 60) + (float(ra_src.split("h")[1].split("m")[1][:-1]) / 3600)) hr_angle_src_end = lst_src_end - ( float(ra_src.split("h")[0]) + (float(ra_src.split("h")[1].split("m")[0]) / 60) + (float(ra_src.split("h")[1].split("m")[1][:-1]) / 3600)) start_time = str(round(hr_angle_src, 2)) + "h" stop_time = str(round(hr_angle_src_end, 2)) + "h" freq_min = str( qa.convert(str(freq_centre_src) + 'MHz', 'MHz')['value'] - (float(nfft_src) / 2) * qa.convert(str(16.0 / nfft_src) + 'MHz', 'MHz')['value']) + 'MHz' conf_file = 'gbd_src.cfg' u = simutil.simutil() xx, yy, zz, diam, padnames, padnames, telescope, posobs = u.readantenna( conf_file) ms_name = 'gbd_src.ms' sm.open(ms_name) pos_gmrt = me.observatory('GMRT') sm.setconfig(telescopename=telescope, x=xx, y=yy, z=zz, dishdiameter=diam.tolist(), mount='alt-az', antname=padnames, padname=padnames, coordsystem='global', referencelocation=pos_gmrt)