Skip to main content

xleaf

Canopy reflectance simulated in rainbows.

Leaf and canopy radiative transfer modeling tools built on PROSPECT-D and SAIL.

GitHub PyPI version GitHub last commit


Introduction

🌳 xleaf is a python package for running leaf and canopy simulation models using PROSAIL. It provides python bindings to the PROSPECT-D & 4SAIL Fortran code.

🌿 It includes sensible defaults that make it easy to get up and running quickly, and clear code documentation in the form of docstrings and type hints.

📚 All credit for the fundamental modeling code and for the underlying science belongs to the original researchers. xleaf is mostly a wrapper. Please cite their most recent research:

@article{feret2017prospect,
  title={PROSPECT-D: Towards modeling leaf optical properties through a complete lifecycle},
  author={Feret, J-B and Gitelson, AA and Noble, SD and Jacquemoud, S},
  journal={Remote Sensing of Environment},
  volume={193},
  pages={204--215},
  year={2017},
  publisher={Elsevier}
}

🧙 Shout out to my man JB.


Install

Install from PyPI:

pip install xleaf

Development

This project uses pixi to manage dependencies and builds. To set up a development environment:

pixi install

This installs all dependencies including the Fortran compiler (gfortran), meson, and numpy. To run tests:

pixi run test

Leaf and canopy simulations

import xleaf
import matplotlib.pyplot as plt

# run with off-the-shelf defaults
leaf = xleaf.simulate_leaf()

# or specify detailed parameters
canopy = xleaf.simulate_canopy(
    chl = 40, # ug/cm2
    car = 8, # ug/cm2
    antho = 0.5, # ug/cm2
    ewt = 0.01, # cm
    lma = 0.009, # g/cm2
    N = 1.5, # unitless
    lai = 3.0, # m2/m2
    lidf = 30, # degrees
    soil_dryness = 0.75, # %
    solar_zenith = 35, # degrees
    solar_azimuth = 120, # degrees
    view_zenith = 0, # degrees
    view_azimuth = 60, # degrees
    hot_spot = 0.01, # unitless
)

# and plot them together
plt.plot(xleaf.wavelengths, leaf, label='leaf')
plt.plot(xleaf.wavelengths, canopy, label='canopy')
plt.legend()

📄 The definitions and expected range of values for each parameter are described in the xleaf docstrings.


Chaining leaf and canopy models

🔗 simulate_canopy runs PROSPECT and 4SAIL together. If you'd rather run the canopy model on a leaf spectrum you already have — a measured spectrum, or one from a different leaf model — use simulate_sail. It takes leaf reflectance and transmittance directly, so you can pair it with simulate_leaf(transmittance=True):

import xleaf
import matplotlib.pyplot as plt

# simulate a leaf, returning both reflectance and transmittance
reflectance, transmittance = xleaf.simulate_leaf(
    chl = 40, # ug/cm2
    car = 8, # ug/cm2
    antho = 0.5, # ug/cm2
    ewt = 0.01, # cm
    lma = 0.009, # g/cm2
    N = 1.5, # unitless
    transmittance = True,
)

# then run the canopy model on that leaf spectrum
canopy = xleaf.simulate_sail(
    reflectance,
    transmittance,
    lai = 3.0, # m2/m2
    lidf = 30, # degrees
    soil_dryness = 0.75, # %
    solar_zenith = 35, # degrees
    solar_azimuth = 120, # degrees
    view_zenith = 0, # degrees
    view_azimuth = 60, # degrees
    hot_spot = 0.01, # unitless
)

plt.plot(xleaf.wavelengths, reflectance, label='leaf')
plt.plot(xleaf.wavelengths, canopy, label='canopy')
plt.legend()

Random forests

📊 xleaf provides classes for generating random parameters within the global range of expected values. These classes have a .sample() method for generating an appropriate random value based on a literature review.

import xleaf
import matplotlib.pyplot as plt

# generate 5 random leaf spectra from global defaults
for idx in range(5):
    chl = xleaf.ChlorophyllSampler.sample()
    car = xleaf.CarotenoidSampler.sample()
    antho = xleaf.AnthocyaninSampler.sample()
    ewt = xleaf.EWTSampler.sample()
    lma = xleaf.LMASampler.sample()
    N = xleaf.NSampler.sample()
    leaf = xleaf.simulate_leaf(chl, car, antho, ewt, lma, N)
    plt.plot(xleaf.wavelengths, leaf, label=f"leaf {idx+1}")

plt.legend()

🧪 Or experiment by setting the range of values yourself:

import xleaf
import matplotlib.pyplot as plt

MyLAISampler = xleaf.UniformSampler(min=2, max=6)
MyVZASampler = xleaf.NormalSampler(mean=0, stdv=3, min=-10, max=10)

# generate 5 random canopy spectra just varying LAI/VZA
for idx in range(5):
    lai = MyLAISampler.sample()
    vza = MyVZASampler.sample()
    canopy = xleaf.simulate_canopy(lai=lai, view_zenith=vza)
    plt.plot(xleaf.wavelengths, canopy, label=f"lai: {lai:0.2f}, vza: {vza:0.2f}")

plt.legend()

⚡ These parameters don't always vary independently. Try to exercise caution when constructing parameter estimates to ensure biological realism.


Developed by

Christopher Anderson1

Twitter Follow GitHub Stars

  1. Planet Labs PBC, San Francisco

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xleaf-1.2.1.tar.gz (282.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

xleaf-1.2.1-cp311-cp311-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.11Windows x86-64

xleaf-1.2.1-cp311-cp311-manylinux_2_24_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ x86-64

xleaf-1.2.1-cp311-cp311-macosx_26_0_arm64.whl (128.0 kB view details)

Uploaded CPython 3.11macOS 26.0+ ARM64

File details

Details for the file xleaf-1.2.1.tar.gz.

File metadata

  • Download URL: xleaf-1.2.1.tar.gz
  • Upload date:
  • Size: 282.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for xleaf-1.2.1.tar.gz
Algorithm Hash digest
SHA256 f50db0181fede7dca80aeca4654227408a44cb32a3d943ae39451117b2e7f61c
MD5 29ca84ebfc295f622aa557e0796ccf3a
BLAKE2b-256 6068ddb00b1d4e3ca7fc8319c25d5e525224b864edf2cd3a8c6989553a54d5bb

See more details on using hashes here.

File details

Details for the file xleaf-1.2.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: xleaf-1.2.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for xleaf-1.2.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 af40bade0a169b7984895f7e1fa512dca12c49f4cdb44643bbe4f25ef62b146f
MD5 8b097a3f77a7007f24d169d0e0db195f
BLAKE2b-256 a6a5688a752dc366f0dedd3d5dacc3685387fb761713f2be5310e49781875c8a

See more details on using hashes here.

File details

Details for the file xleaf-1.2.1-cp311-cp311-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for xleaf-1.2.1-cp311-cp311-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 e4fe7cffe4210fdb5a52be3e3d9c8d7d9b5987e2631fbb5c1650ec84bf2e9810
MD5 59529a80e87659394f3354be0a444041
BLAKE2b-256 f17b7b2e01f0dd8fe517a0ce0552af920bf0e70c2e994b74ab2c3f5d0989e7ba

See more details on using hashes here.

File details

Details for the file xleaf-1.2.1-cp311-cp311-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for xleaf-1.2.1-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 4187d86c8120ba5f846771431dee1bcde910cb8db11e6ade355af34d5ed7863e
MD5 a097c0bbca2995a21aa636f59533a8ed
BLAKE2b-256 3c6bf0500daa972fac3dbdabf4fb2045f12c4a7b1ee088a3bb75143db847914a

See more details on using hashes here.

Release history Release notifications | RSS feed

1.2.2

4 files

This release

1.2.1 This release

4 files

1.2.0

3 files

1.1.0

3 files

1.0.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page