smos 0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
smos/__init__.py ADDED
@@ -0,0 +1,10 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ # Change here if project is renamed and does not equal the package name
5
+ dist_name = __name__
6
+ __version__ = version(dist_name)
7
+ except PackageNotFoundError: # pragma: no cover
8
+ __version__ = "unknown"
9
+ finally:
10
+ del version, PackageNotFoundError
smos/cli.py ADDED
@@ -0,0 +1,25 @@
1
+ """
2
+ Command line interface for all SMOS products: `smos <product> <command>`,
3
+ e.g. `smos l3 download`. See `smos --help`.
4
+ """
5
+ import click
6
+
7
+ from smos.smos_l2.cli import smos_l2
8
+ from smos.smos_ic.cli import smos_ic
9
+ from smos.smos_l3.cli import smos_l3
10
+ from smos.smos_l4.cli import smos_l4
11
+
12
+
13
+ @click.group(short_help="SMOS Command Line Programs.", name="smos")
14
+ def smos():
15
+ """
16
+ Download SMOS data and convert it into time series. Each product has
17
+ its own group of commands, see e.g. `smos l3 --help`.
18
+ """
19
+ pass
20
+
21
+
22
+ smos.add_command(smos_l2, name="l2")
23
+ smos.add_command(smos_ic, name="ic")
24
+ smos.add_command(smos_l3, name="l3")
25
+ smos.add_command(smos_l4, name="l4")
smos/grid.py ADDED
@@ -0,0 +1,121 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from pygeogrids.grids import CellGrid, BasicGrid, lonlat2cell
4
+ from ease_grid import EASE2_grid
5
+ import numpy as np
6
+ from netCDF4 import Dataset
7
+ import os
8
+
9
+
10
+ class EASE25CellGrid(CellGrid):
11
+ """ CellGrid version of EASE25 Grid as used in SMOS IC """
12
+
13
+ def __init__(self, bbox=None, only_land=False):
14
+ """
15
+ Parameters
16
+ ----------
17
+ bbox: tuple, optional (default: None)
18
+ (min_lon, min_lat, max_lon, max_lat)
19
+ Bounding box to create subset for, if None is passed a global
20
+ grid is used.
21
+ only_land: bool, optional (default: False)
22
+ If True, restrict the grid to land points only.
23
+ """
24
+
25
+ ease25 = EASE2_grid(25000)
26
+ glob_lons, glob_lats = ease25.londim, ease25.latdim
27
+
28
+ lons, lats = np.meshgrid(glob_lons, glob_lats)
29
+ assert lons.shape == lats.shape
30
+ shape = lons.shape
31
+
32
+ lats = np.flipud(lats) # flip lats, so that origin in bottom left
33
+
34
+ globgrid = BasicGrid(lons.flatten(), lats.flatten(), shape=shape)
35
+
36
+ self.bbox = bbox
37
+ self.cellsize = 5.
38
+
39
+ # Start with global grid
40
+ grid = globgrid
41
+ sgpis = globgrid.activegpis
42
+ params = {'subset': sgpis}
43
+ land_mask = None
44
+
45
+ # Get land mask if needed
46
+ if only_land:
47
+ mask_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
48
+ "Grid_Point_Mask_USGS.nc")
49
+ with Dataset(mask_path) as ds:
50
+ land_mask = ds.variables["USGS_Land_Flag"][:].flatten().filled() == 0.0
51
+
52
+ # Special handling when both land-only and bbox are specified
53
+ if only_land and self.bbox:
54
+ # Get land points from global grid
55
+ land_points = np.ma.masked_array(globgrid.get_grid_points()[0], land_mask)
56
+ land_sgpis = globgrid.activegpis[~land_points.mask]
57
+
58
+ # Get bbox points from global grid
59
+ bbox_sgpis = globgrid.get_bbox_grid_points(
60
+ latmin=self.bbox[1],
61
+ latmax=self.bbox[3],
62
+ lonmin=self.bbox[0],
63
+ lonmax=self.bbox[2]
64
+ )
65
+
66
+ # Create intersection of land points and bbox points
67
+ # (points that are both on land AND within bbox)
68
+ intersection = np.intersect1d(land_sgpis, bbox_sgpis)
69
+
70
+ # Use global grid with the intersection as subset
71
+ grid = globgrid
72
+ sgpis = intersection
73
+ params = {'subset': sgpis}
74
+ shape = (len(sgpis),)
75
+
76
+ # Apply original land mask if only_land is True but no bbox is specified
77
+ # Land points are a subset of the global grid, i.e. the gpis are the
78
+ # same as in the global grid (not renumbered).
79
+ elif only_land:
80
+ land_points = np.ma.masked_array(globgrid.get_grid_points()[0], land_mask)
81
+ sgpis = globgrid.activegpis[~land_points.mask]
82
+ params = {'subset': sgpis}
83
+ shape = (len(sgpis),)
84
+
85
+ # Apply original bbox filter if only bbox is specified (no land mask)
86
+ elif self.bbox:
87
+ bbox_sgpis = grid.get_bbox_grid_points(
88
+ latmin=self.bbox[1],
89
+ latmax=self.bbox[3],
90
+ lonmin=self.bbox[0],
91
+ lonmax=self.bbox[2]
92
+ )
93
+ sgpis = bbox_sgpis
94
+ params = {'subset': sgpis}
95
+
96
+ # Set final grid parameters
97
+ self.grid = grid
98
+ self.subset = sgpis
99
+ self.shape = shape
100
+
101
+ super().__init__(lon=grid.arrlon,
102
+ lat=grid.arrlat,
103
+ cells=lonlat2cell(grid.arrlon, grid.arrlat,
104
+ self.cellsize),
105
+ shape=shape,
106
+ **params)
107
+
108
+ if only_land:
109
+ self.subset_shape = shape
110
+ else:
111
+ self.subset_shape = (len(np.unique(self.activearrlat)),
112
+ len(np.unique(self.activearrlon)))
113
+
114
+
115
+ def cut(self) -> CellGrid:
116
+ # create a new grid from the active subset
117
+ return BasicGrid(lon=self.activearrlon,
118
+ lat=self.activearrlat,
119
+ gpis=self.activegpis,
120
+ subset=None,
121
+ shape=self.subset_shape).to_cell_grid(self.cellsize)