sylva.als.metrics¶
The same functions are available from sylva.als.
sylva.als.metrics ¶
Area-based metrics of airborne lidar: grids, plots and single clouds.
The standard set follows the area-based metrics of Roussel et al. (2020):
height statistics, quantiles, cumulative deciles and the normalised
Shannon entropy of the heights, with intensity and return metrics, plus
canopy cover and gap fraction from first returns. grid_metrics
computes them on a raster over a whole catalogue, chunk by chunk, so that
a cell on a tile edge has the value it would have in a single-tile run;
plot_metrics computes them for circular or polygon plots, reading
only the tiles each plot overlaps; cloud_metrics for one cloud in
memory. A Python function of the points can replace the standard set, at
the cost of speed.
These functions are also available from sylva.als.
Examples:
>>> from sylva import als
>>> cat = als.catalog("normalised/")
>>> m = als.grid_metrics(cat, 20.0, ["zmean", "zq95", "cover"], dtm=None)
>>> m["zq95"].to_geotiff("zq95.tif")
>>> plots = als.plot_metrics(cat, [(500, 200), (650, 340)], radius=11.28,
... dtm=None)
PlotMetrics
dataclass
¶
Metrics of plots, one row per plot, from plot_metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
columns
|
dict
|
The table, a dict of equal-length arrays: |
required |
names
|
list
|
The metric columns, in order. |
list()
|
metric_names ¶
metric_names(threshold: float = 2.0) -> list[str]
Names of the standard metrics, in the order they are computed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold
|
float
|
The height of |
2.0
|
Returns:
| Type | Description |
|---|---|
list of str
|
|
cloud_metrics ¶
cloud_metrics(cloud: PointCloud, height=None, threshold: float = 2.0, entropy_bin: float = 1.0, cover_break: float = 2.0, min_height: float | None = None, drop_noise: bool = True, clamp_negative: bool = False) -> dict[str, float]
The standard metrics of one cloud.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cloud
|
PointCloud
|
Returns, normalised (z is height above ground) unless |
required |
height
|
None to take z as the height, the name of an attribute holding it
( |
None
|
|
threshold
|
float
|
Height (m) of |
2.0
|
entropy_bin
|
float
|
Bin width (m) of |
1.0
|
cover_break
|
float
|
Height (m) above which a first return counts as canopy for
|
2.0
|
min_height
|
float | None
|
Returns lower than this are left out of every metric (heights below 0 are
often dropped first, since |
None
|
drop_noise
|
bool
|
Leave out returns classified as noise (7 or 18). |
True
|
clamp_negative
|
bool
|
Set heights below 0 to 0 before anything else (the other usual
habit). Ground returns a few centimetres below
the DTM are in nearly every cell of a survey, and make |
False
|
Returns:
| Type | Description |
|---|---|
dict
|
Metric name to value. The intensity and return metrics are present
when the cloud has |
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown attribute, heights of the wrong length or bad settings. |
grid_metrics ¶
grid_metrics(catalog, resolution: float = 20.0, metrics=None, func: Callable | None = None, dtm='auto', dtm_resolution: float = 1.0, threshold: float = 2.0, entropy_bin: float = 1.0, cover_break: float = 2.0, min_height: float | None = None, drop_noise: bool = True, clamp_negative: bool = False, chunk_size: float | None = None, buffer: float = 20.0, workers: int | None = None)
Rasters of area-based metrics over a whole catalogue.
Every return is assigned to the cell of the catalogue grid that holds
it (cells are half-open, [x0, x0 + resolution)), and the metrics of
each cell are computed from all of its returns, whichever tiles they
come from. Each chunk computes the cells within about one cell of its
core from its points and its buffer, so the result is the same, to the
bit, for any chunk_size and any number of workers, and equals
the metrics of the cells of all the tiles merged into one cloud.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog
|
The tiles (a |
required | |
resolution
|
float
|
Cell size (m); 10 to 30 m is usual for area-based models. |
20.0
|
metrics
|
None for every standard metric ( |
None
|
|
func
|
Callable | None
|
A function of one cell's returns, |
None
|
dtm
|
('auto', None, Raster or str)
|
Where heights come from, as for |
'auto'
|
dtm_resolution
|
float
|
Cell size (m) of the |
1.0
|
threshold
|
float
|
As for |
2.0
|
entropy_bin
|
float
|
As for |
2.0
|
cover_break
|
float
|
As for |
2.0
|
min_height
|
float
|
As for |
2.0
|
drop_noise
|
float
|
As for |
2.0
|
clamp_negative
|
float
|
As for |
2.0
|
chunk_size
|
float | None
|
As for |
None
|
buffer
|
float | None
|
As for |
None
|
workers
|
int | None
|
As for |
None
|
Returns:
| Type | Description |
|---|---|
dict of str to Raster, or Raster
|
One |
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown metric, bad settings, a |
Examples:
>>> m = als.grid_metrics(cat, 20.0, ["zmean", "zq95", "cover"])
>>> top = als.grid_metrics(cat, 20.0, "zmax", dtm=None)
>>> def canopy(c):
... z = c.z[c.z > 2]
... return {"hmean": z.mean() if len(z) else np.nan, "npts": len(c)}
>>> mine = als.grid_metrics(cat, 20.0, func=canopy)
plot_metrics ¶
plot_metrics(catalog, plots, radius=None, metrics=None, func: Callable | None = None, dtm='auto', dtm_resolution: float = 1.0, threshold: float = 2.0, entropy_bin: float = 1.0, cover_break: float = 2.0, min_height: float | None = None, drop_noise: bool = True, clamp_negative: bool = False, ids=None, buffer: float = 20.0, workers: int | None = None) -> PlotMetrics
Area-based metrics of field plots from a catalogue.
Plots are grouped by the tiles they overlap; each group reads only
those tiles, and only the points in the group's box (grown by
buffer for dtm="auto"). A plot on a tile edge gets its points
from every tile it overlaps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
catalog
|
The tiles. |
required | |
plots
|
With |
required | |
radius
|
Radius (m) of circular plots, one for all or one per plot. |
None
|
|
metrics
|
None for every standard metric, or a list of names. |
None
|
|
func
|
Callable | None
|
A function of one plot's returns, as for |
None
|
dtm
|
Where heights come from, as for |
'auto'
|
|
dtm_resolution
|
Where heights come from, as for |
'auto'
|
|
threshold
|
float
|
As for |
2.0
|
entropy_bin
|
float
|
As for |
2.0
|
cover_break
|
float
|
As for |
2.0
|
min_height
|
float
|
As for |
2.0
|
drop_noise
|
float
|
As for |
2.0
|
clamp_negative
|
float
|
As for |
2.0
|
ids
|
Labels of the plots (one per plot), kept as an |
None
|
|
buffer
|
float
|
With |
20.0
|
workers
|
int | None
|
Groups of plots read at once, as for |
None
|
Returns:
| Type | Description |
|---|---|
PlotMetrics
|
One row per plot, in the order given. Plots outside every tile have
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For bad plots (a non-positive radius, a ring with fewer than three vertices), an unknown metric or bad settings. |
Examples:
>>> t = als.plot_metrics(cat, [(520.0, 310.0), (580.5, 402.0)], radius=11.28)
>>> t["zq95"], t.to_pandas()
>>> layer = masks.read_polygons("plots.shp")
>>> names = [f.properties["name"] for f in layer]
>>> t = als.plot_metrics(cat, layer, ids=names)