Skip to main content

Canopy Architecture Models

PhyTorch implements models for characterizing canopy architecture, including leaf angle distribution which describes how leaves are oriented within a plant canopy.

Leaf Angle Distribution​

Leaf angle distribution (LAD) describes the angular distribution of leaf inclination angles within a canopy. This is a critical parameter for understanding light interception, photosynthesis, and canopy radiative transfer.

Beta Distribution Model​

The leaf angle distribution follows a beta distribution parameterized by shape parameters μ and ν:

f(θ)=sin⁡μ−1(θ)⋅cos⁡ν−1(θ)B(μ,ν)⋅90f(\theta) = \frac{\sin^{\mu-1}(\theta) \cdot \cos^{\nu-1}(\theta)}{B(\mu, \nu) \cdot 90}

where:

  • θ\theta = Leaf inclination angle from horizontal (0-90°)
  • μ\mu = First shape parameter (controls horizontal tendency)
  • ν\nu = Second shape parameter (controls vertical tendency)
  • B(μ,ν)B(\mu, \nu) = Beta function

Canonical Distribution Types​

Following de Wit (1965), leaf angle distributions are classified into six canonical types based on their fitted μ and ν parameters:

TypeDescriptionμνExample Species
PlanophileMostly horizontal leaves2.7701.172Oak, broadleaf crops
ErectophileMostly vertical leaves1.1722.770Grasses, willow
PlagiophileMostly oblique leaves3.3263.326Many conifers
ExtremophileBoth horizontal and vertical0.4330.433Some shrubs
UniformEqual distribution1.0001.000Theoretical
SphericalSpherical distribution1.1011.930Many tree species

Usage​

from phytorch import fit
from phytorch.models.canopy import LeafAngleDistribution
import numpy as np

# Leaf angle data (degrees from horizontal)
# Can be binned frequency data or individual measurements
data = {
'theta': np.array([5, 15, 25, 35, 45, 55, 65, 75, 85]), # Angle bins
'frequency': np.array([0.05, 0.12, 0.18, 0.22, 0.20, 0.13, 0.07, 0.02, 0.01]) # Relative frequency
}

# Fit the model
model = LeafAngleDistribution()
result = fit(model, data)

# View fitted parameters
print(f"μ = {result.parameters['mu']:.3f}")
print(f"ν = {result.parameters['nu']:.3f}")
print(f"R² = {result.r_squared:.4f}")

# Classify into canonical type
classification = model.classify(result.parameters)
print(f"\nCanopy type: {classification['type']}")
print(f"Distance from canonical: {classification['distance']:.3f}")
print(f"Canonical μ: {classification['canonical_mu']:.3f}")
print(f"Canonical ν: {classification['canonical_nu']:.3f}")

# Plot the distribution
result.plot()

Example: Planophile Canopy​

from phytorch import fit
from phytorch.models.canopy import LeafAngleDistribution
import numpy as np

# Simulate planophile canopy (mostly horizontal leaves)
data = {
'theta': np.array([10, 20, 30, 40, 50, 60, 70, 80]),
'frequency': np.array([0.25, 0.30, 0.20, 0.12, 0.07, 0.04, 0.01, 0.01])
}

model = LeafAngleDistribution()
result = fit(model, data)

classification = model.classify(result.parameters)
print(f"Canopy type: {classification['type']}") # Expected: planophile

Example: Erectophile Canopy​

from phytorch import fit
from phytorch.models.canopy import LeafAngleDistribution
import numpy as np

# Simulate erectophile canopy (mostly vertical leaves)
data = {
'theta': np.array([10, 20, 30, 40, 50, 60, 70, 80]),
'frequency': np.array([0.01, 0.02, 0.05, 0.10, 0.18, 0.25, 0.28, 0.11])
}

model = LeafAngleDistribution()
result = fit(model, data)

classification = model.classify(result.parameters)
print(f"Canopy type: {classification['type']}") # Expected: erectophile

Parameters​

ParameterDescriptionTypical RangeUnitsDefault
muFirst shape parameter0.4-3.5-1.5
nuSecond shape parameter0.4-3.5-1.5

Data Requirements​

Leaf angle distribution data can be provided in two formats:

  1. Binned frequency data (recommended):

    • theta: Center of angle bins (degrees, 0-90)
    • frequency: Relative frequency in each bin (normalized to sum to 1)
  2. Individual measurements:

    • theta: Individual leaf angle measurements
    • frequency: Can be omitted (assumes equal weight)

Measuring Leaf Angles​

Leaf inclination angles are typically measured using:

  • Protractors or inclinometers for direct measurement
  • Hemispherical photography analysis
  • LiDAR-based canopy scanning
  • Manual sampling of representative leaves

Best practices:

  • Sample 30-50 leaves per canopy for robust estimates
  • Stratify sampling across canopy layers if relevant
  • Measure from horizontal (0°) to vertical (90°)
  • Record multiple canopies per species/treatment for variability

Interpretation​

Shape Parameter Relationships:

  • μ>ν\mu > \nu: Tendency toward horizontal leaves (planophile)
  • μ<ν\mu < \nu: Tendency toward vertical leaves (erectophile)
  • μ≈ν\mu \approx \nu: Symmetrical distribution (plagiophile, uniform, or spherical)
  • Low μ\mu and ν\nu (<1< 1): Bimodal distribution (extremophile)

Ecological Significance:

  • Planophile canopies maximize light interception in low-light environments
  • Erectophile canopies reduce light saturation and overheating in high-light environments
  • Spherical distributions are common in mature forest canopies
  • LAD affects canopy photosynthesis, water use efficiency, and microclimate

Classification Confidence​

The distance value in classification results indicates how close the fitted distribution is to the canonical type:

  • Distance < 0.5: Strong match to canonical type
  • Distance 0.5-1.0: Moderate match
  • Distance > 1.0: Weak match, intermediate between types

Applications​

Leaf angle distribution is used in:

  • Radiative transfer models: Light penetration and absorption
  • Photosynthesis models: Canopy-scale carbon assimilation
  • Remote sensing: Vegetation indices and LAI retrieval
  • Crop modeling: Yield prediction and optimization
  • Climate models: Surface energy balance

Custom Parameter Bounds​

Constrain parameters based on expected canopy structure:

from phytorch import fit, FitOptions

# Constrain to planophile-like distributions
options = FitOptions(
bounds={
'mu': (2.0, 4.0), # Higher mu favors horizontal
'nu': (0.5, 2.0) # Lower nu
}
)

result = fit(LeafAngleDistribution(), data, options)

Model Comparison​

Compare leaf angle distributions across species or treatments:

# Fit multiple canopies
canopies = {
'Oak': oak_data,
'Grass': grass_data,
'Pine': pine_data
}

model = LeafAngleDistribution()
results = {}

for name, data in canopies.items():
result = fit(model, data)
classification = model.classify(result.parameters)
results[name] = classification
print(f"{name}: {classification['type']} (μ={classification['mu']:.2f}, ν={classification['nu']:.2f})")

References​

  • de Wit, C. T. (1965). Photosynthesis of Leaf Canopies. Agricultural Research Reports No. 663, Pudoc, Wageningen.
  • Campbell, G. S. (1986). Extinction coefficients for radiation in plant canopies calculated using an ellipsoidal inclination angle distribution. Agricultural and Forest Meteorology, 36(4), 317-321.
  • Wang, W. M., Li, Z. L., & Su, H. B. (2007). Comparison of leaf angle distribution functions: Effects on extinction coefficient and fraction of sunlit foliage. Agricultural and Forest Meteorology, 143(1-2), 106-122.