def compare_with_synth(self,**kwargs): """ Method description ---------------------------- Comparison between the synthesis field and flight level data is achieved by: 1) Find all the indexes of the synth grid where the flight trajectory intersects 2) Filter out repeated indexes of the trajectory (LINE) 3) Save geographic coordinates of the LINE 4) In the synth grid, search the 9 nearest neighbors along each point of LINE 5) Fill missing synth values by averaging the neighbors 6) In the flight data, search 15 values nearest to each point of LINE 7) Average each set of 15 values of the flight array """ synth=kwargs['array'] synth_lons=kwargs['x'] synth_lats=kwargs['y'] synth_z=kwargs['z'] zlevel=kwargs['level'] flightmet = kwargs['met'] # flight level meteo field used for comparison noplot = kwargs['noplot'] idx = np.where(synth_z==zlevel) data = np.squeeze(synth[:,:,idx]) flgt_lats,flgt_lons=zip(*self.flightPath) flight_altitude=self.met['palt'] if flightmet in ['u','v']: wspd=self.met['wspd'] wdir=self.met['wdir'] u = -wspd*np.sin(wdir*np.pi/180.) v = -wspd*np.cos(wdir*np.pi/180.) if flightmet == 'u': flight_wspd = u else: flight_wspd = v else: flight_wspd=self.met[flightmet] flgt_lats = np.asarray(cm.around(flgt_lats,4)) flgt_lons = np.asarray(cm.around(flgt_lons,4)) synth_lats = np.asarray(cm.around(synth_lats,4)) synth_lons = np.asarray(cm.around(synth_lons,4)) idx_lat=[] idx_lon=[] for lat,lon in zip(flgt_lats,flgt_lons): idx_lat.append(cm.find_index_recursively(array=synth_lats,value=lat,decimals=4)) idx_lon.append(cm.find_index_recursively(array=synth_lons,value=lon,decimals=4)) """ filter out repeated indexes """ indexes_filtered=[] first=True for val in zip(idx_lon,idx_lat): if first: val_foo=val indexes_filtered.append(val) first=False elif val!=val_foo: indexes_filtered.append(val) val_foo=val """ save geographic coordinates of the line """ line_lat=[] line_lon=[] for lon,lat in indexes_filtered: line_lon.append(synth_lons[lon]) line_lat.append(synth_lats[lat]) linesynth=zip(line_lon,line_lat) """ search nearest neighbors """ synth_coord=list(product(synth_lons,synth_lats)) tree = cKDTree(synth_coord) neigh = 9 dist, idx = tree.query(linesynth, k=neigh, eps=0, p=2, distance_upper_bound=0.1) """ convert to one-column array """ grid_shape=data.shape data = data.reshape(grid_shape[0]*grid_shape[1],1) """ gets the center point """ idx_split=zip(*idx) idx0 = list(idx_split[0]) """ extract center point value """ data_extract=data[idx0] """ average neighbors """ data_extract2=[] for i in idx: data_extract2.append(np.nanmean(data[i])) """ save center points of line """ line_center=[] line_neighbors=[] for i in idx: value=np.unravel_index(i[0], grid_shape) line_center.append(value) for j in i[1:]: value=np.unravel_index(j, grid_shape) line_neighbors.append(value) """ convert back to 2D array """ data=data.reshape(121,131) """ swap coordinates to (lon,lat)""" flight_coord = [(t[1], t[0]) for t in self.flightPath] tree = cKDTree(flight_coord) neigh = 15 dist, idx = tree.query(linesynth, k=neigh, eps=0, p=2, distance_upper_bound=0.1) """ average flight data """ flgt_mean=[] flgt_altitude=[] for i in idx: flgt_mean.append(np.nanmean(flight_wspd[i])) flgt_altitude.append(np.nanmean(flight_altitude[i])) """ make plots """ jet = plt.get_cmap('jet') cNorm = colors.Normalize(vmin=np.amin(data), vmax=np.amax(data)) scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) synth_alt=str(int(zlevel[0]*1000)) flgt_alt=str(int(np.average(flgt_altitude))) if flightmet == 'wspd': windtype = 'Horizontal' elif flightmet == 'u': windtype = 'U-component' elif flightmet == 'v': windtype = 'V-component' elif flightmet == 'wvert': windtype = 'Vertical' antext1='Synthesis alt: '+synth_alt+' m MSL' antext2='Flight level alt: '+flgt_alt+' m MSL' title1=windtype +' wind speed\n'+self.name title2='Flight level and P3 synthesis comparison - '+windtype+' wind speed\n'+self.name if noplot is True: pass else: ''' grid ''' plt.figure(figsize=(8,7)) im=plt.imshow(data.T, interpolation='none',origin='lower',cmap='jet') for p,val in zip(line_center,data_extract2): colorVal=scalarMap.to_rgba(val) plt.plot(p[0],p[1],color=colorVal,marker='s',markersize=6,linestyle='none') plt.xlabel('X') plt.ylabel('Y') plt.colorbar(im) plt.annotate(antext1, xy=(0.1, 0.95), xycoords="axes fraction",fontsize=14) plt.suptitle(title1) plt.grid(which='major') plt.draw() ''' timeseries ''' fig, ax1 = plt.subplots(figsize=(8,7)) ln1=ax1.plot(data_extract,'bo',label='raw synthesis wind') ln2=ax1.plot(data_extract2,'rs',label='synthesis wind interpolated') ln3=ax1.plot(flgt_mean,'g',label='flight wind') ax1.set_ylabel('wind speed [m/s]') ax1.set_xlabel('Points along line') ax2=ax1.twinx() vmin=min(flgt_altitude)-50 vmax=max(flgt_altitude)+50 ln4=ax2.plot(flgt_altitude,'black',label='flight altitude') ax2.set_ylim([vmin,vmax]) ax2.set_ylabel('Meters MSL') lns=ln1+ln2+ln3+ln4 labs=[l.get_label() for l in lns] ax2.legend(lns,labs,numpoints=1,loc=4,prop={'size':10}) ax2.annotate(antext1, xy=(0.5, 0.9), xycoords="axes fraction",fontsize=14) plt.grid(which='major') plt.suptitle(title2) plt.draw() ''' scatter ''' # with sns.axes_style("darkgrid"): fig,ax=plt.subplots(figsize=(8,7)) # fig,ax=plt.subplots() x=np.asarray(flgt_mean) y=np.asarray(data_extract2) ax.scatter(x,y) #---------- # 1:1 line #========== maxx=np.nanmax(x) minx=np.nanmin(x) maxy=np.nanmax(y) miny=np.nanmin(y) mmax=np.max([maxx,maxy]) mmin=np.min([minx,miny]) x1to1=np.linspace(-30,30,3) y1to1=x1to1 ax.plot(x1to1, y1to1, color='k', linestyle='-', linewidth=2) #------------- # regression #============= xs = x[~np.isnan(y)] ys = y[~np.isnan(y)] model=sm.OLS(ys,xs) result=model.fit() c=0 m=result.params[0] xr=np.linspace(-30,30,3) yr=c+m*xr ax.plot(xr, yr, color='r', linestyle=':', linewidth=2) #-------------- r2=np.round(result.rsquared,decimals=2) m=np.round(m,decimals=2) antext3="R-sqr: "+str(r2) antext4="Y = "+str(m)+" * X" textstr = antext2+'\n'+antext1+'\n'+antext3+'\n'+antext4 ax.text(0.5, 0.05, textstr, transform=ax.transAxes, fontsize=14, verticalalignment='bottom') ax.set_aspect(1) ax.set_xlim([mmin*0.95, mmax*1.05]) ax.set_ylim([mmin*0.95, mmax*1.05]) plt.suptitle(title2) plt.xlabel('Flight wind speed [m s-1]') plt.ylabel('Synthesis wind speed [m s-1]') plt.grid(which='major') return flgt_mean, data_extract2