def get_fit(x, y, order=0, true_equals=None): """true_equals is a test that returns bool values to be fitted""" if true_equals is None: y = y.astype(float) else: y = y == true_equals return fit.PiecewisePolynomial1DFit(order).fit(x, y) #(timestamps[:])
def interp_sensor(compscan, quantity, default): """Interpolate environmental sensor data.""" try: sensor = compscan.dataset.enviro[quantity] except KeyError: return (lambda times: default) else: interp = fit.PiecewisePolynomial1DFit(max_degree=0) interp.fit(sensor['timestamp'], sensor['value']) return interp
def __init__(self,filenameH='',filenameV='',): """ The class aperture_efficiency reads the aperture_efficiency model from file and produces fitted functions for a frequency The class/__init__function takes in one parameter: filename : (default='') This is the filename of the recever model these files have 2 cols: Frequency (MHz),aperture_efficiency (fraction), if there are no file 15k recever is assumed. returns : dict spill with two elements 'HH' 'VV' that are intepolation functions that take in Frequency(MHz) and return fraction. """ try: aperture_eff_h = np.loadtxt(filenameH,comments='#')# Change units to fraction a800 = np.zeros((aperture_eff_h.shape[0]+2,2)) a800[0,:] = [aperture_eff_h[0,0]-100,aperture_eff_h[0,1]]# Extend the model by 100 MHz a800[1:-1,:] = aperture_eff_h a800[-1,:] = [aperture_eff_h[-1,0]+100,aperture_eff_h[-1,1]]# Extend the model by 100 MHz aperture_eff_h = a800 aperture_eff_v = np.loadtxt(filenameV,comments='#')# Change units to fraction a800 = np.zeros((aperture_eff_v.shape[0]+2,2)) a800[0,:] = [aperture_eff_v[0,0]-100,aperture_eff_v[0,1]]# Extend the model by 100 MHz a800[1:-1,:] = aperture_eff_v a800[-1,:] = [aperture_eff_v[-1,0]+100,aperture_eff_v[-1,1]]# Extend the model by 100 MHz aperture_eff_v = a800 except IOError: aperture_eff_h = np.array([[1.,75.],[2000.,75.]]) aperture_eff_v = np.array([[1.,75.],[2000.,75.]]) warnings.warn('Warning: Failed to load aperture_efficiency models, setting models to 0.75 ') print('Warning: Failed to load aperture_efficiency models, setting models to 0.75 ') #Assume Provided models are a function of zenith angle & frequency T_H = fit.PiecewisePolynomial1DFit() T_V = fit.PiecewisePolynomial1DFit() T_H.fit(aperture_eff_h[:,0],aperture_eff_h[:,1]/100.) T_V.fit(aperture_eff_v[:,0],aperture_eff_v[:,1]/100.) self.eff = {} self.eff['HH'] = T_H # The HH and VV is a scape thing self.eff['VV'] = T_V
def __init__(self,filenameH='',filenameV=''): """ The class Rec_temp reads the receiver model from file and produces fitted functions for a frequency The class/__init__function takes in one parameter: filenameH : (default='') This is the filename of the recever model these files have 2 cols: Frequency (MHz),tempreture (MHz), if there are no file 15k recever is assumed. returns : dict spill with two elements 'HH' 'VV' that are intepolation functions that take in Frequency(MHz) and return tempreture in Kelven. """ try: receiver_h = (np.loadtxt(filenameH,comments='%',delimiter=',')[:,[0,2] ]/(1e6,1.)).T # Change units to MHz # discard the gain col a800 = np.zeros((2,np.shape(receiver_h)[-1]+1)) a800[:,0] = [receiver_h[0,0]-100,receiver_h[1,0]] # Extend the model by 100 MHz a800[:,1:] = receiver_h receiver_h = a800 receiver_v = (np.loadtxt(filenameV,comments='%',delimiter=',')[:,[0,2] ]/(1e6,1.)).T # Change units to MHz # discard the gain col a800 = np.zeros((2,np.shape(receiver_v)[-1]+1)) a800[:,0] = [receiver_v[0,0]-100,receiver_v[1,0]] # Extend the model by 100 MHz a800[:,1:] = receiver_v receiver_v = a800 except IOError: receiver_h = np.array([[1.,20.],[2000.,20.]]) receiver_v = np.array([[1.,20.],[2000.,20.]]) warnings.warn('Warning: Failed to load Receiver models, setting models to 20 K ') print('Warning: Failed to load Receiver models, setting models to 20 K ') #Assume Provided models are a function of zenith angle & frequency T_H = fit.PiecewisePolynomial1DFit() T_V = fit.PiecewisePolynomial1DFit() T_H.fit(receiver_h[0],receiver_h[1]) T_V.fit(receiver_v[0],receiver_v[1]) self.rec = {} self.rec['HH'] = T_H # The HH and VV is a scape thing self.rec['VV'] = T_V
def __init__(self,d,freqs=1822,freq_index=0,elevation=None,ra=None,dec=None ,surface_temperature=23.0,air_relative_humidity=0.23):#d, nu, pol """ First extract total power in each scan (both mean and standard deviation) """ T_skytemp = Sky_temp(nu=freqs) T_sky = T_skytemp.Tsky self.units = d.data_unit self.name = d.antenna.name self.filename = d.filename self.elevation = {} self.Tsys = {} self.sigma_Tsys = {} self.Tsys_sky = {} self.T_sky = [] self.height = d.antenna.position_wgs84[2] self.pressure = np.mean([line[1] for line in d.enviro['pressure'] ]) self.air_relative_humidity = air_relative_humidity # Sort data in the order of ascending elevation valid_el = (elevation >= 10) self.elevation = elevation[valid_el] self.ra = ra[valid_el] self.dec = dec[valid_el] self.surface_temperature = surface_temperature# Extract surface temperature from weather data self.freq = freqs #MHz Centre frequency of observation for pol in ['HH','VV']: power_stats = [scape.stats.mu_sigma(s.pol(pol)[:,freq_index]) for s in d.scans] tipping_mu, tipping_sigma = np.array([s[0] for s in power_stats]), np.array([s[1] for s in power_stats]) tipping_mu, tipping_sigma = tipping_mu[sort_ind], tipping_sigma[sort_ind] self.Tsys[pol] = tipping_mu[valid_el] self.sigma_Tsys[pol] = tipping_sigma[valid_el] self.Tsys_sky[pol] = [] self.T_sky = [] for val_el,ra,dec,el in zip(sort_ind,self.ra,self.dec,self.elevation): self.T_sky.append( T_sky(ra,dec)) self.Tsys_sky[pol].append(tipping_mu[val_el]-T_sky(ra,dec)) TmpSky = fit.PiecewisePolynomial1DFit() TmpSky.fit(self.elevation, self.T_sky) self.Tsky = TmpSky
def get_gain_value(filename, no_ants, level=70, plot_graph=False, power=-30): #filename = '1536680347_sdp_l0.full.rdb' data = katdal.open(filename) ants = [] for a in data.ants: if a.name not in no_ants: ants.append(a.name) data.select() nchan = data.channels.shape[0] mid = slice(np.int(2600. / 4096. * nchan), np.int(3000. / 4096. * nchan)) p = {} data.select(corrprods='auto', scans='track', ants=ants) for j in range(data.shape[2]): if data.corr_products[j][0] == data.corr_products[j][1]: label = data.corr_products[j][0] pol = label[4] power, power_std = get_power(data, label[0:4], pol) p[label] = [power, power_std, None, []] for scan in data.compscans(): #print scan[0], vis = data.vis[:, mid, :] #print scan for j in range(data.shape[2]): if data.corr_products[j][0] == data.corr_products[j][1]: label = data.corr_products[j][0] gain_level = float(scan[1].split(',')[1]) dat = np.median(np.abs(vis[:, :, j]), axis=[0, 1]) power, power_std, tmp, gain_arraylist = p[label] gain_arraylist.append((gain_level, dat)) p[label] = [power, power_std, None, gain_arraylist] #print label, for keys in p: p[keys][-1] = np.array(p[keys][-1]) level = level pvals = [] for ant in sorted(p): #print ant poly = fit.PiecewisePolynomial1DFit() valid = (p[ant][3][:, 1] > 10) & (p[ant][3][:, 1] < 2000) if valid.sum() > 0 and p[ant][3][valid, 1].sum() > 0: poly_func = poly.fit(p[ant][3][valid, 0], p[ant][3][valid, 1]) try: fits = inversefunc(poly_func, y_values=level, domain=(p[ant][3][valid, 0].min(), p[ant][3][valid, 0].max())) except: print("Error inverting function ", ant) fits = 0.0 p[ant][2] = fits pvals.append([p[ant][0], p[ant][2] * 1]) #if fits < lowlim or fits > hilim: # print ant,fits else: print(" Error no valid values:", ant) pass pvals = np.array(pvals) lowlim, hilim = np.median(pvals[:, 1]) - np.std(pvals[:, 1]) * 2, np.median( pvals[:, 1]) + np.std(pvals[:, 1]) meanv = np.median(pvals[:, 1]) mask = (pvals[:, 1] > lowlim) * (pvals[:, 1] < hilim) linear = fit.LinearLeastSquaresFit() linear_func = linear.fit(pvals[mask, 0], pvals[mask, 1]) print(data.description, linear_func(-30)[0]) if plot_graph: fig, ax = plt.subplots(figsize=(20, 10)) for ant in np.sort(list(p.keys())): if p[ant][2] > 0: plt.errorbar(p[ant][0], p[ant][2], xerr=p[ant][1], fmt='k.') #plot(poly_func(np.linspace(125,0,20)),np.linspace(125,0,20),'r') plt.ylabel("F-engine gain for a nominal correlator Level=%3.0f" % (level)) plt.xlabel("ADC power level") a, b = plt.xlim() plt.xlim(-40, b) #ax.plot(range(20)) ax.axvspan(-40, -37, alpha=0.5, color='red') ax.axvspan(-37, -31, alpha=0.5, color='yellow') ax.axvspan(-31, np.max([b, -5]), alpha=0.3, color='green') plt.title(data.description) plt.text(-38.5, meanv, 'Error', fontsize=20) plt.text(-35, meanv, 'Warning', fontsize=20) plt.grid() return linear_func(power)[0] #,p
start_time=start_time, end_time=end_time, avg_axis=1, start_channel=100, stop_channel=400, include_ts=True) ##### FIT BEAM AND BASELINE ##### # Query KAT antenna for antenna object antenna = katpoint.Antenna(first_ant.sensor.observer.get_value()) # Expected beamwidth in radians (beamwidth factor x lambda / D) expected_width = antenna.beamwidth * katpoint.lightspeed / ( opts.centre_freq * 1e6) / antenna.diameter # Linearly interpolate pointing coordinates to correlator data timestamps interp = fit.PiecewisePolynomial1DFit(max_degree=1) interp.fit(az[0], az[1]) az = katpoint.deg2rad(interp(timestamps)) interp.fit(el[0], el[1]) el = katpoint.deg2rad(interp(timestamps)) # Calculate target coordinates (projected az-el coordinates relative to target object) target_coords = np.vstack(target.sphere_to_plane(az, el, timestamps, antenna)) # Do quick beam + baseline fitting, where both are fitted in 2-D target coord space # This makes no assumptions about the structure of the scans - they are just viewed as a collection of samples baseline = fit.Polynomial2DFit((1, 3)) prev_err_power = np.inf # Initially, all data is considered to be in the "outer" region and therefore forms part of the baseline outer = np.tile(True, len(power)) print "Fitting quick beam and baseline of degree (1, 3) to target '%s':" % ( target.name, )
x = np.array(baselines)[crosscorr].transpose() gain_product = vis / flux y = np.vstack((gain_product.real, gain_product.imag)) fitter.fit(x, y) p = fitter.params * np.sign(fitter.params[6]) gainsol[0] = p[0] + 1.0j * p[1] gainsol[1] = p[2] + 1.0j * p[3] gainsol[2] = p[4] + 1.0j * p[5] gainsol[3] = p[6] ant_gains.append(gainsol) ant_gains = np.array(ant_gains).transpose() # Interpolate gain as a function of time amp_interps, phase_interps = [], [] for n in range(4): amp_interp = fit.PiecewisePolynomial1DFit() amp_interp.fit(gain_times, np.abs(ant_gains[n])) amp_interps.append(amp_interp) phase_interp = fit.PiecewisePolynomial1DFit() angle = np.angle(ant_gains[n]) # Do a quick and dirty angle unwrapping angle_diff = np.diff(angle) angle_diff[angle_diff > np.pi] -= 2 * np.pi angle_diff[angle_diff < -np.pi] += 2 * np.pi angle[1:] = angle[0] + np.cumsum(angle_diff) phase_interp.fit(gain_times, angle) phase_interps.append(phase_interp) plt.figure(8) plt.clf() plt.subplot(121)