Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

SMART-G

Speed-up Monte Carlo Advanced Radiative Transfer Code using GPU

PyPI version conda-forge version Downloads Requires a CUDA GPU DOI

SMART-G is a radiative transfer code using a Monte-Carlo technique to simulate the propagation of the polarized light in the atmosphere and/or ocean, and using GPU acceleration.

Didier Ramon
Mustapha Moulana
François Steinmetz
Dominique Jolivet
Mathieu Compiègne
HYGEOS


1. Features

  • Polarized (I, Q, U, V) Monte-Carlo radiative transfer, accelerated on NVIDIA GPUs
  • Coupled ocean-atmosphere system, or atmosphere only / ocean only
  • 1D atmospheric profiles (AFGL standard atmospheres or user-provided), aerosols (OPAC or user-defined) and clouds
  • 3D atmospheres (opt3d=True), validated against MYSTIC on the IPRT phase B benchmark
  • Spherical atmosphere (pp=False), validated on the IPRT phase 3 benchmark
  • 3D objects and concentrated solar flux geometries (heliostat fields, solar towers)
  • Flat, rough or Lambertian surfaces, and 1D ocean profiles
  • Spectral integration with the k-distribution and REPTRAN parameterizations
  • Rotational (Ring effect) and vibrational Raman scattering
  • Forward and backward modes, local estimate, and photon-history tracking
  • Results returned as an xarray.Dataset, with built-in visualization helpers

2. Installation

2.1 PyPI

To install SMART-G from PyPI:

pip install smartg

To include extra dependencies use instead:

pip install smartg[extra]

2.2 conda-forge

Use the command:

conda install -c conda-forge smartg

If you need extra dependencies (jax with cuda) we recommend the installation with pip instead.

2.3 github clone (for development)

Click here

First clone the repository:

git clone https://github.com/hygeos/smartg.git

You can now choose between Pixi or Conda for your development environment.

Pixi is recommended for its fast dependency resolution and robust environment management. Unlike Conda, which only considers Conda packages during conflict resolution, Pixi considers both Conda and pip package versions when solving dependencies.

To create and activate the environment, use the following command:

pixi shell

To consider all extra dependencies (e.g. jax), use instead:

pixi shell --environment extra

2.3.2 Anaconda/Miniconda (alternative)

With Anaconda/Miniconda, use the following command:

conda env create -n smartg-env -f environment.yml
conda activate smartg-env

For a full installation (extra dependencies), replace environment.yml by environment-extra.yml.

3. Nvidia driver and CUDA

An installation guide is available in the nvidia website: installation-guide.

You can also install CUDA using conda:

conda install nvidia::cuda

4. Auxiliary data

The auxiliary data can be downloaded as follow:

>>> # Example to download all the data. See the docstrings for more details.
>>> from smartg.auxdata import download
>>> from pathlib import Path
>>> download(Path('dir/path/where/to/save/data/'), data_type='all')
>>> # Only some datasets, in the SMARTG_DIR_AUXDATA directory
>>> download(data_type=['aer', 'cld'])

The datasets already on disk are skipped. Each download is recorded in a .smartg_auxdata.json manifest inside the auxdata directory, which allows checking and refreshing the data when it changes on the server:

>>> from smartg.auxdata import check_update, update
>>> check_update()  # queries the remote versions, downloads nothing
Auxiliary data in /dir/path/where/to/save/data
dataset  status      downloaded (UTC)  remote (UTC)      source / note
aer      up to date  2026-09-15 14:03  2026-04-27 14:37  hygeos
acs      outdated    2026-09-15 14:03  2026-09-16 09:12  hygeos
kdis     missing     -                 2024-05-02 14:13  hygeos
...
update() would download: acs, kdis
>>> update()  # downloads only the missing, outdated or unrecorded datasets
>>> update(data_type='reptran', force=True)  # download again whatever the status

The manifest also records the checksum of every downloaded file, so check_update() lists the files modified or deleted locally (status modified). The remote data is the reference: restore() shows these files and, after confirmation, replaces them by the remote copies without downloading the whole dataset again. Extra files are kept.

>>> from smartg.auxdata import restore
>>> restore()  # lists the modified files and asks before replacing them
>>> restore(data_type='aer', yes=True)  # no question asked

The environment variable SMARTG_DIR_AUXDATA must be defined.

For example, in the .bashrc / .zshrc file the following can be added:

export SMARTG_DIR_AUXDATA="dir/path/where/to/save/data/"

or (not recommended) in a .env file in the SMART-G root directory:

SMARTG_DIR_AUXDATA=dir/path/where/to/save/data/

5. Quick start

Once the auxiliary data are in place, a first simulation takes a few lines:

from smartg.smartg import Smartg
from smartg.atmosphere import Atm1D
from smartg.view import smartg_view

# 1e8 photons at 500 nm, tropical atmosphere, sun at a 30° zenith angle
ds = Smartg().run(wavelength=500., th_deg=30., n_photons=1e8,
                  atmosphere=Atm1D('afglt'))

# ds is an xarray.Dataset holding 'I_up (TOA)', 'Q_up (TOA)',
# 'U_up (TOA)', 'V_up (TOA)', ...
smartg_view(ds)  # polar view of the reflectance and of the polarization

The first call compiles the CUDA kernel; subsequent runs reuse it.

6. Examples

Sample notebooks are provided in the notebooks folder, and jupyter notebook has nice possibilities for interactive development and visualization, in particular if you are using a remote cuda computer. Good entry points are:

6.1 Notebooks as percent scripts

The notebooks are stored as jupytext percent scripts: plain Python files in which # %% starts a code cell and # %% [markdown] a markdown cell. They hold neither outputs nor editor metadata, so their diffs and merges are readable. Jupyter magics are commented (# %%time) so that the scripts stay valid Python, and are restored when a script is opened as a notebook.

jupytext is installed with the other dependencies. Its configuration, in the [tool.jupytext] section of pyproject.toml, pairs each script with a .ipynb notebook of the same name, which keeps the outputs locally and is ignored by git.

  • JupyterLab / Jupyter Notebook (pixi run jupyter lab): right-click a script, then Open With → Jupytext Notebook. Saving updates both the script and its paired notebook. Run pixi run jupytext-config set-default-viewer python once to open the scripts as notebooks with a double click.

  • VS Code: the # %% cells of a script run as is in the Interactive Window. To use the notebook editor, open the paired .ipynb (created by the task below) and either install the Jupytext Sync extension, which updates the script on save, or run the task before committing.

  • Synchronization: after a git pull, or after editing one file of a pair outside Jupyter, run

    pixi run sync-notebooks
    

    The cells are taken from the most recently modified file of each pair, and the outputs from the notebook. Synchronize before pulling as well, so that edits made in a notebook are not overwritten by a newer script.

  • New notebook: save it as smartg/notebooks/<name>.ipynb from Jupyter, which creates its script, or run pixi run jupytext --sync smartg/notebooks/<name>.ipynb. Only the .py script is committed.

7. Tests

To check that SMART-G is running correctly, run the following command at the root of the project:

pytest smartg/tests/test_cuda.py smartg/tests/test_profile.py \
       smartg/tests/test_atm3d.py smartg/tests/test_smartg.py -s -v

A full testing is recommended in dev:

pytest smartg/tests/ -s -v

With Pixi, both are available as tasks:

pixi run test-basic  # the four files above
pixi run test-all    # the whole test suite

test_smartg_jax.py needs the jax dependencies of the extra environment. Without them it skips itself with a message rather than failing, so run it with pixi run -e extra pytest smartg/tests/test_smartg_jax.py.

To avoid repeating some pytest arguments, a pytest.ini file can be created at the root of the project. The following is an example of the contents of such a file:

[pytest]
addopts= --html=test_report.html --self-contained-html -s -v -rs

The arguments --html=test_report.html --self-contained-html generate an html report containing the results of the tests (sometimes with more details e.g. plots), named test_report.html, and -rs lists the reasons why tests have been skipped.

7.1 The IPRT tests

Four files compare SMART-G with the IPRT (International Polarized Radiative Transfer) model intercomparison, one per phase of the benchmark. The durations below were measured on a Ryzen 9 5950X with a GeForce RTX 5070 Ti.

Phase A — test_quick_iprt_phase_a.py runs the 1D cases A1 (a Rayleigh layer), A2 (a Rayleigh layer over a Lambertian surface) and A5 (a water cloud, in the principal plane and in the almucantar), and compares them with MYSTIC. Four tests, about 2 min 30, no slow tier.

Phase B — test_iprt_phase_b_c2.py (cubic cloud) and test_iprt_phase_b_c3.py (cumulus cloud with aerosols) check the 3D atmosphere mode (opt3d=True) against the MYSTIC reference. Reproducing the benchmark photon counts takes hours, so each of their tests exists in two tiers: a fast one, run by default, and a slow one selected with -m slow.

pytest smartg/tests/test_iprt_phase_b_c3.py           # fast, ~3 min
pytest -m slow smartg/tests/test_iprt_phase_b_c3.py   # slow, ~38 min

Both files together take 6 min in the fast tier and 1 h 23 in the slow one. C3 builds each of its atmospheres, one mixed phase matrix per cloudy cell, in a single threaded loop of about 15 s; its truncated cloud costs a few seconds more, being truncated once per distinct effective radius rather than once per cell.

The fast tier detects a 5 % error on the cloud optical properties, the slow one 1 %: run it before a release, or after a change to the 3D kernel, to the phase matrices or to the truncation.

Phase 3 — test_iprt_phase3.py checks the spherical geometry (pp=False) on the one-layer cases D1 to D6 and the vertically inhomogeneous cases E1 to E5, against saved SMART-G results computed with 1e8 photons per viewing direction. It has the same two tiers: the fast one uses 1e6 photons per direction and takes about 5 min for the file, the slow one reproduces the 1e8 of the references and takes about 3 h 50 for the 11 cases. E6, the camera at 300 000 km, is not covered yet.

pytest smartg/tests/test_iprt_phase3.py           # fast, ~5 min
pytest -m slow smartg/tests/test_iprt_phase3.py   # slow, ~3 h 50

Because a GPU run is not reproducible bit for bit, the phase 3 comparison is statistical: the tolerances on the mean bias and on the fraction of directions beyond three combined standard deviations were measured per tier rather than taken from a normal distribution.

8. Coding conventions

Identifiers follow PEP 8: snake_case for modules, functions, variables and parameters, PascalCase for classes, UPPER_SNAKE_CASE for constants. Lines are at most 79 columns of code and 72 of docstrings and comments, and the docstrings follow the numpy convention.

ruff and pyright check all of this, configured in the [tool.ruff] and [tool.pyright] sections of pyproject.toml. Neither is a project dependency, so install them separately; the configuration was written for ruff 0.16 and pyright 1.1.411. Lint the tracked files with:

ruff check $(git ls-files '*.py')
pyright

Passing the tracked files explicitly keeps untracked scratch modules out of the report.

9. Hardware tested

GeForce GTX 1070, GeForce TITAN V, GeForce RTX 2080 Ti, GeForce RTX 3070, GeForce RTX 3090, GeForce RTX 4090, GeForce RTX 5070 Ti, A100, RTX PRO 6000 Blackwell (Workstation Edition)

The use of GPUs before 10xx series (Pascal) is deprecated as of SMART-G 1.0.0

10. Licensing information

This software is available under the SMART-G license v1.0, available in the LICENSE.TXT file. It can be used for free for non-commercial purposes; for commercial use, please contact HYGEOS.

11. Referencing

When acknowledging the use of SMART-G for scientific papers, reports etc please cite the following reference(s):

  • Ramon, D., Steinmetz, F., Jolivet, D., Compiègne, M., & Frouin, R. (2019). Modeling polarized radiative transfer in the ocean-atmosphere system with the GPU-accelerated SMART-G Monte Carlo code. Journal of Quantitative Spectroscopy and Radiative Transfer, 222, 89-107. https://doi.org/10.1016/j.jqsrt.2018.10.017

  • Moulana, M., Cornet, C., Elias, T., Ramon, D., Caliot, C., & Compiègne, M. (2024). Concentrated solar flux modeling in solar power towers with a 3D objects-atmosphere hybrid system to consider atmospheric and environmental gains. Solar Energy, 277, 112675. https://doi.org/10.1016/j.solener.2024.112675

12. Getting help

Metadata

Release files for smartg 2.0.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for smartg 2.0.0b1
File Size Uploaded
smartg-2.0.0b1.tar.gz 2.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for smartg 2.0.0b1
File Interpreter ABI Platform
smartg-2.0.0b1-py3-none-any.whl Python 3 none any Details

Total release size: 5.2 MB

Release files / smartg-2.0.0b1.tar.gz

Download URL smartg-2.0.0b1.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
269c728890fcd7a9e74ebe0bfe50dafb265c7146fc4852877a9992b070194e24
BLAKE2b-256 checksum
How to use checksums
51b4cb794a77c1a6fd91ba5895d5db7a774e3a9921de9712d7c5c605915c24e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / smartg-2.0.0b1-py3-none-any.whl

Download URL smartg-2.0.0b1-py3-none-any.whl
Size 2.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
9aa6265d24b7ec15e3b681a74ac7787a1d3929cccb8b076c3c54896e81cc4dc8
BLAKE2b-256 checksum
How to use checksums
ef720c6ce0e98a163126eb2785aa661e1756cf6b9fca1cdea6875b629df2b434
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

This release

2.0.0b1 This release

2 release files

1.2.0

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release 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