Pydisort Documentation

A modern Python package for DISORT radiative transfer, with support for parallel computation.

pydisort provides a Python interface to the C version of the DISORT (Discrete Ordinates Radiative Transfer) program. It wraps the well-tested cdisort numerical core in a C++ class (DisortImpl), which is in turn bound to Python with pybind11, and uses PyTorch tensors as its primary data structure.

Please consult the DISORT publication [1] for more information on the DISORT program, and the C-DISORT publication [2] for the C version.

pip install pydisort

Prebuilt wheels are published for CPython 3.10-3.14 on selected Linux and macOS targets. No compiler is needed when a wheel matches your platform; see Installation and Quickstart for architectures, OS requirements and source builds.

Why pydisort?

pydisort features the following benefits over the original C-DISORT program:

  • Parallel by design. Wavelength and atmospheric column are batch dimensions, so a spectral or multi-column calculation spreads across cores. On the measured workload, single-threaded speed closely matches cdisort; ten threads reach roughly an order of magnitude faster (see Performance for conditions).

  • PyTorch-native, so radiative transfer drops directly into tensor-based scientific and machine-learning workflows.

  • No build step. Prebuilt binaries on PyPI avoid local Fortran or C compilation.

  • Proper error handling, rather than abrupt exit of the program. Errors can be caught and handled in the Python script.

  • Automatic memory management, handled by the C++ class. The user does not need to worry about allocation and deallocation.

  • Safety guards that prevent setting incorrect values for arrays or calling methods in the wrong order.

  • Documented and tested, with documentation automated through Sphinx and Read the Docs, and a test suite validated against published DISORT reference values (see Automated Tests).

Note that the underlying calculation engine is still the same as the C-DISORT program, so results agree with cdisort to near machine precision.

Statement of Need explains in more detail what problem pydisort solves, who it is for, and how it relates to the other DISORT implementations.

A 30-second example

Every pydisort program has the same two steps: describe the problem with a pydisort.DisortOptions object, then run it by calling forward on a tensor of optical properties.

import torch
from pydisort import Disort, DisortOptions

torch.set_default_dtype(torch.float64)
op = DisortOptions().flags("onlyfl,lamber")
op.ds().nlyr = 4
op.ds().nstr = 4
op.ds().nmom = 4
op.ds().nphase = 4

ds = Disort(op)
tau = torch.tensor([0.1, 0.2, 0.3, 0.4]).unsqueeze(-1)
flux = ds.forward(tau, fbeam=torch.tensor([3.14159]))
assert flux.shape == (1, 1, 5, 2)
print(flux)
tensor([[[[0.0000, 3.1416],
          [0.0000, 2.8426],
          [0.0000, 2.3273],
          [0.0000, 1.7241],
          [0.0000, 1.1557]]]])

The returned tensor has shape (nwave, ncol, nlvl, 2): wavelength, column, level, then upward and downward flux. User Guide explains those dimensions.

Where to go next

Installation and Quickstart

Install pydisort, verify it works, and run your first calculation.

Statement of Need

What problem pydisort solves, who it is for, and its scope.

User Guide

Input/output shapes, singleton dimensions, flags, troubleshooting.

Example Usage

Four complete calculations, ending with a real-world solver-validation study.

API Reference

Full API reference.

Automated Tests

How the package is validated, and how to run the test suite.

Performance

Performance against cdisort and PythonicDISORT, and how to reproduce it.

Contributing

Contributor workflow.

References