Skip to content

Settings

The Settings object configures a GOAD simulation. It controls physical parameters, numerical methods, and output options.

Basic Usage

At a minimum, you must specify the path to a geometry file or directory containing geometry files:

from goad import MultiProblem, Settings

# Basic settings with minimal configuration
settings = Settings(geom_path="path/to/geometry.obj")
mp = MultiProblem(settings)
mp.solve()

The geometry defines the units of the problem. If your geometry file is in microns, then you should also specify the wavelength in microns. All faces in the geometry must be planar and have some non-zero area. GOAD will return with an error if there are faces with zero area (ie. extremely thin triangles), since it needs to compute normals of each face by a cross product of 2 non-colinear edge vectors. You can make geometries in the open-source Blender software, or use some example geometries straight from Python here.

If you specify a directory, GOAD will attempt to load all files with the .obj extension in the directory. It will then choose geometries at random for each orientation in the simulation. See Orientation Distribution for more details.

Physical Parameters

Wavelength

The wavelength of incident light in micrometers:

from goad import MultiProblem, Settings

# Configure wavelength (in micrometers)
settings = Settings(
    geom_path="path/to/geometry.obj",
    wavelength=0.532,  # 532 nm
)
mp = MultiProblem(settings)
mp.solve()

Default: 0.532 (532 nm, green laser)

Refractive Indices

Specify the complex refractive index for both the particle and surrounding medium:

from goad import MultiProblem, Settings

# Configure refractive indices for particle and medium
settings = Settings(
    geom_path="path/to/geometry.obj",
    particle_refr_index_re=1.5,  # Real part of particle refractive index
    particle_refr_index_im=0.01,  # Imaginary part (absorption)
    medium_refr_index_re=1.33,  # Water as medium
    medium_refr_index_im=0.0,
)
mp = MultiProblem(settings)
mp.solve()

Defaults:

  • particle_refr_index_re: 1.31 (typical glass)
  • particle_refr_index_im: 0.0
  • medium_refr_index_re: 1.0 (vacuum/air)
  • medium_refr_index_im: 0.0

Particle Scaling

Scales the entire problem, including geometry and wavelength. Does not change the physics, only used for improving clipping algorithm accuracy. The default value is usually sufficient.

Parameter: scale
Default: 1.0

Orientation Distribution

Define how particle orientations are sampled:

from goad import EulerConvention, MultiProblem, Orientation, Settings

# Configure particle orientation distribution
settings = Settings(
    geom_path="path/to/geometry.obj",
    orientation=Orientation.uniform(
        num_orients=100, euler_convention=EulerConvention("ZYZ")
    ),
)
mp = MultiProblem(settings)
mp.solve()

Default: Orientation.uniform(num_orients=1) with EulerConvention('ZYZ')

For discrete orientations:

from goad import Euler, EulerConvention, MultiProblem, Orientation, Settings

# Configure discrete orientations
orients = Orientation.discrete(
    eulers=[Euler(0, 0, 0), Euler(45, 90, 0)], euler_convention=EulerConvention("ZYZ")
)
settings = Settings(geom_path="path/to/geometry.obj", orientation=orients)
mp = MultiProblem(settings)
mp.solve()

The output will be an average over the orientations. Results from individual orientations are not stored. See Results for more details.

Seed

Seeds the random number generator for reproducibility.

Parameter: seed
Default: None

Zones

Zones define a set of query points to evaluate the far-field scattering at. By default, GOAD creates three zones:

  1. Full zone - The full scattering sphere from θ=0° to θ=180°. Used for computing integrated parameters like asymmetry, scattering cross-section, and albedo.
  2. Forward zone - A single point at θ=0.01° (slightly off-axis for numerical stability). Used for computing extinction cross-section via the optical theorem.
  3. Backward zone - A single point at θ=180°. Used for computing backscatter cross-section, lidar ratio, and depolarization ratio.

You can add additional zones as needed for your application. For backscattering-only applications, you can exclude the full zone and compute only at forward and backward scattering for faster computations.

Note: GOAD automatically determines the zone type based on the theta range of your binning scheme. If the theta range covers 0° to 180°, it is classified as a Full zone and integrated parameters (asymmetry, scattering cross-section, etc.) will be computed. If the range is partial, it is classified as a Custom zone and these parameters will not be computed.

Different parameters are computed depending on the zone type - see Integrated Parameters for more details.

Each zone is specified by a binning scheme and an optional label. See Binning Schemes for more info about binning schemes.

from goad import BinningScheme, MultiProblem, Settings, ZoneConfig

# Default: single full zone with interval binning (high-res forward/back)
settings = Settings(geom_path="path/to/geometry.obj")

# Custom full zone with simple binning
settings = Settings(
    geom_path="path/to/geometry.obj",
    zones=[ZoneConfig(BinningScheme.simple(180, 48))],
)

# Labeled zone
settings = Settings(
    geom_path="path/to/geometry.obj",
    zones=[ZoneConfig(BinningScheme.simple(90, 24), label="coarse")],
)

# Backscatter-only (no full zone, just forward + backward)
settings = Settings(geom_path="path/to/geometry.obj", zones=[])

mp = MultiProblem(settings)
mp.solve()

Default: A single full zone with interval binning (high resolution at forward and backward angles).

Binning Schemes

Control the angular resolution of scattering calculation in the far-field. As particle size increases, the width of peaks in the scattering decreases. GOAD currently requires the user to choose a sufficiently fine binning scheme to resolve the peaks. For phi angles, a relatively course binning scheme can be used, but for theta angles, care should be taken to ensure sufficient resolution, otherwise the integrated parameters lose accuracy. The compute time approximately scales with the number of bins, which for simple and interval binning schemes is just the product of the number of bins in each dimension.

Simple Binning

Uniform spacing in theta and phi:

from goad import BinningScheme, MultiProblem, Settings, ZoneConfig

# Configure angular binning for scattering output
settings = Settings(
    geom_path="path/to/geometry.obj",
    zones=[ZoneConfig(BinningScheme.simple(num_theta=180, num_phi=48))],
)
mp = MultiProblem(settings)
mp.solve()

Default: BinningScheme.interval(thetas=[0, 5, 175, 179, 180], theta_spacings=[0.1, 2.0, 0.5, 0.1], phis=[0, 360], phi_spacings=[7.5])

Interval Binning

Variable resolution for different angular regions:

from goad import BinningScheme, MultiProblem, Settings, ZoneConfig

# Use variable angular resolution
settings = Settings(
    geom_path="path/to/geometry.obj",
    zones=[
        ZoneConfig(
            BinningScheme.interval(
                thetas=[0, 90, 180],
                theta_spacings=[1, 2],  # 1° steps up to 90°, then 2° steps
                phis=[0, 360],
                phi_spacings=[2],
            )
        )
    ],
)
mp = MultiProblem(settings)
mp.solve()

This example uses 1° resolution for forward scattering (0-90°) and 2° for backward scattering (90-180°). interval binning schemes are useful if the user is only interested in a specific angular scattering range, eg 6°-25°.

Custom Binning

Specify arbitrary bin edges:

from goad import BinningScheme, MultiProblem, Settings, ZoneConfig

# Specify arbitrary bin edges
binning = BinningScheme.custom(
    bins=[
        [[0, 10], [0, 360]],  # Forward scattering cone
        [[10, 170], [0, 360]],  # Side scattering
        [[170, 180], [0, 360]],  # Backscattering cone
    ]
)
settings = Settings(geom_path="path/to/geometry.obj", zones=[ZoneConfig(binning)])
mp = MultiProblem(settings)
mp.solve()

GOAD will compute the bin centres automatically. GOAD will not compute the 1D mueller matrix or integrated parameters if using a custom binning scheme.

Mapping Method

Choose how near-field results map to the far-field:

from goad import Mapping, MultiProblem, Settings

# Configure near-to-far field mapping method
settings = Settings(
    geom_path="path/to/geometry.obj",
    mapping=Mapping("ad"),  # 'ad' for Aperture Diffraction, 'go' for Geometric Optics
)
mp = MultiProblem(settings)
mp.solve()

Options:

  • 'ad': Aperture Diffraction (default, more accurate). Suitable for fixed-orientation computations.
  • 'go': Geometric Optics (faster, suitable for very large particles). Generally not suitable for fixed-orientation computations.

Default: Mapping('ad')

Beam Tracing Parameters

Beams traced in the near-field if they pass the following checks, in order:

  • Beam power is below the threshold
  • Beam area is below the threshold
  • Beam number of recursion is above the threshold

If the beam is from a total internal reflection event, the beam is traced even if the recursion is above the threshold, as long as the total internal reflection count is below the threshold.

Beam Thresholds

Control when beams are truncated during ray tracing:

from goad import MultiProblem, Settings

# Configure beam tracing thresholds
settings = Settings(
    geom_path="path/to/geometry.obj",
    beam_power_threshold=1e-6,  # Stop tracking beams below this power
    beam_area_threshold_fac=1e-3,  # Stop tracking beams smaller than this fraction
    cutoff=1e-10,  # Global energy cutoff
)
mp = MultiProblem(settings)
mp.solve()

Defaults:

  • beam_power_threshold: 0.005 (discard beams below 0.5% of incident power).
  • beam_area_threshold_fac: 0.1 (factor × λ² determines the physical area threshold, below which beams are discarded. It scales with λ² following the applicability of geometric optics).
  • cutoff: 0.99 (trace 99% of energy in the near field, then map. You generally want to use a value of at least 0.95 here, unless you have a good reason to do otherwise).

Lower thresholds and higher cutoff increases accuracy but slows computation.

Recursion Limits

Limit internal beams bounces:

from goad import MultiProblem, Settings

# Configure ray tracing limits
settings = Settings(
    geom_path="path/to/geometry.obj",
    max_rec=10,  # Maximum internal reflections
    max_tir=5,  # Maximum total internal reflections
)
mp = MultiProblem(settings)
mp.solve()

Defaults:

  • max_rec: 10 (maximum internal reflections)
  • max_tir: 10 (maximum total internal reflections)

Increase these for complex internal ray paths, but expect slower performance. High numbers of total internal reflections recommended for backscattering computations, ie. 20.

Output Options

Directory

Specify output directory for simulation data:

Parameter: directory
Default: "goad-run"

Coherence

Enable coherent beam addition (phase tracking):

Parameter: coherence
Default: True

Enables coherent beam addition with phase tracking for interference effects. If coherence is enabled, GOAD traces the phase of each beam, and combines amplitude matrices in the far-field with interference. If coherence is disabled, GOAD traces the phase of each beam, but combines the far-field contributions of beams in the far-field only by a linear summation of Mueller matrices. Coherence should be enabled for backscattering computations.

Verbosity

Suppress console output:

Parameter: quiet
Default: False

Set to True to silence progress messages.

Complete Example

from goad import BinningScheme, Mapping, MultiProblem, Orientation, Settings, ZoneConfig

# Complete configuration example
settings = Settings(
    geom_path="path/to/geometry.obj",
    wavelength=0.532,
    particle_refr_index_re=1.5,
    particle_refr_index_im=0.01,
    medium_refr_index_re=1.0,
    medium_refr_index_im=0.0,
    orientation=Orientation.uniform(num_orients=100),
    zones=[ZoneConfig(BinningScheme.simple(num_theta=180, num_phi=48))],
    mapping=Mapping("ad"),
    beam_power_threshold=1e-6,
    beam_area_threshold_fac=1e-3,
    cutoff=0.999,
    max_rec=10,
    max_tir=5,
    coherence=False,
    quiet=False,
    directory="output/",
)
mp = MultiProblem(settings)
mp.solve()

Parameter Reference

Parameter Type Default Description
geom_path str Required Path to geometry file
wavelength float 0.532 Wavelength in geometry units
particle_refr_index_re float 1.31 Real part of particle refractive index
particle_refr_index_im float 0.0 Imaginary part of particle refractive index
medium_refr_index_re float 1.0 Real part of medium refractive index
medium_refr_index_im float 0.0 Imaginary part of medium refractive index
orientation Orientation Orientation.uniform(1) Orientation distribution
zones list[ZoneConfig] Single full zone with interval binning Zone configurations for far-field evaluation
mapping Mapping Mapping('ad') Near-to-far field mapping method
beam_power_threshold float 0.005 Beam power truncation threshold
beam_area_threshold_fac float 0.1 Beam area truncation factor
cutoff float 0.99 Energy tracking cutoff
max_rec int 10 Maximum internal reflections
max_tir int 10 Maximum total internal reflections
scale float 1.0 Geometry scaling factor
seed int None Seed for random number generator
directory str "goad_run" Output directory path
coherence bool True Enable coherent beam addition
quiet bool False Suppress console output