-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasics_02.py
More file actions
106 lines (98 loc) · 3.36 KB
/
Copy pathbasics_02.py
File metadata and controls
106 lines (98 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Exercise: Latitude-Longitude Area Corrections
# =====
#
# It is common that geospatial data is stored in grid format with longitude and latitudes. When dealing with longitude and latitude data, it is so easy to forget that different datapoints represent different areas at the surface of the Earth.
# **This is critical for satellite data analysis!**
#
# By the end of this activity, you should be comfortable with:
# - Understanding why grid cell areas vary with latitude
# - Calculating exact grid cell areas using spherical geometry
# - Applying area corrections to real satellite data (CSR GRACE)
#
# A bit of math
# =====
# The surface area of a grid cell on a sphere, bounded by latitudes
# $\phi_1, \phi_2$ and longitudes $\lambda_1, \lambda_2$, can be derived
# from the spherical surface element.
#
# On a sphere of radius $R$, the infinitesimal surface area is:
#
# $$ dA = R^2 \cos\phi \, d\phi \, d\lambda $$
#
# Now let's do integration over latitude and longitude. Integrating over latitude we have:
#
# $$ \int_{\phi_1}^{\phi_2} \cos\phi \, d\phi = \sin\phi_2 - \sin\phi_1 $$
#
# Integrating over longitude we get:
#
# $$ \int_{\lambda_1}^{\lambda_2} d\lambda = \Delta\lambda $$
#
# Therefore, the area of the grid cell is:
#
# $$ A = R^2 \, \big| \sin\phi_2 - \sin\phi_1 \big| \, \big| \Delta\lambda \big| $$
#
# where all angles are in radians.
#
# Small-Cell Approximation
# =========================
#
# For very small cells, the area can be approximated by:
#
# $$ A \approx R^2 \, \Delta\phi \, \Delta\lambda \, \cos\bar{\phi} $$
#
# with $\Delta\phi = \phi_2 - \phi_1$, $\Delta\lambda = \lambda_2 - \lambda_1$,
# and $\bar{\phi} = \tfrac{1}{2}(\phi_1 + \phi_2)$ is the mean latitude of the cell.
#
# **Key insight:** The exact formula accounts for the curvature of Earth, while the approximation
# works well for small grid cells where $\cos\bar{\phi}$ doesn't change much across the cell.
#
# Let's begin by loading the CSR GRACE solution file and calculating grid cell areas.
# + tags=["empty-cell"]
# Import the required libraries
# import xarray as xr
# from pathlib import Path
# import numpy as np
# import matplotlib.pyplot as plt
# -
# + tags=["solution"]
import xarray as xr
import numpy as np
# Load the CSR GRACE dataset
filename = "./CSR_GRACE_GRACE-FO_RL0603_Mascons_all-corrections.nc"
ds = xr.open_dataset(filename)
print("Dataset overview:")
print(ds)
# -
# + [markdown]
# ## Calculate Grid Cell Areas Using Exact Formula
#
# Now we'll extract the coordinate arrays and calculate the area of each grid cell using the exact spherical formula.
# The CSR GRACE data has a grid spacing of approximately 0.25 × 0.25.
# -
# + tags=["empty-cell"]
# Extract coordinates and calculate grid cell areas using exact formula
# lons =
# lats =
# lons_x, lats_x =
#
# # Earth's radius in meters
# Rearth =
#
# # Calculate areas using exact formula: A = R^2 |sin(\phi_2) - sin(\phi_1)| |\Delta \lambda|
# areas =
# -
# + tags=["solution"]
lons = ds["lon"].values
lats = ds["lat"].values
lons_x, lats_x = np.meshgrid(lons, lats)
Rearth = 6370e3 # Radius of the Earth in meters
areas = Rearth ** 2 * abs(np.sin(np.radians(lats_x[1:, :])) - np.sin(np.radians(lats_x[:-1, :]))) * np.radians(0.25)
area_min = areas.min()
area_max = areas.max()
print(
"Grid cell areas range from "
f"{area_min:,.0f} m^2 ({area_min / 1e6:.2f} km^2) "
"to "
f"{area_max:,.0f} m^2 ({area_max / 1e6:.2f} km^2)"
)
# -