Exemple #1
0
def test_WaspGridSiteDistanceClass(site):
    wgs = WaspGridSite(
        site._ds, distance=TerrainFollowingDistance(distance_resolution=2000))
    assert wgs.distance.distance_resolution == 2000
    assert wgs.distance.__call__.__func__ == TerrainFollowingDistance(
    ).__call__.__func__
    wgs = WaspGridSite(site._ds, distance=StraightDistance())
    assert wgs.distance.__call__.__func__ == StraightDistance(
    ).__call__.__func__
Exemple #2
0
 def __init__(self, ds, distance=TerrainFollowingDistance(), mode='valid'):
     """
     Parameters
     ----------
     ds : xarray
         dataset as returned by load_wasp_grd
     distance : Distance object, optional
         Alternatives are StraightDistance and TerrainFollowingDistance2
     mode : {'valid', 'extrapolate'}, optional
         if valid, terrain elevation outside grid area is NAN
         if extrapolate, the terrain elevation at the grid border is returned outside the grid area
     """
     self.use_WS_bins = True
     ds = ds.rename(A="Weibull_A",
                    k="Weibull_k",
                    f="Sector_frequency",
                    spd='Speedup',
                    orog_trn='Turning',
                    elev='Elevation',
                    sec='wd',
                    z='h')
     ds = ds.assign_coords(wd=(ds.wd - 1) * (360 / len(ds.wd)))
     ds = ds.isel(x=np.where(~np.all(np.isnan(ds.Elevation), 1))[0],
                  y=np.where(~np.all(np.isnan(ds.Elevation), 0))[0])
     super().__init__(ds, distance=distance)
Exemple #3
0
 def __init__(self, ds, distance=TerrainFollowingDistance(), mode='valid'):
     """
     Parameters
     ----------
     ds : xarray
         dataset as returned by load_wasp_grd
     distance : Distance object, optional
         Alternatives are StraightDistance and TerrainFollowingDistance2
     mode : {'valid', 'extrapolate'}, optional
         if valid, terrain elevation outside grid area is NAN
         if extrapolate, the terrain elevation at the grid border is returned outside the grid area
     """
     self._ds = ds
     self.mode = mode
     self.interp_funcs = {}
     self.interp_funcs_initialization()
     self.elevation_interpolator = EqDistRegGrid2DInterpolator(self._ds.coords['x'].data,
                                                               self._ds.coords['y'].data,
                                                               self._ds['elev'].data)
     self.TI_data_exist = 'tke' in self.interp_funcs.keys()
     super().__init__(p_wd=np.nanmean(self._ds['f'].data, (0, 1, 2)),
                      a=np.nanmean(self._ds['A'].data, (0, 1, 2)),
                      k=np.nanmean(self._ds['k'].data, (0, 1, 2)),
                      ti=0)
     self.distance = distance
Exemple #4
0
 def from_wasp_grd(cls,
                   path,
                   globstr='*.grd',
                   speedup_using_pickle=True,
                   distance=TerrainFollowingDistance(),
                   mode='valid'):
     ds = load_wasp_grd(path, globstr, speedup_using_pickle)
     return WaspGridSite(ds, distance, mode)
Exemple #5
0
def WaspGridSite(ds, distance=TerrainFollowingDistance(), mode='valid'):
    if distance.__class__ == StraightDistance:
        cls = type("WaspGridSiteStraightDistance", (WaspGridSiteBase, ), {})
        wgs = cls(ds=ds, mode=mode)
    else:
        cls = type("WaspGridSite" + type(distance).__name__,
                   (type(distance), WaspGridSiteBase), {})
        wgs = cls(ds=ds, mode=mode)
        wgs.__dict__.update(distance.__dict__)

    return wgs
Exemple #6
0
def ParqueFicticioSite(distance=TerrainFollowingDistance(distance_resolution=2000)):
    site = WaspGridSiteBase.from_wasp_grd(ParqueFicticio_path, speedup_using_pickle=True, distance=distance)
    site.distance_type = 'terrain_following'
    site.initial_position = np.array([
        [263655.0, 6506601.0],
        [263891.1, 6506394.0],
        [264022.2, 6506124.0],
        [264058.9, 6505891.0],
        [264095.6, 6505585.0],
        [264022.2, 6505365.0],
        [264022.2, 6505145.0],
        [263936.5, 6504802.0],
    ])
    return site
Exemple #7
0
 def __init__(self,
              distance=TerrainFollowingDistance(distance_resolution=2000),
              mode='valid'):
     ds = load_wasp_grd(ParqueFicticio_path, speedup_using_pickle=True)
     WaspGridSite.__init__(self, ds, distance, mode)
     self.initial_position = np.array([
         [263655.0, 6506601.0],
         [263891.1, 6506394.0],
         [264022.2, 6506124.0],
         [264058.9, 6505891.0],
         [264095.6, 6505585.0],
         [264022.2, 6505365.0],
         [264022.2, 6505145.0],
         [263936.5, 6504802.0],
     ])
def test_additional_input():
    site = ParqueFicticioSite()
    wgs = WaspGridSite(site._ds, distance=TerrainFollowingDistance(distance_resolution=2000))
    wgs.interp_funcs_initialization(['ws_mean'])
    x, y = site.initial_position.T
    h = 70 * np.ones_like(x)
    ws_mean, = wgs.interpolate(['ws_mean'], x, y, h)
    npt.assert_array_almost_equal(ws_mean[0, :50],
                                  np.array([4.77080802, 4.77216214, 4.77351626, 4.77487037, 4.77622449,
                                            4.77757861, 4.77893273, 4.78028685, 4.78164097, 4.78299508,
                                            4.7843492, 4.78570332, 4.78705744, 4.78841156, 4.78976567,
                                            4.79111979, 4.79247391, 4.79382803, 4.79518215, 4.79653626,
                                            4.79789038, 4.7992445, 4.80059862, 4.80195274, 4.80330685,
                                            4.80466097, 4.80601509, 4.80736921, 4.80872333, 4.81007744,
                                            4.81143156, 4.87114138, 4.9308512, 4.99056102, 5.05027084,
                                            5.10998066, 5.16969047, 5.22940029, 5.28911011, 5.34881993,
                                            5.40852975, 5.46823957, 5.52794939, 5.5876592, 5.64736902,
                                            5.70707884, 5.76678866, 5.82649848, 5.8862083, 5.94591812]))
Exemple #9
0
        plt.legend()
        plt.show()
    npt.assert_array_less(
        np.abs(wasp_aep_no_density_correction - AEP_ilk.sum((0, 2)) * 1e6),
        300)
    npt.assert_almost_equal(AEP_ilk.sum(),
                            wasp_aep_no_density_correction_total, 3)


@pytest.mark.parametrize(
    'site,dw_ref',
    [(ParqueFicticioSite(distance=TerrainFollowingDistance2()), [
        0., 207.3842238, 484.3998264, 726.7130743, 1039.148129, 1263.1335982,
        1490.3841602, 1840.6508086
    ]),
     (ParqueFicticioSite(distance=TerrainFollowingDistance()), [
         0, 209.803579, 480.8335365, 715.6003233, 1026.9476322, 1249.5510034,
         1475.1467251, 1824.1317343
     ]),
     (ParqueFicticioSite(distance=StraightDistance()),
      [-0, 207, 477, 710, 1016, 1236, 1456, 1799])])
def test_distances(site, dw_ref):
    x, y = site.initial_position.T
    dw_ijl, cw_ijl, dh_ijl, _ = site.distances(src_x_i=x,
                                               src_y_i=y,
                                               src_h_i=np.array([70]),
                                               dst_x_j=x,
                                               dst_y_j=y,
                                               dst_h_j=np.array([70]),
                                               wd_il=np.array([[0]]))
    npt.assert_almost_equal(dw_ijl[0, :, 0], dw_ref)
Exemple #10
0
 def __init__(self, height, width, distance_resolution):
     self.height = height
     self.width = width
     super().__init__(p_wd=[1], ti=0)
     self.distance = TerrainFollowingDistance(
         distance_resolution=distance_resolution)
Exemple #11
0
class Rectangle(TerrainFollowingDistance, UniformSite):
    def __init__(self, height, width, distance_resolution):
        self.height = height
        self.width = width
        super().__init__(p_wd=[1], ti=0)
        self.distance = TerrainFollowingDistance(
            distance_resolution=distance_resolution)

    def elevation(self, x_i, y_i):
        return np.where(np.abs(x_i) < self.width / 2, self.height, 0)


@pytest.mark.parametrize(
    'distance',
    [StraightDistance(), TerrainFollowingDistance()])
def test_flat_distances(distance):
    x = [0, 50, 100, 100]
    y = [100, 100, 100, 0]
    h = [0, 10, 20, 30]
    wdirs = [0, 30, 90]

    dw_ijl, hcw_ijl, dh_ijl, dw_indices_l = distance(FlatSite(),
                                                     src_x_i=x,
                                                     src_y_i=y,
                                                     src_h_i=h,
                                                     dst_x_j=[0],
                                                     dst_y_j=[0],
                                                     dst_h_j=[0],
                                                     wd_il=np.array(wdirs)[na])
Exemple #12
0
    def from_wasp_grd(cls,
                      path,
                      globstr='*.grd',
                      distance=TerrainFollowingDistance(),
                      speedup_using_pickle=True,
                      mode='valid'):
        '''
        Reader for WAsP .grd resource grid files.

        Parameters
        ----------
        path: str
            path to file or directory containing goldwind excel files

        globstr: str
            string that is used to glob files if path is a directory.

        Returns
        -------
        WindResourceGrid: :any:`WindResourceGrid`:

        Examples
        --------
        >>> from mowflot.wind_resource import WindResourceGrid
        >>> path = '../mowflot/tests/data/WAsP_grd/'
        >>> wrg = WindResourceGrid.from_wasp_grd(path)
        >>> print(wrg)
            <xarray.Dataset>
            Dimensions:            (sec: 12, x: 20, y: 20, z: 3)
            Coordinates:
              * sec                (sec) int64 1 2 3 4 5 6 7 8 9 10 11 12
              * x                  (x) float64 5.347e+05 5.348e+05 5.349e+05 5.35e+05 ...
              * y                  (y) float64 6.149e+06 6.149e+06 6.149e+06 6.149e+06 ...
              * z                  (z) float64 10.0 40.0 80.0
            Data variables:
                flow_inc           (x, y, z, sec) float64 1.701e+38 1.701e+38 1.701e+38 ...
                ws_mean            (x, y, z, sec) float64 3.824 3.489 5.137 5.287 5.271 ...
                meso_rgh           (x, y, z, sec) float64 0.06429 0.03008 0.003926 ...
                obst_spd           (x, y, z, sec) float64 1.701e+38 1.701e+38 1.701e+38 ...
                orog_spd           (x, y, z, sec) float64 1.035 1.039 1.049 1.069 1.078 ...
                orog_trn           (x, y, z, sec) float64 -0.1285 0.6421 0.7579 0.5855 ...
                power_density      (x, y, z, sec) float64 77.98 76.96 193.5 201.5 183.9 ...
                rix                (x, y, z, sec) float64 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ...
                rgh_change         (x, y, z, sec) float64 6.0 10.0 10.0 10.0 6.0 4.0 0.0 ...
                rgh_spd            (x, y, z, sec) float64 1.008 0.9452 0.8578 0.9037 ...
                f                  (x, y, z, sec) float64 0.04021 0.04215 0.06284 ...
                tke                (x, y, z, sec) float64 1.701e+38 1.701e+38 1.701e+38 ...
                A                  (x, y, z, sec) float64 4.287 3.837 5.752 5.934 5.937 ...
                k                  (x, y, z, sec) float64 1.709 1.42 1.678 1.74 1.869 ...
                flow_inc_tot       (x, y, z) float64 1.701e+38 1.701e+38 1.701e+38 ...
                ws_mean_tot        (x, y, z) float64 5.16 6.876 7.788 5.069 6.85 7.785 ...
                power_density_tot  (x, y, z) float64 189.5 408.1 547.8 178.7 402.2 546.6 ...
                rix_tot            (x, y, z) float64 0.0 0.0 0.0 9.904e-05 9.904e-05 ...
                tke_tot            (x, y, z) float64 1.701e+38 1.701e+38 1.701e+38 ...
                A_tot              (x, y, z) float64 5.788 7.745 8.789 5.688 7.716 8.786 ...
                k_tot              (x, y, z) float64 1.725 1.869 2.018 1.732 1.877 2.018 ...
                elev               (x, y) float64 37.81 37.42 37.99 37.75 37.46 37.06 ...

        '''

        var_name_dict = {
            'Flow inclination': 'flow_inc',
            'Mean speed': 'ws_mean',
            'Meso roughness': 'meso_rgh',
            'Obstacles speed': 'obst_spd',
            'Orographic speed': 'orog_spd',
            'Orographic turn': 'orog_trn',
            'Power density': 'power_density',
            'RIX': 'rix',
            'Roughness changes': 'rgh_change',
            'Roughness speed': 'rgh_spd',
            'Sector frequency': 'f',
            'Turbulence intensity': 'tke',
            'Weibull-A': 'A',
            'Weibull-k': 'k',
            'Elevation': 'elev',
            'AEP': 'aep'
        }

        def _read_grd(filename):
            def _parse_line_floats(f):
                return [float(i) for i in f.readline().strip().split()]

            def _parse_line_ints(f):
                return [int(i) for i in f.readline().strip().split()]

            with open(filename, 'rb') as f:
                file_id = f.readline().strip().decode()
                nx, ny = _parse_line_ints(f)
                xl, xu = _parse_line_floats(f)
                yl, yu = _parse_line_floats(f)
                zl, zu = _parse_line_floats(f)
                values = np.array(
                    [l.split() for l in f.readlines() if l.strip() != b""],
                    dtype=np.float)  # around 8 times faster

            xarr = np.linspace(xl, xu, nx)
            yarr = np.linspace(yl, yu, ny)

            # note that the indexing of WAsP grd file is 'xy' type, i.e.,
            # values.shape == (xarr.shape[0], yarr.shape[0])
            # we need to transpose values to match the 'ij' indexing
            values = values.T
            #############
            # note WAsP denotes unavailable values using very large numbers, here
            # we change them into np.nan, to avoid strange results.
            values[values > 1e20] = np.nan

            return xarr, yarr, values

        if speedup_using_pickle:
            if os.path.isdir(path):
                pkl_fn = os.path.join(
                    path,
                    os.path.split(os.path.dirname(path))[1] + '.pkl')
                if os.path.isfile(pkl_fn):
                    return WaspGridSiteBase.from_pickle(pkl_fn,
                                                        distance=distance)
                else:
                    site_conditions = WaspGridSiteBase.from_wasp_grd(
                        path,
                        globstr,
                        distance=distance,
                        speedup_using_pickle=False)
                    site_conditions.to_pickle(pkl_fn)
                    return site_conditions
            else:
                raise NotImplementedError

        if os.path.isdir(path):
            files = sorted(glob.glob(os.path.join(path, globstr)))
        else:
            raise Exception('Path was not a directory...')

        file_height_dict = defaultdict(list)

        pattern = re.compile(
            r'Sector (\w+|\d+) \s+ Height (\d+)m \s+ ([a-zA-Z0-9- ]+)')
        for f in files:
            sector, height, var_name = re.findall(pattern, f)[0]
            # print(sector, height, var_name)
            name = var_name_dict.get(var_name, var_name)
            file_height_dict[height].append((f, sector, name))

        elev_avail = False
        first = True
        for height, files_subset in file_height_dict.items():

            first_at_height = True
            for file, sector, var_name in files_subset:
                xarr, yarr, values = _read_grd(file)

                if sector == 'All':

                    # Only 'All' sector has the elevation files.
                    # So here we make sure that, when the elevation file
                    # is read, it gets the right (x,y) coords/dims.
                    if var_name == 'elev':
                        elev_avail = True
                        elev_vals = values
                        elev_coords = {'x': xarr, 'y': yarr}
                        elev_dims = ('x', 'y')
                        continue

                    else:
                        var_name += '_tot'

                        coords = {
                            'x': xarr,
                            'y': yarr,
                            'z': np.array([float(height)])
                        }

                        dims = ('x', 'y', 'z')

                        da = xr.DataArray(values[..., np.newaxis],
                                          coords=coords,
                                          dims=dims)

                else:

                    coords = {
                        'x': xarr,
                        'y': yarr,
                        'z': np.array([float(height)]),
                        'sec': np.array([int(sector)])
                    }

                    dims = ('x', 'y', 'z', 'sec')

                    da = xr.DataArray(values[..., np.newaxis, np.newaxis],
                                      coords=coords,
                                      dims=dims)

                if first_at_height:
                    ds_tmp = xr.Dataset({var_name: da})
                    first_at_height = False
                else:
                    ds_tmp = xr.merge([ds_tmp, xr.Dataset({var_name: da})])

            if first:
                ds = ds_tmp
                first = False
            else:
                ds = xr.concat([ds, ds_tmp], dim='z')

        if elev_avail:
            ds['elev'] = xr.DataArray(elev_vals,
                                      coords=elev_coords,
                                      dims=elev_dims)
        ############
        # Calculate the compund speed-up factor based on orog_spd, rgh_spd
        # and obst_spd
        spd = 1
        for dr in ds.data_vars:
            if dr in ['orog_spd', 'obst_spd', 'rgh_spd']:
                # spd *= np.where(ds.data_vars[dr].data > 1e20, 1, ds.data_vars[dr].data)
                spd *= np.where(np.isnan(ds.data_vars[dr].data), 1,
                                ds.data_vars[dr].data)

        ds['spd'] = copy.deepcopy(ds['orog_spd'])
        ds['spd'].data = spd

        #############
        # change the frequency from per sector to per deg
        ds['f'].data = ds['f'].data * len(ds['f']['sec'].data) / 360.0

        #         #############
        #         # note WAsP denotes unavailable values using very large numbers, here
        #         # we change them into np.nan, to avoid strange results.
        #         for var in ds.data_vars:
        #             ds[var].data = np.where(ds[var].data > 1e20, np.nan, ds[var].data)

        # make sure coords along z is asending order
        ds = ds.loc[{'z': sorted(ds.coords['z'].values)}]

        ######################################################################

        if 'tke' in ds and np.mean(ds['tke']) > 1:
            ds['tke'] *= 0.01

        return WaspGridSite(ds, distance, mode)
Exemple #13
0
        return np.sqrt(np.maximum(self.height**2 - x_i**2, 0))


class Rectangle(TerrainFollowingDistance, UniformSite):
    def __init__(self, height, width, distance_resolution):
        self.height = height
        self.width = width
        super().__init__(p_wd=[1], ti=0)
        self.distance = TerrainFollowingDistance(distance_resolution=distance_resolution)

    def elevation(self, x_i, y_i):
        return np.where(np.abs(x_i) < self.width / 2, self.height, 0)


@pytest.mark.parametrize('distance', [StraightDistance(),
                                      TerrainFollowingDistance()
                                      ])
def test_flat_distances(distance):
    x = [0, 50, 100, 100, 0]
    y = [100, 100, 100, 0, 0]
    h = [0, 10, 20, 30, 0]
    wdirs = [0, 30, 90]

    site = FlatSite(distance=distance)
    site.distance.setup(src_x_i=x, src_y_i=y, src_h_i=h)
    dw_ijl, hcw_ijl, dh_ijl = site.distance(wd_il=np.array(wdirs)[na], src_idx=[0, 1, 2, 3], dst_idx=[4])
    dw_indices_l = site.distance.dw_order_indices(np.array(wdirs))

    if 0:
        distance.plot(wd_il=np.array(wdirs)[na], src_i=[0, 1, 2, 3], dst_i=[4])
        plt.show()