Summary
NASA's Plankton, Aerosol, Cloud, ocean Ecosystem (PACE) platform carries two multi-angle polarimeters (MAPs): the Spectro-polarimeter for Planetary Exploration one (SPEXone) and the Hyper-Angular Rainbow Polarimeter #2 (HARP2). These sensors offer unique data, which is useful for its own scientific purposes and also complements the data from the Ocean Color Instrument (OCI). Working with data from the MAPs requires you to understand both multi-angle data and some basic concepts about polarization. This notebook will walk you through some basic understanding and visualizations of multi-angle polarimetry so that you feel comfortable incorporating this data into your future projects.
Prerequisites
The following are prerequisites for this tutorial:
- Access Data from OCI (notebook)
- Earthdata Login (required to access data from the NASA Earthdata system, including NASA ocean color data)
Learning Objectives
At the end of this notebook you will know:
- How to acquire data from HARP2.
- How to plot geolocated imagery.
- Some basic concepts about polarization.
- How to make animations of multi-angle data.
1. Setup
Begin by importing all of the packages used in this notebook. If your kernel uses an environment defined following the guidance on the tutorials page, then the imports will be successful.
from pathlib import Path
from tempfile import TemporaryDirectory
from scipy.ndimage import gaussian_filter1d
from matplotlib import animation
import cartopy.crs as ccrs
import earthaccess
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr2. Get Level 1-C Data
Download some HARP2 Level-1C data using the short_name value “PACE_HARP2_L1C_SCI” in earthaccess.search_data. Level-1C corresponds to geolocated imagery. This means the imagery coming from the satellite has been calibrated and assigned to locations on the Earth’s surface. Note that this might take a while, depending on the speed of your internet connection, and the progress bar will seem frozen because we’re only downloading one file.
auth = earthaccess.login(persist=True)tspan = ("2024-05-20", "2024-05-20")
results = earthaccess.search_data(
short_name="PACE_HARP2_L1C_SCI",
temporal=tspan,
count=1,
)Granules found: 1
paths = earthaccess.open(results)
Opening 1 granules, approx size: 0.62 GBusing endpoint: https://obdaac-tea.earthdatacloud.nasa.gov/s3credentials
QUEUEING TASKS | : 0%| | 0/1 [00:00<?, ?it/s]
PROCESSING TASKS | : 0%| | 0/1 [00:00<?, ?it/s]
COLLECTING RESULTS | : 0%| | 0/1 [00:00<?, ?it/s]
prod = xr.open_dataset(paths[0])
view = xr.open_dataset(paths[0], group="sensor_views_bands").squeeze()
geo = xr.open_dataset(paths[0], group="geolocation_data").set_coords(["longitude", "latitude"])
obs = xr.open_dataset(paths[0], group="observation_data").squeeze()The prod dataset, as usual for OB.DAAC products, contains attributes but no variables. Merge it with the “observation_data” and “geolocation_data”, setting latitude and longitude as auxiliary (e.e. non-index) coordinates, to get started.
dataset = xr.merge((prod, obs, geo))
datasetxarray.Dataset
- Dimensions
bins_along_track: 396bins_across_track: 519number_of_views: 90
- Coordinates
- longitude(bins_along_track, bins_across_track)float32...
long_name :
Geodetic Longitude of bin location
units :
degrees_east
valid_min :
-180.0
valid_max :
180.0
[205524 values with dtype=float32]
- latitude(bins_along_track, bins_across_track)float32...
long_name :
Geodetic Latitude of bin location
units :
degrees_north
valid_min :
-90.0
valid_max :
90.0
[205524 values with dtype=float32]
- Data variables
- number_of_observations(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Observations contributing to bin from each view
valid_min :
0
valid_max :
30000
[18497160 values with dtype=float32]
- qc(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
quality indicator
valid_min :
0
valid_max :
10
[18497160 values with dtype=float32]
- i(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
I Stokes vector component
units :
W/m2/micron/sr
valid_min :
0
valid_max :
32760
[18497160 values with dtype=float32]
- q(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Q Stokes vector component
units :
W/m2/micron/sr
valid_min :
-32760
valid_max :
32760
[18497160 values with dtype=float32]
- u(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
U Stokes vector component
units :
W/m2/micron/sr
valid_min :
-32760
valid_max :
32760
[18497160 values with dtype=float32]
- dolp(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Degree of Linear Polarization
units :
none
valid_min :
0
valid_max :
20000
[18497160 values with dtype=float32]
- aolp(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Angle of linear polarization
units :
degrees
valid_min :
-18000
valid_max :
18000
[18497160 values with dtype=float32]
- i_stdev(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Standard deviation of I in bin
units :
W/m2/micron/sr
valid_min :
0
valid_max :
32760
[18497160 values with dtype=float32]
- q_stdev(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Standard deviation of Q in bin
units :
W/m2/micron/sr
valid_min :
0
valid_max :
32760
[18497160 values with dtype=float32]
- u_stdev(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Standard deviation of U in bin
units :
W/m2/micron/sr
valid_min :
0
valid_max :
32760
[18497160 values with dtype=float32]
- dolp_stdev(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Standard deviation of DOLP in bin
units :
none
valid_min :
0
valid_max :
20000
[18497160 values with dtype=float32]
- aolp_stdev(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Standard deviation of AOLP in bin
units :
degrees
valid_min :
0
valid_max :
18000
[18497160 values with dtype=float32]
- height(bins_along_track, bins_across_track)float32...
long_name :
(aggregation) height of bin location above the ellipsoid
units :
meters
valid_min :
-10000
valid_max :
10000
[205524 values with dtype=float32]
- height_stdev(bins_along_track, bins_across_track)float32...
long_name :
Standard deviation of terrain altitude within bin
units :
meters
valid_min :
0
valid_max :
5000
[205524 values with dtype=float32]
- sensor_zenith_angle(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Sensor zenith angle at bin location
units :
degrees
valid_min :
0
valid_max :
18000
[18497160 values with dtype=float32]
- sensor_azimuth_angle(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
View azimuth at bin location to north
units :
degrees
valid_min :
-18000
valid_max :
18000
[18497160 values with dtype=float32]
- solar_zenith_angle(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Solar zenith angle at bin location
units :
degrees
valid_min :
0
valid_max :
18000
[18497160 values with dtype=float32]
- solar_azimuth_angle(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Solar azimuth at bin location to north
units :
degrees
valid_min :
-18000
valid_max :
18000
[18497160 values with dtype=float32]
- scattering_angle(bins_along_track, bins_across_track, number_of_views)float32...
long_name :
Scattering angle at bin location
units :
degrees
valid_min :
0
valid_max :
18000
[18497160 values with dtype=float32]
- rotation_angle(bins_along_track, bins_across_track, number_of_views)float32...
[18497160 values with dtype=float32]
- Indexes
(0)
- Attributes
title :
PACE HARP2 Level-1C data
instrument :
HARP2
product_name :
PACE_HARP2.20240519T235950.L1C.5km.nc
processing_level :
L1C
processing_version :
V00
conventions :
CF-1.10
hipp_version :
v3.9
institution :
NASA Goddard Space Flight Center, Ocean Biology Processing Group
license :
http://science.nasa.gov/earth-science/earth-science-data/data-informati…
naming_authority :
gov.nasa.gsfc.sci.oceancolor
keyword_vocabulary :
NASA Global Change Master Directory (GCMD) Science Keywords
stdname_vocabulary :
NetCDF Climate and Forecast (CF) Metadata Convention
creater_name :
NASA/GSFC
creater_email :
creater_url :
project :
PACE Project
publisher_name :
NASA/GSFC
publisher_email :
publisher_url :
history :
Processed by HIPP version: 3.9
date_created :
2024-05-20T02:52:44 Eastern
cdm_data_type :
swath
time_coverage_start :
2024-05-19T23:59:50
time_coverage_end :
2024-05-20T00:04:50
sun_earth_distance :
1.011914
terrain_data_source :
spectral_response_function :
systematic_uncertainty_model :
nadir_bin :
259
bin_size_at_andir :
5.2km2
geospatial_bounds :
POLYGON((26.182882 -156.695938,20.996824 177.265900,3.291956 -177.878937,8.335972 -153.886566,26.182882 -156.695938))
geospatial_bounds_crs :
EPSG:4326
geospatial_lat_max :
26.182882
geospatial_lat_min :
3.291956
geospatial_lon_max :
179.999954
geospatial_lon_min :
-179.999985
Source :
Observation
comments :
reference :
grid_center_latitude :
15.017247200012207
grid_center_longitude :
-167.93800354003906
grid_average_heading :
0.0
image_index_start_end :
[ 0 -1]
orb_latitude_start_end_degrees :
[ 5.9357533 24.152092 ]
orb_longitude_start_end_degrees :
[-165.9359 -169.9797]
orb_altitude_start_end_meters :
[677224.94 677441.44]
att_roll_start_end_degrees :
[-0.32586172 -0.33870336]
att_pitch_start_end_degrees :
[-0.02427847 -0.02303081]
att_yaw_start_end_degrees :
[-12.048631 -12.34895 ]
sensor_temperature_start_end_degC :
[-18.25 -18.3125 -18.25 -18.25 -18.3125 -18.25 ]
sensor_integtime_start_end_ms :
[16.23648 16.23648 16.23648 16.23648 16.23648 16.23648]
stokes_reference_plane :
View meridian
acquisition_scheme :
4
auxdata_file :
/sdps/sdpsoper/Science/OCSSW/PACE_V1.0/share/harp2/hipp/harp2_hipp_aux.2024.9.nc
dark_correction :
True
flatfield_correction :
True
defect_correction :
True
nonlinear_correction :
True
geolocate_terrain_corr :
True
geolocate_roll_offset :
0.75
geolocate_pitch_offset :
0.0
geolocate_yaw_offset :
0.0
geolocate_xtrack_amplification :
1.0
geolocate_atrack_amplification :
1.0
att_time_offset :
0.0
gps_time_offset :
0.0
harp_time_offset :
0.0
processing_status :
Completed
3. Understanding Multi-Angle Data
HARP2 is a multi-spectral sensor, like OCI, with 4 spectral bands. These roughly correspond to green, red, near infrared (NIR), and blue (in that order). HARP2 is also multi-angle. These angles are with respect to the satellite track. Essentially, HARP2 is always looking ahead, looking behind, and everywhere in between. The number of angles varies per sensor. The red band has 60 angles, while the green, blue, and NIR bands each have 10.
In the HARP2 data, the angles and the spectral bands are combined into one axis. I’ll refer to this combined axis as HARP2’s “channels.” Below, we’ll make a quick plot both the viewing angles and the wavelengths of HARP2’s channels. In both plots, the x-axis is simply the channel index.
Pull out the view angles and wavelengths.
angles = view["sensor_view_angle"]
wavelengths = view["intensity_wavelength"]Create a figure with 2 rows and 1 column and a reasonable size for many screens.
fig, (ax_angle, ax_wavelength) = plt.subplots(2, 1, figsize=(14, 7))
ax_angle.set_ylabel("View Angle (degrees)")
ax_angle.set_xlabel("Index")
ax_wavelength.set_ylabel("Wavelength (nm)")
ax_wavelength.set_xlabel("Index")
plot_data = [
(0, 10, "green", "^", "green"),
(10, 70, "red", "*", "red"),
(70, 80, "black", "s", "NIR"),
(80, 90, "blue", "o", "blue"),
]
for start_idx, end_idx, color, marker, label in plot_data:
ax_angle.plot(
np.arange(start_idx, end_idx),
angles[start_idx:end_idx],
color=color,
marker=marker,
label=label,
)
ax_wavelength.plot(
np.arange(start_idx, end_idx),
wavelengths[start_idx:end_idx],
color=color,
marker=marker,
label=label,
)
ax_angle.legend()
ax_wavelength.legend()
plt.show()