Beispiel #1
0
    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