def time2filename(msfile, timerange='', spw=''): from astropy.time import Time tb.open(msfile) starttim = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd') endtim = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() datstr = starttim.iso[:10] ms.open(msfile) metadata = ms.metadata() observatory = metadata.observatorynames()[0] ms.close() if timerange is None or timerange == '': starttim1 = starttim endtim1 = endtim else: (tstart, tend) = timerange.split('~') if tstart[2] == ':': starttim1 = Time(datstr + 'T' + tstart) endtim1 = Time(datstr + 'T' + tend) else: starttim1 = Time(qa.quantity(tstart, 'd')['value'], format='mjd') endtim1 = Time(qa.quantity(tend, 'd')['value'], format='mjd') midtime = Time((starttim1.mjd + endtim1.mjd) / 2., format='mjd') tstr = midtime.to_datetime().strftime('{}_%Y%m%dT%H%M%S'.format(observatory)) if spw: spstr = 'spw{}'.format(spw.replace('~', '-')) filename = '.'.join([tstr, spstr]) else: filename = tstr return filename
def checkMS(msFile, cont=True): """ get the number of spw and channels in the measurement set for continuum: combine into 1 channel and spw before running uvmcmcfit Parameters ---------- msFile: string CASA measurement set Returns ------- nspw: number of spw nchan: number of channels """ from taskinit import ms ms.open(msFile) metadata = ms.metadata() ms.done() nspw = metadata.nspw() for i in range(nspw): # number of channels in each spw nchan = metadata.nchan(spw) metadata.done() return nspw, nchan
def read_horizons(t0=None, dur=None, vis=None, observatory=None, verbose=False): ''' This function visits JPL Horizons to retrieve J2000 topocentric RA and DEC of the solar disk center as a function of time. Keyword arguments: t0: Referece time in astropy.Time format dur: duration of the returned coordinates. Default to 2 minutes vis: CASA visibility dataset (in measurement set format). If provided, use entire duration from the visibility data observatory: observatory code (from JPL Horizons). If not provided, use information from visibility. if no visibility found, use earth center (code=500) verbose: True to provide extra information Usage: >>> from astropy.time import Time >>> out = read_horizons(t0=Time('2017-09-10 16:00:00'), observatory='-81') >>> out = read_horizons(vis = 'mydata.ms') History: BC (sometime in 2014): function was first wrote, followed by a number of edits by BC and SY BC (2019-07-16): Added docstring documentation ''' try: # For Python 3.0 and later from urllib.request import urlopen except ImportError: # Fall back to Python 2's urllib2 from urllib2 import urlopen import ssl if not t0 and not vis: t0 = Time.now() if not dur: dur = 1. / 60. / 24. # default to 2 minutes if t0: try: btime = Time(t0) except: print('input time ' + str(t0) + ' not recognized') return -1 if vis: if not os.path.exists(vis): print('Input ms data ' + vis + ' does not exist! ') return -1 try: # ms.open(vis) # summary = ms.summary() # ms.close() # btime = Time(summary['BeginTime'], format='mjd') # etime = Time(summary['EndTime'], format='mjd') ## alternative way to avoid conflicts with importeovsa, if needed -- more time consuming if observatory == 'geocentric': observatory = '500' else: ms.open(vis) metadata = ms.metadata() if metadata.observatorynames()[0] == 'EVLA': observatory = '-5' elif metadata.observatorynames()[0] == 'EOVSA': observatory = '-81' elif metadata.observatorynames()[0] == 'ALMA': observatory = '-7' ms.close() tb.open(vis) btime_vis = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd') etime_vis = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() if verbose: print("Beginning time of this scan " + btime_vis.iso) print("End time of this scan " + etime_vis.iso) # extend the start and end time for jpl horizons by 0.5 hr on each end btime = Time(btime_vis.mjd - 0.5 / 24., format='mjd') dur = etime_vis.mjd - btime_vis.mjd + 1.0 / 24. except: print('error in reading ms file: ' + vis + ' to obtain the ephemeris!') return -1 # default the observatory to geocentric, if none provided if not observatory: observatory = '500' etime = Time(btime.mjd + dur, format='mjd') try: cmdstr = "https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1&TABLE_TYPE='OBSERVER'&QUANTITIES='1,17,20'&CSV_FORMAT='YES'&ANG_FORMAT='DEG'&CAL_FORMAT='BOTH'&SOLAR_ELONG='0,180'&CENTER='{}@399'&COMMAND='10'&START_TIME='".format( observatory ) + btime.iso.replace( ' ', ',' ) + "'&STOP_TIME='" + etime.iso[:-4].replace( ' ', ',' ) + "'&STEP_SIZE='1m'&SKIP_DAYLT='NO'&EXTRA_PREC='YES'&APPARENT='REFRACTED'" cmdstr = cmdstr.replace("'", "%27") try: context = ssl._create_unverified_context() f = urlopen(cmdstr, context=context) except: f = urlopen(cmdstr) lines = f.readlines() f.close() except: # todo use geocentric coordinate for the new VLA data import requests, collections params = collections.OrderedDict() params['batch'] = '1' params['TABLE_TYPE'] = "'OBSERVER'" params['QUANTITIES'] = "'1,17,20'" params['CSV_FORMAT'] = "'YES'" params['ANG_FORMAT'] = "'DEG'" params['CAL_FORMAT'] = "'BOTH'" params['SOLAR_ELONG'] = "'0,180'" if observatory == '500': params['CENTER'] = "'500'" else: params['CENTER'] = "'{}@399'".format(observatory) params['COMMAND'] = "'10'" params['START_TIME'] = "'{}'".format(btime.iso[:-4].replace(' ', ',')) params['STOP_TIME'] = "'{}'".format(etime.iso[:-4].replace(' ', ',')) params['STEP_SIZE'] = "'1m'" params['SKIP_DAYLT'] = "'NO'" params['EXTRA_PREC'] = "'YES'" params['APPAENT'] = "'REFRACTED'" results = requests.get("https://ssd.jpl.nasa.gov/horizons_batch.cgi", params=params) lines = [ll for ll in results.iter_lines()] # add a check for python 3 if py3: lines = [l.decode('utf-8', 'backslashreplace') for l in lines] nline = len(lines) istart = 0 for i in range(nline): if lines[i][0:5] == '$$SOE': # start recording istart = i + 1 if lines[i][0:5] == '$$EOE': # end recording iend = i newlines = lines[istart:iend] nrec = len(newlines) ephem_ = [] t = [] ra = [] dec = [] p0 = [] delta = [] for line in newlines: items = line.split(',') t.append(Time(float(items[1]), format='jd').mjd) ra.append(np.radians(float(items[4]))) dec.append(np.radians(float(items[5]))) p0.append(float(items[6])) delta.append(float(items[8])) # convert list of dictionary to a dictionary of arrays ephem = {'time': t, 'ra': ra, 'dec': dec, 'p0': p0, 'delta': delta} return ephem
def read_msinfo(vis=None, msinfofile=None, use_scan_time=True): import glob # read MS information # msinfo = dict.fromkeys([ 'vis', 'scans', 'fieldids', 'btimes', 'btimestr', 'inttimes', 'ras', 'decs', 'observatory' ]) ms.open(vis) metadata = ms.metadata() observatory = metadata.observatorynames()[0] scans = ms.getscansummary() scanids = sorted(scans.keys(), key=lambda x: int(x)) nscanid = len(scanids) btimes = [] btimestr = [] etimes = [] fieldids = [] inttimes = [] dirs = [] ras = [] decs = [] ephem_file = glob.glob(vis + '/FIELD/EPHEM*SUN.tab') if ephem_file: print('Loading ephemeris info from {}'.format(ephem_file[0])) tb.open(ephem_file[0]) col_ra = tb.getcol('RA') col_dec = tb.getcol('DEC') col_mjd = tb.getcol('MJD') if use_scan_time: from scipy.interpolate import interp1d f_ra = interp1d(col_mjd, col_ra) f_dec = interp1d(col_mjd, col_dec) for idx, scanid in enumerate(scanids): btimes.append(scans[scanid]['0']['BeginTime']) etimes.append(scans[scanid]['0']['EndTime']) fieldid = scans[scanid]['0']['FieldId'] fieldids.append(fieldid) inttimes.append(scans[scanid]['0']['IntegrationTime']) ras = f_ra(np.array(btimes)) decs = f_dec(np.array(btimes)) ras = qa.convert(qa.quantity(ras, 'deg'), 'rad') decs = qa.convert(qa.quantity(decs, 'deg'), 'rad') else: ras = qa.convert(qa.quantity(col_ra, 'deg'), 'rad') decs = qa.convert(qa.quantity(col_dec, 'deg'), 'rad') else: for idx, scanid in enumerate(scanids): btimes.append(scans[scanid]['0']['BeginTime']) etimes.append(scans[scanid]['0']['EndTime']) fieldid = scans[scanid]['0']['FieldId'] fieldids.append(fieldid) inttimes.append(scans[scanid]['0']['IntegrationTime']) dir = ms.getfielddirmeas('PHASE_DIR', fieldid) dirs.append(dir) ras.append(dir['m0']) decs.append(dir['m1']) ms.close() btimestr = [ qa.time(qa.quantity(btimes[idx], 'd'), form='fits', prec=10)[0] for idx in range(nscanid) ] msinfo['vis'] = vis msinfo['scans'] = scans msinfo['fieldids'] = fieldids msinfo['btimes'] = btimes msinfo['btimestr'] = btimestr msinfo['inttimes'] = inttimes msinfo['ras'] = ras msinfo['decs'] = decs msinfo['observatory'] = observatory if msinfofile: np.savez(msinfofile, vis=vis, scans=scans, fieldids=fieldids, btimes=btimes, btimestr=btimestr, inttimes=inttimes, ras=ras, decs=decs, observatory=observatory) return msinfo
def calc_phasecenter_from_solxy(vis, timerange='', xycen=None, usemsphacenter=True): ''' return the phase center in RA and DEC of a given solar coordinates :param vis: input measurement sets file :param timerange: can be a string or astropy.time.core.Time object, or a 2-element list of string or Time object :param xycen: solar x-pos and y-pos in arcsec :param usemsphacenter: :return: phasecenter midtim: mid time of the given timerange ''' tb.open(vis + '/POINTING') tst = Time(tb.getcell('TIME_ORIGIN', 0) / 24. / 3600., format='mjd') ted = Time(tb.getcell('TIME_ORIGIN', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() datstr = tst.iso[:10] if isinstance(timerange, Time): try: (sttim, edtim) = timerange except: sttim = timerange edtim = sttim else: if timerange == '': sttim = tst edtim = ted else: try: (tstart, tend) = timerange.split('~') if tstart[2] == ':': sttim = Time(datstr + 'T' + tstart) edtim = Time(datstr + 'T' + tend) # timerange = '{0}/{1}~{0}/{2}'.format(datstr.replace('-', '/'), tstart, tend) else: sttim = Time(qa.quantity(tstart, 'd')['value'], format='mjd') edtim = Time(qa.quantity(tend, 'd')['value'], format='mjd') except: try: if timerange[2] == ':': sttim = Time(datstr + 'T' + timerange) edtim = sttim else: sttim = Time(qa.quantity(timerange, 'd')['value'], format='mjd') edtim = sttim except ValueError: print("keyword 'timerange' in wrong format") ms.open(vis) metadata = ms.metadata() observatory = metadata.observatorynames()[0] ms.close() midtim_mjd = (sttim.mjd + edtim.mjd) / 2. midtim = Time(midtim_mjd, format='mjd') eph = read_horizons(t0=midtim) if observatory == 'EOVSA' or (not usemsphacenter): print('This is EOVSA data') # use RA and DEC from FIELD ID 0 tb.open(vis + '/FIELD') phadir = tb.getcol('PHASE_DIR').flatten() tb.close() ra0 = phadir[0] dec0 = phadir[1] else: ra0 = eph['ra'][0] dec0 = eph['dec'][0] if not xycen: # use solar disk center as default phasecenter = 'J2000 ' + str(ra0) + 'rad ' + str(dec0) + 'rad' else: x0 = np.radians(xycen[0] / 3600.) y0 = np.radians(xycen[1] / 3600.) p0 = np.radians(eph['p0'][0]) # p angle in radians raoff = -((x0) * np.cos(p0) - y0 * np.sin(p0)) / np.cos(eph['dec'][0]) decoff = (x0) * np.sin(p0) + y0 * np.cos(p0) newra = ra0 + raoff newdec = dec0 + decoff phasecenter = 'J2000 ' + str(newra) + 'rad ' + str(newdec) + 'rad' return phasecenter, midtim
def read_horizons(t0=None, dur=None, vis=None, observatory=None, verbose=False): import urllib2 import ssl if not t0 and not vis: t0 = Time.now() if not dur: dur = 1. / 60. / 24. # default to 2 minutes if t0: try: btime = Time(t0) except: print('input time ' + str(t0) + ' not recognized') return -1 if vis: if not os.path.exists(vis): print 'Input ms data ' + vis + ' does not exist! ' return -1 try: # ms.open(vis) # summary = ms.summary() # ms.close() # btime = Time(summary['BeginTime'], format='mjd') # etime = Time(summary['EndTime'], format='mjd') ## alternative way to avoid conflicts with importeovsa, if needed -- more time consuming if observatory == 'geocentric': observatory = '500' else: ms.open(vis) metadata = ms.metadata() if metadata.observatorynames()[0] == 'EVLA': observatory = '-5' elif metadata.observatorynames()[0] == 'EOVSA': observatory = '-81' elif metadata.observatorynames()[0] == 'ALMA': observatory = '-7' ms.close() tb.open(vis) btime_vis = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd') etime_vis = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() if verbose: print "Beginning time of this scan " + btime_vis.iso print "End time of this scan " + etime_vis.iso # extend the start and end time for jpl horizons by 0.5 hr on each end btime = Time(btime_vis.mjd - 0.5 / 24., format='mjd') dur = etime_vis.mjd - btime_vis.mjd + 1.0 / 24. except: print 'error in reading ms file: ' + vis + ' to obtain the ephemeris!' return -1 # default the observatory to VLA, if none provided if not observatory: observatory = '-5' etime = Time(btime.mjd + dur, format='mjd') try: cmdstr = "https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1&TABLE_TYPE='OBSERVER'&QUANTITIES='1,17,20'&CSV_FORMAT='YES'&ANG_FORMAT='DEG'&CAL_FORMAT='BOTH'&SOLAR_ELONG='0,180'&CENTER='{}@399'&COMMAND='10'&START_TIME='".format( observatory ) + btime.iso.replace( ' ', ',' ) + "'&STOP_TIME='" + etime.iso[:-4].replace( ' ', ',' ) + "'&STEP_SIZE='1m'&SKIP_DAYLT='NO'&EXTRA_PREC='YES'&APPARENT='REFRACTED'" cmdstr = cmdstr.replace("'", "%27") try: context = ssl._create_unverified_context() f = urllib2.urlopen(cmdstr, context=context) except: f = urllib2.urlopen(cmdstr) lines = f.readlines() f.close() except: #todo use geocentric coordinate for the new VLA data import requests, collections params = collections.OrderedDict() params['batch'] = '1' params['TABLE_TYPE'] = "'OBSERVER'" params['QUANTITIES'] = "'1,17,20'" params['CSV_FORMAT'] = "'YES'" params['ANG_FORMAT'] = "'DEG'" params['CAL_FORMAT'] = "'BOTH'" params['SOLAR_ELONG'] = "'0,180'" if observatory == '500': params['CENTER'] = "'500'" else: params['CENTER'] = "'{}@399'".format(observatory) params['COMMAND'] = "'10'" params['START_TIME'] = "'{}'".format(btime.iso[:-4].replace(' ', ',')) params['STOP_TIME'] = "'{}'".format(etime.iso[:-4].replace(' ', ',')) params['STEP_SIZE'] = "'1m'" params['SKIP_DAYLT'] = "'NO'" params['EXTRA_PREC'] = "'YES'" params['APPAENT'] = "'REFRACTED'" results = requests.get("https://ssd.jpl.nasa.gov/horizons_batch.cgi", params=params) lines = [ll for ll in results.iter_lines()] nline = len(lines) istart = 0 for i in range(nline): line = lines[i] if line[0:5] == '$$SOE': # start recording istart = i + 1 if line[0:5] == '$$EOE': # end recording iend = i newlines = lines[istart:iend] nrec = len(newlines) ephem_ = [] t = [] ra = [] dec = [] p0 = [] delta = [] for line in newlines: items = line.split(',') t.append(Time(float(items[1]), format='jd').mjd) ra.append(np.radians(float(items[4]))) dec.append(np.radians(float(items[5]))) p0.append(float(items[6])) delta.append(float(items[8])) # convert list of dictionary to a dictionary of arrays ephem = {'time': t, 'ra': ra, 'dec': dec, 'p0': p0, 'delta': delta} return ephem
def mk_qlook_image(vis, ncpu=10, twidth=12, stokes='I,V', antenna='', imagedir=None, spws=[], toTb=True, overwrite=True, doslfcal=False, phasecenter='', c_external=True): vis = [vis] subdir = ['/'] for idx, f in enumerate(vis): if f[-1] == '/': vis[idx] = f[:-1] if not imagedir: imagedir = './' imres = {'Succeeded': [], 'BeginTime': [], 'EndTime': [], 'ImageName': [], 'Spw': [], 'Vis': [], 'Freq': []} msfile = vis[0] ms.open(msfile) metadata = ms.metadata() observatory = metadata.observatorynames()[0] # axisInfo = ms.getdata(["axis_info"], ifraxis=True) spwInfo = ms.getspectralwindowinfo() # freqInfo = axisInfo["axis_info"]["freq_axis"]["chan_freq"].swapaxes(0, 1) / 1e9 # freqInfo_ravel = freqInfo.ravel() ms.close() if not spws: if observatory == 'EVLA': spws = ['0', '1', '2', '3', '4', '5', '6', '7'] if observatory == 'EOVSA': spws = ['1~5', '6~10', '11~15', '16~25'] if observatory == 'EOVSA': print 'Provide stokes: ' + str(stokes) + '. However EOVSA has linear feeds. Force stokes to be IV' stokes = 'I,V' msfilebs = os.path.basename(msfile) imdir = imagedir + subdir[0] if not os.path.exists(imdir): os.makedirs(imdir) if doslfcal: slfcalms = './' + msfilebs + '.rr' split(msfile, outputvis=slfcalms, datacolumn='corrected', correlation='RR') for spw in spws: spwran = [s.zfill(2) for s in spw.split('~')] # freqran = [ # (int(s) * spwInfo['0']['TotalWidth'] + spwInfo['0']['RefFreq'] + spwInfo['0']['TotalWidth'] / 2.0) / 1.0e9 # for s in spw.split('~')] spw_ = spw.split('~') if len(spw_) == 2: freqran = [(spwInfo['{}'.format(s)]['RefFreq'] + spwInfo['{}'.format(s)]['TotalWidth'] / 2.0) / 1.0e9 for s in spw.split('~')] elif len(spw_) == 1: s = spw_[0] freqran = np.array([0, spwInfo['{}'.format(s)]['TotalWidth']]) + spwInfo['{}'.format(s)]['RefFreq'] freqran = freqran / 1.0e9 freqran = list(freqran) else: raise ValueError("Keyword 'spw' in wrong format") cfreq = np.mean(freqran) bmsz = max(30. / cfreq, 30.) uvrange = '<3km' if cfreq < 10.: imsize = 512 cell = ['5arcsec'] else: imsize = 1024 cell = ['2.5arcsec'] if len(spwran) == 2: spwstr = spwran[0] + '~' + spwran[1] else: spwstr = spwran[0] restoringbeam = ['{0:.1f}arcsec'.format(bmsz)] imagesuffix = '.spw' + spwstr.replace('~', '-') # if cfreq > 10.: # antenna = antenna + ';!0&1;!0&2' # deselect the shortest baselines sto = stokes.replace(',', '') if c_external: cleanscript = os.path.join(imdir, 'ptclean_external.py') resfile = os.path.join(imdir, os.path.basename(msfile) + '.res.npz') os.system('rm -rf {}'.format(cleanscript)) inpdict = {'vis': msfile, 'imageprefix': imdir, 'imagesuffix': imagesuffix, 'twidth': twidth, 'uvrange': uvrange, 'spw': spw, 'ncpu': ncpu, 'niter': 1000, 'gain': 0.05, 'antenna': antenna, 'imsize': imsize, 'cell': cell, 'stokes': sto, 'doreg': True, 'overwrite': overwrite, 'toTb': toTb, 'restoringbeam': restoringbeam, 'uvtaper': True, 'outertaper': ['30arcsec'], 'phasecenter': phasecenter} for key, val in inpdict.items(): if type(val) is str: inpdict[key] = '"{}"'.format(val) fi = open(cleanscript, 'wb') fi.write('from ptclean_cli import ptclean_cli as ptclean \n') fi.write('import numpy as np \n') fi.write( 'res = ptclean(vis={i[vis]},imageprefix={i[imageprefix]},imagesuffix={i[imagesuffix]},twidth={i[twidth]},uvrange={i[uvrange]},spw={i[spw]},ncpu={i[ncpu]},niter={i[niter]},gain={i[gain]},antenna={i[antenna]},imsize={i[imsize]},cell={i[cell]},stokes={i[stokes]},doreg={i[doreg]},overwrite={i[overwrite]},toTb={i[toTb]},restoringbeam={i[restoringbeam]},uvtaper={i[uvtaper]},outertaper={i[outertaper]},phasecenter={i[phasecenter]}) \n'.format( i=inpdict)) fi.write('np.savez("{}",res=res) \n'.format(resfile)) fi.close() os.system('casa --nologger -c {}'.format(cleanscript)) res = np.load(resfile) res = res['res'].item() else: res = ptclean(vis=msfile, imageprefix=imdir, imagesuffix=imagesuffix, twidth=twidth, uvrange=uvrange, spw=spw, ncpu=ncpu, niter=1000, gain=0.05, antenna=antenna, imsize=imsize, cell=cell, stokes=sto, doreg=True, overwrite=overwrite, toTb=toTb, restoringbeam=restoringbeam, uvtaper=True, outertaper=['30arcsec'], phasecenter=phasecenter) if res: imres['Succeeded'] += res['Succeeded'] imres['BeginTime'] += res['BeginTime'] imres['EndTime'] += res['EndTime'] imres['ImageName'] += res['ImageName'] imres['Spw'] += [spwstr] * len(res['ImageName']) imres['Vis'] += [msfile] * len(res['ImageName']) imres['Freq'] += [freqran] * len(res['ImageName']) else: return None # save it for debugging purposes np.savez(os.path.join(imagedir, '{}.imres.npz'.format(os.path.basename(msfile))), imres=imres) return imres
def svplot(vis, timerange=None, spw='', workdir='./', specfile=None, bl=None, uvrange=None, stokes='RR,LL', dmin=None, dmax=None, goestime=None, reftime=None, xycen=None, fov=[500.,500.], xyrange=None, restoringbeam=[''], robust=0.0, niter=500, imsize=[512], cell=['5.0arcsec'],interactive=False, usemsphacenter=True, imagefile=None, fitsfile=None, plotaia=True, aiawave=171, aiafits=None, savefig=False, mkmovie=False, overwrite=True, ncpu=10, twidth=1, verbose=True): ''' Required inputs: vis: calibrated CASA measurement set Important optional inputs: timerange: timerange for clean. Standard CASA time selection format. If not provided, use the entire range (*BE CAREFUL, COULD BE VERY SLOW*) spw: spectral window selection following the CASA syntax. Examples: spw='1:2~60' (spw id 1, channel range 2-60); spw='*:1.2~1.3GHz' (selects all channels within 1.2-1.3 GHz; note the *) specfile: supply dynamic spectrum save file (from suncasa.utils.dspec2.get_dspec()). Otherwise generate a median dynamic spectrum on the fly Optional inputs: bl: baseline to generate dynamic spectrum uvrange: uvrange to select baselines for generating dynamic spectrum stokes: polarization of the clean image, can be 'RR,LL' or 'I,V' dmin,dmax: color bar parameter goestime: goes plot time, example ['2016/02/18 18:00:00','2016/02/18 23:00:00'] rhessisav: rhessi savefile reftime: reftime for the image xycen: center of the image in helioprojective coordinates (HPLN/HPLT), in arcseconds. Example: [900, -150.] fov: field of view in arcsecs. Example: [500., 500.] xyrange: field of view in solar XY coordinates. Format: [[x1,x2],[y1,y2]]. Example: [[900., 1200.],[0,300]] ***NOTE: THIS PARAMETER OVERWRITES XYCEN AND FOV*** aiawave: wave length of aia file in a imagefile: if imagefile provided, use it. Otherwise do clean and generate a new one. fitsfile: if fitsfile provided, use it. Otherwise generate a new one savefig: whether to save the figure Example: ''' if xycen: xc, yc = xycen xlen, ylen = fov if parse_version(sunpy.__version__)>parse_version('0.8.0'): xyrange = [[xc - xlen / 2.0, yc - ylen / 2.0], [xc + xlen / 2.0, yc + ylen / 2.0]] else: xyrange = [[xc - xlen / 2.0, xc + xlen / 2.0], [yc - ylen / 2.0, yc + ylen / 2.0]] stokes_allowed = ['RR,LL', 'I,V', 'RRLL', 'IV'] if not stokes in stokes_allowed: print 'wrong stokes parameter ' + str(stokes) + '. Allowed values are ' + ', '.join(stokes_allowed) return -1 if stokes == 'RRLL': stokes = 'RR,LL' if stokes == 'IV': stokes = 'I,V' if vis[-1] == '/': vis = vis[:-1] if not os.path.exists(vis): print 'input measurement not exist' return -1 if aiafits is None: aiafits = '' # split the data # generating dynamic spectrum if not os.path.exists(workdir): os.makedirs(workdir) if specfile: try: specdata = np.load(specfile) except: print('Provided dynamic spectrum file not numpy npz. Generating one from the visibility data') specfile = os.path.join(workdir, os.path.basename(vis) + '.dspec.npz') dspec_external(vis, workdir=workdir, specfile=specfile) specdata = np.load(specfile) # specdata = ds.get_dspec(vis, domedian=True, verbose=True) else: print('Dynamic spectrum file not provided; Generating one from the visibility data') # specdata = ds.get_dspec(vis, domedian=True, verbose=True) specfile = os.path.join(workdir, os.path.basename(vis) + '.dspec.npz') dspec_external(vis, workdir=workdir, specfile=specfile) specdata = np.load(specfile) tb.open(vis) starttim = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd') endtim = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() datstr = starttim.iso[:10] if timerange is None or timerange == '': starttim1 = starttim endtim1 = endtim timerange = '{0}~{1}'.format(starttim.iso.replace('-', '/').replace(' ', '/'), endtim.iso.replace('-', '/').replace(' ', '/')) else: try: (tstart, tend) = timerange.split('~') if tstart[2] == ':': starttim1 = Time(datstr + 'T' + tstart) endtim1 = Time(datstr + 'T' + tend) timerange = '{0}/{1}~{0}/{2}'.format(datstr.replace('-', '/'), tstart, tend) else: starttim1 = Time(qa.quantity(tstart, 'd')['value'], format='mjd') endtim1 = Time(qa.quantity(tend, 'd')['value'], format='mjd') except ValueError: print "keyword 'timerange' in wrong format" midtime_mjd = (starttim1.mjd + endtim1.mjd) / 2. if vis.endswith('/'): vis = vis[:-1] visname = os.path.basename(vis) bt = starttim1.plot_date et = endtim1.plot_date # find out min and max frequency for plotting in dynamic spectrum ms.open(vis) metadata = ms.metadata() observatory = metadata.observatorynames()[0] spwInfo = ms.getspectralwindowinfo() nspw = len(spwInfo) if not spw: spw = '0~' + str(nspw - 1) staql = {'timerange': timerange, 'spw': spw} if ms.msselect(staql, onlyparse=True): ndx = ms.msselectedindices() chan_sel = ndx['channel'] nspw = chan_sel.shape[0] bspw = chan_sel[0, 0] bchan = chan_sel[0, 1] espw = chan_sel[-1, 0] echan = chan_sel[-1, 2] bfreq = spwInfo[str(bspw)]['Chan1Freq'] + spwInfo[str(bspw)]['ChanWidth'] * bchan efreq = spwInfo[str(espw)]['Chan1Freq'] + spwInfo[str(espw)]['ChanWidth'] * echan bfreqghz = bfreq / 1e9 efreqghz = efreq / 1e9 if verbose: print 'selected timerange {}'.format(timerange) print 'selected frequency range {0:6.3f} to {1:6.3f} GHz'.format(bfreqghz, efreqghz) else: print "spw or timerange selection failed. Aborting..." ms.close() return -1 ms.close() if observatory == 'EOVSA': print 'Provide stokes: ' + str(stokes) + '. However EOVSA has linear feeds. Force stokes to be IV' stokes = 'I,V' if mkmovie: plt.ioff() # fig = plt.figure(figsize=(12, 7.5), dpi=100) if fitsfile: pass else: if not imagefile: # from ptclean_cli import ptclean_cli as ptclean eph = hf.read_horizons(t0=Time(midtime_mjd, format='mjd')) if observatory == 'EOVSA' or (not usemsphacenter): phasecenter = '' else: phasecenter = 'J2000 ' + str(eph['ra'][0])[:15] + 'rad ' + str(eph['dec'][0])[:15] + 'rad' print 'use phasecenter: ' + phasecenter qlookfitsdir = os.path.join(workdir, 'qlookfits/') qlookfigdir = os.path.join(workdir, 'qlookimgs/') imresfile = os.path.join(qlookfitsdir, '{}.imres.npz'.format(os.path.basename(vis))) if overwrite: imres = mk_qlook_image(vis, twidth=twidth, ncpu=ncpu, imagedir=qlookfitsdir, phasecenter=phasecenter, stokes=stokes, c_external=True) else: if os.path.exists(imresfile): imres = np.load(imresfile) imres = imres['imres'].item() else: print('Image results file not found; Creating new images.') imres = mk_qlook_image(vis, twidth=twidth, ncpu=ncpu, imagedir=qlookfitsdir, phasecenter=phasecenter, stokes=stokes, c_external=True) if not os.path.exists(qlookfigdir): os.makedirs(qlookfigdir) plt_qlook_image(imres, figdir=qlookfigdir, specdata=specdata, verbose=True, stokes=stokes, fov=xyrange) else: spec = specdata['spec'] (npol, nbl, nfreq, ntim) = spec.shape tidx = range(ntim) fidx = range(nfreq) tim = specdata['tim'] freq = specdata['freq'] freqghz = freq / 1e9 spec_tim = Time(specdata['tim'] / 3600. / 24., format='mjd') timstrr = spec_tim.plot_date plt.ion() fig = plt.figure(figsize=(12, 7), dpi=100) gs1 = gridspec.GridSpec(3, 1) gs1.update(left=0.08, right=0.32, wspace=0.05) gs2 = gridspec.GridSpec(2, 2) gs2.update(left=0.38, right=0.98, hspace=0.02, wspace=0.02) spec_1 = np.absolute(spec[0, 0, :, :]) spec_2 = np.absolute(spec[1, 0, :, :]) if observatory == 'EVLA': # circular feeds polstr = ['RR', 'LL'] if observatory == 'EOVSA' or observatory == 'ALMA': # linear feeds polstr = ['XX', 'YY'] print 'plot the dynamic spectrum in pol ' + ' & '.join(polstr) ax1 = plt.subplot(gs1[0]) ax1.pcolormesh(timstrr, freqghz, spec_1, cmap='jet', vmin=dmin, vmax=dmax) ax1.set_xlim(timstrr[tidx[0]], timstrr[tidx[-1]]) ax1.xaxis_date() ax1.xaxis.set_major_formatter(DateFormatter("%H:%M:%S")) # ax1.set_xticklabels(['']*10) ax1.set_ylim(freqghz[fidx[0]], freqghz[fidx[-1]]) ax1.set_ylabel('Frequency (GHz)', fontsize=10) ax1.set_title(observatory + ' ' + datstr + ' ' + polstr[0] + ' & ' + polstr[1], fontsize=12) ax1.set_autoscale_on(False) ax1.add_patch(patches.Rectangle((bt, bfreqghz), et - bt, efreqghz - bfreqghz, ec='w', fill=False)) ax1.plot([(bt + et) / 2.], [(bfreqghz + efreqghz) / 2.], '*w', ms=12) for tick in ax1.get_xticklabels(): tick.set_fontsize(8) for tick in ax1.get_yticklabels(): tick.set_fontsize(8) ax2 = plt.subplot(gs1[1]) ax2.pcolormesh(timstrr, freqghz, spec_2, cmap='jet', vmin=dmin, vmax=dmax) ax2.set_xlim(timstrr[tidx[0]], timstrr[tidx[-1]]) ax2.xaxis_date() ax2.xaxis.set_major_formatter(DateFormatter("%H:%M:%S")) ax2.set_ylim(freqghz[fidx[0]], freqghz[fidx[-1]]) ax2.set_ylabel('Frequency (GHz)', fontsize=10) for tick in ax2.get_xticklabels(): tick.set_fontsize(8) for tick in ax2.get_yticklabels(): tick.set_fontsize(8) ax2.set_autoscale_on(False) ax2.add_patch(patches.Rectangle((bt, bfreqghz), et - bt, efreqghz - bfreqghz, ec='w', fill=False)) ax2.plot([(bt + et) / 2.], [(bfreqghz + efreqghz) / 2.], '*w', ms=12) # Second part: GOES plot if goestime: btgoes = goestime[0] etgoes = goestime[1] else: datstrg = datstr.replace('-', '/') btgoes = datstrg + ' ' + qa.time(qa.quantity(tim[0] - 1800, 's'), form='clean', prec=9)[0] etgoes = datstrg + ' ' + qa.time(qa.quantity(tim[tidx[-1] - 1] + 1800, 's'), form='clean', prec=9)[0] if verbose: print 'Acquire GOES soft X-ray data in from ' + btgoes + ' to ' + etgoes ax3 = plt.subplot(gs1[2]) try: from sunpy import lightcurve as lc from sunpy.time import TimeRange goest = lc.GOESLightCurve.create(TimeRange(btgoes, etgoes)) except: goesscript = os.path.join(workdir, 'goes.py') goesdatafile = os.path.join(workdir, 'goes.dat') os.system('rm -rf {}'.format(goesscript)) fi = open(goesscript, 'wb') fi.write('import os \n') fi.write('from sunpy.time import TimeRange \n') fi.write('from sunpy import lightcurve as lc \n') fi.write('import pickle \n') fi.write('goesplottim = TimeRange("{0}", "{1}") \n'.format(btgoes, etgoes)) fi.write('goes = lc.GOESLightCurve.create(goesplottim) \n') fi.write('fi2 = open("{}", "wb") \n'.format(goesdatafile)) fi.write('pickle.dump(goes, fi2) \n') fi.write('fi2.close()') fi.close() try: os.system('python {}'.format(goesscript)) os.system('rm -rf {}'.format(goesscript)) except NameError: print "Bad input names" except ValueError: print "Bad input values" except: print "Unexpected error:", sys.exc_info()[0] print "Error in generating GOES light curves. Proceed without GOES..." if os.path.exists(goesdatafile): fi1 = file(goesdatafile, 'rb') goest = pickle.load(fi1) fi1.close() try: dates = mpl.dates.date2num(parse_time(goest.data.index)) goesdif = np.diff(goest.data['xrsb']) gmax = np.nanmax(goesdif) gmin = np.nanmin(goesdif) ran = gmax - gmin db = 2.8 / ran goesdifp = goesdif * db + gmin + (-6) ax3.plot_date(dates, np.log10(goest.data['xrsb']), '-', label='1.0--8.0 $\AA$', color='red', lw=2) ax3.plot_date(dates[0:-1], goesdifp, '-', label='derivate', color='blue', lw=0.4) ax3.set_ylim([-7, -3]) ax3.set_yticks([-7, -6, -5, -4, -3]) ax3.set_yticklabels([r'$10^{-7}$', r'$10^{-6}$', r'$10^{-5}$', r'$10^{-4}$', r'$10^{-3}$']) ax3.set_title('Goes Soft X-ray', fontsize=12) ax3.set_ylabel('Watts m$^{-2}$') ax3.set_xlabel(datetime.datetime.isoformat(goest.data.index[0])[0:10]) ax3.axvspan(dates[899], dates[dates.size - 899], alpha=0.2) ax2 = ax3.twinx() # ax2.set_yscale("log") ax2.set_ylim([-7, -3]) ax2.set_yticks([-7, -6, -5, -4, -3]) ax2.set_yticklabels(['B', 'C', 'M', 'X', '']) ax3.yaxis.grid(True, 'major') ax3.xaxis.grid(False, 'major') ax3.legend(prop={'size': 6}) formatter = mpl.dates.DateFormatter('%H:%M') ax3.xaxis.set_major_formatter(formatter) ax3.fmt_xdata = mpl.dates.DateFormatter('%H:%M') except: print 'Error in downloading GOES soft X-ray data. Proceeding with out soft X-ray plot.' # third part # start to download the fits files if plotaia: if not aiafits: newlist = [] items = glob.glob('*.fits') for names in items: str1 = starttim1.iso[:4] + '_' + starttim1.iso[5:7] + '_' + starttim1.iso[8:10] + 't' + starttim1.iso[ 11:13] + '_' + starttim1.iso[14:16] str2 = str(aiawave) if names.endswith(".fits"): if names.find(str1) != -1 and names.find(str2) != -1: newlist.append(names) newlist.append('0') if newlist and os.path.exists(newlist[0]): aiafits = newlist[0] else: print 'downloading the aiafits file' wave1 = aiawave - 3 wave2 = aiawave + 3 t1 = Time(starttim1.mjd - 0.02 / 24., format='mjd') t2 = Time(endtim1.mjd + 0.02 / 24., format='mjd') try: from sunpy.net import vso client = vso.VSOClient() qr = client.query(vso.attrs.Time(t1.iso, t2.iso), vso.attrs.Instrument('aia'), vso.attrs.Wave(wave1 * u.AA, wave2 * u.AA)) res = client.get(qr, path='{file}') except: SdoDownloadscript = os.path.join(workdir, 'SdoDownload.py') os.system('rm -rf {}'.format(SdoDownloadscript)) fi = open(SdoDownloadscript, 'wb') fi.write('from sunpy.net import vso \n') fi.write('from astropy import units as u \n') fi.write('client = vso.VSOClient() \n') fi.write( "qr = client.query(vso.attrs.Time('{0}', '{1}'), vso.attrs.Instrument('aia'), vso.attrs.Wave({2} * u.AA, {3} * u.AA)) \n".format( t1.iso, t2.iso, wave1, wave2)) fi.write("res = client.get(qr, path='{file}') \n") fi.close() try: os.system('python {}'.format(SdoDownloadscript)) except NameError: print "Bad input names" except ValueError: print "Bad input values" except: print "Unexpected error:", sys.exc_info()[0] print "Error in Downloading AIA fits files. Proceed without AIA..." # Here something is needed to check whether it has finished downloading the fits files or not if not aiafits: newlist = [] items = glob.glob('*.fits') for nm in items: str1 = starttim1.iso[:4] + '_' + starttim1.iso[5:7] + '_' + starttim1.iso[8:10] + 't' + starttim1.iso[ 11:13] + '_' + starttim1.iso[14:16] str2 = str(aiawave) if nm.find(str1) != -1 and nm.find(str2) != -1: newlist.append(nm) if newlist: aiafits = newlist[0] print 'AIA fits ' + aiafits + ' selected' else: print 'no AIA fits files found. Proceed without AIA' try: aiamap = smap.Map(aiafits) except: print 'error in reading aiafits. Proceed without AIA' # RCP or I ax4 = plt.subplot(gs2[0, 0]) ax5 = plt.subplot(gs2[1, 0]) # LCP or V ax6 = plt.subplot(gs2[0, 1]) ax7 = plt.subplot(gs2[1, 1]) if fitsfile: pass else: if not imagefile: eph = hf.read_horizons(t0=Time(midtime_mjd, format='mjd')) if observatory == 'EOVSA' or (not usemsphacenter): print 'This is EOVSA data' # use RA and DEC from FIELD ID 0 tb.open(vis+'/FIELD') phadir = tb.getcol('PHASE_DIR').flatten() tb.close() ra0 = phadir[0] dec0 = phadir[1] if stokes == 'RRLL' or stokes == 'RR,LL': print 'Provide stokes: ' + str(stokes) + '. However EOVSA has linear feeds. Force stokes to be IV' stokes = 'I,V' else: ra0 = eph['ra'][0] dec0 = eph['dec'][0] if not xycen: # use solar disk center as default phasecenter = 'J2000 ' + str(ra0) + 'rad ' + str(dec0) + 'rad' else: x0 = np.radians(xycen[0]/3600.) y0 = np.radians(xycen[1]/3600.) p0 = np.radians(eph['p0'][0]) # p angle in radians raoff = -((x0) * np.cos(p0) - y0 * np.sin(p0))/np.cos(eph['dec'][0]) decoff = (x0) * np.sin(p0) + y0 * np.cos(p0) newra = ra0 + raoff newdec = dec0 + decoff phasecenter = 'J2000 ' + str(newra) + 'rad ' + str(newdec) + 'rad' imagename = os.path.join(workdir, visname + '.outim') if os.path.exists(imagename + '.image') or os.path.exists(imagename + '.flux'): os.system('rm -rf ' + imagename + '.*') sto = stokes.replace(',', '') print 'do clean for ' + timerange + ' in spw ' + spw + ' stokes ' + sto print 'Original phasecenter: '+ str(ra0) + str(dec0) print 'use phasecenter: ' + phasecenter clean(vis=vis, imagename=imagename, selectdata=True, spw=spw, timerange=timerange, stokes=sto, niter=niter, interactive=interactive, npercycle=50, imsize=imsize, cell=cell, restoringbeam=restoringbeam, weighting='briggs', robust=robust, phasecenter=phasecenter) os.system('rm -rf ' + imagename + '.psf') os.system('rm -rf ' + imagename + '.flux') os.system('rm -rf ' + imagename + '.model') os.system('rm -rf ' + imagename + '.mask') os.system('rm -rf ' + imagename + '.residual') imagefile = imagename + '.image' fitsfile = imagefile + '.fits' hf.imreg(vis=vis, ephem=eph, imagefile=imagefile, timerange=timerange, reftime=reftime, fitsfile=fitsfile, verbose=True, overwrite=True) print 'fits file ' + fitsfile + ' selected' ax4.cla() ax5.cla() ax6.cla() ax7.cla() rfits = fitsfile try: hdulist = fits.open(rfits) hdu = hdulist[0] (npol, nf, nx, ny) = hdu.data.shape rmap = smap.Map(hdu.data[0, 0, :, :], hdu.header) except: print 'radio fits file not recognized by sunpy.map. Aborting...' return -1 if npol > 1: rmap1 = smap.Map(hdu.data[0, 0, :, :], hdu.header) rmap2 = smap.Map(hdu.data[1, 0, :, :], hdu.header) XX, YY = np.meshgrid(np.arange(rmap.data.shape[1]), np.arange(rmap.data.shape[0])) try: rmapx, rmapy = rmap.pixel_to_data(XX * u.pix, YY * u.pix) except: rmapxy = rmap.pixel_to_data(XX * u.pix, YY * u.pix) rmapx = rmapxy.Tx rmapy = rmapxy.Ty if not xyrange: if xycen: x0 = xycen[0] * u.arcsec y0 = xycen[1] * u.arcsec if not xycen: row, col = rmap1.data.shape positon = np.nanargmax(rmap1.data) m, n = divmod(positon, col) x0 = rmap1.xrange[0] + rmap1.scale[1] * (n + 0.5) * u.pix y0 = rmap1.yrange[0] + rmap1.scale[0] * (m + 0.5) * u.pix if len(fov) == 1: fov=[fov]*2 sz_x = fov[0] * u.arcsec sz_y = fov[1] * u.arcsec x1 = x0 - sz_x/2. x2 = x0 + sz_x/2. y1 = y0 - sz_y/2. y2 = y0 + sz_y/2. xyrange = [[x1.value, x2.value], [y1.value, y2.value]] else: sz_x = xyrange[0][1] - xyrange[0][0] sz_y = xyrange[1][1] - xyrange[1][0] clevels1 = np.linspace(0.2, 0.9, 5) if stokes.split(',')[1] == 'V': clevels2 = np.array([0.8, -0.6, -0.4, -0.2, 0.2, 0.4, 0.6, 0.8]) else: clevels2 = np.linspace(0.2, 0.9, 5) if 'aiamap' in vars(): aiamap.plot_settings['cmap'] = plt.get_cmap('binary') if rmap: title = 'AIA {0:.0f} + {1} {2:6.3f} GHz'.format(aiamap.wavelength.value, observatory, (bfreqghz + efreqghz) / 2.0) else: title = 'AIA {0:.0f}'.format(aiamap.wavelength.value) aiamap.plot(axes=ax4) ax4.set_title(title + ' ' + stokes.split(',')[0], fontsize=12) aiamap.draw_limb() aiamap.draw_grid() aiamap.draw_rectangle((xyrange[0][0], xyrange[1][0]) * u.arcsec, sz_x, sz_y) aiamap.plot(axes=ax6) ax6.set_title(title + ' ' + stokes.split(',')[1], fontsize=12) aiamap.draw_limb() aiamap.draw_grid() aiamap.draw_rectangle((xyrange[0][0], xyrange[1][0]) * u.arcsec, sz_x, sz_y) if rmap: ax4.contour(rmapx.value, rmapy.value, rmap1.data, levels=clevels1 * np.nanmax(rmap1.data), cmap=cm.jet) ax6.contour(rmapx.value, rmapy.value, rmap2.data, levels=clevels2 * np.nanmax(rmap2.data), cmap=cm.RdBu) ax4.text(0.02, 0.02, 'AIA {0:.0f} '.format(aiamap.wavelength.value) + aiamap.date.strftime('%H:%M:%S'), verticalalignment='bottom', horizontalalignment='left', transform=ax4.transAxes, color='k', fontsize=10) ax6.text(0.02, 0.02, 'AIA {0:.0f} '.format(aiamap.wavelength.value) + aiamap.date.strftime('%H:%M:%S'), verticalalignment='bottom', horizontalalignment='left', transform=ax6.transAxes, color='k', fontsize=10) else: title = '{0} {1:6.3f} GHz'.format(observatory, (bfreqghz + efreqghz) / 2.0) rmap1.plot(axes=ax4, cmap=cm.jet) ax4.set_title(title + ' ' + stokes.split(',')[0], fontsize=12) rmap1.draw_limb() rmap1.draw_grid() rmap1.draw_rectangle((xyrange[0][0], xyrange[1][0]) * u.arcsec, sz_x, sz_y) rmap2.plot(axes=ax6, cmap=cm.RdBu) ax6.set_title(title + ' ' + stokes.split(',')[1], fontsize=12) rmap2.draw_limb() rmap2.draw_grid() # ax4.contour(rmapx.value, rmapy.value, rmap1.data, levels=np.linspace(0.2, 0.9, 5) * np.nanmax(rmap1.data), # cmap=cm.gray) # ax6.contour(rmapx.value, rmapy.value, rmap2.data, levels=np.linspace(0.2, 0.9, 5) * np.nanmax(rmap2.data), # cmap=cm.gray) rmap2.draw_rectangle((xyrange[0][0], xyrange[1][0]) * u.arcsec, sz_x, sz_y) ax4.set_xlim(-1200, 1200) ax4.set_ylim(-1200, 1200) ax6.set_xlim(-1200, 1200) ax6.set_ylim(-1200, 1200) try: subrmap1 = rmap1.submap(xyrange[0] * u.arcsec, xyrange[1] * u.arcsec) subrmap2 = rmap2.submap(xyrange[0] * u.arcsec, xyrange[1] * u.arcsec) except: bl = SkyCoord(xyrange[0][0] * u.arcsec, xyrange[1][0] * u.arcsec, frame=rmap1.coordinate_frame) tr = SkyCoord(xyrange[0][1] * u.arcsec, xyrange[1][1] * u.arcsec, frame=rmap1.coordinate_frame) subrmap1 = rmap1.submap(bl, tr) subrmap2 = rmap2.submap(bl, tr) XX, YY = np.meshgrid(np.arange(subrmap1.data.shape[1]), np.arange(subrmap1.data.shape[0])) try: subrmapx, subrmapy = subrmap1.pixel_to_data(XX * u.pix, YY * u.pix) except: subrmapxy = subrmap1.pixel_to_data(XX * u.pix, YY * u.pix) subrmapx = subrmapxy.Tx subrmapy = subrmapxy.Ty if 'aiamap' in vars(): try: subaiamap = aiamap.submap(xyrange[0] * u.arcsec, xyrange[1] * u.arcsec) except: bl = SkyCoord(xyrange[0][0] * u.arcsec, xyrange[1][0] * u.arcsec, frame=aiamap.coordinate_frame) tr = SkyCoord(xyrange[0][1] * u.arcsec, xyrange[1][1] * u.arcsec, frame=aiamap.coordinate_frame) subaiamap = aiamap.submap(bl, tr) subaiamap.plot(axes=ax5, title='') subaiamap.draw_limb() subaiamap.draw_grid() subaiamap.plot(axes=ax7, title='') subaiamap.draw_limb() subaiamap.draw_grid() ax5.contour(subrmapx.value, subrmapy.value, subrmap1.data, levels=clevels1 * np.nanmax(subrmap1.data), cmap=cm.jet) ax7.contour(subrmapx.value, subrmapy.value, subrmap2.data, levels=clevels2 * np.nanmax(subrmap2.data), cmap=cm.RdBu) # subaiamap.draw_rectangle((fov[0][0], fov[1][0]) * u.arcsec, 400 * u.arcsec, 400 * u.arcsec) else: subrmap1.plot(axes=ax5, cmap=cm.jet, title='') subrmap1.draw_limb() subrmap1.draw_grid() subrmap2.plot(axes=ax7, cmap=cm.RdBu, title='') subrmap2.draw_limb() subrmap2.draw_grid() # ax5.contour(subrmapx.value, subrmapy.value, subrmap1.data, # levels=clevels1 * np.nanmax(subrmap1.data), cmap=cm.gray) # ax7.contour(subrmapx.value, subrmapy.value, subrmap2.data, # levels=clevels2 * np.nanmax(subrmap2.data), cmap=cm.gray) # subrmap1.draw_rectangle((fov[0][0], fov[1][0]) * u.arcsec, 400 * u.arcsec, 400 * u.arcsec) # subrmap2.draw_rectangle((fov[0][0], fov[1][0]) * u.arcsec, 400 * u.arcsec, 400 * u.arcsec) ax5.set_xlim(xyrange[0]) ax5.set_ylim(xyrange[1]) ax5.text(0.02, 0.02, observatory + ' ' + rmap.date.strftime('%H:%M:%S.%f')[:-3], verticalalignment='bottom', horizontalalignment='left', transform=ax5.transAxes, color='k', fontsize=10) ax7.set_xlim(xyrange[0]) ax7.set_ylim(xyrange[1]) ax7.text(0.02, 0.02, observatory + ' ' + rmap.date.strftime('%H:%M:%S.%f')[:-3], verticalalignment='bottom', horizontalalignment='left', transform=ax7.transAxes, color='k', fontsize=10) fig.show()
def get_dspec(vis=None, savespec=True, specfile=None, bl='', uvrange='', field='', scan='', datacolumn='data', domedian=False, timeran=None, spw=None, timebin='0s', regridfreq=False, fillnan=None, verbose=False, usetbtool=False): # from split_cli import split_cli as split if vis.endswith('/'): vis = vis[:-1] msfile = vis if not spw: spw = '' if not timeran: timeran = '' if domedian: if not uvrange: uvrange = '0.2~0.8km' # bl = '' else: uvrange = '' if not bl: bl = '' else: uvrange = '' # Open the ms and plot dynamic spectrum if verbose: print('Splitting selected data...') if usetbtool: try: tb.open(vis + '/POLARIZATION') corrtype = tb.getcell('CORR_TYPE', 0) pols = [stokesenum[p] for p in corrtype] tb.close() except: pols = [] antmask = [] if uvrange is not '' or bl is not '': ms.open(vis) ms.selectinit(datadescid=0) mdata = ms.metadata() antlist = mdata.antennaids() mdata.done() staql = {'uvdist': uvrange, 'baseline': bl, 'spw': spw, 'field': field, 'scan': scan, 'timerange': timeran} ### todo the selection only works for uvrange and bl. To make the selection of other items works, ## I need to make mask for other items. a = ms.msselect(staql) mdata = ms.metadata() baselines = mdata.baselines() for lidx, l in enumerate(antlist): antmask.append(baselines[l][antlist[lidx:]]) antmask = np.hstack(antmask) mdata.done() ms.close() tb.open(vis) spwtb = tbtool() spwtb.open(vis + '/SPECTRAL_WINDOW') ptb = tbtool() ptb.open(vis + '/POLARIZATION') ms.open(vis) spwlist = [] mdata = ms.metadata() nspw = mdata.nspw() nbl = mdata.nbaselines() + mdata.nantennas() nscans = mdata.nscans() spw_nfrq = [] # List of number of frequencies in each spw for i in range(nspw): spw_nfrq.append(mdata.nchan(i)) spw_nfrq = np.array(spw_nfrq) nf = np.sum(spw_nfrq) smry = mdata.summary() scan_ntimes = [] # List of number of times in each scan for iscan in range(nscans): scan_ntimes.append( smry['observationID=0']['arrayID=0']['scan=' + str(iscan)]['fieldID=0']['nrows'] / nspw / nbl) scan_ntimes = np.array(scan_ntimes) scan_ntimes_integer = scan_ntimes.astype(np.int) if len(np.where(scan_ntimes % scan_ntimes_integer != 0)[0]) != 0: # if True: scan_ntimes = [] # List of number of times in each scan for iscan in range(nscans): scan_ntimes.append( len(smry['observationID=0']['arrayID=0']['scan=' + str(iscan)]['fieldID=0'].keys()) - 6) scan_ntimes = np.array(scan_ntimes) else: scan_ntimes = scan_ntimes_integer nt = np.sum(scan_ntimes) times = tb.getcol('TIME') if times[nbl] - times[0] != 0: # This is frequency/scan sort order order = 'f' elif times[nbl * nspw - 1] - times[0] != 0: # This is time sort order order = 't' npol = ptb.getcol('NUM_CORR', 0, 1)[0] ptb.close() freq = np.zeros(nf, float) times = np.zeros(nt, float) if order == 't': specamp = np.zeros((npol, nf, nbl, nt), np.complex) for j in range(nt): fptr = 0 # Loop over spw for i in range(nspw): # Get channel frequencies for this spw (annoyingly comes out as shape (nf, 1) cfrq = spwtb.getcol('CHAN_FREQ', i, 1)[:, 0] if j == 0: # Only need this the first time through spwlist += [i] * len(cfrq) if i == 0: times[j] = tb.getcol('TIME', nbl * (i + nspw * j), 1) # Get the time spec_ = tb.getcol('DATA', nbl * (i + nspw * j), nbl) # Get complex data for this spw flag = tb.getcol('FLAG', nbl * (i + nspw * j), nbl) # Get flags for this spw nfrq = len(cfrq) # Apply flags if type(fillnan) in [int, float]: spec_[flag] = float(fillnan) else: spec_[flag] = 0.0 # Insert data for this spw into larger array specamp[:, fptr:fptr + nfrq, :, j] = spec_ freq[fptr:fptr + nfrq] = cfrq fptr += nfrq else: specf = np.zeros((npol, nf, nt, nbl), np.complex) # Array indexes are swapped iptr = 0 for j in range(nscans): # Loop over scans for i in range(nspw): # Loop over spectral windows s = scan_ntimes[j] f = spw_nfrq[i] s1 = np.sum(scan_ntimes[:j]) # Start time index s2 = np.sum(scan_ntimes[:j + 1]) # End time index f1 = np.sum(spw_nfrq[:i]) # Start freq index f2 = np.sum(spw_nfrq[:i + 1]) # End freq index spec_ = tb.getcol('DATA', iptr, nbl * s) flag = tb.getcol('FLAG', iptr, nbl * s) if j == 0: cfrq = spwtb.getcol('CHAN_FREQ', i, 1)[:, 0] freq[f1:f2] = cfrq spwlist += [i] * len(cfrq) times[s1:s2] = tb.getcol('TIME', iptr, nbl * s).reshape(s, nbl)[:, 0] # Get the times iptr += nbl * s # Apply flags if type(fillnan) in [int, float]: spec_[flag] = float(fillnan) else: spec_[flag] = 0.0 # Insert data for this spw into larger array specf[:, f1:f2, s1:s2] = spec_.reshape(npol, f, s, nbl) # Swap the array indexes back to the desired order specamp = np.swapaxes(specf, 2, 3) tb.close() spwtb.close() ms.close() if len(antmask) > 0: specamp = specamp[:, :, np.where(antmask)[0], :] (npol, nfreq, nbl, ntim) = specamp.shape tim = times else: # Open the ms and plot dynamic spectrum if verbose: print('Splitting selected data...') vis_spl = './tmpms.splitted' if os.path.exists(vis_spl): os.system('rm -rf ' + vis_spl) # split(vis=msfile, outputvis=vis_spl, timerange=timeran, antenna=bl, field=field, scan=scan, spw=spw, # uvrange=uvrange, timebin=timebin, datacolumn=datacolumn) try: from split_cli import split_cli as split split(vis=msfile, outputvis=vis_spl, datacolumn=datacolumn, timerange=timeran, spw=spw, antenna=bl, field=field, scan=scan, uvrange=uvrange, timebin=timebin) except: ms.open(msfile, nomodify=True) ms.split(outputms=vis_spl, whichcol=datacolumn, time=timeran, spw=spw, baseline=bl, field=field, scan=scan, uvrange=uvrange, timebin=timebin) ms.close() if verbose: print('Regridding into a single spectral window...') # print('Reading data spw by spw') try: tb.open(vis_spl + '/POLARIZATION') corrtype = tb.getcell('CORR_TYPE', 0) pols = [stokesenum[p] for p in corrtype] tb.close() except: pols = [] if regridfreq: ms.open(vis_spl, nomodify=False) ms.cvel(outframe='LSRK', mode='frequency', interp='nearest') ms.selectinit(datadescid=0, reset=True) data = ms.getdata(['amplitude', 'time', 'axis_info'], ifraxis=True) specamp = data['amplitude'] freq = data['axis_info']['freq_axis']['chan_freq'] else: ms.open(vis_spl) ms.selectinit(datadescid=0, reset=True) spwinfo = ms.getspectralwindowinfo() specamp = [] freq = [] time = [] for descid in range(len(spwinfo.keys())): ms.selectinit(datadescid=0, reset=True) ms.selectinit(datadescid=descid) data = ms.getdata(['amplitude', 'time', 'axis_info'], ifraxis=True) specamp_ = data['amplitude'] freq_ = data['axis_info']['freq_axis']['chan_freq'] time_ = data['time'] if fillnan is not None: flag_ = ms.getdata(['flag', 'time', 'axis_info'], ifraxis=True)['flag'] if type(fillnan) in [int, float, long]: specamp_[flag_] = float(fillnan) else: specamp_[flag_] = 0.0 specamp.append(specamp_) freq.append(freq_) time.append(time_) specamp = np.concatenate(specamp, axis=1) freq = np.concatenate(freq, axis=0) ms.selectinit(datadescid=0, reset=True) ms.close() os.system('rm -rf ' + vis_spl) (npol, nfreq, nbl, ntim) = specamp.shape freq = freq.reshape(nfreq) tim = data['time'] if verbose: print('npol, nfreq, nbl, ntime:', (npol, nfreq, nbl, ntim)) spec = np.swapaxes(specamp, 2, 1) if domedian: if verbose: print('doing median of all the baselines') # mask zero values before median # spec_masked = np.ma.masked_where(spec < 1e-9, spec) # spec_masked2 = np.ma.masked_invalid(spec) # spec_masked = np.ma.masked_array(spec, mask=np.logical_or(spec_masked.mask, spec_masked2.mask)) # spec_med = np.ma.filled(np.ma.median(spec_masked, axis=1), fill_value=0.) spec = np.abs(spec) spec_med = np.nanmedian(spec, axis=1) nbl = 1 ospec = spec_med.reshape((npol, nbl, nfreq, ntim)) else: ospec = spec # Save the dynamic spectral data if savespec: if not specfile: specfile = msfile + '.dspec.npz' if os.path.exists(specfile): os.system('rm -rf ' + specfile) np.savez(specfile, spec=ospec, tim=tim, freq=freq, timeran=timeran, spw=spw, bl=bl, uvrange=uvrange, pol=pols) if verbose: print('Median dynamic spectrum saved as: ' + specfile) return {'spec': ospec, 'tim': tim, 'freq': freq, 'timeran': timeran, 'spw': spw, 'bl': bl, 'uvrange': uvrange, 'pol': pols}
def read_horizons(vis): import urllib2 import ssl if not os.path.exists(vis): print 'Input ms data ' + vis + ' does not exist! ' return -1 try: # ms.open(vis) # summary = ms.summary() # ms.close() # btime = Time(summary['BeginTime'], format='mjd') # etime = Time(summary['EndTime'], format='mjd') ## alternative way to avoid conflicts with importeovsa, if needed -- more time consuming ms.open(vis) metadata = ms.metadata() if metadata.observatorynames()[0] == 'EVLA': observatory_code = '-5' elif metadata.observatorynames()[0] == 'EOVSA': observatory_code = '-81' elif metadata.observatorynames()[0] == 'ALMA': observatory_code = '-7' ms.close() tb.open(vis) btime = Time(tb.getcell('TIME', 0) / 24. / 3600., format='mjd') etime = Time(tb.getcell('TIME', tb.nrows() - 1) / 24. / 3600., format='mjd') tb.close() print "Beginning time of this scan " + btime.iso print "End time of this scan " + etime.iso cmdstr = "http://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=l&TABLE_TYPE='OBSERVER'&QUANTITIES='1,17,20'&CSV_FORMAT='YES'&ANG_FORMAT='DEG'&CAL_FORMAT='BOTH'&SOLAR_ELONG='0,180'&CENTER='{}@399'&COMMAND='10'&START_TIME='".format( observatory_code ) + btime.iso.replace( ' ', ',' ) + "'&STOP_TIME='" + etime.iso[:-4].replace( ' ', ',' ) + "'&STEP_SIZE='1 m'&SKIP_DAYLT='NO'&EXTRA_PREC='YES'&APPARENT='REFRACTED'" try: context = ssl._create_unverified_context() f = urllib2.urlopen(cmdstr, context=context) except: f = urllib2.urlopen(cmdstr) except: print 'error in reading ms file: ' + vis + ' to obtain the ephemeris!' return -1 # inputs: # ephemfile: # OBSERVER output from JPL Horizons for topocentric coordinates with for example # target=Sun, observer=VLA=-5 # extra precision, quantities 1,17,20, REFRACTION # routine goes through file to find $$SOE which is start of ephemeris and ends with $$EOE # outputs: a Python dictionary containing the following: # timestr: date and time as a string # time: modified Julian date # ra: right ascention, in rad # dec: declination, in rad # rastr: ra in string # decstr: dec in string # p0: solar p angle, CCW with respect to the celestial north pole # delta: distance from the disk center to the observer, in AU # delta_dot: time derivative of delta, in the light of sight direction. Negative means it is moving toward the observer # # initialize the return dictionary ephem0 = dict.fromkeys(['time', 'ra', 'dec', 'delta', 'p0']) lines = f.readlines() f.close() nline = len(lines) istart = 0 for i in range(nline): line = lines[i] if line[0:5] == '$$SOE': # start recording istart = i + 1 if line[0:5] == '$$EOE': # end recording iend = i newlines = lines[istart:iend] nrec = len(newlines) ephem_ = [] t = [] ra = [] dec = [] p0 = [] delta = [] for line in newlines: items = line.split(',') # t.append({'unit':'mjd','value':Time(float(items[1]),format='jd').mjd}) # ra.append({'unit': 'rad', 'value': np.radians(float(items[4]))}) # dec.append({'unit': 'rad', 'value': np.radians(float(items[5]))}) # p0.append({'unit': 'deg', 'value': float(items[6])}) # delta.append({'unit': 'au', 'value': float(items[8])}) t.append(Time(float(items[1]), format='jd').mjd) ra.append(np.radians(float(items[4]))) dec.append(np.radians(float(items[5]))) p0.append(float(items[6])) delta.append(float(items[8])) # convert list of dictionary to a dictionary of arrays ephem = {'time': t, 'ra': ra, 'dec': dec, 'p0': p0, 'delta': delta} return ephem