BRDF Data Containers#
pydirectional contains data container classes to help with handling BRDF data. These objects can also implement helpful methods for analysis.
BRDFMeasurements is used for handling multi-angular reflectance data and BRDFParameters is used for handling the parameters used by the BRDF models.
They can be imported with:
from pydirectional import BRDFMeasurements
from pydirectional import BRDFParameters
BRDFMeasurements#
To instantiate a BRDFMeasurements object, you must provide at least:
reflectance- array with final dimensionangle_indexreflectance_dims- list of dimension namessolar_zenith_angleviewing_zenith_anglerelative_azimuth_angleor bothsolar_azimuth_angleandviewing_azimuth_anglevalues for the dimensions in
reflectances_dims(eg.wavelength)
The measurand must be either "HCRF" or "BRF".
For "HCRF", the direct_to_diffuse_irr must be supplied.
Example:
refl = np.random.rand(5, 10)
wl = np.linspace(400, 900, 5)
sza = np.linspace(20, 40, 10)
vza = np.linspace(0, 50, 10)
raa = np.linspace(0, 180, 10)
meas = BRDFMeasurements(
reflectance=refl,
measurand="BRF",
reflectance_dims=["wavelength", "angle_index"],
solar_zenith_angle=sza,
viewing_zenith_angle=vza,
relative_azimuth_angle=raa,
wavelength=wl,
)
Note
relative_azimuth_angle is computed automatically when
solar_azimuth_angle and viewing_azimuth_angle are provided.
Coordinates and Dimensions#
BRDFMeasurements can store one or more of:
wavelength- spectral coordinatex- spatial coordinatey- spatial coordinate
At least one coordinate must be supplied at creation time. Coordinates may be scalars or 1-D arrays.
Uncertainty Inputs#
The class supports three uncertainty components:
u_rand_reflectance- random uncertaintyu_syst_reflectance- systematic uncertaintyu_strct_reflectance- structured uncertainty
Structured uncertainties may include error-correlation matrices along:
angle_indexwavelengthxy
These are stored in the underlying obsarray dataset.
Accessing Data#
Convenience methods allow retrieval of geometry, reflectance, uncertainties, and ancillary metadata:
sza = meas.get_solar_zenith_angle()
refl = meas.get_reflectance()
u_tot = meas.get_total_uncertainty()
wl = meas.get_wavelength()
Subsetting can be performed by wavelength and/or spatial position:
refl_550 = meas.get_reflectance(wavelength=550)
irr_xy = meas.get_direct_to_diffuse_irr(x=0, y=0)
The whole dataset can be subset using:
subset_meas_ds = meas.subset_dataset(wavelength=550, x=0, y=0)
Selecting Geometries#
Specific angular geometries can be selected using:
subset = meas.select_geometry(
sza=30,
vza=10,
raa=150,
)
Selection uses nearest interpolation with an optional tolerance set in the context, the interpolation method can also be changed within the context.
Adding Measurements#
New reflectance measurements with additional angle indices may be appended:
meas.add_measurement(
reflectance=new_refl,
solar_zenith_angle=new_sza,
viewing_zenith_angle=new_vza,
relative_azimuth_angle=new_raa,
wavelength=new_wl,
)
All coordinate sizes and dimensionality must be consistent with existing data.
Working with NetCDF#
BRDF measurement objects can be saved to NetCDF using:
BRDFMeasurements.to_netcdf(path = "my_measurements.nc")
BRDF measurement datasets saved in NetCDF format can be reloaded:
loaded = BRDFMeasurements.load_netcdf("my_measurements.nc")
Plotting#
There are several internal plotting functions that wrap pydirectional.plotting functionality:
plot_reflectance_polarplot_reflectance_spectralplot_reflectance_timeseries
BRDFParameters#
To instantiate a BRDFParameters object, you must provide at least:
brdf_model- name of the BRDF model, e.g."RPV"params- parameter arrayparameter_dims- list of dimension namesvalues for the dimensions in
parameter_dims(eg.wavelength)
Example:
params = np.array([[0.1, 0.3, 0.2],
[0.2, 0.5, 0.1]]) # example parameter set
wl = np.linspace(400, 900, 2)
brdf_params = BRDFParameters(
brdf_model="RPV",
params=params,
parameter_dims=["wavelength", "parameter_names"],
wavelength=wl,
)
The class automatically retrieves the correct parameter names from the model via
BRDFModelFactory and associates them with the final dimension.
Note
Parameter names must match the underlying BRDF model. They can be checked using:
BRDFModelFactory().get_brdf_model("RPV", sza=0, vza=0, raa=0).get_coefficient_names()
Coordinates and Dimensions#
The following optional coordinate axes may be defined:
wavelengthxy
You must provide at least one of these. Coordinates may be scalar or vector values.
All parameter and uncertainty inputs must be consistent with these dimensions.
Uncertainty Inputs#
Two uncertainty inputs are supported:
uncertainties- uncertainty values for each parametererr_corr- error correlation matrices along theparameter_namesaxis
Example with uncertainties:
BRDFParameters(
brdf_model="RTLS",
params=params,
parameter_dims=["wavelength", "parameter_names"],
wavelength=wl,
uncertainties=np.full_like(params, 0.01),
err_corr='rand'
)
Adding Parameter Sets#
Additional parameter sets can be appended using:
brdf_params.add_measurement(
params=new_params,
wavelength=new_wl,
)
All dimensions must be compatible with the existing dataset, and the provided coordinate values must match (or extend) existing dimensions.
Selecting Parameters#
Individual parameters may be selected using:
ds_sel = brdf_params.select_parameter("theta")
If rewrite_ds=True is used, the internal dataset will be replaced with the
subset.
Accessing Parameters and Metadata#
Several helper methods extract subsets of the stored data:
wl = brdf_params.get_wavelengths()
pars = brdf_params.get_params(wavelength=550)
unc = brdf_params.get_uncertainties(wavelength=550)
corr = brdf_params.get_err_corr(wavelength=550)
Evaluating BRF and HCRF#
BRDFParameters allows direct evaluation of BRF or HCRF using the stored
parameter sets.
Evaluating BRF:
brf = brdf_params.evaluate_BRF(
sza=30,
vza=10,
raa=150,
wavelength=550,
)
Evaluating HCRF (requires direct_to_diffuse_irr):
hcrf = brdf_params.evaluate_HCRF(
sza=30,
vza=10,
raa=150,
wavelength=550,
)
Both methods return a BRDFMeasurements object for further analysis or
plotting.
Working with NetCDF#
BRDF parameter objects can be saved to NetCDF using:
BRDFParameters.to_netcdf(path = "my_parameters.nc")
BRDF parameter datasets saved in NetCDF format can be reloaded:
loaded = BRDFParameters.load_netcdf("my_parameters.nc")
Plotting#
There are several internal plotting functions that wrap pydirectional.plotting functionality:
plot_parameter_spectralplot_uncertainty_spectralplot_err_corr_matrix