Example #1
0
    def __init__(self,
                 lon=2,
                 lat=66,
                 proj4='+proj=stere +lat_0=90 +lon_0=70 +lat_ts=60 ' +
                 '+units=m +a=6.371e+06 +e=0 +no_defs'):

        self.fileName = 'ArtificialOceanEddy'
        self.name = 'ArtificialOceanEddy'

        self.proj4 = proj4
        self.proj = pyproj.Proj(proj4)

        # Calculate x,y of center of eddy from given lon and lat
        x0, y0 = self.proj(lon, lat)
        width = 600000  # 600 km box
        self.pixelsize = 10000  # Artificial 10 km pixel size
        self.delta_x = self.pixelsize
        self.delta_y = self.pixelsize
        self.x0 = x0
        self.y0 = y0
        self.xmin = x0 - width
        self.xmax = x0 + width
        self.ymin = y0 - width
        self.ymax = y0 + width
        self.start_time = None
        self.end_time = None
        self.time_step = None
        self.variables = ['x_sea_water_velocity', 'y_sea_water_velocity']

        # Run constructor of parent Reader class
        super(Reader, self).__init__()
    def __init__(self,
                 initial_time=datetime(2000, 1, 1, 0, 0),
                 epsilon=0.1,
                 omega=0.628,
                 A=0.25,
                 proj4='+proj=stere +lat_0=0 +lon_0=0 +lat_ts=0 ' +
                 '+units=m +a=6.371e+06 +e=0 +no_defs'):

        self.fileName = 'double_gyre'
        self.name = 'double_gyre'

        self.proj4 = proj4
        self.proj = pyproj.Proj(proj4)

        self.return_block = False
        self.xmin = 0.
        self.xmax = 2.
        self.ymin = 0.
        self.ymax = 1.
        self.A = A
        self.epsilon = epsilon
        self.omega = omega
        self.initial_time = initial_time
        self.start_time = None
        self.end_time = None
        self.time_step = None
        self.variables = ['x_sea_water_velocity', 'y_sea_water_velocity']

        # Run constructor of parent Reader class
        super(Reader, self).__init__()
Example #3
0
    def update_surface_oilfilm_thickness(self):
        '''The mass of oil is summed within a grid of 20x20
        cells covering the oil at a given time. Each oil particle
        within each cell is given a film thickness as the amount of
        oil divided by the cell area.
        '''
        from scipy.stats import binned_statistic_2d
        surface = np.where(self.elements.z == 0)[0]
        if len(surface) == 0:
            print('No oil at surface, no film thickness to update')
            return
        print('Updating oil film thickness for %s of %s elements at surface' %
              (len(surface), self.num_elements_active()))
        meanlon = self.elements.lon[surface].mean()
        meanlat = self.elements.lat[surface].mean()
        # Using stereographic coordinates to get regular X and Y
        psproj = pyproj.Proj('+proj=stere +lat_0=%s +lat_ts=%s +lon_0=%s' %
                             (meanlat, meanlat, meanlon))
        X, Y = psproj(self.elements.lon[surface], self.elements.lat[surface])
        mass_bin, x_edge, y_edge, binnumber = binned_statistic_2d(
            X,
            Y,
            self.elements.mass_oil[surface],
            expand_binnumbers=True,
            statistic='sum',
            bins=100)
        bin_area = (x_edge[1] - x_edge[0]) * (y_edge[1] - y_edge[0])
        oil_density = 1000  # ok approximation here
        film_thickness = (mass_bin / oil_density) / bin_area
        # Postulating min and max film thickness
        max_thickness = 0.01  # 1 cm
        min_thickness = 1e-9  # 1 nanometer
        if film_thickness.max() > max_thickness:
            print('Warning: decreasing thickness to %sm for %s of %s bins' %
                  (max_thickness, np.sum(film_thickness > max_thickness),
                   film_thickness.size))
            film_thickness[film_thickness > max_thickness] = max_thickness
        num_too_thin = np.sum((film_thickness < min_thickness)
                              & (film_thickness > 0))
        if num_too_thin > 0:
            print('Warning: increasing thickness to %sm for %s of %s bins' %
                  (min_thickness, num_too_thin, film_thickness.size))
            film_thickness[film_thickness < min_thickness] = min_thickness

        # https://github.com/scipy/scipy/issues/7010
        binnumber = binnumber - 1

        bx = binnumber[0, :]
        by = binnumber[1, :]
        # Update thickness
        self.elements.oil_film_thickness[
            surface] = self.elements.oil_film_thickness[surface] * np.nan
        self.elements.oil_film_thickness[surface] = \
            film_thickness[bx, by]
Example #4
0
    def seed_from_gml(self, gmlfile, num_elements=1000, *args, **kwargs):
        """Read oil slick contours from GML file, and seed particles within."""

        # Specific imports
        import datetime
        from matplotlib.path import Path
        from xml.etree import ElementTree
        from matplotlib.patches import Polygon
        from mpl_toolkits.basemap import pyproj

        namespaces = {
            'od': 'http://cweb.ksat.no/cweb/schema/geoweb/oil',
            'gml': 'http://www.opengis.net/gml'
        }
        slicks = []

        with open(gmlfile, 'rt') as e:
            tree = ElementTree.parse(e)

        pos1 = 'od:oilDetectionMember/od:oilDetection/od:oilSpill/gml:Polygon'
        pos2 = 'gml:exterior/gml:LinearRing/gml:posList'

        # This retrieves some other types of patches, found in some files only
        # Should be combines with the above, to get all patches
        #pos1 = 'od:oilDetectionMember/od:oilDetection/od:oilSpill/
        # gml:Surface/gml:polygonPatches'
        #pos2 = 'gml:PolygonPatch/gml:exterior/gml:LinearRing/gml:posList'

        # Find detection time
        time_pos = 'od:oilDetectionMember/od:oilDetection/od:detectionTime'
        oil_time = datetime.datetime.strptime(
            tree.find(time_pos, namespaces).text, '%Y-%m-%dT%H:%M:%S.%fZ')

        for patch in tree.findall(pos1, namespaces):
            pos = patch.find(pos2, namespaces).text
            c = np.array(pos.split()).astype(np.float)
            lon = c[0::2]
            lat = c[1::2]
            slicks.append(Polygon(list(zip(lon, lat))))

        # Find boundary and area of all patches
        lons = np.array([])
        lats = lons.copy()
        for slick in slicks:
            ext = slick.get_extents()
            lons = np.append(lons, [ext.xmin, ext.xmax])
            lats = np.append(lats, [ext.ymin, ext.ymax])
            # Make a stereographic projection centred on the polygon
        lonmin = lons.min()
        lonmax = lons.max()
        latmin = lats.min()
        latmax = lats.max()

        # Place n points within the polygons
        proj = pyproj.Proj(
            '+proj=aea +lat_1=%f +lat_2=%f +lat_0=%f +lon_0=%f' %
            (latmin, latmax, (latmin + latmax) / 2, (lonmin + lonmax) / 2))
        slickarea = np.array([])
        for slick in slicks:
            lonlat = slick.get_xy()
            lon = lonlat[:, 0]
            lat = lonlat[:, 1]
            x, y = proj(lon, lat)

            area_of_polygon = 0.0
            for i in range(-1, len(x) - 1):
                area_of_polygon += x[i] * (y[i + 1] - y[i - 1])
            area_of_polygon = abs(area_of_polygon) / 2.0
            slickarea = np.append(slickarea, area_of_polygon)  # in m2

        # Make points
        deltax = np.sqrt(np.sum(slickarea) / num_elements)

        lonpoints = np.array([])
        latpoints = np.array([])
        for i, slick in enumerate(slicks):
            lonlat = slick.get_xy()
            lon = lonlat[:, 0]
            lat = lonlat[:, 1]
            x, y = proj(lon, lat)
            xvec = np.arange(x.min(), x.max(), deltax)
            yvec = np.arange(y.min(), y.max(), deltax)
            x, y = np.meshgrid(xvec, yvec)
            lon, lat = proj(x, y, inverse=True)
            lon = lon.ravel()
            lat = lat.ravel()
            points = np.c_[lon, lat]
            ind = Path(slick.xy).contains_points(points)
            lonpoints = np.append(lonpoints, lon[ind])
            latpoints = np.append(latpoints, lat[ind])

        # Finally seed at found positions
        kwargs['lon'] = lonpoints
        kwargs['lat'] = latpoints
        self.seed_elements(time=oil_time, **kwargs)