### Install pydisort and run example_01_beam_attenuation.py Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/examples.rst Commands to install pydisort and run the first example script from a repository checkout. Requires numpy, torch, and pydisort. ```bash pip install pydisort python examples/example_01_beam_attenuation.py ``` -------------------------------- ### Install development tools Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Install pytest and pre-commit, then install the pre-commit hooks. ```bash python -m pip install pytest pre-commit pre-commit install ``` -------------------------------- ### Run all examples as tests with pytest Source: https://github.com/zoeyzyhu/pydisort/blob/main/examples/README.md Exercise all four examples via the test suite. See docs/source/testing.rst for full details. ```bash pytest tests/test_examples.py -v ``` -------------------------------- ### Install build dependencies for C++ wrapper Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Installs required Python packages and runs CMake to configure and build the C++ wrapper. Requires CMake 3.20+, C++17 compiler, and PyTorch installed in the active environment. ```bash python -m pip install 'torch==2.10.0' numpy pytest 'cmake>=3.20' ninja setuptools 'setuptools-scm>=8' wheel cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON cmake --build build --parallel ``` -------------------------------- ### Clone pydisort repository and run Beer-Lambert example Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/installation.rst Use these bash commands to clone the pydisort repository, change into its directory, and run the example script. The example ends with 'OK: direct beam reproduces the Beer-Lambert law to machine precision.' ```bash git clone https://github.com/zoeyzyhu/pydisort.git cd pydisort python examples/example_01_beam_attenuation.py ``` -------------------------------- ### Install and run Python tests with pytest Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Installs pydisort and pytest, then runs the Python test suite with verbose output. Requires an installed pydisort package. ```bash pip install pydisort pytest pytest tests/ -v ``` -------------------------------- ### Install torch with CPU index on Linux Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/devops.rst Installs torch 2.10.0, using the CPU index on Linux to avoid downloading a large CUDA wheel, and the default index on other platforms. ```bash if [[ "$RUNNER_OS" == "Linux" ]]; then pip install 'torch==2.10.0' --index-url https://download.pytorch.org/whl/cpu else pip install 'torch==2.10.0' fi ``` -------------------------------- ### Run Example 4 with a Figure Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/examples.rst Command to execute the example script and save a plot to two_stream.png. The script runs the validation study and produces a figure. ```bash python examples/example_04_two_stream_validation.py --plot two_stream.png ``` -------------------------------- ### Install PythonicDISORT and threadpoolctl Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/benchmarks.rst Installs the PythonicDISORT package and threadpoolctl, which is required for the benchmark. ```bash pip install PythonicDISORT threadpoolctl ``` -------------------------------- ### Build documentation and run doctests Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Install documentation dependencies, run the documentation extension tests, build HTML docs, and run doctests. The HTML build needs only documentation dependencies; doctests also need the built/installed solver. ```bash python -m pip install -r docs/requirements.txt python -m unittest discover -s docs/_ext -p 'test_*.py' python -m sphinx -E -b html -W --keep-going docs/source docs/_build/html python -m sphinx -b doctest -W docs/source docs/_build/doctest ``` -------------------------------- ### Build and run full CTest suite Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/testing.rst For development, build from source and run the full CTest suite. Requires following the source-build procedure first. Optionally include examples as tests with -DBUILD_EXAMPLES=ON. ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON cmake --build build python -m pip install --no-build-isolation . ctest --test-dir build --output-on-failure ``` -------------------------------- ### Install and run mypy for type checking Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/type_hints.rst Use these commands to install mypy and check a Python script for type errors. The stub files follow PEP 561, so type checkers automatically find them when the package is installed. ```bash pip install mypy mypy your_script.py ``` -------------------------------- ### Install and run PythonicDISORT comparison benchmark Source: https://github.com/zoeyzyhu/pydisort/blob/main/benchmarks/README.md Install pydisort, PythonicDISORT, and threadpoolctl, then run the comparison script with various options. The --verify-only flag checks agreement and exits; without it, a default sweep runs. Use --nwave, --threads, and --compare-modes to customize the sweep. ```bash pip install pydisort PythonicDISORT threadpoolctl python benchmarks/compare_pythonicdisort.py --verify-only # seconds python benchmarks/compare_pythonicdisort.py # default sweep python benchmarks/compare_pythonicdisort.py \ --nwave 1,10,100,1000 --threads 10 --compare-modes ``` -------------------------------- ### Record Python and package versions for development Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/venv.rst Prints the Python version and the list of installed packages. Use this when reporting a problem or reproducing a calculation. ```bash python --version python -m pip freeze ``` -------------------------------- ### Install pydisort with pip Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/installation.rst Installs the latest pydisort release from PyPI. pip automatically installs a compatible torch version. ```bash python -m pip install pydisort ``` -------------------------------- ### Build commands for two-step build Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/devops.rst Run these commands in order to build the project. The first two configure and build the C++ library with CMake, and the third installs the Python extension without build isolation. This order is required because setup.py links against the existing build/lib directory. ```bash cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel pip install . --no-build-isolation ``` -------------------------------- ### Create and activate a venv for pydisort Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/venv.rst Creates a virtual environment, activates it, upgrades pip, installs pydisort, and verifies the installation. Use this in a bash/zsh shell on macOS or Linux. ```bash python3 -m venv env source env/bin/activate python -m pip install --upgrade pip python -m pip install pydisort python -c "import sys, pydisort; print(sys.executable); print(pydisort.__version__)" ``` -------------------------------- ### Build C++ library and run tests with cmake and ctest Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/installation.rst Use these commands to build the C++ library and run its tests. Requires cmake (>= 3.20), a C++17 compiler, and Python 3.10 or newer. The commands install pytest, configure the build with tests enabled, build, install the Python package without build isolation, and run the test suite. ```bash python -m pip install pytest cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON cmake --build build --parallel python -m pip install --no-build-isolation . ctest --test-dir build --output-on-failure ``` -------------------------------- ### Benchmark results table Source: https://github.com/zoeyzyhu/pydisort/blob/main/benchmarks/README.md Example output showing speed-up over PythonicDISORT for various nwave values, comparing single-core and 10-core performance. The single-thread speed-up is about 40x, and multi-threaded speed-up reaches about 335x by 1000 wavenumbers. ```text Speed-up over PythonicDISORT nwave vs 1 core vs 10 cores 1 42.0x 42.4x 10 41.7x 265.2x 100 40.8x 314.8x 1000 39.4x 332.1x 10000 39.9x 334.7x ``` -------------------------------- ### Create and configure a disort_state object Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Shows how to instantiate a disort_state object and set its nlyr, nstr, and nphase attributes. The example prints the assigned values to confirm the configuration. ```pycon >>> import pydisort >>> ds = pydisort.disort_state() >>> ds.nlyr, ds.nstr, ds.nphase = 10, 4, 4 >>> ds.nlyr, ds.nstr, ds.nphase (10, 4, 4) ``` -------------------------------- ### Verify PythonicDISORT installation Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/benchmarks.rst Runs a verification script to ensure PythonicDISORT is correctly installed and functioning. ```bash python benchmarks/compare_pythonicdisort.py --verify-only ``` -------------------------------- ### Verify pydisort installation with Python import and version check Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/installation.rst Run these Python commands in an interactive session to confirm pydisort is installed and check its version. The expected output is '1.8.5'. ```python >>> import pydisort >>> pydisort.__version__ '1.8.5' ``` -------------------------------- ### Install pydisort with pip Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/index.rst Install the pydisort package using pip. Prebuilt wheels are available for CPython 3.10-3.14 on selected Linux and macOS targets; no compiler is needed when a matching wheel is available. ```bash pip install pydisort ``` -------------------------------- ### Register Python examples as CTest tests Source: https://github.com/zoeyzyhu/pydisort/blob/main/examples/CMakeLists.txt Registers Python example scripts (matching example_*.py) as CTest tests. Each script is copied to the build directory and executed with the Python3 interpreter; a non-zero exit status indicates the example no longer reproduces its own results, as each script ends with assertions against an analytic solution or conservation law. ```cmake file(GLOB example_scripts example_*.py) foreach(script ${example_scripts}) get_filename_component(name ${script} NAME) configure_file(${script} ${CMAKE_CURRENT_BINARY_DIR}/${name} COPYONLY) add_test(NAME examples.${name} COMMAND ${Python3_EXECUTABLE} ${name} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endforeach() ``` -------------------------------- ### Build pydisort from source Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/installation.rst Clones the repository, sets up a virtual environment, installs build dependencies, and builds the C++ library and Python bindings. Requires a C++17 compiler and uses the same Python environment for CMake and pip. ```bash git clone https://github.com/zoeyzyhu/pydisort.git cd pydisort python3 -m venv env source env/bin/activate python -m pip install --upgrade pip python -m pip install 'torch==2.10.0' numpy 'cmake>=3.20' ninja \ setuptools 'setuptools-scm>=8' wheel cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF cmake --build build --parallel python -m pip install --no-build-isolation . ``` -------------------------------- ### Calculate attenuation of radiative flux in a plane-parallel atmosphere Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/usage.rst Sets up a Disort solver with the same configuration as the first example, creates an optical thickness tensor tau with shape (4, 1), and calls forward with fbeam=3.14159. The output flx has shape (1, 1, 5, 2) representing (nwave, ncol, nlvl, nflx), where the first element of the last dimension is upward flux and the second is downward flux. This example is from test_attenuation.py. ```python >>> import torch >>> from pydisort import DisortOptions, Disort >>> 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) >>> flx = ds.forward(tau, fbeam=torch.tensor([3.14159])) >>> flx tensor([[[[0.0000, 3.1416], [0.0000, 2.8426], [0.0000, 2.3273], [0.0000, 1.7241], [0.0000, 1.1557]]]]) ``` -------------------------------- ### Run separate developer checks Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Run benchmark, documentation renderer, and setup guidance checks from the repository root. These are not registered with CTest and are not added to GitHub Actions. ```bash # Benchmark thread control and optional-dependency handling python -m pip install PythonicDISORT threadpoolctl python -m pytest benchmarks/tests/ -v -rs # Documentation API renderer (no compiled solver needed) python -m pip install -r docs/requirements.txt python -m unittest discover -s docs/_ext -p 'test_*.py' # Source-build installation guidance python -m pytest tests/test_setup_guidance.py -v -rs ``` -------------------------------- ### Run benchmark scripts for Python wrapper and solver performance Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Commands to run benchmark scripts that compare pydisort's Python wrapper cost and end-to-end solver performance. The scripts verify agreement between implementations before reporting timing and exit non-zero on mismatch. The first script builds its own C baseline and needs no cmake; the second requires installing PythonicDISORT and threadpoolctl. ```bash # what the Python wrapper costs; builds its own C baseline, needs no cmake python benchmarks/compare_cdisort.py --verify-only python benchmarks/compare_cdisort.py --alloc both # end-to-end solver performance against PythonicDISORT python -m pip install PythonicDISORT threadpoolctl python benchmarks/compare_pythonicdisort.py --verify-only python benchmarks/compare_pythonicdisort.py --threads 10 ``` -------------------------------- ### ds() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Get or set the disort state for disort. The getter returns a disort_state object, and the setter accepts a disort_state object and returns the DisortOptions object. ```APIDOC ## ds() ### Description Get or set the disort state for disort. ### Method Getter/Setter ### Signature - `ds() -> disort_state` - `ds(ds: disort_state) -> DisortOptions` ### Parameters (Setter) - **ds** (pydisort.disort_state) - Required - Disort state for disort ### Returns - **Getter**: disort_state - Disort state for disort - **Setter**: DisortOptions - Class object ``` -------------------------------- ### Warn if pytest is missing Source: https://github.com/zoeyzyhu/pydisort/blob/main/tests/CMakeLists.txt Emits a CMake warning if pytest is not importable, noting that Python tests are registered but will fail until pytest is installed. ```cmake if(PYTEST_NOT_FOUND) message(WARNING "pytest is not importable by ${Python3_EXECUTABLE}. The Python tests are " "registered but will fail until it is installed (pip install pytest).") endif() ``` -------------------------------- ### DisortOptions.nwave() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the number of wavelengths for disort. When called with no arguments, returns the current number of wavelengths. When called with an nwave argument, sets the number and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.nwave() ### Description Gets or sets the number of wavelengths for disort. When called with no arguments, returns the current number of wavelengths. When called with an nwave argument, sets the number and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `nwave() -> int` `nwave(nwave: int) -> DisortOptions` ### Parameters #### Setter - **nwave** (int) - Required - number of wavelengths for disort ### Returns #### Getter - **int** - number of wavelengths for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### DisortOptions.header() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the header for disort. When called with no arguments, returns the current header string. When called with a header argument, sets the header and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.header() ### Description Gets or sets the header for disort. When called with no arguments, returns the current header string. When called with a header argument, sets the header and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `header() -> str` `header(header: str) -> DisortOptions` ### Parameters #### Setter - **header** (str) - Required - header for disort ### Returns #### Getter - **str** - header for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### wave_upper() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Get or set upper wavenumber in cm^-1 for each spectral bin. The getter returns a list of floats, and the setter accepts a list of floats or ndarray and returns the DisortOptions object. ```APIDOC ## wave_upper() ### Description Get or set upper wavenumber in cm^-1 for each spectral bin. ### Method Getter/Setter ### Signature - `wave_upper() -> List[float]` - `wave_upper(wave_upper: List[float] | ndarray) -> DisortOptions` ### Parameters (Setter) - **wave_upper** (list[float] | ndarray) - Required - Upper wavenumber in cm^-1 for each spectral bin ### Returns - **Getter**: list[float] - Upper wavenumber in cm^-1 for each spectral bin - **Setter**: DisortOptions - Class object ``` -------------------------------- ### user_phi() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Get or set user azimuthal angles in degrees. The getter returns a list of floats, and the setter accepts a list of floats or ndarray and returns the DisortOptions object. ```APIDOC ## user_phi() ### Description Get or set user azimuthal angles in degrees. ### Method Getter/Setter ### Signature - `user_phi() -> List[float]` - `user_phi(user_phi: List[float] | ndarray) -> DisortOptions` ### Parameters (Setter) - **user_phi** (list[float] | ndarray) - Required - User azimuthal angles in degrees ### Returns - **Getter**: list[float] - User azimuthal angles in degrees - **Setter**: DisortOptions - Class object ``` -------------------------------- ### Build Python bindings and run validation tests Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Installs the Python package without build isolation, runs pytest with verbose and skip reasons, and runs CTest. The pip step links the C++ library from build/lib and does not run CMake. ```bash python -m pip install --no-build-isolation . python -m pytest tests/ -v -rs ctest --test-dir build --output-on-failure ``` -------------------------------- ### DisortOptions.accur() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the accuracy for disort. When called with no arguments, returns the current accuracy. When called with an accur argument, sets the accuracy and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.accur() ### Description Gets or sets the accuracy for disort. When called with no arguments, returns the current accuracy. When called with an accur argument, sets the accuracy and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `accur() -> float` `accur(accur: float) -> DisortOptions` ### Parameters #### Setter - **accur** (float) - Required - accuracy for disort ### Returns #### Getter - **float** - accuracy for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### wave_lower() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Get or set lower wavenumber in cm^-1 for each spectral bin. The getter returns a list of floats, and the setter accepts a list of floats or ndarray and returns the DisortOptions object. ```APIDOC ## wave_lower() ### Description Get or set lower wavenumber in cm^-1 for each spectral bin. ### Method Getter/Setter ### Signature - `wave_lower() -> List[float]` - `wave_lower(wave_lower: List[float] | ndarray) -> DisortOptions` ### Parameters (Setter) - **wave_lower** (list[float] | ndarray) - Required - Lower wavenumber in cm^-1 for each spectral bin ### Returns - **Getter**: list[float] - Lower wavenumber in cm^-1 for each spectral bin - **Setter**: DisortOptions - Class object ``` -------------------------------- ### DisortOptions.ncol() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the number of columns for disort. When called with no arguments, returns the current number of columns. When called with an ncol argument, sets the number and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.ncol() ### Description Gets or sets the number of columns for disort. When called with no arguments, returns the current number of columns. When called with an ncol argument, sets the number and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `ncol() -> int` `ncol(ncol: int) -> DisortOptions` ### Parameters #### Setter - **ncol** (int) - Required - number of columns for disort ### Returns #### Getter - **int** - number of columns for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### user_mu() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Get or set user viewing zenith cosines (positive upward, negative downward). The getter returns a list of floats, and the setter accepts a list of floats or ndarray and returns the DisortOptions object. ```APIDOC ## user_mu() ### Description Get or set user viewing zenith cosines (positive upward, negative downward). ### Method Getter/Setter ### Signature - `user_mu() -> List[float]` - `user_mu(user_mu: List[float] | ndarray) -> DisortOptions` ### Parameters (Setter) - **user_mu** (list[float] | ndarray) - Required - User viewing zenith cosines (positive upward, negative downward) ### Returns - **Getter**: list[float] - User viewing zenith cosines (positive upward, negative downward) - **Setter**: DisortOptions - Class object ``` -------------------------------- ### DisortOptions.upward() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the direction for disort. When called with no arguments, returns the current direction. When called with an upward argument, sets the direction and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.upward() ### Description Gets or sets the direction for disort. When called with no arguments, returns the current direction. When called with an upward argument, sets the direction and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `upward() -> int` `upward(upward: int) -> DisortOptions` ### Parameters #### Setter - **upward** (int) - Required - direction for disort ### Returns #### Getter - **int** - direction for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### DisortOptions.flags() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the radiation flags for disort. When called with no arguments, returns the current flags string. When called with a flags argument, sets the flags and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.flags() ### Description Gets or sets the radiation flags for disort. When called with no arguments, returns the current flags string. When called with a flags argument, sets the flags and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `flags() -> str` `flags(flags: str) -> DisortOptions` ### Parameters #### Setter - **flags** (str) - Required - radiation flags for disort ### Returns #### Getter - **str** - radiation flags for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### DisortOptions.user_tau() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the user optical depths for disort. When called with no arguments, returns the current list of user optical depths. When called with a user_tau argument, sets the user optical depths and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.user_tau() ### Description Gets or sets the user optical depths for disort. When called with no arguments, returns the current list of user optical depths. When called with a user_tau argument, sets the user optical depths and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `user_tau() -> List[float]` `user_tau(user_tau: List[float] | ndarray) -> DisortOptions` ### Parameters #### Setter - **user_tau** (list[float]) - Required - user optical depths for disort ### Returns #### Getter - **list[float]** - user optical depths for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### DisortOptions.user_mu() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Gets or sets the user-specified viewing zenith cosines for disort. When called with no arguments, returns the current list of user mu values. When called with a user_mu argument, sets the user mu values and returns the DisortOptions instance for chaining. ```APIDOC ## DisortOptions.user_mu() ### Description Gets or sets the user-specified viewing zenith cosines for disort. When called with no arguments, returns the current list of user mu values. When called with a user_mu argument, sets the user mu values and returns the DisortOptions instance for chaining. ### Method Getter/Setter ### Signature `user_mu() -> List[float]` `user_mu(user_mu: List[float] | ndarray) -> DisortOptions` ### Parameters #### Setter - **user_mu** (list[float]) - Required - user-specified viewing zenith cosines for disort ### Returns #### Getter - **list[float]** - user-specified viewing zenith cosines for disort #### Setter - **DisortOptions** - class object ``` -------------------------------- ### Create and configure DisortOptions Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Shows how to create a DisortOptions instance, set flags and dimensions, and verify the values. The output (10, 10, 10) confirms the settings. ```pycon >>> import pydisort >>> op = pydisort.DisortOptions().flags('onlyfl').nwave(10).ncol(10) >>> op.ds().nlyr, op.ds().nstr, op.ds().nmom = 10, 4, 4 >>> op.nwave(), op.ncol(), op.ds().nlyr (10, 10, 10) ``` -------------------------------- ### DisortOptions.__init__() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Initializes a new DisortOptions instance. ```APIDOC ## DisortOptions.__init__() ### Description Initializes a new DisortOptions instance. ### Method Constructor ### Signature `__init__() -> None` ### Parameters None ### Returns None ``` -------------------------------- ### Configure DISORT dimensions and options Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Step 2: create a DisortOptions instance, set radiation flags, and configure the number of layers, streams, moments, and phase-function grid points. ```python op = DisortOptions().flags("onlyfl,lamber") op.ds().nlyr = 4 op.ds().nstr = 4 op.ds().nmom = 4 op.ds().nphase = 4 ``` -------------------------------- ### Create test executables for cdisort and cdisort_09 Source: https://github.com/zoeyzyhu/pydisort/blob/main/tests/cdisort213/CMakeLists.txt Invokes the cdisort_setup_test macro to create two test executables: test_cdisort and test_cdisort_09, the latter for large scale testing. ```cmake cdisort_setup_test(test_cdisort test_cdisort.c) cdisort_setup_test(test_cdisort_09 test_cdisort_09.c) ``` -------------------------------- ### Create a working branch Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Fork the repository if needed, clone your fork, and create a branch for the change. ```bash git switch -c your-name/describe-the-change ``` -------------------------------- ### Run cdisort comparison benchmark Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/benchmarks.rst Use these commands to run the benchmark script comparing pydisort against cdisort. The --verify-only flag runs only verification, the default runs a sweep, and the third command specifies custom nwave values, threads, and repeat count. No prepared build is needed; the script compiles its own baseline from bench_cdisort.cpp. ```bash python benchmarks/compare_cdisort.py --verify-only # seconds python benchmarks/compare_cdisort.py # default sweep python benchmarks/compare_cdisort.py --nwave 1,10,100,1000,10000 \ --threads 10 --repeat 3 ``` -------------------------------- ### Configure DisortOptions and run Disort forward pass Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Sets up a DisortOptions instance with the flags "onlyfl,lamber", configures layer/stream/moment/phase counts, builds a Disort solver, and runs a forward pass with a single optical-depth column and a beam flux of 3.14159. Ends by gathering flux outputs with gather_flx(). ```pycon >>> import torch >>> from pydisort import DisortOptions, Disort >>> 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) >>> flx = ds.forward(tau, fbeam=torch.tensor([3.14159])) >>> ds.gather_flx() ``` -------------------------------- ### Configure DisortOptions and initialize Disort solver Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/usage.rst Creates a DisortOptions object with the 'onlyfl,lamber' flags, sets dimensions (nlyr, nstr, nmom, nphase) to 4, and initializes a Disort solver. Configure options before constructing the solver; do not change dimensions or flags afterwards. ```python >>> import pydisort >>> op = pydisort.DisortOptions().flags("onlyfl,lamber") >>> op.ds().nlyr = 4 >>> op.ds().nstr = 4 >>> op.ds().nmom = 4 >>> op.ds().nphase = 4 >>> ds = pydisort.Disort(op) ``` -------------------------------- ### Define cdisort_setup_test macro Source: https://github.com/zoeyzyhu/pydisort/blob/main/tests/cdisort213/CMakeLists.txt Defines a macro to create a test executable from a source file, setting compile flags, include directories, linking to pydisort::cdisort, and adding a test. ```cmake macro(cdisort_setup_test name srcfile) add_executable(${name}.${buildl} ${srcfile} print_test.c) set_target_properties( ${name}.${buildl} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS_${buildu}}) target_include_directories(${name}.${buildl} PRIVATE ${DISORT_INCLUDE_DIR}/src ${DISORT_INCLUDE_DIR}/cdisort213) target_link_libraries(${name}.${buildl} pydisort::cdisort) add_test(NAME ${name}.${buildl} COMMAND ${name}.${buildl}) endmacro() ``` -------------------------------- ### Register C++ tests with setup_test Source: https://github.com/zoeyzyhu/pydisort/blob/main/tests/CMakeLists.txt Registers C++ unit tests for the project using the setup_test function. The function is defined elsewhere in the build system. ```cmake setup_test(test_disort) setup_test(test_clone) ``` -------------------------------- ### Run radiative transfer with ds.forward Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Step 5: call the forward function with the optical properties and boundary conditions as keyword arguments. The output is upward and downward fluxes at each level. ```python ds.forward(tau, fbeam=torch.tensor([3.14159])) ``` -------------------------------- ### Run tests and pre-commit checks Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Run the test suite and pre-commit checks on all files. Pre-commit checks formatting and lint rules but does not run the solver's test suite. ```bash python -m pytest tests/ -v -rs pre-commit run --all-files ``` -------------------------------- ### Usage instructions for disrot library Source: https://github.com/zoeyzyhu/pydisort/blob/main/src/CMakeLists.txt Comments at the top of the file explain how to use the library: define DISORT_INCLUDE_DIR and link against pydisort::disort or pydisort::disort_cu. Normal usage includes include_directories and target_link_libraries. ```cmake # Install disrot library # # library: libdisort_debug.so # library: libdisort_release.so # # Define the following symbols # # DISORT_INCLUDE_DIR # pydisort::disort # pydisort::disort_cu # # Normal usage would be: # # include_directories(${DISORT_INCLUDE_DIR}) # target_link_libraries(pydisort::disort) ``` -------------------------------- ### Build and run full test suite with CTest Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Configures a CMake build with tests enabled, builds the project, and runs the full C and C++ test suite via CTest, showing output on failure. ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON cmake --build build ctest --test-dir build --output-on-failure ``` -------------------------------- ### Import pydisort modules Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Step 1 of the tutorial: import the pydisort module and the DisortOptions and Disort classes. ```python import pydisort from pydisort import DisortOptions, Disort ``` -------------------------------- ### Symlink input files to binary directory Source: https://github.com/zoeyzyhu/pydisort/blob/main/examples/CMakeLists.txt Globs input files with extensions .inp, .dat, and .yaml in the current directory and creates symbolic links to them in the binary directory's bin folder using the ln -sf command. The variable ${inp} is used in the destination path, which may be a typo for ${input}. ```cmake file(GLOB inputs *.inp *.dat *.yaml) foreach(input ${inputs}) execute_process(COMMAND ln -sf ${input} ${CMAKE_BINARY_DIR}/bin/${inp}) endforeach() ``` -------------------------------- ### Run benchmark with multiple wavenumbers and threads Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/benchmarks.rst Executes the benchmark comparing pydisort and PythonicDISORT for wavenumbers 1, 10, 100, and 1000 using 10 threads and comparing modes. ```bash python benchmarks/compare_pythonicdisort.py --nwave 1,10,100,1000 \ --threads 10 --compare-modes ``` -------------------------------- ### Check pip and torch interpreter paths Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/venv.rst Shows the pip version and the Python executable and torch file path. Use this to verify which interpreter and packages are being used. ```bash python -m pip --version python -c "import sys, torch; print(sys.executable); print(torch.__file__)" ``` -------------------------------- ### Basic usage of pydisort.DisortOptions and pydisort.Disort Source: https://github.com/zoeyzyhu/pydisort/blob/main/README_pypi.md Create a DisortOptions object, set flags and layer parameters, initialize a Disort object, and run a forward calculation with a tensor of optical depths. The output is a tensor of fluxes. ```python >>> import torch >>> from pydisort import DisortOptions, Disort >>> 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) >>> flx = ds.forward(tau, fbeam=torch.tensor([3.14159])) >>> flx tensor([[[[0.0000, 3.1416], [0.0000, 2.8426], [0.0000, 2.3273], [0.0000, 1.7241], [0.0000, 1.1557]]]]) ``` -------------------------------- ### Disort.__init__ Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Constructs a new Disort module. Can be called with no arguments for default options or with a DisortOptions instance for custom configuration. ```APIDOC ## Disort.__init__ ### Description Constructs a new Disort module. Can be called with no arguments for default options or with a DisortOptions instance for custom configuration. ### Method Constructor ### Signature `__init__() -> None` `__init__(options: DisortOptions) -> None` ### Parameters - **options** (DisortOptions) - Optional - Configuration options for DISORT ### Returns None ``` -------------------------------- ### Run a DISORT simulation with pydisort Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/_snippets/quickstart.rst Sets up a DISORT simulation with 4 layers, 4 streams, and 4 moments. Uses the 'onlyfl,lamber' flags and computes fluxes for a given optical depth vector. The output shape is (1, 1, 5, 2) and the printed tensor shows the computed fluxes. ```python 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) ``` ```output tensor([[[[0.0000, 3.1416], [0.0000, 2.8426], [0.0000, 2.3273], [0.0000, 1.7241], [0.0000, 1.1557]]]]) ``` -------------------------------- ### Recorded benchmark results on Apple M5 Max Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/benchmarks.rst This text block shows the recorded speed-up results from running the benchmark on an Apple M5 Max with 18 logical CPUs, best of 3, in radiance mode. It includes the pydisort and torch versions, compiler, and a table of speed-up ratios for various nwave and core counts. ```text pydisort : 1.8.5 torch : 2.10.0 compiler : Apple clang 21 Speed-up over cdisort (hoisted) nwave 1 core 10 cores 1 0.98x 0.98x 10 1.00x 6.35x 100 1.00x 7.80x 1000 1.00x 8.17x 10000 1.01x 8.34x (same problem at 18 threads: 12.71x at nwave=1000, 13.25x at nwave=10000) ``` -------------------------------- ### Set up optical properties with torch tensors Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Step 4: set the default dtype to float64 and create a tau tensor for layer optical thickness. The last dimension is the number of optical properties; the second-to-last is the number of layers. ```python import torch torch.set_default_dtype(torch.float64) tau = torch.tensor([0.1, 0.2, 0.3, 0.4]).unsqueeze(-1) ``` -------------------------------- ### Calculate thermal emission with temperature profile using pydisort Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/usage.rst Sets up DisortOptions with flags 'onlyfl,lamber,planck', configures layers, streams, moments, and phase, sets a single wave band from 20 to 4000 cm-1, and calls forward with a temperature profile and boundary conditions. The output tensor shows the computed fluxes. Note that wave_lower and wave_upper are wavenumbers in cm-1, and the integration over the band introduces spectral truncation errors. ```python >>> import torch >>> from pydisort import DisortOptions, Disort >>> op = DisortOptions().flags("onlyfl,lamber,planck") >>> op.ds().nlyr = 4 >>> op.ds().nstr = 4 >>> op.ds().nmom = 4 >>> op.ds().nphase = 4 >>> op.nwave(1) >>> op.wave_lower([20.]) >>> op.wave_upper([4000.]) >>> ds = Disort(op) >>> tau = torch.tensor([0.1, 0.2, 0.3, 0.4]).unsqueeze(-1) >>> ds.forward(tau, temf=torch.linspace(200, 240, 5).unsqueeze(0), albedo=torch.tensor([0.]), btemp=torch.tensor([240.]), ttemp=torch.tensor([0.]), temis=torch.tensor([1.]), fisot=torch.tensor([0.]), ) tensor([[[[145.2179, 0.0000], [153.2714, 17.5241], [165.8178, 47.9667], [179.6727, 84.7606], [188.1117, 124.8982]]]]) ``` ```python >>> bc = { >>> "albedo": torch.tensor([0.]), >>> "btemp": torch.tensor([240.]), >>> "ttemp": torch.tensor([0.]), >>> "temis": torch.tensor([1.]), >>> "fisot": torch.tensor([0.]), >>> } >>> ds.forward(tau, temf=torch.linspace(200, 240, 5).unsqueeze(0), **bc) tensor([[[[145.2179, 0.0000], [153.2714, 17.5241], [165.8178, 47.9667], [179.6727, 84.7606], [188.1117, 124.8982]]]]) ``` -------------------------------- ### Inspect dimensions via options state Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/usage.rst Shows how to inspect dimension values through the options' state rather than relying on printed representation. The output confirms the configured values (4, 4, 4). ```python >>> op.ds().nlyr, op.ds().nstr, op.ds().nmom (4, 4, 4) ``` -------------------------------- ### Run tests with CTest Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/devops.rst Runs the test suite via CTest, which includes C, C++, and Python solver tests, with output on failure. ```bash ctest --test-dir build --output-on-failure ``` -------------------------------- ### Submit a pull request Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/contribute.rst Check for whitespace errors, stage changed files, commit, and push to your branch. ```bash git diff --check git add path/to/changed-file git commit -m "Describe the change" git push -u origin your-name/describe-the-change ``` -------------------------------- ### disort_state.__init__() Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/api.rst Creates a new default DISORT state object. This is the constructor for the disort_state class, which wraps the C DISORT library state. The object's attributes (nlyr, nstr, nmom, nphase) can be set after creation. ```APIDOC ## disort_state.__init__() ### Description Creates a new default DISORT state object. This is the constructor for the disort_state class, which wraps the C DISORT library state. The object's attributes (nlyr, nstr, nmom, nphase) can be set after creation. ### Method Constructor ### Signature `__init__() -> None` ### Parameters None ### Returns - **Returns:** class object - **Return type:** pydisort.disort_state ### Example ```pycon >>> import pydisort >>> ds = pydisort.disort_state() >>> ds.nlyr, ds.nstr, ds.nphase = 10, 4, 4 >>> ds.nlyr, ds.nstr, ds.nphase (10, 4, 4) ``` ``` -------------------------------- ### CI matrix strategy for build-and-test job Source: https://github.com/zoeyzyhu/pydisort/blob/main/docs/source/devops.rst Defines the build-and-test job's matrix with fail-fast enabled, testing on Ubuntu and macOS with Python 3.11 and 3.14. ```yaml strategy: fail-fast: true matrix: os: [ubuntu-latest, macOS-latest] python-version: ["3.11", "3.14"] ``` -------------------------------- ### Set C test files to compile as C++ Source: https://github.com/zoeyzyhu/pydisort/blob/main/tests/cdisort213/CMakeLists.txt Sets the LANGUAGE property to CXX for the C test driver files because the cdisort impl headers are C++ with DISPATCH_MACRO inline. ```cmake set_source_files_properties(test_cdisort.c test_cdisort_09.c print_test.c PROPERTIES LANGUAGE CXX) ``` -------------------------------- ### Construct Disort object Source: https://github.com/zoeyzyhu/pydisort/blob/main/README.md Step 3: construct the Disort object from the options. Internal memory is allocated for the DISORT model. ```python ds = Disort(op) ``` -------------------------------- ### Run thread-control regression tests Source: https://github.com/zoeyzyhu/pydisort/blob/main/benchmarks/README.md Run the benchmark's thread-control regression checks with pytest. ```bash python -m pytest benchmarks/tests/ -q ```