def fit_vs_freq(out): import matplotlib.pylab as plt import rstn from astropy.time import Time t = Time(out['mjd'][0], format='mjd') frq, flux = rstn.rd_rstnflux(t=t) rstn_flux = rstn.rstn2ant(frq, flux, out['fghz'] * 1000, t=t) band = [] fghz = [] eqrad = [] polrad = [] allrad = [] sfac = [] sflux = [] for i in range(50): uvfitrange = np.array([10, 150]) + np.array([1, 18]) * i a, b, c, d, e, f, g = fit_diskmodel(out, i, rstn_flux, uvfitrange=uvfitrange, angle_tolerance=np.pi / 2, doplot=False) band.append(a) fghz.append(b) eqrad.append(c) polrad.append(d) allrad.append(e) sfac.append(f) sflux.append(g) if (i % 10) == 0: print(i) result = {'band': np.array(band), 'fghz': np.array(fghz), 'eqradius': np.array(eqrad), 'polradius': np.array(polrad), 'radius': np.array(allrad), 'flux_correction_factor': np.array(sfac), 'disk_flux': np.array(sflux) * 2.} plt.figure() plt.plot(result['fghz'], result['eqradius'], 'o', label='Equatorial Radius') plt.plot(result['fghz'], result['polradius'], 'o', label='Polar Radius') plt.plot(result['fghz'], result['radius'], 'o', label='Circular Radius') plt.legend() plt.xlabel('Frequency [GHz]') plt.ylabel('Radius [arcsec]') plt.title('Frequency-dependent Solar Disk Size for 2019-Sep-01') return result
def cal_qual(t=None, savfig=True): ''' Check the quality of the total power and gain calibrations for a given date ''' import cal_header as ch from stateframe import extract import dump_tsys as dt import pipeline_cal as pc import matplotlib.pylab as plt import rstn from util import get_idbdir import socket if t is None: t = Time.now() mjd = t.mjd # First check whether the total power calibration is current caltype = 10 xml, buf = ch.read_cal(caltype, t=t) tp_mjd = Time(extract(buf, xml['SQL_timestamp']), format='lv').mjd if mjd - tp_mjd > 0.5: print 'CAL_QUAL: Warning, TP Calibration not (yet) available for this date.' # Find GCAL scan for this date fdb = dt.rd_fdb(Time(mjd, format='mjd')) gcidx, = np.where(fdb['PROJECTID'] == 'GAINCALTEST') if len(gcidx) == 1: datadir = get_idbdir(t) + fdb['FILE'][gcidx][0][3:11] + '/' # List of GCAL files gcalfile = [datadir + i for i in fdb['FILE'][gcidx]] else: print 'CAL_QUAL: Warning, no GAINCALTEST scan for this date. Will try using the GAINCALTEST from previous day.' fdb = dt.rd_fdb(Time(mjd - 1, format='mjd')) gcidx, = np.where(fdb['PROJECTID'] == 'GAINCALTEST') if len(gcidx) == 1: datadir = get_idbdir(t) # Add date path if on pipeline # if datadir.find('eovsa') != -1: datadir += fdb['FILE'][gcidx][0][3:11]+'/' host = socket.gethostname() if host == 'pipeline': datadir += fdb['FILE'][gcidx][0][3:11] + '/' # List of GCAL files gcalfile = [datadir + i for i in fdb['FILE'][gcidx]] else: print 'CAL_QUAL: Error, no GAINCALTEST scan for previous day.' return # Find SOLPNTCAL scan for this date fdb = dt.rd_fdb(Time(mjd, format='mjd')) gcidx, = np.where(fdb['PROJECTID'] == 'SOLPNTCAL') if len(gcidx) > 0: datadir = get_idbdir(t) # Add date path if on pipeline # if datadir.find('eovsa') != -1: datadir += fdb['FILE'][gcidx][0][3:11]+'/' host = socket.gethostname() if host == 'pipeline': datadir += fdb['FILE'][gcidx][0][3:11] + '/' # List of SOLPNTCAL files solpntfile = [datadir + i for i in fdb['FILE'][gcidx]] else: print 'CAL_QUAL: Error, no SOLPNTCAL scan(s) for this date.' return files = gcalfile + solpntfile outnames = [] for file in files: outnames.append( pc.udb_corr(file, calibrate=True, attncal=True, desat=True)) out = ri.read_idb(outnames, srcchk=False) nt = len(out['time']) nf = len(out['fghz']) tpfac = 500. / nf frq, flux = rstn.rd_rstnflux(t) s = rstn.rstn2ant(frq, flux, out['fghz'] * 1000., t) fluximg = s.repeat(nt).reshape(nf, nt) f, ax = plt.subplots(4, 7) f.set_size_inches(16, 7, forward=True) f.tight_layout(rect=[0.0, 0.0, 1, 0.95]) ax.shape = (2, 14) for i in range(13): for j in range(2): ax[j, i].imshow(out['p'][i, j], aspect='auto', origin='lower', vmax=np.max(s), vmin=0) ax[j, i].plot(np.clip(out['p'][i, j, int(nf / 3.)] / tpfac, 0, nf), linewidth=1) ax[j, i].plot(np.clip(out['p'][i, j, int(2 * nf / 3.)] / tpfac, 0, nf), linewidth=1) ax[j, i].set_title('Ant ' + str(i + 1) + [' X Pol', ' Y Pol'][j], fontsize=10) for j in range(2): ax[j, 13].imshow(fluximg, aspect='auto', origin='lower', vmax=np.max(s), vmin=0) ax[j, 13].set_title('RSTN Flux', fontsize=10) for i in range(13): for j in range(2): ax[j, i].plot(np.clip(fluximg[int(nf / 3.)] / tpfac, 0, nf), '--', linewidth=1, color='C0') ax[j, i].plot(np.clip(fluximg[int(2 * nf / 3.)] / tpfac, 0, nf), '--', linewidth=1, color='C1') f.suptitle('Total Power Calibration Quality for ' + t.iso[:10]) date = t.iso[:10].replace('-', '') if savfig: try: plt.savefig('/common/webplots/flaremon/daily/' + date[:4] + '/QUAL_' + date + 'TP.png') except: plt.savefig('/tmp/' + date[:4] + '/QUAL_' + date + 'TP.png') print 'The .png file could not be created in the /common/webplots/flaremon/daily/ folder.' print 'A copy was created in /tmp/.' f, ax = plt.subplots(4, 7) f.set_size_inches(16, 7, forward=True) f.tight_layout(rect=[0.0, 0.0, 1, 0.95]) ax.shape = (2, 14) for i in range(13): for j in range(2): ax[j, i].imshow(np.real(out['a'][i, j]), aspect='auto', origin='lower', vmax=np.max(s), vmin=0) ax[j, i].plot(np.clip(np.real(out['a'][i, j, int(nf / 3.)] / tpfac), 0, nf), linewidth=1) ax[j, i].plot(np.clip( np.real(out['a'][i, j, int(2 * nf / 3.)] / tpfac), 0, nf), linewidth=1) ax[j, i].set_title('Ant ' + str(i + 1) + [' X Pol', ' Y Pol'][j], fontsize=10) for j in range(2): ax[j, 13].imshow(fluximg, aspect='auto', origin='lower', vmax=np.max(s), vmin=0) ax[j, 13].set_title('RSTN Flux', fontsize=10) for i in range(13): for j in range(2): ax[j, i].plot(np.clip(fluximg[int(nf / 3.)] / tpfac, 0, nf), '--', linewidth=1, color='C0') ax[j, i].plot(np.clip(fluximg[int(2 * nf / 3.)] / tpfac, 0, nf), '--', linewidth=1, color='C1') f.suptitle('Cross-Power Calibration Quality for ' + t.iso[:10]) date = t.iso[:10].replace('-', '') if savfig: try: plt.savefig('/common/webplots/flaremon/daily/' + date[:4] + '/QUAL_' + date + 'XP.png') except: plt.savefig('/tmp/' + date[:4] + '/QUAL_' + date + 'XP.png') print 'The .png file could not be created in the /common/webplots/flaremon/daily/ folder.' print 'A copy was created in /tmp/.'
def sp_get_calfac(x, y, do_plot=True): ''' Reads the RSTN/Penticton flux, fits to the observed frequencies, and applies them to the antenna solar response in input dictionaries x and y to return the calibration factors with which to MULTIPLY solar data to convert to solar flux units. The offsun (background) spectrum for each polarization and antenna is also returned. if do_plot is True, also make a nice plot of the factors applied to the data TODO: These need to be scaled for gain state ''' import rstn import matplotlib.pyplot as plt t = Time(x['ut_mjd'][0], format='mjd') frq, flux = rstn.rd_rstnflux(t) if frq is None: print 'Cannot continue.' return None nfrq, npnt, nant = x['rao'].shape fmhz = x['fghz'] * 1000. fghz = x['fghz'] s = rstn.rstn2ant(frq, flux, fmhz, t) calfac = np.zeros((2, nfrq, nant), 'float') offsun = np.zeros((2, nfrq, nant), 'float') if do_plot: # Set up summary plot nrow = 2 ncol = (nant + 1) / 2 f, ax = plt.subplots(nrow, ncol, sharex='col', sharey='row') f.set_size_inches(2 * nant, 7, forward=True) f.suptitle('Calibration for SOLPNT scan at ' + t.iso[:19] + ' UT', fontsize=18) for ant in range(nant): ax[ant % nrow, ant / nrow].set_title('Ant ' + str(ant + 1) + ' Solar Spectrum') if ant % ncol == 0: ax[ant / ncol, 0].set_ylabel('Solar Flux [sfu]') if ant >= nant / nrow: ax[1, ant - nant / nrow].set_xlabel('Frequency [GHz]') for ant in range(nant): # Do flux calculation for X feed a1 = x['raparms'][ 2, :, ant] # 1/e half-width of RA beam (1/10000th of a degree) a2 = x['decparms'][ 2, :, ant] # 1/e half-width of Dec beam (1/10000th of a degree) s1 = x['raparms'][0, :, ant] # RA peak flux in arb. units s2 = x['decparms'][0, :, ant] # Dec peak flux in arb. units o1 = x['raparms'][1, :, ant] # RA offset (1/10000th of a degree) o2 = x['decparms'][1, :, ant] # Dec offset (1/10000th of a degree) s01 = s1 * np.exp( (o2 / a1)**2) # Corrects RA flux for off-pointing in Dec s02 = s2 * np.exp( (o1 / a2)**2) # Corrects Dec flux for off-pointing in RA s0 = (s01 + s02) / 2. # S01 should equal S02, take the mean s0[np.where(s0 == 0)] = np.nan calfac[0, :, ant] = s / s0 # sfu/unit offsun[0, :, ant] = (x['raparms'][3, :, ant] + x['decparms'][3, :, ant]) / 2 # arb. units if do_plot: ax[ant % 2, ant / 2].plot(fghz, s1 * calfac[0, :, ant], '.', label='X-RA') ax[ant % 2, ant / 2].plot(fghz, s2 * calfac[0, :, ant], '.', label='X-Dec') # Repeat for Y feed a1 = y['raparms'][2, :, ant] a2 = y['decparms'][2, :, ant] s1 = y['raparms'][0, :, ant] s2 = y['decparms'][0, :, ant] o1 = y['raparms'][1, :, ant] o2 = y['decparms'][1, :, ant] s01 = s1 * np.exp( (o2 / a1)**2) # Corrects RA flux for off-pointing in Dec s02 = s2 * np.exp( (o1 / a2)**2) # Corrects Dec flux for off-pointing in RA s0 = (s01 + s02) / 2. s0[np.where(s0 == 0)] = np.nan calfac[1, :, ant] = s / s0 # sfu/unit offsun[1, :, ant] = (y['raparms'][3, :, ant] + y['decparms'][3, :, ant]) / 2 # arb. units if do_plot: ax[ant % nrow, ant / nrow].plot(fghz, s1 * calfac[1, :, ant], '.', label='Y-RA') ax[ant % nrow, ant / nrow].plot(fghz, s2 * calfac[1, :, ant], '.', label='Y-Dec') ax[ant % nrow, ant / nrow].set_ylim(0, 600) ax[ant % nrow, ant / nrow].set_xlim(0, 19) ax[ant % nrow, ant / nrow].legend(loc='upper left', fontsize='small') return calfac, offsun
def sp_get_calfac(x,y, do_plot=True): ''' Reads the RSTN/Penticton flux, fits to the observed frequencies, and applies them to the antenna solar response in input dictionaries x and y to return the calibration factors with which to MULTIPLY solar data to convert to solar flux units. The offsun (background) spectrum for each polarization and antenna is also returned. if do_plot is True, also make a nice plot of the factors applied to the data TODO: These need to be scaled for gain state ''' import rstn import matplotlib.pyplot as plt t = Time(x['ut_mjd'][0],format='mjd') frq, flux = rstn.rd_rstnflux(t) if frq is None: print 'Cannot continue.' return None nfrq, npnt, nant = x['rao'].shape fmhz = x['fghz']*1000. fghz = x['fghz'] s = rstn.rstn2ant(frq, flux, fmhz, t) calfac = np.zeros((2,nfrq,nant),'float') offsun = np.zeros((2,nfrq,nant),'float') if do_plot: # Set up summary plot f, ax = plt.subplots(2, nant/2, sharex='col', sharey='row') f.set_size_inches(2*nant,7,forward=True) f.suptitle('Calibration for SOLPNT scan at '+t.iso[:19]+' UT',fontsize=18) for ant in range(nant): ax[ant % 2, ant/2].set_title('Ant '+str(ant+1)+' Solar Spectrum') if ant % 4 == 0: ax[ant/4,0].set_ylabel('Solar Flux [sfu]') if ant >= nant/2: ax[1,ant - nant/2].set_xlabel('Frequency [GHz]') for ant in range(nant): # Do flux calculation for X feed a1 = x['raparms'][2,:,ant] # 1/e half-width of RA beam (1/10000th of a degree) a2 = x['decparms'][2,:,ant] # 1/e half-width of Dec beam (1/10000th of a degree) s1 = x['raparms'][0,:,ant] # RA peak flux in arb. units s2 = x['decparms'][0,:,ant] # Dec peak flux in arb. units o1 = x['raparms'][1,:,ant] # RA offset (1/10000th of a degree) o2 = x['decparms'][1,:,ant] # Dec offset (1/10000th of a degree) s01 = s1*np.exp((o2/a1)**2) # Corrects RA flux for off-pointing in Dec s02 = s2*np.exp((o1/a2)**2) # Corrects Dec flux for off-pointing in RA s0 = (s01 + s02)/2. # S01 should equal S02, take the mean s0[np.where(s0 == 0)] = np.nan calfac[0,:,ant] = s/s0 # sfu/unit offsun[0,:,ant] = (x['raparms'][3,:,ant] + x['decparms'][3,:,ant])/2 # arb. units if do_plot: ax[ant % 2, ant/2].plot(fghz,s1*calfac[0,:,ant],'.',label='X-RA') ax[ant % 2, ant/2].plot(fghz,s2*calfac[0,:,ant],'.',label='X-Dec') # Repeat for Y feed a1 = y['raparms'][2,:,ant] a2 = y['decparms'][2,:,ant] s1 = y['raparms'][0,:,ant] s2 = y['decparms'][0,:,ant] o1 = y['raparms'][1,:,ant] o2 = y['decparms'][1,:,ant] s01 = s1*np.exp((o2/a1)**2) # Corrects RA flux for off-pointing in Dec s02 = s2*np.exp((o1/a2)**2) # Corrects Dec flux for off-pointing in RA s0 = (s01 + s02)/2. s0[np.where(s0 == 0)] = np.nan calfac[1,:,ant] = s/s0 # sfu/unit offsun[1,:,ant] = (y['raparms'][3,:,ant] + y['decparms'][3,:,ant])/2 # arb. units if do_plot: ax[ant % 2, ant/2].plot(fghz,s1*calfac[1,:,ant],'.',label='Y-RA') ax[ant % 2, ant/2].plot(fghz,s2*calfac[1,:,ant],'.',label='Y-Dec') ax[ant % 2, ant/2].set_ylim(0,600) ax[ant % 2, ant/2].set_xlim(0,19) ax[ant % 2, ant/2].legend(loc='upper left',fontsize='small') return calfac,offsun