Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

OPOSSUM Handbook

OPOSSUM (OPen Source Optics Simulation System and Unified Modeller) is a platform for simulating and designing optical systems, with an emphasis on large-scale, high‑energy/intensity laser systems. This book is the project documentation for OPOSSUM.

How to read this manual

This manual follows the Diátaxis framework and is organized into four complementary sections:

  • Concepts / Explanation — Overview of OPOSSUM and its design principles. Start with the introduction and see concepts for detailed explanations.
  • Tutorials — Step‑by‑step guides to install and use the software. Begin with installation and then follow the tutorials.
  • How‑to Guides — Practical recipes for accomplishing specific tasks (e.g., modeling a particular optical system). See How‑to Guides.
  • Reference — Comprehensive, in‑depth documentation of the software. See the reference.

Suggested reading order: Concepts (first chapters only) → Tutorials → How‑to Guides → Concepts (further chapters) → Reference.

Concepts

This section gives an overview of the project and describes the concepts, design and programming principles of OPOSSUM.

Introduction

What is OPOSSUM?

OPOSSUM is a powerful software framework designed to simulate large-scale optical systems.

Imagine your entire optical setup consisting of mirrors, lenses, filters, and prisms as a network or a graph. OPOSSUM uses this graph-based approach:

  • Nodes: Each interconnected node in the graph represents a single optical component.
  • Analyzers: On top of this model, we have specialized modules called Analyzers. These modules run specific types of simulations (e.g., raytracing, thermal analysis) on the exact same model.

This approach lets you build your optical model once and analyze it often in many different ways without having to rebuild the system every time you switch simulation types.

Why OPOSSUM?

There are already many excellent, mostly commercial, tools available for optics simulation and calculation. So, why create another one?

Existing solutions are great, but they often struggle with the complexity of modern, large-scale systems:

The Challenge of Complexity

When designing state-of-the-art laser facilities, you often end up with hundreds of optical components. The laser beam path is no longer a simple, single line; it involves:

  • Parallel Paths: Beam splitters create multiple paths.
  • Main and Side Paths: There’s usually a “main” path for the high-energy beam and several “side” paths for diagnostics and monitoring.
  • Subsystems: Facilities are broken down into distinct stages like a frontend, a pre-amplifier, a main amplifier, and a target chamber.

The Problem of Fragmentation

Existing tools typically only address specific aspects of an optical system:

  • Some are fantastic for pure geometric optics (raytracing), but were originally built for smaller systems (like a single camera lens). Managing hundreds of optics or parallel beam lines in these tools can become a nightmare.
  • Others focus entirely on non-linear material effects, wavefront propagation, parasitic lasing, or straylight simulation.

The Need for Unification

In high-energy laser design, you must consider all these effects at the same time:

  • Beam path (geometric ray or Fourier optics)
  • Temperature stability
  • Ghost focus formation
  • Thermal lensing effects
  • …and much more.

Relying on fragmented tools means you constantly have to switch software and/or repeatedly remodel your system to simulate the next effect.

OPOSSUM is an approach to unifying this entire design workflow. It offers a consistent, comprehensive environment to model and analyze the full complexity of your optical system.

Modelling Optical Systems

In general, optical systems consist of light sources, which provide a more or less complex light field (time-invariant or time-dependent), and optical components, which modify this light field.

A typical system includes the following elements:

  • Light Sources: Elements that generate light (e.g., lasers).
  • Optical Components: Elements that modify the light field (e.g., lenses, mirrors, Faraday isolators).
  • Light Sinks: Elements that produce a “result” or measurable signal (e.g., beam dumps, targets, or detectors).

Components may consist of sub-components with an unlimited nesting level.

The “Design Idea” vs. Physical Layout

For a full physical description, it would be sufficient to place the mechanical model of the optical components—along with their optical properties—into a 3D space with specific orientations. This approach is appropriate for tasks such as straylight analysis and is supported by our model.

However, a purely physical layout often misses the design idea.

For example, if one places a light source and two lenses in a setup, a physical model simply sees three objects. The design idea, however, specifies the intent: the two lenses form a Kepler or Galilei telescope to image an object or act as a beam expander. The light is intended to hit the first lens and then the second lens.

Therefore, optical systems are best described as networks or tree-like structures where optical rays or light fields are cast in a specific direction from one component to the next.

Directed Graphs as Primary Model Structure

To model these networks of optical components, OPOSSUM uses directed graphs. A directed graph consists of nodes and edges:

  • Nodes: Represent the optical components.
  • Edges: Represent the information about the light (energy, wavelength, wavefront, nearfield distribution, etc.) being handed from one node to the next.

Ports and Connections

A node has one or more ports where edges can be connected. We strictly distinguish between incoming and outgoing ports:

  • Light Source: A node with no input ports.
  • Detector: A node with no output ports.
  • Ideal Lens: Typically has one input and one output port.
  • Beam Splitter: Typically has one input port and two or more output ports.

Note: Realistic components may have additional ports, for example, to simulate ghost reflections from lens surfaces.

Node Types and Groups

There are different node types representing various optical components (ideal/real lenses, beam splitters, waveplates, etc.). Each node has attributes describing its parameters, such as center thickness (for glass plates), focal length (ideal lenses), or radii of curvature (real lenses).

Additionally, Group Nodes represent a set of other nodes arranged in a subgraph. Non-connected ports within the group form the “externally visible” ports of the group node. This allows for the creation of hierarchical, nested structures.

Loops for Modelling Resonators

Directed graphs can model optical resonators by forming loops. While this works well for ring resonators, it can create ambiguities for linear resonators.

Consider a simple linear cavity consisting of: Mirror 1 -> Propagation -> Mirror 2.

Creating a simple “reverse” edge from Mirror 2 back to Mirror 1 would technically form three loops:

  1. The intended large loop (Mirror 1 to Mirror 2 and back).
  2. A small loop between Mirror 1 and Propagation.
  3. A small loop between Mirror 2 and Propagation.

This structure is physically nonsensical and becomes unmanageable with complex resonators containing additional components (lenses, amplifier rods, etc.).

Reference Nodes

To solve this, OPOSSUM uses Reference Nodes. A reference node contains only a reference to another existing node and behaves exactly like the node it references. This allows a linear resonator to be “unrolled” in the graph, effectively translating it into a ring resonator structure without topological ambiguity.

Note: Strictly speaking, light in a ring resonator can propagate in both directions (unless suppressed by optical components). Since we use a directed graph, only one direction can be modelled at a time. Solutions for bidirectional propagation are currently being investigated.

Note: A reference node that refers to a group must not be placed inside that same group, or inside any group nested within it. This would make the group depend on its own reference, which OPOSSUM rejects when creating, moving, cutting, or pasting the reference node.

Amplification

Laser systems do not only transport light, they make more of it. This section explains how an amplifying component is represented in OPOSSUM and why it is split across two places instead of one. For the settings themselves see Pump scenarios; for the steps to set one up, see Model an amplifier. Its passive counterpart — energy a real medium takes out of the beam — is covered in Absorption, and the two are designed to act together.

There is no amplifier node

An amplifier is not a node type of its own. Amplification happens inside a component that encloses a volume of material — currently only within a lens, a wedge or a cylindric lens — because that is where light spends a path length inside a medium that can hand energy to it.

This follows from what an amplifier head physically is. The same slab of doped glass is a passive window when it is not pumped and an amplifier when it is; nothing about the component changes between the two. Giving amplification its own node type would mean the user has to decide which one a component is while drawing the model, and would force a different model for every operating condition of the same hardware.

Hardware and operating point

The two halves of an amplifier are therefore kept apart:

The hardware — the geometry of the component and the material it is made of — belongs to the node, is drawn on the canvas and travels with the model.

The operating point — how hard a component is driven during one particular analysis — belongs to a pump scenario, which is a property of the document rather than of any node. A scenario is named (e.g., “full power”, “half power”, “cold alignment”) and states, for every amplifying component, which gain model applies to it.

The gain is what an analysis is run at, not what a component is.

The practical consequence is that one model can be analyzed at several operating points without being edited in between. An analyzer is given a list of scenarios and produces one report per scenario, so the same chain at full and at half pump power is a single run and two reports that can be compared directly. A component no scenario mentions behaves exactly like the passive optic it is, which is why adding amplification to OPOSSUM changed no existing model’s result.

The “ideal” amplifier

The simplest gain model available today is a constant one: it multiplies the energy passing through the medium by a fixed factor. That factor is independent of wavelength, independent of the path length the light actually takes through the medium, and independent of how much energy has already been extracted — the medium has no state that a pass could deplete.

This is deliberately a bookkeeping model, not a description of an amplifier. It is the right tool for laying out a chain and seeing where the energy of a system ends up, and the wrong tool for designing a single amplifier head. Saturation, in particular, is absent: an ideal amplifier will happily turn a joule into a kilojoule if the factor says so.

Every pass through the medium counts

The factor applies once per traversal of the medium, not once per analysis. Sending light through the same head several times — a multipass amplifier, modeled with reference nodes — applies it once per pass.

The same is true in a ghost focus analysis. A stray reflection that runs back through a pumped head picks up the gain on that pass just like the main beam. This matters more than it may sound: a ghost is dangerous because of the fluence it carries onto a surface, and a ghost that has crossed an amplifier more often than the main beam carries correspondingly more of it. Counting those passes as unamplified would understate exactly the hazard the analysis exists to find.

The monochromatic small signal gain model

The constant gain model is deliberately unphysical — it is a bookkeeping tool. The monochromatic small signal gain model is the first step towards a physical description of a laser amplifier.

Inversion field. A pumped medium has more atoms in the upper laser level than the lower one. That population inversion is what a passing photon can stimulate: the local gain per unit path length is g(r) = g₀ × β(r), where g₀ is the peak gain coefficient the model carries and β(r) ∈ [0, 1] is the normalized pump shape — how strongly pumped that point is relative to the peak. For a spatially non-uniform pump, OPOSSUM discretizes β onto a three-dimensional grid so that two parallel rays at different radial positions pick up different gain.

Two phases. Before any ray is traced, OPOSSUM builds the inversion shape from the pump source. During ray tracing, each ray accumulates a gain factor exp(∫ g₀ × β ds) along its actual path through the medium — a voxel-exact integration. The path is the ray’s real geometric path, not an on-axis approximation, so off-axis and angled rays see the correct medium thickness automatically.

Pump profiles. The pump source defines only the shape β — the peak gain coefficient g₀ is stated once on the model. A constant pump is the shapeless case: β = 1 throughout the medium, no grid needed, and the model integrates over the exact chord each ray travels. An analytic pump composes a transversal profile (flat or super-Gaussian across the aperture) with a longitudinal profile (flat or Lambert-Beer along the propagation axis, for end-pumped or side-pumped geometries), resolved onto a grid stated on the pump itself.

Monochromatic. The gain coefficient g₀ is wavelength-independent — all wavelengths in a polychromatic beam receive the same gain. A wavelength-dependent gain (gain bandwidth, lineshape) is a separate model that builds on this one.

Why energy analysis is excluded. The gain a ray accumulates depends on the path it takes — an off-axis ray through the edge of a Gaussian gain profile picks up less than an on-axis ray. An energy flow analysis carries no spatial or geometric information about rays; it cannot determine this, and silently averaging over it would give the wrong answer. Energy flow analysis therefore refuses a model that includes a small signal gain component, rather than silently returning an incorrect result.

Still ideal. This model is called small signal because it assumes the signal is too weak to change the inversion. The gain field is built from the pump alone and is not modified as rays pass through. That makes multi-pass counting exact — a ray that traverses the medium three times accumulates three times the single-pass gain — but it overstates the gain for strong pulses, where the first pass depletes the medium for subsequent ones.

What comes next

The monochromatic small signal model has two idealisations: the signal is too weak to deplete the medium, and the gain does not depend on wavelength. Later models lift one at a time.

Spectral gain first: a real gain medium amplifies some wavelengths more than others. This is manifested in the spectroscopic properties of a material. This behaviour can already be implemented for the small signal gain model

Saturation second: a strong pulse changes the inversion as it passes through. The first part of the pulse sees more gain than the last, because the population inversion the front extracted is no longer available to the tail. The Frantz–Nodvik model captures this depletion — the gain is then a function of the fluence the pulse has already delivered, not just of the local inversion.

Absorption

Light does not cross a real medium unchanged: some of it is absorbed on the way through. This section explains how OPOSSUM represents that loss and why it is bound to the material rather than to the analysis. For the individual models and their parameters see Materials; absorption is the passive counterpart of Amplification, and the two are designed to work together.

Absorption belongs to the material

Like amplification, absorption happens inside a component that encloses a volume of material — currently a lens, a wedge or a cylindric lens — because that is where light spends a path length inside a medium that can take energy from it.

Unlike amplification, absorption is not part of the operating point. How strongly a medium absorbs is a fixed property of what it is made of: a slab of glass absorbs the same whether the system is run at full or at half power. Absorption therefore lives on the component’s host material and travels with the model, exactly like the refractive index does. There is nothing to switch on in an analysis and no scenario to name — a material simply carries an absorption model, or it does not.

The consequence is that absorption is automatic and opt-in through the material: whenever a component’s material defines an absorption model, rays crossing that component are attenuated accordingly. A material with no absorption model is perfectly transparent, which is the default, so adding absorption to OPOSSUM changed no existing model’s result.

Along the real path through the medium

Absorption is applied over the ray’s actual geometric path length through the body, the same chord the gain integration uses. An off-axis or angled ray travels a longer way through the medium and is attenuated more, without any on-axis approximation. Most models follow the Beer–Lambert law T(λ, L) = exp(−α(λ)·L), where α is the material’s absorption coefficient at the ray’s wavelength and L is the chord through the medium. The transmittance depends on the ray’s own wavelength, so a polychromatic beam is attenuated line by line.

As with gain, the loss applies once per traversal of the medium, not once per analysis. A multipass geometry, or a stray reflection running back through the same component in a ghost focus analysis, is attenuated on every pass.

Absorption and gain together

A doped gain medium is the case where both effects act at once, and they come from different places: the gain comes from the dopant and is set by the pump scenario, while the absorption is a property of the surrounding host material. In a real amplifier head the doped glass still absorbs at the signal wavelength; representing that faithfully means letting the two coexist.

OPOSSUM applies them together on a single traversal of the medium. Both act multiplicatively on the ray energy and commute, so the net factor over one pass is simply their product — the gain exp(∫ g₀ × β ds) from the dopant times the transmittance T(λ, L) of the host material.

A component may carry either effect, both, or neither. With neither it is the passive optic it always was; with only a host-material absorption it attenuates but does not amplify; with a gain model named by the scenario and an absorbing host material it does both at once.

Where absorption does not yet apply

Absorption is currently evaluated during ray tracing, where every ray carries a wavelength and a path length. An energy flow analysis carries neither, so — exactly like the small signal gain model — a path-length-dependent absorption cannot be evaluated there yet. That step is left for a later stage, once a nominal path length is defined for the energy analysis.

Position Distribution Design

In OPOSSUM, position distributions define how rays are initially placed at the source before they enter an optical system. They describe the spatial structure of the beam at the start of the simulation, which is important because all subsequent ray tracing results depend on this initial ray pattern.

In other words, the position distribution determines where rays start in space, and this directly influences the appearance of the spot diagram in the ray tracing analysis report.

General Concepts

Physically, a real light source emits energy continuously over an area. In ray-tracing simulations, this continuous optical field is approximated using a finite number of rays.

The position distribution defines how these discrete rays are placed so that they represent the continuous optical beam as accurately as possible.

In simple terms, it answers the question:

“How should rays be distributed in space to best approximate a continuous optical beam?”

The choice of distribution affects how many rays are required to obtain stable results, how uniform the spot diagram appears, and whether clusters, gaps, or regular geometric patterns become visible in the sampled beam.

The spot diagram therefore provides a convenient way to compare different position distributions and to evaluate how the result changes as the number of rays increases.

Spot diagrams

The spot diagram in the ray tracing analysis report is the main tool to visualize the effect of a position distribution. Because every ray starts from a defined spatial pattern, the final spot diagram reflects:

  1. How evenly the rays were originally spaced
  2. Whether rays appear in clusters or structured patterns
  3. Whether the sampling is random or quasi-uniform

At low ray counts, the spot diagram may exhibit clusters, gaps, or visible sampling structures that do not accurately represent the continuous beam. As the number of rays increases, the diagram becomes smoother and more representative of the physical source, although differences between distributions remain visible.

Position Distributions

All distributions in OPOSSUM share these properties:

  1. Rays originate from a source centered at the origin
  2. The source can be rotated or translated using an isometry
  3. You specify the number of rays and the source area
  4. The average spacing between rays decreases as the number of rays increases (for a fixed source area), producing smoother spot diagrams

Random Distribution

The random distribution places rays without any spatial order. Each ray position is generated independently.

In the spot diagram, this appears as an irregular cloud of points. At low ray counts, strong clustering and empty regions are visible. These patterns are not physical effects of the optical system but purely a result of stochastic sampling.

As the number of rays increases, the overall coverage improves, but local clustering and density variations remain. Random distributions therefore typically require more rays than quasi-random distributions to achieve similarly smooth results.

Fibonacci Distribution

The Fibonacci distribution places rays using a quasi-uniform sequence based on the golden ratio.

In the spot diagram, this produces a smooth and evenly filled pattern even at relatively low ray counts. There are no visible rows, rings, or clusters, and the points are distributed in a way that avoids repetition.

Compared to random sampling, Fibonacci distributions reduce clustering effects and produce a more stable representation of a continuous beam. The average distance between neighboring points remains nearly constant, resulting in highly uniform spatial coverage.

Sobol Distribution

The Sobol distribution is a low-discrepancy quasi-random sequence designed for uniform spatial coverage.

In the spot diagram, it appears more evenly distributed than random sampling, even at low ray counts. Large empty regions and strong clustering are avoided.

As the number of rays increases, the source area is filled very evenly. Because clustering is minimized, Sobol distributions often achieve smooth and stable results using fewer rays than purely random sampling.

Hexagonal Tiling

Hexagonal tiling arranges rays in a regular honeycomb structure.

In the spot diagram, this appears as a tightly packed pattern with uniform spacing. At low ray counts, the hexagonal geometry is clearly visible. As ray count increases, the pattern becomes denser and gradually appears more uniform.

This distribution provides very even spatial coverage and nearly constant spacing between neighboring rays, making it suitable for simulations where highly uniform sampling is required.

Hexapolar Distribution

Hexapolar distribution arranges rays in a radial structure centered on the source origin.

In the spot diagram, this results in concentric rings combined with angular symmetry. At low ray counts, the radial structure is clearly visible as spoke-like patterns. As ray count increases, the rings fill in and form a circularly symmetric distribution.

This makes hexapolar particularly suitable for systems with circular apertures or strong rotational symmetry. The radial organization often aligns naturally with the geometry of rotationally symmetric optical systems.

Grid Distribution

The grid distribution places rays on a regular rectangular lattice in the source plane. Rays are arranged in evenly spaced rows and columns, forming a structured Cartesian sampling pattern.

In the spot diagram, this appears as a clear grid-like pattern, especially at low ray counts. The structure remains visible even as the number of rays increases, although it becomes finer and denser.

Unlike quasi-random or random sampling methods, the grid distribution introduces a strong geometric structure into the sampling. This makes the spatial arrangement highly predictable, but it can also introduce artificial alignment effects if the optical system interacts with the grid symmetry. Because neighboring rays are equally spaced along the horizontal and vertical directions, the sampling pattern is highly predictable and reproducible.

Key Takeaways

All position distributions represent the same physical concept: approximating a continuous optical source using a finite number of rays.

The primary difference between distributions is how rays are positioned within the source area. Random distributions may contain clusters and gaps, while Sobol and Fibonacci distributions provide more uniform coverage. Hexagonal and Grid distributions introduce regular geometric structures, whereas Hexapolar distributions preserve rotational symmetry.

These differences influence the appearance of the spot diagram and determine how many rays are required to obtain smooth and stable ray-tracing results.

Energy Distribution

In OPOSSUM, the energy distribution defines how energy values are assigned to rays at the source. While the position distribution determines where rays originate, the energy distribution determines how the energy is distributed among those rays.

In a real optical beam, the energy is generally not distributed uniformly across the beam cross section. Depending on the beam profile, different regions of the beam may contain different amounts of energy. The energy distribution models this spatial variation by assigning an energy value to each ray according to its position within the source.

The following energy distributions are currently available:

  • Uniform
  • Generalized Gaussian

General Concepts

The energy distribution describes how energy varies across the source aperture. During source generation, each ray is assigned an energy value according to its position and the selected energy distribution.

The energy distribution is independent of the position distribution. The position distribution determines where rays are placed, whereas the energy distribution determines the energy assigned to those rays.

Different energy distributions therefore produce different spatial energy profiles while using the same ray positions.

Uniform Distribution

The uniform distribution assigns the same energy value to every ray, regardless of its position within the source.

Since every ray receives the same energy value, the distribution contains no spatial variation in energy across the source. This distribution is suitable when a constant energy profile across the entire source is required.

Generalized Gaussian Distribution

The generalized Gaussian distribution assigns energy values according to a two-dimensional generalized Gaussian function. The energy assigned to each ray depends on its position within the source and the selected distribution parameters.

Compared to a standard Gaussian distribution, the generalized Gaussian introduces an additional Power parameter that controls the shape of the distribution. A Power value of 1 corresponds to a standard Gaussian distribution. Increasing the Power produces super-Gaussian distributions with progressively flatter central regions and steeper edges.

The generalized Gaussian distribution is defined by the following parameters:

  • μx, μy – define the center of the distribution. Changing these values shifts the center of the distribution along the x and y directions.
  • σx, σy – define the distribution widths in the x and y directions. Larger values produce a wider distribution, while smaller values produce a narrower distribution.
  • Power – controls the shape of the distribution. A value of 1 produces a standard Gaussian distribution, while larger values produce super-Gaussian distributions.
  • θ – defines the rotation angle of the distribution. Positive values rotate the distribution counter-clockwise.
  • Shape – specifies whether the generalized Gaussian is evaluated using an elliptical or a rectangular formulation.

OPOSSUM supports both elliptical and rectangular generalized Gaussian formulations. For a Power value of 1, both formulations correspond to a standard two-dimensional Gaussian distribution. For larger Power values, the elliptical and rectangular formulations produce different generalized Gaussian profiles.

Conceptually, the generalized Gaussian distribution first evaluates the position of each ray relative to the center of the distribution. The distribution widths define how rapidly the energy decreases along the x and y directions, the Power parameter controls the overall beam profile, and the rotation angle θ changes the orientation of the distribution. The resulting value determines the relative energy assigned to each ray.

The generalized Gaussian distribution provides relative energy weights for the rays based on their spatial positions. The final energy carried by each ray depends on the selected source energy and the calculated distribution value. By changing the distribution parameters, different spatial energy profiles can be represented while keeping the same ray positions.

Fluence calculcations

Fluence

In OPOSSUM, fluence describes the spatial distribution of optical energy deposited on a detector surface. It represents energy per unit area after the optical system has transformed the incoming beam.

Since ray tracing represents light using a finite number of rays, fluence must be reconstructed from discrete energy samples. Each ray carries a portion of energy and contributes to the detector at its intersection point. The reconstruction method defines how these discrete contributions are converted into a continuous fluence map.

This step is essential because quantities such as peak fluence, beam shape, and local intensity cannot be interpreted reliably from raw ray positions alone.

Why Reconstruction is Needed

A straightforward approach is to divide the detector into a fixed grid and accumulate ray energy per cell. However, this introduces limitations. If the grid is too coarse, peak fluence is underestimated because energy is averaged over large areas. If the grid is too fine, the result becomes noisy unless a very large number of rays is used.

This creates a trade-off between spatial resolution and statistical stability. To address this, OPOSSUM provides multiple reconstruction methods that interpret the same ray data in different ways.

Binning

The binning method divides the detector into a regular grid of square cells. Each ray contributes its energy to the cell where it lands, and fluence is computed as energy divided by cell area.

This method behaves like a pixelated representation of the detector. It is simple and computationally efficient, and it guarantees energy conservation within each cell.

However, the result strongly depends on grid resolution. A coarse grid smooths out details and can hide peak fluence regions, while a fine grid requires a high number of rays to avoid noise. As a result, binning is often used for fast but lower-resolution analysis.

Voronoi

The Voronoi method divides the detector into regions based on proximity to rays. Each position on the detector belongs to the nearest ray, forming irregular cells that adapt to the spatial distribution of samples.

Each ray is treated as the center of a region that represents its local area of influence. The energy of the ray is assigned to this region.

This approach removes the dependence on a fixed grid and naturally adapts to variations in ray density. In dense regions, cells become small; in sparse regions, they become larger.

The result is more geometrically consistent than binning and better preserves local variations in the fluence distribution.

KDE (Kernel Density Estimation)

The KDE method reconstructs fluence by treating each ray as a smooth energy distribution rather than a single point. Instead of assigning energy to a single location or cell, each ray spreads its energy over a surrounding area using a smooth kernel function.

The final fluence map is obtained by summing the contributions of all rays, resulting in a continuous and smooth intensity field.

The smoothing strength is controlled by the kernel width. If the width is too small, the result becomes noisy and resembles raw sampling. If it is too large, fine spatial details are lost and peak fluence can be reduced.

To balance this, the kernel width is typically chosen based on the density of samples using established statistical rules that adapt smoothing to the number and spread of rays.

This method provides the smoothest representation of fluence and is especially useful when a continuous interpretation of the beam profile is required.

Peak Fluence and Interpretation

Peak fluence represents the maximum energy concentration on the detector surface and is one of the most important quantities in optical system analysis.

It is sensitive to both sampling density and reconstruction method. Insufficient sampling can underestimate peak values, while excessive smoothing can reduce peak intensity. Conversely, coarse binning can either exaggerate or suppress peaks depending on grid alignment and resolution.

Despite these differences, all reconstruction methods conserve total energy globally. The differences lie only in how the energy is distributed spatially.

For this reason, fluence reconstruction should always be interpreted together with ray density and system geometry.

Key Takeaways

Fluence reconstruction converts discrete ray energy into a continuous spatial representation.

Binning uses fixed grid cells and is fast but resolution-dependent.

Voronoi uses adaptive geometric regions based on proximity to rays and better reflects local structure.

KDE produces a smooth continuous distribution by spreading each ray’s energy over space.

The choice of method affects how clearly peak fluence and spatial energy distribution are represented, especially in systems with focused beams or non-uniform illumination.

Material Catalogue

The Material Catalogue provides a library for managing materials. A material can be added to the library using the green Add New Material button on the right side of the Material Catalogue. The catalogue contains the material’s name, manufacturer, description, refractive index (nd), latest version, and available actions. It also provides Search Name / Manufacturer, Min nd, and Max nd for finding and filtering materials.

n_d refers to the refractive index of an optical material measured at the yellow sodium D-line wavelength of approximately 587.56 nm.

Adding materials to the catalogue

A new material can be added to the library by pressing the green Add New Material button on the right side of the Material Catalogue. When adding a material, a name and refractive index can be provided. If no name is given, the material is assigned the default name New Material.

Each material in the catalogue has the options to Edit, Delete, and Publish New Version. Editing allows the material properties to be changed, while deleting removes the material. Publish New Version is used when changes to the properties of a material are published as a new version.

Searching and filtering materials

The Material Catalogue provides Search Name / Manufacturer for finding materials using their name or manufacturer. Materials can also be filtered using Min nd and Max nd, which specify the minimum and maximum refractive index values.

Material selection for nodes

When a node requires a material, such as a lens, the Lens Material property is available in the node properties. The material can be defined locally or selected from the Material Catalogue.

The Ad Hoc option is used when the material is required locally and should not be stored in the library. An Ad Hoc material can be used in the GUI for a single use.

The properties of a local material can be edited using the Material Editor. After the local material properties have been changed, the changes can be saved.

Another option is to replace the material with an existing catalogue material. In this case, a material can be selected from the Material Catalogue library. When a particular material is selected from the catalogue, the version of the selected material is shown. A different material can also be selected from the catalogue.

A material selected from the catalogue can also be detached from the library and converted into a local copy.

Material versions

Materials in the catalogue can have different versions. If changes are made to the properties of the first version of a material, the changes can be published as the second version.

The version information was introduced to allow optical models to refer to a specific (older) version of a material definition. This way, (community) updates to the material catalogue do not break older models. In the future there will be a mechanism to optionally update material references in optical nodes to the most up to date catalogue version.

The version that is currently being used in the GUI does not change automatically when a new version is published. The version already being used in the GUI remains unchanged unless the user intentionally changes it to the newly published version.

Asset Catalog Synchronization

The Asset Catalog Synchronization feature allows the material versions used in an Opossum model to be synchronized with the corresponding versions available in the Material Catalogue.

When a new material or a new version of an existing material is added to the catalogue, the model can be synchronized with the updated catalogue information. The synchronization functionality is available near Add New Material.

Synchronization can be performed in both directions:

  • Catalogue → Model: The material used in the model can be updated to a corresponding version available in the catalogue.
  • Model → Catalogue: The catalogue can be synchronized with the material version defined in the model.

This allows users to explicitly manage differences between the material version referenced by a model and the version available in the catalogue, rather than changing the material reference automatically when a new catalogue version is published.

Opossum also provides a shared opossum Catalog, which serves as the standard asset catalogue for Opossum.

The catalogue can be updated from the shared repository using Pull Updates from Git on the main Opossum page. This retrieves the latest catalogue updates and makes newly added materials and material versions available for synchronization with models.

Background

This project was started as a task within the THRILL project and is meanwhile also supported by further projects (e.g. LASE-FUSE); see Funding & Acknowledgments for the full list and per-project attribution. The THRILL acronym stands for Technology for High-Repetition-rate Intense Laser Laboratories and is a project funded by the European Union.

Within the THRILL project, this task (3.4) has the title “supporting calculations for system design” and is led by GSI. The task description from the proposal is as follows:

[…] To strengthen the design decisions and later benchmark the system performance, the use of theoretical modelling is of vital importance. It exists a number of simulation tools for certain aspects of the laser chain (broadband generation, nonlinear frequency conversion and amplification, laser amplification, dispersion management, wavefront propagation, calculation of parasitic lasing, etc.) distributed among the project partners (GSI, FZU/ELI-BL, HZDR, CNRS-LULI) and in the wider community. In this task, we will gather calculations with the aim to make them accessible to the partners as well as to the wider community. For this purpose a common platform for input and output formats possibly with suitable interfaces will be developed. […]

The project has a funding period of four years. The more specific goals and the project structure will be discussed in the following.

Project Goals

Before defining the project goals, let us first look at the current situation while designing laser systems.

Current Issues

As stated in the introduction, the design of complex high-energy / intensity laser systems requires a detailed simulation of optical (and of course mechanical) effects and aspects. Often, these aspects have to be simultaneously taken into account while optimizing a system design. Different aspects might even stand against each other, such that optimizing (e.g. maximizing/ minimizing) one effect degrades the performance of other system parameters. So, a holistic approach would be desirable.

In the past, many tools were developed, often addressing very particular optical effects at several companies and research institutes. Often these tools are only used at the institutions which developed the software and even there only used by one or two people (e.g. in the frame of a master or PhD thesis). This of course sometimes leads to the situation that different institutes repeat the work and “reinvent the wheel”. Hence, a common set of tools accompanied by proper knowledge exchange would significantly reduce this inefficiency.

Besides the solutions for modelling particular aspects of optical systems, there are many more general-purpose tools on the market which are unfortunately commercial, closed-source solutions. Each software has its own underlying design strategy. Furthermore, many of these tools (e.g. ZEMAX, OSLO, etc.) are designed for simulating more “traditional” optical systems such as camera objectives or illumination setups. In contrast, laser (chain) systems often demand different features which are not always fully supported (or easy to model) by these software packages.

The usage of different tools during the design phase often requires repeatedly modelling the optical system in the particular software and providing a bunch of input parameters. A common platform would allow for modelling the desired system once and analysing it with the above-mentioned tools and providing the input data in the particular format.

Goals

Based on the current situation discussed above the project tries to address the following goals:

  • Improve the knowledge exchange about already existing software to model particular aspects of optical systems.
  • Conception of a general system for describing optical systems. This concept would also be helpful as a base for open-science / open-data efforts serving as a metadata standard.
  • Development of a software platform / framework with the goal to provide clear interfaces (e.g. API or file-based) for the interoperation of the different tools.
  • (Depending on time constraints), direct implementation of modules within the above framework instead of external interfaces (e.g. geometric optics / raytracing).
  • (Depending on time constraints), development of intuitive GUI for easy modelling of optical systems.

Software architecture

This chapter discusses the overall software structure of the OPOSSUM system.

In the first version, we want to concentrate on a framework providing the necessary entities (i.e. structs and traits) in order to model optical systems as previously described. This system would simply require a main function calling the necessary structs. For better debugging purposes, we should already implement an export system to the graphviz package (dot-files) for visualization of the graph structures.

In a further step, a command line tool should be developed to accept a data file containing the model. This requires a proper serialization / deserialization system to be implemented. For this, we would propose a very well-established standard crate serde which can then read and write data in various formats such as JSON or YAML.

For future extension steps, the possibilities of modular design should be investigated in detail. This approach helps to keep the basic framework simple and might improve the integration of external code contributions. Hence, the possibilities of a plugin architecture should be considered.

How OPPUSUM works?

The OPPOSUM core library is the ‘brain’ of the system. It contains all optical functionalities and calculation tools. Depending on how you would like to proceed, there are two main ways of talking to this brain.

  1. The GUI (Graphical User Interface) frontend is designed to be more user-friendly and visual. When you click a button in the GUI, it sends the message over HTTP (Hypertext Transfer Protocol) to our backend server. The server then asks the core library to run the input data and shows you the results instantly.

The backend server is the bridge; it not only transfers the data from the GUI to the core library, but it can also be connected to large industrial machines.

  1. CLI (Command Line Interface). It is a direct door to the core library. Because the CLI works with the Rust programming language, it talks directly to the core library without needing a server in the middle.

OpticScenery

The OpticScenerystruct contains the entire model and possibly further metadata (e.g. such as a description field). It should also implement functions serialization / deserialization (which will be forwarded to the corresponding functions of the struct members) which allow for writing / reading an optical system to / from a storage medium.

In addition, it should implement the top-most function to export the graph to the graphwiz format for easy visualization. Last but not least it also contains the top-level analyze function starting the actual analysis process. The type of analysis has to be given here making use of the well-known strategy pattern.

OpticNode

Component geometry

This page follows the shape of a component from the properties a user enters to the surfaces rays are traced at. It is written for developers. The first part explains the concepts. The second part follows two components through the code from start to end, and the last part lists where to change what.

For how components are placed along the optical axis, see Model geometry. For what the optic shape means to a user, see Optic shape.

Part 1: Concepts

Defined, derived, used

The chart shows what depends on what. Its three bands separate what the user defines from what is derived from it and from what uses the result; the rest of this page explains each box.

  1. Defined by the user. What the user enters in the GUI and the .opm file stores:
    • the node properties: the node type, which acts as a preset (a lens is a singlet whose parameters are the properties of the lens), the shape (curvatures, thickness, optic shape and so on), and one surface property per face with its coating and its laser induced damage threshold (LIDT);
    • the placement: an absolute position, or an automatic one that the alignment run fills in, and the alignment (decenter, tilt);
    • the connections between ports, each with its distance.
  2. Derived. None of it is written to the file:
    • The node derives its geometry from the shape (create_geometry), stated relative to the node. It is derived again whenever it is needed, so it cannot fall out of step with the properties. It holds the numbered faces, each with its optic surface, where each face ends sideways, and, for a solid, the body of material between its faces. The body has no surfaces of its own; it is bounded by the very faces rays are traced at.
    • effective_node_iso states where the node sits and how it is turned: its position followed by its alignment.
    • Installing the geometry (install_geometry) moves it by the node’s placement: every face and every rim moves, nothing else changes. Every face then takes the coating and the LIDT of its surface property, and every port names the face it sits on. The result is the node’s runtime geometry. For a volume node, its body is the node’s medium, which holds the inversion a gain model builds in it. Unlike the geometry, the runtime geometry is kept until it is rebuilt (see When surfaces are rebuilt).
  3. Used.
    • Ray tracing and ghost focus analysis intersect rays with the faces and let the surface act on them. A node finds the face under the port the light arrives at or leaves through.
    • Gain and absorption act in the body: along the chord of each ray in a ray trace, and without rays in an energy flow analysis.
    • The alignment run traces the axis ray through the faces. Where the ray leaves a node, carried on by the distance of the connection, is the automatic position of the next node.
    • The 3D view moves the geometry to the node’s placement itself and never reads the runtime geometry.

All of it comes from one description: the surface a ray hits, the edge that decides whether it hits, and the medium a gain model acts in. They therefore cannot disagree.

Surface or solid

The first thing a geometry states is what kind of component it is:

  • A surface has no thickness: a thin mirror, a grating, a filter, a detector.
  • A solid encloses material between its faces: a lens, a wedge. There are three kinds of solid, see below.

Separate from its geometry, a node declares capabilities:

  • Volumetric: the node has a medium, with a material, absorption and possibly gain, and is drawn as a body.
  • Planar: the node is drawn as a single surface of a given kind (reflective, transmissive, detector).

The two answers go together but are not the same question. Some nodes are traced at a plane but are neither planar nor volumetric, so they are not drawn at all.

GroupNodesGeometry presetCapability
Volume componentslens, cylindric lens, wedgesinglet, cylindrical_singlet, wedge (all extruded solids)Volumetric
Surface componentsmirror, parabolic mirrorsurfacePlanar
grating, beam splitter, ideal filter, paraxial surfaceplanePlanar
energy meter, fluence detector, spectrometer, spot diagram, wavefront monitordetectorPlanar
Traced, not drawnsource, dummy, ray propagation visualizerplanenone
No shape of its owngroup, referencenonenone

Every node type has to state its geometry: the compiler forces it. Nothing ties the capability to the kind of geometry, though. A volumetric node has to describe a solid, otherwise preparing its medium fails at run time; a test checks this for every node type.

Three kinds of solid

  • Extruded. Two faces cap a profile that is extruded along an axis. The profile is the optic shape. The center thickness is not stored separately: it is where the vertex of the rear face sits, together with any tilt of that face (a wedge). Lens, cylindric lens and wedge are extruded solids.
  • Parametric solid. The intersection of the inner sides of several faces. Built from flat faces only, it is always convex: prisms, corner cubes, roof prisms. Curved faces whose inner side is their outside also allow concave shapes.
  • Assembly. Several solids (parts), each with its own placement and material, joined by interfaces. An interface is a pair of faces of different parts that lie on each other, such as the cemented surface of a doublet or the diagonal of a beam splitter cube. A part has to enclose a volume and must not be an assembly itself; this is checked when the part is created. The assembly checks its interfaces when it is created:
    • an interface joins two different parts,
    • the faces it refers to exist,
    • they are the same surface at the same place,
    • the two parts lie on opposite sides of it.

All kinds are moved the same way. Each says whether a point lies inside it, how far a ray travels through it and which side of each of its faces it lies on (the Body), and where its faces end sideways (GeometryKind::includes). No node type uses a parametric solid or an assembly so far; they are described already so that the data model is settled before the first component needs them. Two limits are stated, not hidden:

  • The bounding box of a parametric solid or an assembly is not determined yet, so a gain grid over such a medium is refused.
  • A face is the part of its surface on the sheet through its vertex, as for every component. A face that is a whole closed surface, such as a ball, cannot be traced yet.

Faces, optic shape and rim

  • A face describes one optical surface: its surface shape (plane, sphere, cylinder or parabola) and its frame. The frame sits at the vertex of the surface, its z axis along the axis of the surface, and the shape is computed in it; a sphere or a cylinder is curved around its center of curvature, one radius along z from the vertex. The faces of a geometry are numbered: an extruded solid has its front face as 0 and its rear face as 1, a surface has the one face 0, a parametric solid counts its faces in the order they are given, and an assembly counts the faces of its parts one after the other. What a face means, for instance which one light enters through, is not decided there but by the node.
  • The optic shape is the property that states how far the component reaches sideways: an outline, an edge with bores through it, in the plane perpendicular to the axis of the component. An open optic shape has no outline, and the component is unbounded.
  • A rim places the outline in space. It holds the outline and a frame: the outline lies in the xy plane of that frame and is extruded along its z axis.

An extruded solid holds exactly such a rim next to its two faces and ends there. A surface states what its rim means, its extent:

  • open: there is no rim, and the surface is unbounded;
  • edge: the component ends at the rim, so a ray outside misses it;
  • window (detectors only): all light passes, but only the light inside the rim is recorded.

A curved face has to reach the edge of its optic shape. A sphere or a cylinder ends at its radius of curvature, so a radius smaller than the largest distance of the edge from the axis is rejected when the geometry is derived. A hemisphere is still allowed.

Where a face ends

The surface of a face is unbounded: a plane reaches in every direction, a sphere closes on itself. Where the face of a component ends is a question every kind of geometry answers for itself (GeometryKind::includes):

KindA point on the surface belongs to the face if
Extruded solidit lies within the rim of the profile, measured along the z axis of the rim
Surfacethe same, if its extent is an edge. A window is no edge: the surface reaches as far as light does
Parametric solidit lies on the inner side of every other face
Assemblythe part the face belongs to says so

On a closed surface such as a sphere, the point also has to lie on the part that contains the vertex. A rim is thus one way to state an edge, the way an extrusion does. The faces of a parametric solid end at each other and need none.

Ports and surfaces

Ports belong to the graph and nothing else. Edges connect them; a port has a name and carries no optical property, no coating, no LIDT, no aperture. Ports are not written to the .opm file either: a node creates them with its geometry.

Surfaces belong to the geometry. Every face holds its optic surface:

  • the face itself, its shape at the frame of its vertex,
  • the coating and the LIDT,
  • per-surface ray caches and a hit map, which an analysis fills.

The coating and the LIDT are properties of the node, one per face and named after it (GeometryKind::face_name): surface for a single surface, front surface and rear surface for an extruded solid, surface 1, surface 2, … for a parametric solid or an assembly. Each holds a SurfaceConfig: by default an ideal antireflective coating, or a Separator of 50 % on a splitting face (see below), and an infinite LIDT. A node creates these properties when it is made (create_default_surface_properties), and every face gets its own, whether a port sits on it or not.

The node decides which port sits on which face (OpticNode::surface_ports): a list of port names, each with the number of its face. It also names the faces at which it follows both parts of the light, the transmitted and the reflected one (SurfacePorts::splitting; today only the face of a beam splitter). The surface property of such a face takes only a Separator coating, that of every other face any coating but a Separator (Validator::SurfaceCoating), so neither a file nor the node editor gives a face a coating its node is not made for. A lens puts its input port on the front face and its output port on the rear face; what is “in” and what is “out” is thus the node’s decision, not the geometry’s. A mirror or a beam splitter has one face, so all of its ports name that face, and they share its one optic surface: its coating, its caches and its hit map. A face without a port still exists and keeps its coating.

What a node keeps while it is traced is its runtime geometry: the placed geometry with the optic surfaces of its faces and, for a volume node, the body as the node’s medium with the inversion a gain model builds in it (Body::inversion). None of this is written to the .opm file; it is built again after loading. A port on a face the geometry does not have is an error that names the port, the face and the number of faces.

Surface effects

To trace rays at a surface, a node lets its runtime geometry act on them: Geometry::interact_with_rays(face, &mut rays, effect, part, missed), with the face under the port the light arrives at (OpticNodeExt::face_of_port). The component acts on the light, not the other way round. The coating of the face is built once for the whole bundle (Box<dyn Coating>), so a Separator builds its spectrum once, not per ray. For every valid ray:

  1. The geometry answers where the ray hits the face (Geometry::intersect, which returns a SurfaceHit). A ray that misses follows the missed-surface strategy.
  2. At a hit, the surface effect acts on the ray (SurfaceEffect::act_at): it moves the ray to the hit, lets it continue as the transmitted part and returns a reflected part, if any. The effect calls the physics of a single ray, which needs nothing geometric any more.
  3. The effect acts on the helper rays of the ray as well, each where it hits the face; a helper ray that misses follows the missed-surface strategy like any ray.
  4. Once every ray is answered, the optic surface of the face records the hits in its hit map.

What a surface does is one effect per kind of surface. Each lives next to the type that defines it, so a new one does not touch the loop:

EffectWhereAt a hit
Refractioncore_optics/surface_effect.rsSnell’s law into the index behind the surface; the coating splits off a reflected part (Ray::refract_at). Without an index the surface is passive and keeps each ray’s direction
SplittingConfigcoatings/separator.rsa passive refraction with the reflectivity 1 − T(λ) of the splitting configuration instead of the surface’s coating; only the positioning of a beam splitter uses it, for a neutral 50:50 split
FilterTypenodes/ideal_filter/filter_types/mod.rsa passive refraction, then the attenuation by the transmission (Ray::filter_energy)
ParaxialLensnodes/paraxial_surface.rsa passive refraction, then the deflection of an ideal thin lens (Ray::refract_paraxial)
Diffractionnodes/reflective_grating.rsthe grating equation for one order (Ray::diffract_at); the whole energy goes into the order, and no hit is recorded

At every surface the light is split into a transmitted and a reflected part. Which of them is the intended beam is bookkeeping of the node, not physics; the node states it as a ReflectedPart:

ReflectedPartUsed byThe reflected part
Ghostlens, filter, detectorsis a ghost reflection: it branches off the bundle and starts a position history of its own
Mainmirror, parabolic mirror, gratingis the intended beam: it continues the bundle, and the bounce does not count as a ghost
Branchbeam splitteris a second intended beam: a bundle of its own, and both parts keep their position history

Geometry::propagate_rays does the same for all bundles of an analysis. After each bundle it lets the analyzer act at the surface (PropagationStrategy::on_surface_interaction, for instance the ghost-focus cache), and it appends the ghost reflections cached at the surface for the current direction.

Surfaces in the sequential trace

The analyzers trace the graph node by node. The analysis of a node receives the light per input port and addresses surfaces by port name; the node’s surface ports say which face lies under the port. A lens traces its rays in through the front face under its input port and out through the rear face under its output port.

Inverting a node rebuilds nothing; ghost focus analysis does this on every second pass. The ports of the node swap inputs and outputs, so the same lookup returns the rear face first. The geometry stays as it physically is; only the direction light takes through it changes. A single surface is the same surface in both directions, so light passing it forward and backward is recorded in its one hit map.

Whether a ray hits a component is decided in exactly one place, by the geometry (GeometryKind::includes). It is asked when a ray is traced at a face (Geometry::intersect) and when the body of a volume node measures how far a ray travels through it. The point has to meet two conditions:

  • the face reaches there (see Where a face ends); for a lens, the point lies within the rim, measured along the z axis of the rim;
  • on a closed surface such as a sphere, it lies on the part that contains the vertex. A ray that reaches a sphere only behind its equator misses.

What happens to a ray that misses is decided by the analyzer’s missed-surface strategy, not by the surface:

  • Stop: the ray is lost.
  • Ignore: the ray passes unchanged.

The alignment run always uses Stop.

When surfaces are rebuilt

Surfaces are never moved one by one. A rebuild installs a new runtime geometry: the geometry derived anew and moved to the node’s current placement as a whole, every face with the coating and the LIDT of its surface property, the ports set from the node’s surface ports, and an empty inversion. It replaces the runtime geometry installed before, with everything an analysis left on it; caches and hit maps are not carried over. No rebuild falls between an analysis writing them and the report reading them: every analysis clears them after the alignment run, and nothing is rebuilt while it traces. Since the medium is the body of the geometry, it is rebuilt with it; the inversion stays empty until the medium is prepared for an analysis.

EventRebuilds the surfaces
Creating a node (Default, new)yes
Loading an .opm fileyes
Placing the node (alignment run, absolute position)yes
Changing the alignment (decenter, tilt)yes
Changing the coating or LIDT of a surface through set_coating or set_lidtyes
Start of a ray-trace or ghost-focus analysisyes, for every node
Preparing the medium of a volume nodeyes
Changing any other property (curvature, thickness, optic shape, a surface property in the GUI, …)no
Inverting a nodeno, nothing to rebuild

A property change does not rebuild anything. For that reason, every analysis that traces rays first rebuilds all surfaces. The 3D view does not depend on the rebuilt surfaces at all: it moves the geometry to the node’s current placement itself.

Part 2: In the code

All paths are relative to opossum_core/src unless stated otherwise.

The types

TypeFileRole
Geometrygeometry/node_geometry.rsthe geometry of a component with the optic surface of every face, one variant per kind: Surface, Extruded, Parametric, Assembly. Geometry::kind is the one place that tells the kinds apart; Geometry::intersect answers where a ray hits a face; interact_with_rays and propagate_rays let the surface of a face act on rays; move_by moves it
SurfaceHitgeometry/node_geometry.rswhere a ray hits a face: the point, in the frame of the geometry and in that of the face, the normal, and whether a detector records it
GeometryKindgeometry/node_geometry.rswhat every kind answers: the optic surfaces of its numbered faces (surface, surface_mut), the names of its faces (face_name), where they end (includes), the window of a detector, its body (as_body, as_body_mut) and how it moves (move_by). It has no default methods, so a new kind has to answer every question
FaceIndexgeometry/face.rsthe number of a face in its geometry
SurfaceGeometry, SurfaceExtentgeometry/node_geometry.rsa single surface: one face, and whether it is open, ends at an edge or records within a window
Extrudedgeometry/solid/extruded.rstwo faces capping a profile; holds a Rim
ParametricSolid, Sidegeometry/solid/parametric.rs, geometry/solid/mod.rsthe intersection of the inner sides of several faces
Assembly, Part, Interface, FaceIdgeometry/solid/assembly.rsseveral solids sharing interfaces
Facegeometry/face.rsone surface: its shape at the frame of its vertex. Intersects rays, tells which side of it a point lies on, moves
SurfaceShape, GeoSurface, Plane, Sphere, Cylinder, Parabolageometry/surface/the shape of a surface and its math in the vertex frame; SurfaceShape::as_geo_surface hands out the math
Rimgeometry/rim.rsan outline at a frame: whether a point lies within it, whether a face reaches a point
Body, BoundingBoxgeometry/body/mod.rswhat a volume answers: is a point inside, how far a ray travels in it, which box encloses it, which side of a face it lies on, and the inversion a gain model built in it (inversion, inversion_mut). Each kind of solid implements it next to its definition
OpticShape, Outline, Boreapertures/optic_shape.rsvalue of the optic shape property; the outline says whether a point lies within it
OpticSurfacecore_optics/optic_surface.rsthe surface of one face: the face, coating, LIDT, caches and hit map
SurfaceConfigcore_optics/surface_config.rsvalue of a surface property: the coating and the LIDT of one face
NodeAttrcore_optics/node_attr.rskeeps the runtime geometry (runtime_geometry, set_runtime_geometry), #[serde(skip)]
SurfaceEffect, Refractioncore_optics/surface_effect.rswhat a surface does to a ray at a hit; the other effects live next to their nodes (see Surface effects)
ReflectedPartlight/rays.rswhich part of a split is the intended beam: the position history, bounce counter and bundle identity of both parts
OpticPortscore_optics/optic_ports.rsthe names of the input and output ports, graph logic only
SurfacePortscore_optics/optic_ports.rsthe ports a node declares, each with the face it sits on, and its splitting faces (OpticNode::surface_ports); face_of looks one up
Volumetric, Planarcore_optics/volumetric.rs, core_optics/planar.rsthe capabilities

Example 1: a plano-convex lens

The setup is a source, then a lens 100 mm further on:

  • front curvature 50 mm,
  • rear curvature infinite (flat),
  • center thickness 5 mm,
  • the default optic shape, a circle of 12.5 mm radius.

Light runs along +z.

Step 1: describe.

  1. Lens::create_geometry (nodes/lens/mod.rs) reads the three properties.
  2. It asks OpticNodeExt::cross_section (core_optics/optic_node_ext.rs) for the outline of the optic shape. An open optic shape has none, and Lens::create_geometry refuses it, since the medium would be unbounded.
  3. It returns Geometry::singlet(50 mm, ∞, 5 mm, circle).

Geometry::singlet hands this on to Geometry::two_faced as:

  • front shape SurfaceShape::spherical(50 mm), which is a Sphere,
  • rear shape spherical(∞), which is a Plane,
  • the rear vertex Isometry::new_along_z(5 mm).

two_faced builds Extruded::new(axis = identity, front = Face(Sphere, identity), rear = Face(Plane, z = 5 mm), circle) and returns it as Geometry::Extruded.

Extruded::new checks the reach of both faces: the circle reaches 12.5 mm from the axis, and the sphere reaches 50 mm. A front curvature of 10 mm would be refused with “the front face does not reach the edge of its optic shape, 12.500 mm from the axis: its radius of curvature is smaller”. It then moves both faces by the axis, gives the rim the axis as its frame and wraps each face in an optic surface with the default coating and LIDT; for a lens the axis is the identity.

Step 2: place. RayTracingAnalyzer::analyze (analyzers/raytrace.rs) first calls NodeGroup::rebuild_surfaces. It then calls calc_node_positions with RayTraceConfig::for_positioning. For the lens, OpticGraph::set_node_isometry (nodes/node_group/optic_graph/analysis.rs) does the following:

  1. It propagates the axis ray by the 100 mm of the connection.
  2. It turns the ray into a frame, world_frame.
  3. It computes node_iso = world_frame ∘ entrance_frame⁻¹. The entrance frame (AnalysisRayTrace::axis_entrance_frame) is the identity for every node except the second input of a beam splitter. Here node_iso is therefore a translation by (0, 0, 100 mm).
  4. It stores the result through OpticNode::set_positioning(NodePositioning::Automatic(..)), which calls update_surfaces.

The origin of the node, its anchor point, is the vertex of the front face.

Step 3: build. Lens::surface_ports returns SurfacePorts::THROUGH_SOLID: input_1 on Extruded::FRONT and output_1 on Extruded::REAR. OpticNode::update_surfaces, the same for every node, hands these ports to OpticNodeExt::install_geometry (core_optics/optic_node_ext.rs), which does the following:

  1. placed_geometry calls create_geometry again, so it works from the properties as they are now, and moves the result by effective_node_iso(), the position followed by the alignment, or the identity for a node that has not been placed. Geometry::move_by(&node_iso) moves every face and the rim: each frame becomes node_iso ∘ frame.
  2. For every port it checks that the geometry has its face; a face it does not have is an error. The node’s ports are set from these port names.
  3. Every face takes the coating and the LIDT of its surface property: face 0 those of front surface, face 1 those of rear surface.
  4. NodeAttr::set_runtime_geometry keeps the result, with an empty inversion. Since the geometry encloses a volume (GeometryKind::as_body), it is the medium of the lens too; a single surface would leave the node without one.
Faceframe in the geometryframe at the node
0, front, sphere R = 50 mmidentity(0, 0, 100 mm)
1, rear, planez = 5 mm(0, 0, 105 mm)

The frame of a face sits at its vertex for every shape; the sphere computes around its center of curvature, (0, 0, 50 mm) in its own frame.

The runtime geometry of the lens then holds:

face 0, front  = OpticSurface { Sphere with its vertex at z = 100 mm, coating + LIDT of "front surface" }
face 1, rear   = OpticSurface { Plane at z = 105 mm, coating + LIDT of "rear surface" }
rim            = the circle, at z = 100 mm
inversion      = none
ports          = input_1 → face 0, output_1 → face 1

The rim was moved together with the faces, so asking where a face ends needs no recomputation.

Step 4: the medium. After the alignment run the analyzer calls reset_data and then OpticNode::prepare_volume. For a volume node, prepare_volume does the following:

  1. It calls update_surfaces once more, which rebuilds the surfaces and the medium as in Step 3.
  2. If the gain model reads an inversion, it builds one and stores it in the body of the medium (Extraction::build_inversion, Body::inversion_mut).

The body is the extruded solid of the placed geometry from Step 3, with the frame of its rim, node_iso ∘ axis. It is bounded by the very faces light is traced at: its front face is face 0 under input_1, the sphere, its rear face face 1 under output_1, the plane. It knows no port names.

Step 5: trace. OpticGraph::analyze_raytrace (nodes/node_group/optic_graph/raytrace.rs) walks the graph and hands each node the light that arrives at its ports. Lens::analyze (nodes/lens/analysis_raytrace.rs) calls Volumetric::unified_analyze_volume_node, which does two things:

  1. single_io_port_names(self) returns ("input_1", "output_1"). It takes them from self.ports(), which accounts for inversion.
  2. Volumetric::pass_through_volume_generic("input_1", "output_1", ..) runs three steps:
    1. pass_through_surface_generic("input_1", &Refraction(Some(index of the material)), .., ReflectedPart::Ghost) finds the face under input_1 (face_of_port, face 0), lets the runtime geometry of the lens act on the bundles and follows this chain: Geometry::propagate_rays → Geometry::interact_with_rays → Geometry::intersect(face 0, ray) → Refraction::act_at → Ray::refract_at(&hit, coating, n).
    2. propagate_inside_medium applies gain and absorption along the chord through the body of the medium. It does not move the rays.
    3. pass_through_surface_generic("output_1", &Refraction(Some(ambient index)), ..) runs the same chain at face 1, the rear plane.

Geometry::intersect (geometry/node_geometry.rs) decides between hit and miss:

  1. Face::intersect turns the ray into the vertex frame of the face, intersects it with the unbounded surface (GeoSurface::calc_intersect_and_normal) and turns the result back.
  2. The point counts only if the geometry says its face reaches there: GeometryKind::includes(face, point). For the lens this is Rim::bounds: Rim::contains(point) and Face::is_on_vertex_sheet(point) both hold.
  3. The SurfaceHit carries the point, the normal, the point in the frame of the face (for the hit map and the phase of a grating) and whether it is recorded, which only the window of a detector denies.

Ray::refract_at then needs nothing geometric any more: it applies Snell’s law and the coating, adds the path length and leaves a hit point in the frame of the face. Body::path_length_inside of the extruded solid asks the same includes when it measures the chord through the body.

A ray parallel to the axis at y = 13 mm meets the sphere, but outside the 12.5 mm circle, so it misses. With Stop, Geometry::interact_with_rays invalidates it (MissedSurfaceStrategy::apply_to); with Ignore, it stays unchanged. Nothing else acts on a ray that misses: whatever a surface does happens in its effect, at the hit.

Variations.

  • Inverted lens. On every second ghost-focus pass the whole scenery is inverted. Nothing is rebuilt:
    • ports() swaps, so single_io_port_names returns ("output_1", "input_1").
    • pass_through_volume_generic passes backward = self.inverted(), and the rear plane is traced first.
    • The body stays the same.
  • Changed property. After set_property("center thickness", ..) the description changes at once. The runtime surfaces, and the medium with them, stay stale until the next rebuild: at the start of an analysis, or through an explicit update_surfaces. Whatever builds the shape from create_geometry() directly, such as the 3D view, is always current.

Example 2: a flat mirror tilted by 45°

The setup is a source, then a thin mirror 100 mm further on:

  • curvature infinite (flat),
  • the default optic shape,
  • an alignment tilt of 45° about x, which turns the beam by 90°.

Describe. ThinMirror::create_geometry (nodes/thin_mirror.rs) returns Geometry::surface(identity, SurfaceShape::spherical(∞), identity, Some(circle)). The shape spherical(∞) is a Plane, and the result is a SurfaceGeometry with the face Face(Plane, identity) and the extent Edge(Rim(circle, identity)). Its reach check always passes, since a plane reaches any edge.

Place and build.

  1. The mirror is placed as in the lens example, at a translation by (0, 0, 100 mm).
  2. effective_node_iso is that position followed by the alignment: the translation, then 45° about x.
  3. ThinMirror::surface_ports returns SurfacePorts::SINGLE_SURFACE: input_1 and output_1, both on face 0 (SurfaceGeometry::FACE), and install_geometry installs the geometry as in the lens example.
  4. A surface has its one face, so both ports share its one optic surface. A surface encloses no volume, so the mirror gets no medium.
  5. ThinMirror::default gives its surface a 100 % ConstantR coating through set_coating(SurfaceGeometry::FACE, ..), which rebuilds as well.

Trace. ThinMirror::analyze (the AnalysisRayTrace implementation in nodes/thin_mirror.rs) uses neither the volume helper nor the single-surface helper:

  1. It takes the first input and output names from self.ports().
  2. It calls interact_with_rays(face, &mut rays, &Refraction(None), ReflectedPart::Main, missed strategy) on its runtime geometry directly, with the face under its input port (face_of_port): a passive surface whose reflected part is the intended beam.
  3. It emits only the reflected bundle at the output port. Outside the alignment run it first drops rays below the energy threshold.

A ray that misses the mirror is lost in every analysis, because only reflected light leaves it. In the alignment run the next node is placed along the reflected axis. If the axis misses the mirror, the run stops with an error that names the mirror.

Draw. The 3D view (for_each_drawable in opossum_backend/src/scene_export.rs) asks each node as_volume and as_surface and moves the node’s geometry to its current placement itself (Geometry::move_by):

  • For the mirror, Planar::surface_mesh (core_optics/planar.rs) meshes its face within the rim.
  • A volume node is drawn from the faces and the rim of its solid.

Neither reads the runtime surfaces, so a property that was changed without a rebuild is drawn as it is now. The endpoint for a single component (opossum_backend/src/document.rs) therefore meshes the node without rebuilding it.

Other components

NodeWhat differs
Parabolic mirrorGeometry::surface with an axis other than the identity. The node sits where the chief ray hits the mirror. calc_off_axis_frames returns two frames: the frame of the parent parabola’s axis through the node, in which the optic shape is measured, and the vertex of the parent parabola, stated in that frame.
Beam splitterOne plane, face 0, under four port names: its surface ports put input_1 and input_2 and the outputs out1_trans1_refl2 and out2_trans2_refl1 all on SurfaceGeometry::FACE, so all four share the one optic surface, and declare that face splitting, so its surface takes only a Separator. Its analysis addresses the ports by name itself and splits with Refraction(None) and ReflectedPart::Branch, so the coating of its surface is the split (by default a Separator of 50 %). Its positioning splits the axis with SplittingConfig::Ratio(0.5) as the effect, whatever the coating. The second input enters mirrored on the plane (axis_entrance_frame).
DetectorsGeometry::detector gives the extent window. A window is no edge: the face reaches everywhere, so all light passes. SurfaceHit::recorded decides which hit points are recorded, and record_within_window cuts the recorded light to the window of the geometry. With an open optic shape there is no window, and everything is recorded.
Ideal filter, paraxial surfaceGeometry::plane. Their effects (FilterType, ParaxialLens) attenuate or deflect at the hit, so a ray or helper ray that misses is neither. The paraxial surface may be unbounded.
GratingGeometry::plane. Its effect, Diffraction, sends the whole energy into one order, and the diffracted part is the intended beam (ReflectedPart::Main), like the reflection of a mirror.
Source, dummy, ray propagation visualizerGeometry::plane. Source and visualizer are unbounded. A dummy is bounded only if it is given an optic shape, and then acts as an iris. None of them is planar, so none is drawn. A source declares only output_1.
Group, referencecreate_geometry() returns None, the surface ports are SurfacePorts::NONE, and update_surfaces does nothing. The nodes inside a group have their own geometry. A reference is traced through the node it refers to.

One analysis run, in order

A ray-tracing analysis (RayTracingAnalyzer::analyze) runs these steps:

  1. NodeGroup::rebuild_surfaces calls update_surfaces on every node, recursing into groups, so the trace sees the properties as they are now.
  2. calc_node_positions runs with RayTraceConfig::for_positioning:
    • the missed-surface strategy is fixed to Stop;
    • positioning_run is true, so there is no energy threshold and no medium;
    • every node that gets placed rebuilds its surfaces through set_positioning;
    • if the axis ray leaves a node invalid and the node has successors, the run stops with an error naming the node.
  3. reset_data clears light data, the caches and hit maps of the optic surfaces, and the inversion.
  4. prepare_volume makes the volume nodes rebuild their surfaces and media, and builds the inversion where the gain model needs one (see Example 1, Step 4).
  5. AnalysisRayTrace::analyze performs the trace itself.

A ghost-focus analysis (GhostFocusAnalyzer::analyze, analyzers/ghostfocus/analyzer.rs) runs the same first four steps. Its alignment run uses AnalyzerType::positioning_config: a plain ray-trace configuration with the analysis’s sources. Then the bounce passes follow:

  • Even passes run forward.
  • Odd passes run with the scenery inverted. OpticGraph::analyze_ghostfocus then reverses the graph for the pass through an InvertGraphGuard. Surfaces are not rebuilt.
  • A ghost reflected in one pass is cached on the optic surface it came from and re-enters at that surface in the next pass.

Part 3: Where to change what

  • A new node type.
    • Implement OpticNode::create_geometry with a preset. The method has no default, so the compiler forces an answer; None is the answer for a node without a shape of its own.
    • Implement OpticNode::surface_ports: the port names of the node, each with the number of the face it sits on, and the faces at which the node follows both parts of the light (splitting, usually none). SurfacePorts::SINGLE_SURFACE and SurfacePorts::THROUGH_SOLID cover the usual cases.
    • In Default, declare the OPTIC_SHAPE property and the properties the geometry is derived from, then call create_default_surface_properties before anything installs the surfaces (update_surfaces, set_positioning, set_coating), as ThinMirror::default does.
    • Declare the capability: Volumetric and as_volume for a solid with a material, or Planar, as_surface and surface_kind for a surface that is drawn.
  • A new preset, such as another kind of lens: add a constructor on Geometry next to singlet that builds an Extruded or a SurfaceGeometry. Nothing downstream changes.
  • A new effect at a surface. Implement SurfaceEffect next to the type that defines it, as the filter and the grating do, and pass it to interact_with_rays or pass_through_surface_generic. The trait has no default methods, and the loop in Geometry::interact_with_rays stays as it is.
  • A new surface shape.
    • Add a type for it in a file of its own in geometry/surface/, like Sphere, and implement GeoSurface for it in its vertex frame. Its local_z_at has to describe the sheet through the vertex: is_on_vertex_sheet, and with it every hit test, is derived from it.
    • Add a variant to SurfaceShape in geometry/surface/mod.rs. The compiler then points at as_geo_surface, matches and depends_on_roll.
  • A node made of a parametric solid or an assembly. Geometry::move_by, GeometryKind, Body and install_geometry accept every kind. A node only has to return such a geometry from create_geometry() and name the face of each port in its surface ports; an assembly numbers the faces of its parts one after the other. The limits are listed under Three kinds of solid: no bounding box for a parametric solid or an assembly yet, and no face that is a whole closed surface.
  • A new kind of solid. Add a file in geometry/solid/ with the type, holding an OpticSurface per face, and its implementations of GeometryKind and Body, a variant in Geometry, and its arms in Geometry::kind and Geometry::kind_mut. Nothing else changes.
  • Where a face ends. To change how a kind decides it, change its implementation of GeometryKind::includes. Surfaces, the body and the analyzers ask nothing else.
  • Who reads what.
    • Read the geometry directly: install_geometry and the 3D view.
    • Read the runtime geometry, its surfaces and its medium: all analyzers and OpticNodeExt::effective_surface_iso, the frame of the face under a port in the runtime geometry (used by the paraxial surface, the grating, the source, the spot diagram and the wavefront monitor).
    • install_geometry is the only place that installs a runtime geometry; the surfaces and the medium are part of it.
    • The coating and the LIDT of a face are read from its surface property only when the geometry is installed.

Optic Analyzer Ideas

Sequential analyzers

The analyzer is also responsible for deciding which nodes in a graph must be calculated at all. Sometimes the user is only interested in a part of the optical network and in this case, often not all nodes need to be calculated at all. Furthermore, modifications of the model often do not need a complete recalculation of the graph but use results from earlier simulation runs. Finally, the analyzer could also decide, which nodes do not directly depend on each other. In this case, nodes can be calculated in parallel thus saving time on multi-core CPU computers.

There might be different analyzers available such as:

  • geometric analysis (Matrix optics)
  • Gauss mode propagation (also matrix based, see LaserCalc)
  • wavefront propagation (Fourier optics)
  • simple calculation of energy / power
  • ghost focus / back reflection analysis
  • …

Sequential Analyzer

Note: Also in this case the model might contain inconsistent values such as a wavefront that does not fit the set of rays defined. How do we deal with this?

Non-sequential Analyzer

A non-sequential analyzer does not make use of the edges for traversing the node network. This is the case for performing a free 3D raytracing analysis of an optical setup located in 3D space. Hence, for using this analyzer all nodes must have information of their location and orientation set by the respective attributes. Otherwise, these nodes are simply skipped in the simulation. One or more light source nodes are used to cast light rays into the scene. Detectors on the other hand can collect all incoming rays for further analysis. For ray casting, each node has to have a 3D mechanical representation and a (maybe default) surface definition.

Existing Software

The following software already exists in the field of optical simulation and should be considered while designing the model concept.

Free / Open Source

SoftwareInstituteContact personLanguagecomment
HASEonGPUHZDRDaniel AlbachC/C++parasitic lasing in high-power laser amplifiers
SHGGSIMarcus MalkiPythonsecond harmonic generation
SNLOfree-Binary (APL or matlab)three-wave mixing
LightPipesfreeLeonard DoylePython / C++Beam propagation Toolbox
SisyphosFFI (Norway)Gunnar ArisholmPython / Cparametric amplifiers, spectral broadening, postcompression
GoLPGoncalo Figuera?spatio-temporal coupling
LULI?
Rochester?

Commercial

SoftwareInstituteContact personLanguagecomment
GLADHZDRMathias SieboldMatlabuniversal modelling of laser amplifier chains
ZEMAXcommercialUdo EisenbarthBinarygeneral geometric optics simulation
Commod ProcommercialD. KramerBinaryuniversal modelling of laser amplifier chains
MiroLULI-universal modelling of laser amplifier chains

Project plan

Funding & Acknowledgments

OPOSSUM is developed as open-source research software and is financed through several externally funded projects. This page documents which project funds which part of the work, so that funders and third parties can trace individual contributions. Contributions are also attributed per person (with ORCID) in the CITATION.cff file at the repository root, which powers GitHub’s “Cite this repository” button.

Funding sources

THRILLLASE-FUSE
Full nameTechnology for High-Repetition-rate Intense Laser LaboratoriesLAser Simulation for Enhanced FUSion Efficiency
FunderEuropean UnionGerman Federal Ministry of Research, Technology and Space (BMFTR)
Grant / funding referencegrant agreement No 101095207funding reference 13F1041
Duration4 years (Task 3.4, led by GSI)5 years
GroupGSI (Plasma physics group / PHELIX)GSI Plasma physics group / LASE-FUSE
Work during funding periodProject start; core graph model and ray-tracing capabilitiesGraphical User Interface, amplification modeling, material catalogue

The GitHub Milestones group the tracked work; the “Work during funding period” row links each funding source to the milestones and features it financed, making a group’s contribution concretely traceable.

THRILL

OPOSSUM was started as a task within the THRILL project, a project funded by the European Union. Within THRILL, this task (3.4) has the title “supporting calculations for system design” and is led by GSI. The task description from the proposal reads:

[…] To strengthen the design decisions and later benchmark the system performance, the use of theoretical modelling is of vital importance. It exists a number of simulation tools for certain aspects of the laser chain (broadband generation, nonlinear frequency conversion and amplification, laser amplification, dispersion management, wavefront propagation, calculation of parasitic lasing, etc.) distributed among the project partners (GSI, FZU/ELI-BL, HZDR, CNRS-LULI) and in the wider community. In this task, we will gather calculations with the aim to make them accessible to the partners as well as to the wider community. For this purpose a common platform for input and output formats possibly with suitable interfaces will be developed. […]

Acknowledgment statement:

This project has received funding from the European Union under grant agreement No 101095207.

LASE-FUSE

Continued development is supported by LASE-FUSE (LAser Simulation for Enhanced FUSion Efficiency), funded by the German Federal Ministry of Research, Technology and Space (BMFTR) and carried out by the GSI Plasma physics group by Yannik Zobus.

Acknowledgment statement:

This work is supported by the German Federal Ministry of Research, Technology and Space (BMFTR) within the LASE-FUSE project (funding reference 13F1041).

How to cite

If you use OPOSSUM, please cite it using the metadata in CITATION.cff (GitHub’s “Cite this repository” button exports BibTeX/APA automatically), and acknowledge the funding sources above where appropriate.

Model Geometry

When modeling an optical system, the precise location and alignment of optical nodes in 3D space are critical. This section illustrates how OPOSSUM handles geometry.

General Concept

In contrast to other optical design software, OPOSSUM aims for a geometry model that is simple and covers 95% of typical situations encountered in a laser laboratory, while still making the remaining 5% possible to model.

In daily practice, the relative position of optical components to one another is often more important than their absolute global coordinates. Therefore, OPOSSUM simplifies system modeling by allowing you to define the geometric distance between components along the optical axis.

The Optical Axis

Many optical design tools avoid the concept of an “optical axis” because, physically, no single ray path should be treated differently from others. OPOSSUM respects this: during the actual simulation run, all rays are treated equally.

However, before the simulation begins, OPOSSUM performs a Component Alignment step. It is during this layout phase that the concept of an optical axis becomes extremely useful.

Strictly speaking, there is no single, stringent definition of an optical axis—especially for non-rotationally symmetric components, where it can be a matter of definition. Nevertheless, this concept works exceptionally well for most standard setups.

Component Placement

Although relative positioning is key, every system needs a defined starting point. By default, the Sourceport node is placed at the global coordinate origin (0, 0, 0). All subsequent nodes are placed relative to this point.

During the component alignment run, OPOSSUM traces a reference ray along the optical axis. By default, this starts at the center of the Sourceport and propagates (usually along the Z-axis) by the distance specified in the connection to the next node.

Consider the following diagram:

In this example:

  • The Source port is placed at (0mm, 0mm, 0mm).
  • The Lens is placed at (0mm, 0mm, 100mm).

Crucially, the optical axis follows physical laws regarding reflection and refraction. For example, if we place a mirror in the beamline:

The situation is as follows:

  1. The Source port is at (0mm, 0mm, 0mm).
  2. The Mirror is placed at (0mm, 0mm, 100mm).

By default, a mirror node has an alignment of 0°. This means the light (and thus the optical axis) is reflected directly back towards the source. If a lens is connected after the mirror with a distance of 100 mm, it is placed along this reflected optical axis. Consequently, the lens would land back at (0mm, 0mm, 0mm), facing the opposite direction.

To model a 90° beam deflection, the mirror must be rotated. This is done in the Node Editor panel under the Alignment section. For a 90° turn, set the Roll Angle (rotation around the X-axis) to 45°.

With this setting, the components are placed as follows:

ComponentPosition
Source(0mm, 0mm, 0mm)
Mirror(0mm, 0mm, 100mm)
Lens(0mm, 100mm, 100mm)

Anchor point

We have just discussed how a component is placed at a certain position. This description is actually a bit unprecise since an optical component is not a point-like object but has a finite size. Hence we clarify here that each optical component has an anchor point which is normally the center of the incoming surface. This is described in the reference section for each particular node type. In the above mentioned Alignment setting the component is turned around this point. Furthermore, a component can be shifted (e.g. for modeling a shifted lens) along all axes. How a component’s surfaces are built around its anchor point is described in Component geometry.

Absolute Placement

While OPOSSUM primarily uses relative positioning, certain scenarios require placing a component at a specific coordinate in the global system. This is achieved using the Position property of an optical node.

Consider the following example:

In this model:

  1. The Sourceport is at the origin (0, 0, 0) by default.
  2. The Lens has its Position property set to absolute with explicit coordinates (0mm, 0mm, 200mm).

Behavior: When a component is set to absolute, OPOSSUM places it at the defined coordinates and skips the relative positioning calculation for that specific node.

Important Caveat: When using absolute placement, the distance value specified in the connection before the component is completely ignored.

Pitfalls of Relative Positioning

While relative positioning is convenient, it can lead to geometric inconsistencies in complex setups. Below are common edge cases to watch for.

Beam Combiners and Parallel Paths

Issues often arise when combining parallel beam paths of unequal lengths, such as in a Mach-Zehnder interferometer setup.

The Scenario:

  • The beam splits into two arms.
  • Arm 1 (Straight): Total distance to the combiner is 100 mm.
  • Arm 2 (Lower): Due to the additional component, the total distance is 200 mm.

The Conflict: OPOSSUM must decide where to place the Beam Combiner in 3D space. The logic is as follows:

  1. Placement: The Beam Combiner is placed from the beam reaching its first input (input_1) — deterministically, independently of the order in which the two arms happen to be traced. Here that puts it at the end of the 100 mm Arm 1.
  2. Consistency check: The axis reaching the second input (input_2) is then checked against that placement. Since Arm 2 is 200 mm long, its beam does not meet the Combiner where Arm 1 placed it.

Result: OPOSSUM keeps the placement from input_1 and issues a warning. The warning does more than flag the problem: it reports how far the second beam is off (in direction, in distance along the axis, and as a sideways miss), the connection length that would remove the along-axis error, and the exact position and direction the second arm would need at its predecessor to be consistent. Use it to correct the offending connection distance or alignment; you must verify warnings in split-path setups.

Two Sources on One Combiner

A beam combiner can also be fed by two independent sources rather than by two arms of one split beam. Every source is placed at the global origin by default, so two sources both start at (0, 0, 0) — which is almost never what a real two-arm setup looks like, and the combiner’s consistency check (above) will warn.

To resolve this, give the second source an absolute position: in the Node Editor, set its Position property to absolute (see Absolute Placement). You do not have to work out the pose by hand — the combiner’s warning prints the exact start point and direction the input_2 beam needs; enter those as the second source’s absolute position and orientation. The first source stays at the origin as the anchor of the system.

Misaligned Absolute Components

Care must be taken when mixing absolute positioning with the optical axis logic.

The Scenario:

  • The Sourceport emits along the Z-axis.
  • An absolute Lens is placed at (0mm, 100mm, 100mm)—offset by 100mm in the Y-direction.

The Consequence: The reference ray (optical axis) travels straight from the source. Because the lens is physically located outside this path, the ray misses the lens entirely.

  • The optical axis is “lost” at this point.
  • The downstream components (e.g., the Energy meter) cannot be placed, so OPOSSUM stops the alignment with an error naming the lens. A component at the end of a path, without successors, is only warned about.

The same happens if the axis reaches a component but passes it outside its optic shape, e.g. a lens decentered by more than its radius or a double pass whose return path walks off. Enlarge the optic shape (see Optic shape) or correct the position. If the axis misses the window of a detector, OPOSSUM only warns that the measurement may fail.

Multi-pass and Reference Nodes

Reference nodes are used to represent a component that already exists elsewhere in the model (common in multi-pass amplifiers or ring cavities).

Behavior:

  1. Original Node: During the positioning run, the “real” node is placed normally.
  2. Reference Node: When the reference node is encountered, OPOSSUM attempts to route the beam back to the location of the “real” node.
  3. Conflict Check: Similar to the Beam Combiner scenario, if the calculated optical path does not align perfectly with the “real” node’s existing position, the placement fails, and a warning is issued.

Tutorial

The following pages describe the

Further in-depth documentation can be found at

  • the general concepts section
  • the reference section for detailed information about specific optical nodes or analyzer modes.

Installation

There are two ways to install OPOSSUM: using the pre-built binary packages (recommended for most users) or building it from the source code.

For the easiest installation, download the latest installer for your operating system from our GitHub releases page:

Run the installer following the standard procedure for your operating system.

Recommendation: To utilize the full potential of OPOSSUM, we strongly recommend installing Graphviz.

This tool is used to generate graphical representations of the optical graph model. OPOSSUM is fully functional without it, but analysis reports will not include diagrams.

2. Build from Source

To build OPOSSUM, you must have the Rust programming language installed. If you have not installed Rust yet, please follow the instructions on the official Rust installation page.

If you build OPOSSUM on Linux it might be necessary to install some necessary tools first. On Debian based systems this can be achieved in the following way with the following command sudo apt install build-essential cmake libfontconfig1-dev.

Get the Code

Clone the repository to get the latest (potentially unstable) version, or download a stable source archive from the releases page.

git clone [https://github.com/opossum-labs/opossum.git](https://github.com/opossum-labs/opossum.git)
cd opossum

Prerequisities

Before building, some tools need to be installed first. Since the OPOSSUM frontend GUI is based on the dioxus framework we need to install the dioxus CLI. The easiest is to install the binary directly. For this, cargo-binstall must be installed first.

cargo install cargo-binstall
cargo binstall dioxus-cli

Option A: Build Development Version

Use this method if you want to develop or debug OPOSSUM. The executables will be unoptimized (debug build), and the backend and frontend must be run in separate terminals.

Step 1: Build the CLI

First, build the Command Line Interface tool.

cd opossum_cli
cargo build
cd ..

Step 2: Run the Backend (Terminal 1)

The frontend requires the REST backend server to be running. In your current terminal, build and run the backend:

cd opossum_backend
cargo run

Leave this terminal open.

Step 3: Run the GUI Frontend (Terminal 2)

Open a new terminal, navigate to the opossum directory, and start the Dioxus development server:

cd opossum_gui
dx serve

Option B: Build Installation Packages

Use this method to create optimized release bundles. Fortunately, there is a preconfigured process for the entire bundling process (based on xtask). To build installation packages for the respective platform simply use:

cargo xtask bundle

This does the entire job of compiling the backend, CLI and GUI as well as creating the installer packages. Depending on your platform (Windows or Linux), the final installation packages will be generated in: <target dir>/dx/bundle/opossum_gui/.

3. Build documentation (Optional)

The OPOSSUM suite has three main sources of documentation:

  1. The Book: The comprehensive guide you are currently reading.
  2. Library API Documentation: For the core Rust library.
  3. REST API Documentation: For the backend server interface.

1. 📖 Build the Documentation Book

The book is built using mdBook. This system compiles the Markdown source files into a static, readable website.

  1. Install mdBook:

    cargo binstall mdbook
    
  2. Navigate and Build:

    cd opossum/doc/book
    mdbook build
    

The generated documentation website is located at: <target dir>/doc/book/book/index.html. You can open this file directly in any web browser.


2. 🦀 Build the Library API Documentation

The API documentation for the Rust core library is generated using rustdoc, the standard tool for Rust projects.

  1. Navigate to the Core Library:

    cd opossum_core
    
  2. Generate Documentation:

    cargo doc --no-deps --features "doc-images"
    

    The --no-deps flag speeds up the process by excluding documentation for dependencies.

The resulting HTML documentation can be found in your target directory, typically at: <target dir>/doc/opossum_core/index.html


3. 🌐 Access the REST API Documentation

The documentation for the backend’s REST API is automatically served by the backend application itself when it is running.

  1. Ensure the backend server is running (e.g., in a separate terminal).
  2. Open the following URL in your web browser: http://localhost:8001

Once the page loads, click the View API Documentation button to see the interactive Swagger UI.

Usage

The following section describes how to use the OPOSSUM suite via the graphical user interface (GUI).

Starting the GUI

We assume that the software has already been installed using the appropriate installer for your platform.

Windows

On Windows, both the MSI and EXE installers create an entry in the Start Menu and a desktop icon named Opossum_GUI.

Linux

On Linux, the launch method depends on the installation package type. Debian and Redhat packages (.deb & .rpm) install an icon in the system menu. Alternatively, the OPOSSUM GUI can be launched directly from the command line:

opossum_gui

For the AppImage package, you can execute the file directly by double-clicking it in your file manager or running it via the command line. You may need to mark the file as executable first:

cd <path to AppImage>
chmod u+x OpossumGui-0.7.0.AppImage
./OpossumGui-0.7.0.AppImage

Once started, the main window will appear:

First Steps

The top menu bar contains standard file handling options, while the window controls are located on the right. We recommend maximizing the window to ensure sufficient space on the canvas for modeling your optical system.

In this tutorial, we will model a simple Kepler telescope consisting of a source and two convex lenses.

Adding an Optical Node and Using the Canvas

Use the Node menu to add either an optical node or an analyzer node. Let’s start by selecting an optical node: a Source node, which represents the starting point of our optical system.

Once selected, the source port node appears on the canvas. You can move the node by simply clicking and dragging it. Next, add two Lens nodes and place them on the canvas as well.

The canvas itself is virtually infinite. You can pan the viewport by clicking and dragging on the background, and zoom in or out using the mouse wheel.

Connecting Nodes

To form an optical network, the nodes must be connected. Click on an output port (the light green square on the right side of a node) and drag a line to the input port of another node. Connect them in this order: Sourceport -> Lens -> Lens. Your screen should look similar to this:

Each node port can only be connected to exactly one other port, i.e., a single source cannot be connected to multiple inputs simultaneously. For example, if a light source or signal needs to be split into multiple paths, a dedicated beamsplitter node must be used.

Each connection displays a numeric value representing the spatial separation between the connected nodes (the distance along the optical axis). For a detailed discussion on element placement, please refer to the Concepts section. For this example, set the distance between the sourceport and the first lens to 10 mm, and the distance between the two lenses to 200 mm.

Numeric values can be entered manually, with units, and unit prefixes are supported. For example, distances can be specified from millimeters (mm) to kilometers (km), including metric system prefixes from quecto (q) to quetta (Q). The system automatically reads these prefixes and converts the values into a standard internal unit.

You can easily delete a node by selecting it and pressing the ‘Delete’ key on the keyboard if it was created by mistake or is no longer needed.

You can also tidy up the node arrangement using the auto-layout function: Select Auto Layout from the Layout menu or press Ctrl + Shift + A. The result should look like this:

Configuring Nodes

Now that the optical system structure is set, we need to define the parameters for each component. For this tutorial, we will configure only the essential parameters.

Start with the first lens. Click on the node to highlight it. Its properties are displayed in the Node Editor panel on the left. Focus on the Properties section, which shows the center thickness and the radii of curvature. Set the Center Thickness to 3 mm, the Front Radius to 60 mm, and check the box for a Plane Back Surface. Leave the refractive index at 1.5. This configures the component as a convex-plano lens.

Repeat this step for the second lens: Set the Center Thickness to 3 mm, the Front Surface to Flat (Plane), and the Back Surface to -40 mm.

Finally, select the Sourceport node to configure the spectral properties. Navigate to Properties -> Light definition -> Spectral distribution. Change the Rays spectral distribution from “Gaussian” to “Laser Lines”. This generates a monochromatic source (defaulting to 1054 nm) instead of a broad spectrum.

Adding an Analyzer

Although the optical setup is complete, we must define the analysis method. Select Add Analyzer from the Node menu and choose RayTracing. As implied, this node performs the ray tracing calculations. We will keep the default settings for this tutorial.

Adding Detector Nodes

Technically, we could start the simulation now, but we would see almost no output because we haven’t specified any Detector Nodes.

We want to visualize the spot diagram at the end of the system and see the beam propagation path. Add the Spot Diagram and Ray Propagation detector nodes. Connect them to the end of the lens system.

Detector nodes are typically “transparent”—they have no thickness and do not alter the light passing through them. This allows you to chain multiple detectors with zero distance between them to monitor different aspects of the beam at the same location. For now, connect the detectors and set a distance of 50 mm between the last lens and the spot diagram, so we can see the light propagate slightly beyond the second lens.

Undo and Redo

Almost every editing action in the GUI can be undone and redone:

  • Press Ctrl + Z to undo and Ctrl + Y to redo, or use the corresponding entries in the Edit menu. The menu entries are grayed out while there is nothing to undo or redo.
  • All model edits are covered: adding, deleting, moving, renaming and reconfiguring nodes and analyzers, connecting and disconnecting ports, changing connection distances, cut/copy/paste, group operations (creating groups, converting a selection to a group, dragging nodes into a group) and port mappings.
  • Composite actions count as a single step: pasting several nodes, cutting a selection, or dragging a multi-node selection is reverted by one undo.
  • Camera movements (panning, zooming, centering, zoom-to-fit) are undo steps of their own, so undoing a model edit never moves the camera and undoing a camera move never changes the model. A continuous scroll-zoom burst or consecutive, sperate scroll-zooms are combined into a single step.
  • The history holds the last 100 steps and is cleared when a file is loaded or a new document is created. Undo and redo count as modifications, so the document is marked as unsaved afterwards.
  • The reflective grating’s Littrow alignment aids (reference wavelength, incident/diffracted mode) are entry helpers, not stored with the model, so they are not undoable — only the resulting alignment is.
  • The RayTrace analyzer’s spectral-distribution laser-line list and the Energy analyzer’s laser-line list work the same way: the wavelength/intensity (or wavelength/energy) fields for the line currently being entered are not sent to the backend until “Add laser line” is pressed, so only adding or deleting a line is undoable, not the individual field edits leading up to it.
  • The bore list of an optic shape follows the same pattern: the shape, offset and rotation fields of the bore currently being drafted are not sent to the backend until “Add bore” or “Update bore” is pressed. Each add, update, or delete of a bore is its own undo step, but the field edits leading up to it are not individually undoable. Choosing another kind of edge starts a fresh edge without bores; one undo brings back the previous edge with its bores.

Groups

Groups allow multiple nodes in an optical system to be combined into a single grouped element. The grouped nodes remain accessible individually when the group is opened, while the main system view displays the group as a simplified structure.

Groups can also contain other groups, allowing complex systems to be organized hierarchically.

Creating a Group

A group can be created in different ways:

Group option from nodes
Select the required nodes and use the Group option to create a new group.
Convert selection to group
Select multiple nodes by dragging the cursor over them. After the selection is made, choose Convert to Group to create a group from the selected nodes.
Drag and drop
Additional nodes can be added to an existing group using drag and drop.

Connecting a Group

A group can be connected to the main optical system using input and output ports.

Map Port to Group
Right-click a node inside the group and select Map Port to Group. This maps the selected input or output port to the group, making it available at the group level.

A group can have one input port and one output port. When using a beam splitter, two ports can be mapped and connected to the main optical system.

Working with Groups

When a group is opened, the individual nodes inside the group remain accessible and can be edited independently. In the main system view, the group is displayed as a single simplified element.

Performing the Simulation

We are now ready to run the simulation. First, save your model by selecting File -> Save (saved as an .opm file).

Start the simulation by clicking the green Simulate button at the top. On the first run, you will be asked to select a report directory where the output files will be stored.

Note: Use a dedicated directory that does not contain other important files (like your model file), as the contents may be overwritten or deleted between simulation runs.

After selecting the directory, the simulation will start in a separate window.

Once the simulation finishes, you can close the simulation window.

Viewing the Report

The analysis data has been written to your selected report directory. OPOSSUM generates an HTML report (e.g., <report dir>/report_0.html) which you can open in any web browser. It should look similar to this:

Further Reading

You have now built a simple (albeit not perfectly collimated) Kepler telescope.

  • Check the Reference documentation for details on all available optical components, detectors, and analyzers.
  • Specific tasks are described in the How-to Guides.
  • For general background information, consult the Concepts section.

How-to Guides

Practical recipes for specific tasks. Unlike the Tutorial, which walks through building a first model from scratch, these guides assume you already have a model and want to accomplish something particular with it.

  • Model an amplifier

    Turn a lens, wedge or cylindric lens into an amplifier and analyze the model at several pump conditions — in the graphical user interface and in code.

Model an amplifier

This guide turns an existing optical component into an amplifier and analyzes the model at two operating points. It assumes a model that already contains a source, at least one lens, wedge or cylindric lens, and an energy meter or another detector at the end.

The task splits in two: the component stays what it is, and a pump scenario says how hard it is driven during a run. Both routes below produce the same thing — pick the one that fits how you work. For what the settings mean, see Pump scenarios.

In the graphical user interface

1. Mark the component as an amplifier. Right-click the lens, wedge or cylindric lens on the canvas and choose As amplifier. The entry only appears on components that enclose a volume of material. As passive optic in the same menu takes the marking back.

If the document has no pump scenario yet, one is created automatically — a marked component with nowhere to configure it would be a dead end.

2. Open the scenario editor. Click the amplifier icon in the narrow bar at the side of the canvas to switch the sidebar to its Pump scenarios view. (Clicking the icon of the view that is already open collapses the sidebar again.)

3. Create the operating points you need. Type a name into the New scenario name field and press Add. Repeat for a second scenario, for instance full power and half power.

Clicking a scenario card makes it the active one. That choice only affects what the canvas shows; it does not decide what is analyzed.

4. Set the gain. Expand a scenario card with the ▸ amplifiers toggle. Every marked component in the document gets a row there, whether or not it amplifies in this particular scenario. Per row:

  • Gain model — choose Const.
  • The gain factor field appears next to it. Enter the energy gain of that component in this scenario, e.g. 5 in full power and 2.5 in half power.

The factor is set per scenario, so editing one scenario never changes another. A component left at None stays passive in that scenario.

5. Tell the analysis which scenarios to run. Select the analyzer node. In the node editor, tick the scenarios under Pump scenarios. One report is produced per ticked scenario. Ticking nothing runs the model once, passively.

6. Simulate. Press the green Simulate button as usual. The reports are named after the scenario they belong to (Energy Analysis - full power), so they can be told apart directly.

On the canvas, a marked component shows amp: <model> in its footer — the gain model it runs with in the active scenario. Switching the active scenario switches what is shown there.

In code

A model built in Rust configures the same three things: the components, the scenarios, and which scenarios the analyzer runs in. The complete, runnable program is opossum_core/examples/amplifier_const_gain_chain.rs; run it with

cargo run -p opossum_core --example amplifier_const_gain_chain

and open the resulting .opm file in the GUI to see the very same set-up there. The parts that matter here:

#![allow(unused)]
fn main() {
use opossum_core::{
    gain::{ConstGain, GainModel},
    prelude::*,
};

// The components are ordinary lenses - nothing about them says "amplifier".
let first_head = scenery.add_node(Lens::new(/* ... */)?)?;
let second_head = scenery.add_node(Lens::new(/* ... */)?)?;

let mut document = OpmDocument::new(scenery);

// Optional: makes the GUI show these nodes as amplifiers when the file is opened there.
// The analysis does not read it - the gain model below is what amplifies.
document.set_is_amplifier_node(first_head, true);
document.set_is_amplifier_node(second_head, true);

// One operating point per pump condition to be analyzed.
let scenario_id = document.add_pump_scenario("full power");
let scenario = document
    .pump_scenario_mut(scenario_id)
    .expect("the scenario just added must be there");
scenario.set_gain_model(first_head, GainModel::Const(ConstGain::new(5.0)?));
scenario.set_gain_model(second_head, GainModel::Const(ConstGain::new(4.0)?));

// Without this the model is analyzed once, passively.
document
    .analyzer_mut(analyzer_id)
    .expect("the analyzer just added must be there")
    .set_pump_scenarios(vec![scenario_id]);
}

ConstGain::new rejects a factor that is negative or not finite, so an invalid gain is refused where it is set rather than halfway through an analysis.

Checking the result

Read the energy at the detector at the end of the chain in each report and compare it with the product of the factors you entered. The example above starts from 1 J and amplifies by 5 and then 4, so the full power report has to read 20 J, and half power — 2.5 and 2 — has to read 5 J. If a report reads the input energy unchanged, the analyzer was not given the scenario in step 5.

Small-signal gain with a shaped pump profile

This guide shows how to move beyond a constant gain factor and model an amplifier head where the pump beam itself is shaped: it has a transversal intensity profile across the aperture and it is partially absorbed along the optical axis. The amplifier_chain.rs example covers the simpler Const model; here the gain field depends on position inside the medium, so two parallel rays through the same slab leave with different gain factors.

When to use Monochromatic Small Signal Gain instead of Const

Const assigns one factor to the whole ray bundle regardless of where a ray enters the medium or how long its chord through it is. That is appropriate for chain layout and first estimates. Use Monochromatic Small Signal Gain when any of the following matters:

  • The pump spot does not cover the full aperture — rays near the edge are less pumped than axial ones.
  • The pump is end-pumped and partially absorbed — the near face of the medium is more strongly inverted than the far face.
  • Oblique rays travel longer chords and therefore accumulate more gain than on-axis ones.
  • The analysis needs to be run in ray tracing or ghost focus mode (energy flow cannot use Small Signal Gain because it carries no per-ray geometry).

Monochromatic Small Signal Gain is an unsaturated model: extracting energy does not draw the inversion down. It holds as long as the extracted fluence is small compared with the stored fluence in the medium. For saturating amplifiers the next gain stage (Frantz–Nodvik) will be the right tool.

Setting it up in code

The complete, runnable program that shows these concepts with a fluence detector is opossum_core/examples/amplifier_gaussian_pump_fluence.rs; run it with

cargo run -p opossum_core --example amplifier_gaussian_pump_fluence

That example uses a flat longitudinal profile to isolate the transversal effect. The code below focuses on the gain and pump source configuration for a Lambert-Beer longitudinal profile; the rest of the setup follows the same pattern.

The hardware is a plane-parallel glass slab — a Lens with infinite radii of curvature. The slab is 40 mm thick and refractive index 1.5, exactly as any passive lens would be. Nothing about the node says “amplifier”:

#![allow(unused)]
fn main() {
use opossum_core::{
    gain::{
        AnalyticPump, LambertBeerProfile, GainModel, LongitudinalProfile, MonochromaticSmallSignalGain,
        PumpDirection, PumpSource, TransversalProfile,
    },
    prelude::*,
    reciprocal_centimeter,
    utils::super_gaussian::SuperGaussianShape,
};

let head = scenery.add_node(Lens::new(
    "amplifier head",
    millimeter!(f64::INFINITY),  // flat input surface
    millimeter!(f64::INFINITY),  // flat output surface
    millimeter!(40.0),
    RefrIndexConst::new(1.5)?,
)?)?;
}

A pump scenario assigns the gain model and the pump source to that node separately. The gain model carries the magnitude — the peak gain coefficient g₀ where the pump is strongest; the pump source carries only the shape — the spatial profile β ∈ [0, 1] that says how strongly each point of the medium is pumped relative to that peak:

#![allow(unused)]
fn main() {
// Gain model: unsaturated path-integral gain.
// g₀ is the peak small-signal gain coefficient at the strongest point of the pump profile.
scenario.set_gain_model(
    head,
    GainModel::MonochromaticSmallSignalGain(MonochromaticSmallSignalGain::new(
        reciprocal_centimeter!(0.3), // peak g₀ where the pump is strongest (axis, near face)
    )?),
);

// Pump source: Super-Gaussian spot × Lambert-Beer longitudinal decay.
// The pump carries only the shape and the grid it is resolved on — no amplitude here.
scenario.set_pump_source(
    head,
    PumpSource::Analytic(AnalyticPump::new(
        TransversalProfile::SuperGaussian(SuperGaussianShape::new(
            millimeter!(0.0, 0.0),  // pump centered on the optical axis
            millimeter!(5.0, 5.0),  // 1/e² half-width 5 mm along x and y
            2.0,                    // order 2: flatter top, steeper edges than a Gaussian
            degree!(0.0),
            false,
        )?),
        LongitudinalProfile::LambertBeer(LambertBeerProfile::new(
            reciprocal_centimeter!(0.5), // pump absorption coefficient in the medium
            PumpDirection::Forward,      // pump enters from the input surface
        )?),
        (64, 64, 32), // 64 × 64 transversal, 32 longitudinal cells
    )?),
);
}

Choosing the grid

The (64, 64, 32) grid is the third argument of AnalyticPump::new — the resolution at which the pump shape β is discretized over the medium. Each cell holds one β value. A ray traverses the cells exactly (Amanatides–Woo algorithm), so there is no step-size error — only the discretization of the pump profile onto the grid introduces approximation. Rules of thumb:

  • Make cells_z fine enough to resolve the longitudinal profile: for Lambert-Beer with α = 0.5 cm⁻¹ over 40 mm, roughly 16–32 slices are sufficient for < 1 % error.
  • Make cells_x and cells_y fine enough to resolve the transversal profile: a Super-Gaussian with σ = 5 mm over a 20 mm aperture needs around 32–64 cells to be well-sampled.
  • Finer grids cost proportionally more memory but no additional traversal time per ray.

A constant pump (PumpSource::Const) has no shape to resolve, so it needs no grid and no grid argument — the model integrates over the exact chord the ray travels through the body.

Running the analysis

Monochromatic Small Signal Gain requires a ray-tracing or ghost-focus analysis; an energy-flow analysis is refused because it carries no per-ray geometry and cannot integrate g₀ along a path. Configuring one is the same as for any other model:

#![allow(unused)]
fn main() {
let mut config = RayTraceConfig::default();
config.map_source(
    source,
    round_collimated_ray_builder(millimeter!(9.0), joule!(1.0), 5)?,
);
let analyzer_id = document.add_analyzer(AnalyzerType::RayTrace(config));

// Tell the analyzer which scenarios to run — without this the model is analyzed passively.
let scenario_ids = document.pump_scenarios().keys().copied().collect();
document
    .analyzer_mut(analyzer_id)
    .expect("the analyzer just added must be there")
    .set_pump_scenarios(scenario_ids);
}

round_collimated_ray_builder produces five concentric rings of collimated rays up to a radius of 9 mm. With the pump spot at σ = 5 mm, the inner rings (r ≈ 0–2 mm) sit near the peak of the profile; the outer rings (r ≈ 7–9 mm) sit on the tail where the profile has fallen to a small fraction of its peak.

What to look for in the result

Open the amplifier_gaussian_pump_fluence.opm file in the GUI, run the analysis in the Gaussian pump scenario, and open the fluence detector report. The fluence map shows:

  • A bright central spot where the Gaussian pump profile is strongest and gain is highest.
  • A smooth radial fall-off that mirrors the pump’s σ = 5 mm half-width.
  • Near-zero fluence beyond the pump spot (r ≫ σ): rays there barely see the pump.

To see the Lambert-Beer longitudinal effect on top of a transversal profile, configure the pump source as shown above (Super-Gaussian × Lambert-Beer) and compare the fluence map with the flat-profile result: oblique rays and axial rays at the same radius will carry slightly different energies because they enter the slab at different longitudinal inversion gradients.

For parameter definitions and the full list of transversal and longitudinal profile options see Pump scenarios.

Visualizing the pump profile in the output fluence

This guide shows what happens when a collimated beam with a uniform energy distribution passes through a medium whose pump spot does not fill the full aperture. Because the gain is stronger where the pump is most intense, the output fluence map at the detector reproduces the transversal pump profile — even though the input beam was flat. The complete, runnable program is opossum_core/examples/amplifier_gaussian_pump_fluence.rs; run it with

cargo run -p opossum_core --example amplifier_gaussian_pump_fluence

The setup

The optical chain is minimal: a source, a single amplifier head, and a fluence detector.

oscillator ──[200 mm]── amplifier head ──[100 mm]── output fluence

The amplifier head is a plane-parallel glass slab (flat surfaces, 100 mm thick, n = 1.5). No special node type is needed — a Lens with infinite radii of curvature is the active medium. Marking it as an amplifier is what makes the GUI show it in the pump-scenario editor:

#![allow(unused)]
fn main() {
document.set_is_amplifier_node(head, true);
}

Pump scenario

A pump scenario assigns the gain model and the pump source to the head separately.

Gain model. MonochromaticSmallSignalGain integrates the local gain coefficient along each ray’s path through the medium: G = exp(∫ g₀·β ds). The peak coefficient g₀ = 0.2 cm⁻¹ is the gain per unit length where the pump is strongest (on axis). For a ray going straight through the 100 mm slab, the peak single-pass gain is

G = exp(g₀ · L) = exp(0.2 cm⁻¹ × 10 cm) = exp(2) ≈ 7.4

Pump source. The pump carries only the spatial shape — how the gain coefficient is distributed across the medium. Here it is a standard Gaussian (SuperGaussian of order 1) with a half-width σ = 5 mm, combined with a flat longitudinal profile. A flat longitudinal profile means the inversion is the same at the entrance face and at the exit face, so the only spatial variation is the Gaussian fall-off across the aperture.

#![allow(unused)]
fn main() {
scenario.set_gain_model(
    head,
    GainModel::MonochromaticSmallSignalGain(MonochromaticSmallSignalGain::new(
        reciprocal_centimeter!(0.2),
    )?),
);
scenario.set_pump_source(
    head,
    PumpSource::Analytic(AnalyticPump::new(
        TransversalProfile::SuperGaussian(SuperGaussianShape::new(
            millimeter!(0.0, 0.0),  // pump centered on the optical axis
            millimeter!(5.0, 5.0),  // 1/e² half-width 5 mm
            1.0,                    // order 1 = standard Gaussian
            degree!(0.0),
            false,
        )?),
        LongitudinalProfile::Flat,   // uniform inversion from entrance to exit
        (64, 64, 16),                // 64 × 64 transversal cells; 16 longitudinal
    )?),
);
}

For an explanation of the grid argument and a comparison with the Lambert-Beer longitudinal profile, see Shaped pump profiles.

Source and detector

The input source uses 10 000 rays distributed on a Fibonacci grid, which tiles a circular aperture of radius 10 mm without clustering. The energy distribution is a high-order Super-Gaussian (order 8 ≈ flat-top): every ray starts with roughly the same energy per unit area, so any fluence variation at the output is entirely due to position-dependent gain, not to the input beam shape.

The output detector is a FluenceDetector using the Voronoi estimator, which assigns each ray an area equal to its Voronoi cell and reports the energy per area. With a Fibonacci source grid the cells have nearly equal area, giving a low-noise estimate.

What to look for

Open the .opm file in the GUI, select the Gaussian pump scenario in the pump-scenarios panel, and run the analysis. The fluence map at the output detector should show:

  • A bright circular spot in the centre where the Gaussian pump profile is strongest, and where the gain is highest.
  • A smooth radial fall-off that mirrors the pump’s σ = 5 mm half-width. At a radius of 5 mm the fluence has dropped to 1/e of its axial value.
  • Near-zero fluence beyond the pump spot (r ≫ σ): rays there barely see the pump and leave the medium essentially unamplified.

If you switch the gain model to Const with the same overall factor for a quick comparison, the fluence map becomes uniform across the aperture — the spatial information that MonochromaticSmallSignalGain preserves is lost.

When to use a flat longitudinal profile

LongitudinalProfile::Flat is the right choice when the pump is not significantly absorbed on its way through the medium — for example when the medium is short compared with the pump absorption length, or when the pump is a side-pump geometry whose longitudinal variation is captured in the transversal profile instead. For end-pumped media where the pump is partially absorbed along the optical axis, LongitudinalProfile::LambertBeer models the exponential fall-off of the pump intensity from entrance to exit. That case is covered in Shaped pump profiles.

For the full list of transversal and longitudinal profile options and their parameters, see Pump scenarios.

Reference

Application Settings

The Settings dialog configures application-wide preferences, directory locations, catalog synchronisation, and default physical parameters[cite: 16]. Settings persist across sessions in a local configuration file (config.ron)[cite: 2].

Accessing the Settings Dialog

Open the settings dialog from the top navigation bar[cite: 16]:

  • Navigate to File → Settings (or press Ctrl+Alt+,).

Changes are staged in a temporary buffer while the dialog is open[cite: 16]. Clicking Cancel discards all changes, while Save & Close validates and writes the configuration to disk[cite: 16].


Settings Reference

The dialog is organised into two categories: General and Physics / Model[cite: 16].

General Settings

Configures filesystem directories and external asset synchronisation[cite: 16].

SettingTypeDefaultDescription
Report Base DirectoryFilesystem path~/Documents/opossum_reportsDirectory where simulation runs and generated analysis reports (PDF, CSV, diagrams) are stored[cite: 2, 16].
Catalog DirectoryFilesystem path<local_data>/catalogsDirectory for local material and coating catalog registries[cite: 2, 16].
Catalog Git Remote URLURL / Stringhttps://github.com/opossum-labs/opossum_catalog.gitRemote Git repository used to pull and update optical material definitions[cite: 2, 16].
Synchronise Catalog on StartupBooleanfalseWhen enabled, OPOSSUM checks the remote catalog URL and pulls updates on application startup[cite: 2, 16].
  • Directory Selectors (Browse...): Spawns a native directory picker to select valid folders on the filesystem[cite: 16].

Physics / Model Settings

Configures global optical defaults applied when creating components, sources, and analyzers[cite: 16].

SettingUnit / TypeDefaultConstraintsDescription
Default WavelengthLength (m, SI prefixed: nm, µm, etc.)1053.0 nmPositive, finite, non-zero (AllPositive && AllFinite && AllNotZero)[cite: 2]Nominal wavelength used to initialise optical sources and analyzers[cite: 16].

Behavior and Validation

  • Validation Rules: Wavelengths must be strictly positive and finite[cite: 2]. Non-numeric values, negative numbers, zero, and infinite values trigger an inline validation error and prevent saving[cite: 2, 16].
  • Analyzer Instantiation: Newly created analyzers adopt this default wavelength and initialise their spectral distributions and laser line definitions accordingly[cite: 1, 12].
  • Source Port Mapping: When a new optical SourcePort node is added to the optical graph, analyzers map the source port using this default wavelength[cite: 13, 14].
  • Distribution Editors: Switching spectral distribution types in the node editor (e.g. from Gaussian to Laser Lines) seeds new entries with this value[cite: 1].

Configuration File & Storage

All settings are serialized using the Rusty Object Notation (RON) format and saved to config.ron[cite: 2].

Storage Paths by Operating System

Operating SystemFile Path
Linux~/.config/opossum/config.ron
Windows%LOCALAPPDATA%\Opossumlabs\Opossum\config\config.ron
macOS~/Library/Application Support/org.Opossumlabs.Opossum/config.ron

File Format Example

(
    report_dir: Some("/home/user/Documents/opossum_reports"),
    catalog_dir: Some("/home/user/.local/share/opossum/catalogs"),
    catalog_remote_url: "[https://github.com/opossum-labs/opossum_catalog.git](https://github.com/opossum-labs/opossum_catalog.git)",
    sync_catalog_on_startup: false,
    default_wavelength: 0.000001053,
)

Nodes

Nodes form the building blocks of the optical model and normally represent optical components. Nodes are configured through properties (see below) and can be connected by edges. Furthermore, nodes might contain an “inner state” (which cannot be modified directly). This is interesting (in the future) for simulating effects like depletion or simply accumulating energy on an energy meter during multiple passes etc… In addition, there are two special nodes

  • Group node

    A (sequential) group node contains a nested directed graph of other nodes or even further group nodes. This allows for struturing the model by modeling subsystems. Each group defines external ports by mapping input and / or output ports of internal nodes.

  • Reference node

    A reference node refers to an already existing node in the model. Reference nodes are necessary in multi pass setups. Another use case is the modeling of linear resonators. A reference to a group must not be placed inside that same group or any group nested within it (see Reference node).

Node Properties

All nodes con be configured through node properties. All nodes have a common set of properties as shown below. In addition, nodes can have additional properties specific to the respective node type. An example would be the center thickness of a lens. Properties common to all nodes are:

  • name

    While not strictly necessary it is strongly recommended to assign a name to a node for easier identification. In principle, different nodes can have the same name but this might cause much confusion. Internally the model uses unique IDs for each node in order to distinguish them but these IDs are not available to the user.

  • inverted

    Flag denoting the direction of the passing light. It might be necessary to propagate through a node in a reverse direction (e.g. for back reflection / ghost-focus analysis). Hence each node should have a “reverse” function. In the case of a propagation node, this would be identical. For a basic node, it might change the sign of some properties such as the radius of curvature. For group nodes, the underlying order of sub-nodes has to be reversed. The reference node only needs a qualifier to denote whether the propagation is reversed or not.

  • global position

    Global position in 3D space.

  • local position

    Local position / alignment relative to the global position.

Every node with a shape of its own also has one property per surface, holding its coating and its laser induced damage threshold, see Surfaces.

Ports

Ports are the connector points between nodes and can be connected by edges. Ports are strictly distinguished as “input_1” and “output_1” ports. Output ports can only be connected to input ports of another node and vice versa while it is forbidden to connect two input or two output ports. In addition, output ports do not need to be connected to other nodes. During analysis, any result will be simply discarded.

Ports have a specific name in order to distinguish them. For example, a beamsplitter cube might have one input port (e.g. named “input_1”) and two output ports named “output_1” and “transmitted” for the two outgoing beams.

Nodes with output ports only form the optical sources while nodes containing (usually only one) input source will be called detectors. In most cases, a simulation of the model traverses the graph from all sources to a detector node using all possible paths (see Analyzers).

A port is a connection point of the graph and nothing else: it carries no coating, no damage threshold and no aperture. What happens to light at a component is a matter of its surfaces and its optic shape. Each port sits on one surface of the node, which the node type decides: the input of a lens on its front surface, its output on its rear surface, both ports of a mirror on its one surface.

Attributes

Each node can have a set of attributes that represent its specific properties. For example, a propagation node contains a propagation length and a material. An ideal lens contains the focal length as an attribute. Each attribute has a name and a strictly defined data type. Attributes may have default values or are completely optional.

In addition, nodes have a set of attributes that are common to all of them. However, all of these attributes are optional (e.g. can be “empty”).

Common attributes for all nodes

  1. Component Database ID (optional)

    If set, this could be a reference to a (local) component database. It should be considered to also include the database information while exporting the model to a file. If the ID is not set, it would be a “manually configured” component.

  2. Material

    Each optical element consists of a given material. These are mostly different glass materials but could also be metals (i.e. for mirrors) or other substances. Even for free-space propagation nodes a material must be given. This might often be “air” or “vacuum”. Since materials have a plethora of attributes and will be used by different nodes within a model, the material will be a reference pointing to a materials database.

    Note: For interoperability, it might not be always a good idea to only have the material properties in a (local) database. If the model data is given to another user, this data might not be found in his (also local) database. Hence it should be possible to attach the actual material data to the model during export. The alternative would be to have a global database…

  3. 3D location

    Each node can have information about its location in 3D space determined as XYZ coordinates with respect to a given global origin. The anchor position of the node depends on the specific node type. This attribute together with the orientation information (see next point) can be used for doing a 3D ray-trace analysis or simply for visualization.

  4. 3D orientation

    Besides the location (see previous point) an optical component has a given orientation in 3D space. This orientation is defined by angles around the axes of the global coordinate system.

  5. Optic shape

    Each real-world optical component has a limited transversal size, which decides the light it can catch. Nodes state it in their optic shape property, see Optic shape.

  6. 3D mechanical model

    For non-sequential analysis (e.g. ray tracing), a 3D geometric model is necessary. This could be provided as static 3D files (OBJ, STL, etc.) or programmatically derived. For example, the model of a spherical lens could be directly calculated.

  7. Surface definitions

    Each surface of a component has a coating and a laser induced damage threshold, see Surfaces. Further surface properties such as roughness are not modeled yet.

Optic shape

Every component that light hits has a transversal size, its optic shape: where the material or the coated surface actually is, the size a supplier quotes, with any bores through it. The optic shape decides which rays hit the component. A ray that reaches the surface outside of it, or through one of its bores, misses the component. What happens to that ray depends on the analysis:

  • Ray tracing follows its missed surface strategy (see Analyzers): with Stop, the default, the ray is lost; with Ignore it passes the component unchanged.
  • Ghost focus analysis always lets it pass unchanged.
  • Energy analysis traces no rays and ignores optic shapes.

A mirror, a parabolic mirror and a grating only reflect: a ray that misses them has no way on and is lost in every analysis. A ray outside the optic shape of a beam splitter, or through one of its bores as on a scraper mirror, follows the strategy above: with Ignore it passes on as transmitted light, with Stop it is lost.

Edge and bores. An optic shape is an edge with bores through it. The edge is a circle, a rectangle or a polygon, centered on the component’s axis and not turned: to shift or turn a component, align its node. A bore is a circle, a rectangle or a polygon too, shifted off the axis and turned by its own offset and rotation; a ring, for instance, is a circle with a centered bore. Every bore lies within the edge, and bores neither overlap nor touch each other or the edge: OPOSSUM refuses a bore that does and says why. Overlapping bores and a notch cut into the edge cannot be stated. In the node editor, choosing another kind of edge starts a fresh edge of that kind without bores.

The default depends on the kind of component:

ComponentDefault optic shape
lens, wedge, mirror, parabolic mirror, beam splitter, ideal filter, paraxial surfacecircle of 12.5 mm radius, the usual 1 inch mount
cylindric lensrectangle of 20 mm across its curvature (x) and 30 mm along its cylinder axis (y)
gratingsquare of 25 mm × 25 mm
detectorssquare window of 25 mm × 25 mm
dummyunbounded (Open)

The optic shape lies in the plane perpendicular to the component’s axis and extends along that axis: for a rod cut at Brewster’s angle it is the cross section of the rod, as its manufacturer states it. An off-axis parabola measures it parallel to its parent axis, as catalogs do. A curved surface has to reach the edge of the optic shape, so its radius of curvature cannot be smaller than the largest distance of that edge from the axis. The edge thickness of a lens or a wedge is not checked: where its surfaces would cross, rays miss the rear surface.

Detectors let all light pass. Their optic shape is the window they record within, a square of 25 mm × 25 mm by default. Light outside the window passes on unrecorded, and the log and the report warn about it. Set the window to the size of the actual sensor, or to Open to record all light. The paraxial surface is an idealization and may be unbounded as well. Every other component refuses Open.

Iris. A dummy passes light unchanged and is unbounded (Open) by default. Given an optic shape, it acts as an iris: a ray outside of it misses the dummy and follows the rules above.

Only the optic shape limits light; ports and surfaces carry no aperture. Sources, ray propagation visualizers and groups are idealized or abstract nodes and have no optic shape. To limit the beam of a source, place a dummy behind it or shrink its ray distribution.

Alignment. The component alignment run (see Geometry) respects optic shapes too: if the optical axis misses the optic shape of a component, beside its edge or through one of its bores, the alignment stops with an error naming that node. A bore meant to let the beam pass along the axis, as on a scraper mirror for the main beam, is therefore not supported yet. At a detector a missed window only warns that the measurement may fail.

Surfaces

Every face of a component is a surface of its own, with a coating and a laser induced damage threshold (LIDT). A node keeps them as one property per face, named after the face:

NodeSurface properties
lens, cylindric lens, wedgefront surface, rear surface
every other node except groups and referencessurface

The coating decides which part of the light a surface reflects and which part it transmits; the LIDT is the fluence above which the ghost focus analysis reports the surface as at risk. By default a surface has an ideal antireflective coating (IdealAR, no reflection) and an infinite LIDT, so it cannot be damaged. Further coatings are a constant reflectivity (ConstantR), the Fresnel reflection of an uncoated surface (Fresnel), and a Separator, which transmits a fixed ratio or a spectrum and reflects the rest, whatever the angle of incidence. A thin mirror and a parabolic mirror start with a fully reflecting coating (ConstantR of 100 %).

A Separator belongs to a splitting surface, one at which the node follows both the transmitted and the reflected part of the light; today that is the surface of a beam splitter, whose coating is its split (see Beam splitter). A splitting surface takes only a Separator, by default one that transmits half of the light, and every other surface takes any coating but a Separator. The node editor offers only the coatings a surface takes, and a file that gives a surface another coating loads with the default one.

A surface is one surface, however many ports sit on it. The input and the output of a mirror or a detector, and all four ports of a beam splitter, share the one surface of the node: its coating, and the hits an analysis records on it. The ghost focus report names a surface after its face, for instance front surface.

Analysis interface

As discussed, the actual calculation is performed by the nodes. The presented framework will only make sure that all necessary input data will be provided. For this, each node has to implement an Analysis function with light data from the incoming edges as parameters. This function can now either directly perform a calculation or call specific external modules (such as C/C++ library code or a Python script).

Beam propagation visualizer

The Beam Propagation Visualizer is a virtual detector that plots the path of all incoming light rays in a 2D projection. It is an essential tool for debugging and understanding ray behavior in an optical system, especially for ray tracing and ghost focus analysis.

Rays of different wavelengths are automatically plotted in different colors for easy identification.

Key Usage Considerations

  • Placement: This node only visualizes the ray history up to its own position. For a complete view of a system, you should typically place it at the very end of your optical network graph.

  • Multi-Path Systems: When used in a system with components like beamsplitters, the visualizer will only plot the rays for the specific path it is on.

Analysis

As a detector node, incoming light data is simply passed unmodified through the node.

  • Energy Analysis

    In energy analysis, this node does not report anything.

  • Ray tracing Analysis

    In ray tracing analysis, this node generates a 2D plot as described above.

  • Ghost focus Analysis

    In ghost focus analysis, this node generates a 2D plot as described above.

Ports

  • input_1

    Input port

  • output_1

    Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

  • view direction

    The generated plot shows the 2D projection of the ray propagation. This parameter determines the projection plane defined by a normal vector. Default is the yz plane.

  • ray transparency

    Sets the alpha (transparency) of the plotted rays. Useful for visualizing dense or overlapping beams. Must be in the interval [0.0,1.0]. The default value is 0.4.

Ideal beam splitter

Analysis

For energy analysis, the spectrum arriving at each input is split according to the Separator coating of the surface (see Properties): the transmitted part leaves through the output of the same number (e.g. input_1 → out1_trans1_refl2), the reflected part through the other output (e.g. input_1 → out2_trans2_refl1).

For ray tracing, the beam splitter acts as a thin splitting surface lying in the plane of the node. The coating of its surface is the split: what the coating does not reflect is transmitted (see Surfaces). Transmitted rays keep their direction, while reflected rays are deflected according to the laws of reflection. The same holds for the optical axis, so nodes connected to the reflected output are placed along the reflected axis (see Geometry).

Like a mirror, a beam splitter with an alignment of 0° therefore reflects the light directly back towards the source. To deflect the reflected beam by 90°, rotate the beam splitter in the Node Editor panel under the Alignment section, e.g. by setting the Roll Angle to 45°.

Positioning

During the alignment run (which precedes ray tracing and ghost-focus analysis), the beam splitter is placed from the optical axis of one of its inputs, and that axis is then split onto the two outputs so the following nodes can be placed in turn. The axis is always split half and half, whatever the coating of the surface: both outputs are placed even if the coating sends all light to one of them or the alignment wavelength lies outside its spectrum.

Which input places the splitter. If input_1 carries the optical axis it is used; otherwise input_2 is used. A beam splitter can therefore be positioned from either input on its own — connecting only input_2 works just as well as connecting only input_1.

Where the second input’s beam comes from. Both inputs share the same splitting surface. Because a beam entering input_2 passes straight through to out2_trans2_refl1, its optical axis must arrive travelling in the direction that leaves out2 — the mirror image, on the splitting surface, of the input_1 axis. For an untilted beam splitter (0°) this is the direction straight back towards a source on the opposite side; for one rolled to fold the beam by 90°, it is the folded (sideways) direction. The up direction is mirrored to match, so both inputs share a consistent frame.

Both inputs connected. When both inputs carry an axis, the splitter is placed from input_1 — deterministically, regardless of the order in which the two arms happen to be traced — and the axis reaching input_2 is then checked against that placement. If the two do not agree (different direction, wrong distance along the axis, or a sideways miss), OPOSSUM keeps the placement from input_1 and logs a warning describing the deviation and the exact position and direction the input_2 beam would need to be consistent. See Geometry → Beam Combiners and Parallel Paths for the details and for the case of two independent sources.

Ports

Inputs

input_1
Input 1 of the beam splitter / combiner.
input_2
Input 2 of the beam splitter / combiner.

Outputs

out1_trans1_refl2
Output 1. In terms of a beamsplitter cube, this corresponds to the transmitted light from input_1 and the reflected light from input_2.
out2_trans2_refl1
Output 2. In terms of a beamsplitter cube, this corresponds to the transmitted light from input_2 and the reflected light from input_1.

Properties

surface
Coating and laser induced damage threshold of the splitting surface (see Surfaces). The coating defines how incoming beams are split or merged respectively. The surface is a splitting surface, so it takes only a Separator, by default one that transmits half of the light. A Separator transmits according to its splitting configuration and reflects the rest, whatever the angle of incidence:
  • Fixed Ratio: The incoming light is split according to a fixed (wavelength-independent) transmission between 0.0 and 1.0. A value of 1.0 fully transmits both inputs (input_1 → out1_trans1_refl2, input_2 → out2_trans2_refl1), while a value of 0.0 fully reflects them (input_1 → out2_trans2_refl1, input_2 → out1_trans1_refl2).
  • Spectral filter: The incoming light is split with respect to its wavelength. The provided spectrum defines a wavelength-dependent transmission between 0.0 and 1.0.
optic shape
Transversal extent of the splitting surface. Only rays within it are split. A ray outside of it, or through one of its bores, follows the analyzer’s missed surface strategy: with Ignore (always in a ghost focus analysis) it passes on as transmitted light, with Stop it is lost. A bore therefore models a scraper mirror whose hole lets part of the beam pass (see Optic shape). Defaults to a circle of 12.5 mm radius; Open is refused.

Cylindric lens

This element represents a “real” lens with cylindrical front and back surfaces. Furthermore, the lens consists of an optical material, which carries the refractive index model among other data. The center thickness denotes the distance of the front and back surfaces at symmetry axis of the lens.

By default, both cylinder axex are oriented along the y axis. This can be easily changed using the alignment property.

The optic shape decides which rays hit the lens (see Optic shape). Choose it so that the lens keeps a positive edge thickness: where the front and back surfaces would cross, e.g. beyond the rim of a thin biconvex lens, rays miss the rear surface.

Since this element encloses a volume of material, it can be operated as an amplifier: a pump scenario assigns it a gain model, and light travelling through the medium is amplified accordingly. Without such an assignment the lens is the passive component described here.

Analysis

  • Energy Analysis

    During energy analysis, besides the common behaviour, this element does not alter the incoming the incoming light. The output is a copy of the input light. Above mentioned apertures are ignored.

  • Ray tracing Analysis

    During ray tracing analysis, incoming rays are refracted on the frontsurface according to Snellius’ law of refraction. Inside the lens the ray propagate within the given medium. On the rearsurface, the rays are again refracted. A ray reaching a surface outside the optic shape misses the lens and follows the analyzer’s missed surface strategy.

  • Ghost focus Analysis

    During this analysis, the lens behaves similar to the ray tracing analysis. A ray outside the optic shape passes the lens unchanged.

Ports

input_1
Input port. This represents the front surface of the lens.
output_1
Light ouput. This represents the rear surface of the lens.

Properties

front curvature
Radius of curvature of the front surface.
rear curvature
Radius if curvature of the rear surface.
center thickness
Thickness of the lens center along the optical axis.
material
The (glass-) material the lens is made of. It carries the refractive index model — a constant value or a dispersion formula such as Sellmeier or Schott — which is what the refraction at both surfaces is calculated from.
optic shape
Transversal extent of the lens: the size the material is actually available in. It decides which rays hit the lens. Defaults to a rectangle 20 mm across the curvature (x) and 30 mm along the cylinder axis (y). Both curvatures must reach the point of its edge farthest from the axis, 18 mm for the default; Open is refused.

Dummy

Analysis

The incoming light data is simply passed unmodified through the node. Given an optic shape, the dummy acts as an iris: a ray outside of it misses the dummy (see Optic shape).

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

optic shape
The opening of the iris, unbounded (Open) by default, so that all light passes. Any shape with an edge can be set instead. A ray outside of it follows the analyzer’s missed surface strategy: with Ignore it passes unchanged, with Stop it is lost (see Optic shape).

Energy meter

Analysis

As a detector node, incoming light data is passed unmodified through the node. In a ray tracing or ghost focus analysis, the node measures only the light within its optic shape: light outside its window passes on unmeasured, and the log and the report warn about it.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

meter type
The type of the energy meter. This property will be used in the future to model different energy / power meters with its characteristic properties (e.g. wavelength depenedent sensitivity, etc.). Current options are:
  • IdealEnergyMeter
  • IdealPowerMeter (currently not used)
optic shape
The window the meter measures within, a square of 25 mm × 25 mm by default. Set it to the size of the sensor, or to Open to measure all light. If the optical axis misses the window during the alignment run, a warning says that the measurement may fail (see Optic shape).

Fluence detector

Analysis

As a detector node, incoming light data is passed unmodified through the node. In a ray tracing or ghost focus analysis, the node records only the light within its optic shape: light outside its window passes on unrecorded, and the log and the report warn about it.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

fluence estimator
The algorithm used to estimate the fluence. Currently there are the following options:
  • Voronoi:
  • KDE:
  • Binning:
  • HelperRays:

Further information can be found here

optic shape
The window the detector records within, a square of 25 mm × 25 mm by default. Set it to the size of the camera chip, or to Open to record all light. If the optical axis misses the window during the alignment run, a warning says that the measurement may fail (see Optic shape).

Ideal filter

This node represents an ideal absorptive filter. Hence it has no geometric thickness or material properties. This element only changes the energy of the incoming light. The geometry of single rays remains unchanged.

Analysis

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

filter type
The filter definition. Currently there are these options:
  • Constant: The incoming energy is attenuated by a constant (wavelength independent) factor. A value of 0.0 corresponds to a total absorption while 1.0 denotes a fully transparent filter.
  • Spectrum: The incoming energy is attenuated according to the given filter spectrum. The filter spectrum is an array of filter values (between 0.0 and 1.0) with respect to a wavelength bin.
optic shape
Transversal extent of the filter. Only rays within it are filtered. A ray outside of it follows the analyzer’s missed surface strategy: with Ignore it passes unfiltered, with Stop it is lost (see Optic shape). Defaults to a circle of 12.5 mm radius; Open is refused.

Mirror

This node represents a perfect mirror, which can be flat or spherically curved. Note, that it only represents the mirror surface thus being a thin mirror. Hence it only has one input and one output port and does not provide a “leakage” output.

Aanalysis

For ray tracing analysis, incoming rays are deflected according to the laws of reflection. For energy analysis, the incoming light is unmodified.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers reflected light data from the port input_1.

Properties

curvature
The radius of curvature of the mirror surface. A negative value corresponds to a concave (= focussing) mirror while a positive value corresponds to a convex (= defocussing) mirror. A value of +infinity or -infinity represents a flat mirror. The curved surface must reach the edge of the optic shape: for a radius below 12.5 mm, reduce the optic shape first.
optic shape
Transversal extent of the mirror. It decides which rays are reflected: a ray outside of it, or through one of its bores, is lost in every analysis, since the mirror has no output for it (see Optic shape). Defaults to a circle of 12.5 mm radius; Open is refused.

Node group

Analysis

Ports

The ports of this node are defined by the port mapping of the internal node within this group.

Properties

expand view
A boolean value, which determines if the containing nodes are displayed in the report diagram (true) or just the collapsed group node (false). Defaults to false.

Parabolic mirror

Analysis

Ports

input_1
Input port.
output_1
Light ouput. This port represents the light after the refelction on the mirro surface.

Properties

focal length
The focal length of the parabola. A positive value corresponds to a concave (=focussing) parabola.
oa angle
Off-axis angle. This value determines the off-axis angle of the parabola. Internally the parabola surface is shifted accordingly by the respective amount with respect to the parabola’s origin. The direction of the shift is defined by the property oa direction.
oa direction
Orientation of the off-axis angle (see oa angle). This is a 2D vector denoting the direction of the off-axis shift with respect to the local coordinates.
collimating
Boolean value determinig if the parabola is used to collimate a beam.
optic shape
Transversal extent of the mirror, measured parallel to the parent axis of the parabola, as catalogs state it for off-axis parabolas. It decides which rays are reflected: a ray outside of it is lost in every analysis (see Optic shape). Defaults to a circle of 12.5 mm radius; Open is refused.

Paraxial surface

A paraxial surface represents an ideal lens which is free of geometric or chromatic aberrations. During ray analysis, an incoming collimated beam is focussed down to a spot size of zero. During energy analysis, the light is not modified.

Analysis

Ports

input_1
Input port.
output_1
Light ouput. This port represents the light having passed this ideal lens.

Properties

focal length
The focal length of this ideal lens. A positive values denotes a focussing lens.
optic shape
Transversal extent of the ideal lens. Only rays within it are focussed. A ray outside of it follows the analyzer’s missed surface strategy: with Ignore it passes unchanged, with Stop it is lost (see Optic shape). Defaults to a circle of 12.5 mm radius. As an idealization, the paraxial surface may also be unbounded (Open): it then focusses every ray, however far off the axis.

Reference node

Key Usage Considerations

  • Placement restriction: A reference to a group node must not be placed inside that same group, or inside any group nested within it, at any depth. Doing so would make the group depend on its own reference, which is rejected when creating, moving, cutting, or pasting a reference node. hence, this operation is prohibited.

Analysis

Ports

The ports of a reference node correspond to the ports of the node it refers to.

Properties

This node type has no specific properties itself. All properties of this node correspond to the original node it refers to.

Reflective grating

Analysis

Ports

input_1
Input port.
output_1
Light ouput. This port represents the light which has being reflected on the grating.

Properties

line density
The density (lines per length) of the regular structure on the grating.
diffraction order
The diffraction order delivered a output port output_1.
optic shape
Transversal extent of the grating. It decides which rays are diffracted: a ray outside of it is lost in every analysis (see Optic shape). Defaults to a square of 25 mm × 25 mm. Open is refused.

SourcePort

Spectrometer

Analysis

As a detector node, incoming light data is passed unmodified through the node. In a ray tracing or ghost focus analysis, the node records only the light within its optic shape: light outside its window passes on unrecorded, and the log and the report warn about it.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

spectrometer type
The type of the spectrometer. Currently the following options are available.
  • Ideal: Ideal spectrometer with constant (wavelength independent) sensitivity.
  • H2000: Ocean Optics HR2000 spectrometer. Not really supported yet.
optic shape
The window the spectrometer records within, a square of 25 mm × 25 mm by default. Set it to the size of the entrance, or to Open to record all light. If the optical axis misses the window during the alignment run, a warning says that the measurement may fail (see Optic shape).

Spherical lens

This element represents a “real” lens with spherical front and back surfaces. Furthermore, the lens consists of an optical material, which carries the refractive index model among other data. The center thickness denotes the distance of the front and back surfaces at symmetry axis of the lens.

The optic shape decides which rays hit the lens (see Optic shape). Choose it so that the lens keeps a positive edge thickness: where the front and back surfaces would cross, e.g. beyond the rim of a thin biconvex lens, rays miss the rear surface.

Since this element encloses a volume of material, it can be operated as an amplifier: a pump scenario assigns it a gain model, and light travelling through the medium is amplified accordingly. Without such an assignment the lens is the passive component described here.

Analysis

  • Energy Analysis

    During energy analysis, besides the common behaviour, this element does not alter the incoming the incoming light. The output is a copy of the input light. Above mentioned apertures are ignored.

  • Ray tracing Analysis

    During ray tracing analysis, incoming rays are refracted on the frontsurface according to Snellius’ law of refraction. Inside the lens the ray propagate within the given medium. On the rearsurface, the rays are again refracted. A ray reaching a surface outside the optic shape misses the lens and follows the analyzer’s missed surface strategy.

  • Ghost focus Analysis

    During this analysis, the lens behaves similar to the ray tracing analysis. A ray outside the optic shape passes the lens unchanged.

Ports

  • input_1

    Input port. Corresponds to the frontsurface of the lens.

  • output_1

    Light ouput. This port represents the light having passed the rear surface of the lens.

Properties

  • front curvature

    Radius of curvature of the front surface. This value must not be zero. A positive value denotes a convex surface. The value infinity or -infinity denotes a flat surface.

  • rear curvature

    Radius of curvature of the rear surface. This value must not be zero. A positive value denotes a concave surface. The value infinity or -infinity denotes a flat surface.

  • center thickness

    Thickness of the lens center at its symmetry axis. This value must be positive and finite.

  • material

    The (glass-) material the lens is made of. It carries the refractive index model — a constant value or a dispersion formula such as Sellmeier or Schott — which is what the refraction at both surfaces is calculated from.

  • optic shape

    Transversal extent of the lens: the size the material is actually available in, the figure a supplier quotes next to the curvatures and the thickness. It decides which rays hit the lens. Defaults to a circle of 12.5 mm radius, i.e. the usual 1 inch mount. Both curvatures must reach its edge; Open is refused.

Spot diagram

Analysis

As a detector node, incoming light data is passed unmodified through the node. In a ray tracing or ghost focus analysis, the node records only the light within its optic shape: light outside its window passes on unrecorded, and the log and the report warn about it.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

plot aperture
Boolean value. Outline the recording window (optic shape, unless it is Open) in the plot. Defaults to false.
optic shape
The window the spot diagram records within, a square of 25 mm × 25 mm by default. Set it to the size of the camera chip, or to Open to record all light. If the optical axis misses the window during the alignment run, a warning says that the measurement may fail (see Optic shape).

Wavefront monitor

Analysis

As a detector node, incoming light data is passed unmodified through the node. In a ray tracing or ghost focus analysis, the node records only the light within its optic shape: light outside its window passes on unrecorded, and the log and the report warn about it.

Ports

input_1
Input port.
output_1
Light ouput. This port delivers a copy of the light data from the port input_1.

Properties

optic shape
The window the wavefront monitor records within, a square of 25 mm × 25 mm by default. Set it to the size of the sensor, or to Open to record all light. If the optical axis misses the window during the alignment run, a warning says that the measurement may fail (see Optic shape).

Wedge

This element represents a plate of optical material whose front and back surfaces are flat but not parallel. A wedge angle of zero turns it into a plane-parallel plate.

Since this element encloses a volume of material, it can be operated as an amplifier: a pump scenario assigns it a gain model, and light travelling through the medium is amplified accordingly. Without such an assignment the wedge is the passive component described here. With flat surfaces and a suitable optic shape it is the closest match to a slab or disk amplifier head.

Ports

input_1
Input port.
output_1
Light ouput. This port represents the light having passed the back surface of the wedge.

Properties

center thickness
Thickness of the wedge in its center along the (local) optical axis.
material
The (glass-) material the wedge is made of. It carries the refractive index model — a constant value or a dispersion formula such as Sellmeier or Schott — which is what the refraction at both surfaces is calculated from.
wedge
Wedge angle. Angle between the front and back surface. An angle of zero corresponds to parallel surfaces.
optic shape
Transversal extent of the wedge: the size the material is actually available in. It decides which rays hit the wedge, at both of its faces: a ray that would enter or leave through the side misses it and follows the analyzer’s missed surface strategy (see Optic shape). Defaults to a circle of 12.5 mm radius, i.e. the usual 1 inch mount. Choose it so that the wedge keeps a positive thickness: beyond its thin edge rays miss the rear surface. Open is refused.

Edges

Materials

A material describes what an optical component is made of. It bundles a set of optical properties — a refractive index model and an absorption model — with optional thermal and mechanical data, and it is stored independently of any node so the same material can be reused across components and models. A component that encloses a volume (a lens, a wedge or a cylindric lens) refers to a material for both its refraction and, when defined, its absorption.

This page documents the absorption models. For the physical picture — why absorption is a property of the material rather than of an analysis, and how it combines with gain — see Absorption.

Absorption models

A material’s optical properties carry one absorption model. It is applied during ray tracing over the geometric path length L a ray travels through the component’s medium, at the ray’s own wavelength λ, and yields a transmittance T ∈ [0, 1] that scales the ray’s energy. The default is None (perfectly transparent), so a material with no absorption defined leaves rays unchanged.

ModelParameter(s)Transmittance T(λ, L)
None—1 (transparent; the default)
Constant attenuationa flat factor f ∈ [0, 1]f, independent of wavelength and path length
Lambert–Beer, constantabsorption coefficient α (in 1/m)exp(−α·L)
Lambert–Beer, spectrumα(λ) as a spectrum (values in 1/m)exp(−α(λ)·L)
Catalog transmittancetabulated internal transmittance τ(λ) at a reference thickness d_refτ(λ)^(L / d_ref)
Extinction coefficientk, the imaginary part of the complex index n + ikexp(−α·L) with α = 4π·k / λ

Notes on the individual models:

  • Constant attenuation is a path-length-independent factor — a flat fraction of energy removed on transit. It is a bookkeeping model, not a bulk absorption, and does not scale with how far the ray travels through the medium.
  • Lambert–Beer, constant / spectrum are the physical bulk-absorption models. The constant form uses one coefficient for all wavelengths; the spectrum form looks the coefficient up per wavelength, so different lines of a polychromatic beam are attenuated differently.
  • Catalog transmittance takes an internal transmittance quoted by a glass catalog at a reference thickness and scales it to the ray’s actual path length by the power law above.
  • Extinction coefficient derives the Beer–Lambert coefficient from the imaginary part of the complex refractive index, α = 4π·k / λ.

A wavelength or path length outside a model’s valid range (for instance a wavelength not covered by a spectrum) is reported as an error rather than silently extrapolated.

Physical Processes, Subsystems and Components

Modern laser systems are composed of a large number of optical subsystems and individual optical components. For a holistic description of such a system, all these optical components and the structures that are built from these must be modeled. Furthermore, a numerous amount of physical effects/processes must be included to create a realistic view of the full system.

In the following, a, probably not complete, list of relevant effects/processes, subsystems and components for high-intensity lasers will be compiled.

Physical Effects/Processes

Gain

Obviously, gain modeling of high-intensity lasers is indispensable to design either single amplifier modules or to get useful output predictions of the whole laser facility. Furthermore, spatially, temporally and spectrally dependent gain will alter the dynamics of the beam propagation and is needed for a full description of the laser system. Therefore, several gain models should be on hand for this:

  • Gain as simple multiplicator
  • Full rate-equation modeling
  • 3-level, 4-level, quasi-three level
  • Analytic approximations
  • Saturation effects:
    • Frantz-Nodvik equation
    • Wavelength-dependent saturation: Homogeneous/Inhomogeneous broadening
    • Absorption
    • Spatial Hole Burning
  • 3D, 2D, 1D descriptions
  • Spatial/Temporal Mode support of the amplifier

Simultaneously, effects that may alter or limit the gain and output of an amplifier should be regarded, such as:

  • Amplified Spontaneous Emission
  • Parasitic Lasing
  • Parametric Fluorescence

Second-order nonlinear effects

Second-order nonlinear effects include all processes that result from the response of the second-order susceptibility $\chi^{(2)}$:

  • Second-Harmonic Generation (SHG)
  • Sum-Frequency Generation (SFG)
  • Difference-Frequency Generation (DFG)
  • Optical Rectification (OR)

Furthermore, processes that utilize these processes shall be part of the description, such as:

  • Optical Parametric Amplification (OPA)
  • Optical Parametric Chirped-Pulse Amplification (OPCPA)
  • Optical Parametric Generation/Oscillation (OPG/OPO)
  • Spontaneous Parametric Down Conversion (SPDC, Parametric Fluorescence)
  • Cascaded Mixing effects
  • THz Generation

These effects are typically modeled by solving the nonlinear propagation equation with $\chi^{(2)}$ acting as the source term.

Third-order nonlinear effects

Similar to the second-order effects, third-order effects result from the response of the medium, described by the third-order nonlinear susceptibility $\chi^{(3)}$. This nonlinear response is responsible for a variety of effects:

  • Kerr effect
    • Self-Phase Modulation (SPM)
    • Cross-Phase Modulation (XPM)
    • Modulational Instability
    • Self-focusing (Whole beam and small scale)
    • Two-Photon Absorption
    • Self-Steepening
  • Four-Wave Mixing
    • Third Harmonic Generation
    • Parametric Amplification in fibers
    • Cross-Polarized Wave Generation
    • Self-Diffraction
    • Optical Phase Conjugation

While the above-mentioned processes act quasi-instantaneous, delayed nonlinear responses of the medium are also relevant for the description of some processes. The most prominent effects here are:

  • Stimulated Raman Scattering (SRS)
  • Stimulated Brillouin Scattering (SBS)

Other Effects

Aside from processes that are related to the nonlinear susceptibility of the medium, various other processes exist which may alter the electric field during propagation/amplification. These include:

  • Thermal Effects such as thermal lenses, thermally induced birefringence
  • Electro-Optic Effects: Pockels Effect, Photorefraction
  • Acousto-Optic Effects: Deflection or frequency shifts in, e.g., acousto-optic modulators
  • Gain/Absorption saturation

Subsystems of modern laser facilities

Amplifiers

The most relevant subsystems to create high intensities are the amplifiers of the laser. In modern laser systems, the amplification follows the structure of the “Master-Oscillator Power Amplifier” (MOPA). This means that the amplifiers are linked in succession and the output of a previous amplifier is used as input for the next one. This allows the amplifier chain to be conveniently described by means of nodes, whereby the individual amplifier nodes themselves can be, but do not necessarily have to be, described using a node system. Nowadays, there are a large number of amplifier types that are implemented in modern laser systems. In the following, several amplifier types and their relevant pumping mechanisms are listed:

  • Fiber-based amplifiers
    • Continuous/pulsed laser diode pumping: Forward, backward, forward + backward
  • Cavity-based amplifiers
    • Short-Pulse Oscillators (CW pump: e.g. frequency-doubled Nd:YAG)
    • Regenerative amplifiers (pulsed pumping: flash lamp, laser diode)
    • Optical parametric oscillators (CW pumping or two coupled resonators)
    • Thin-Disk amplifiers (same as regenerative amplifier but also CW laser-diode pumping for high repetition rate)
  • Non-Cavity-based Multi-Pass Amplifiers
    • Relay-imaged multi-pass (pulsed/cw laser diodes)
    • Non-imaged multi-pass (pulsed/cw laser diodes)
    • Innoslab Amplifiers (pulsed/cw laser diodes)
  • Rod Amplifiers (Complex Flash-Lamp Pump geometries)
  • Slab Amplifiers (Complex Flash-Lamp Pump geometries)
  • Coherent Beam Combination (no pump)
  • OPA/uOPA/OPCPA (from cw to narrowband long pulse, broadband long pulse or short pulse pump)

Beam Transport

As laser facilities consist of multiple, subsequent amplifier modules, beam transportation is necessary which is typically done via telescopes. Here, certain aspects are of relevance:

  • Magnification
  • Imaging of the beam: Relay-Imaging
  • Aberrations
  • Use for mode matching
  • Use for diffractive Beam shaping
  • Transmissive or reflective telescope
  • Parabola usage

Stretching and Compression

To reach highest intensities, the concept of chirped-pulse amplification is typically used which requires temporally stretching the pulses and compressing them after amplification. While the use of gratings for the main stretching and compression modules have prevailed, other systems are nonetheless found in laser systems. Accordingly, various setups should be regarded:

  • Grating stretcher
    • Martinez setup (Unfolded with lenses)
    • Martinez setup (Unfolded with mirrors)
    • folded Martinez (Banks)
    • Öffner setup
  • Grating Compressor
    • Four gratings
    • Two gratings with a double pass
    • Two gratings with single pass
  • Prisms
  • Grisms
  • Chirped Fiber/Volume Bragg Gratings
  • Dispersion-based Fiber Stretcher (long fiber)
  • Chirped mirror setups
  • Gires-Tournois Interferometer setups

Effects concerning stretching and compression process which should be included are:

  • Calculation of the phase
  • Misalignment sensitivity
  • Contrast issues due to Spatiospectral coupling

Measurement devices

Every laser system relies on constantly doing measurements to observe the quality of the provided pulses/beams. Consequently, holistic simulation software should provide the outcome of the simulation either in a direct, “ideal” way or modulated as measured with a certain device. For example, a measured signal of a photodiode is a convolution of the real input signal with the response function of the diode. Such a response of a device may be specifically calculated for each type of device or even more specific for an exact rebuild of a given device. Below, a list of potential parameters of interest and a list of measurement devices is given.

  • Parameters
    • Energy
    • Power
    • Fluence
    • Intensity
    • Spectrum
    • Spectral Phase
    • Pulse duration
    • Electric Field
    • Beam size
    • Wave front
    • Temporal Contrast
    • Spatial Contrast
  • Measurement Devices
    • Energy Meter
    • Photo Diode
    • Camera
    • Shack-Hartmann Sensor
    • Spectrometer
    • FROG, SPIDER, Wizzler
    • Autocorrelator, Cross-Correlator
    • Shear Plate
    • Interferometer setups

Optical Components

Every subsystem is composed of at least one or multiple optical components, which are the basis for the modeling of the whole laser system. Each component itself may be modeled separately and effective values may be used in its simulation node. Alternatively, the whole structure of the component may be modeled to get the most realistic output. For example, a more idealistic lens may contain information about its focal length only and a more thorough lens may use information such as the radius of curvature of all surfaces, its aperture and refractive index profile. In optical systems, a broad variety of different single optical components are used, which however may be classified into several groups:

  • Lenses
    • Spherical, Aspherical, Achromatic, Cylindrical,
    • Fresnel, Axicon, GRIN, Powel Lens
    • Microlens array
  • Mirrors
    • Flat, Curved
    • Dielectric, Metalic
  • Beamsplitter
    • Polarizing, Spectral, Pellicle, Polka Dot
  • Filter
    • Spectral, Polarizing, Neutral density
  • Dispersive Elements
    • Prisms, gratings, Grisms, fiber gratings
  • Nonlinear Crystals
    • Uniaxial, Biaxial
  • Laser Medium
  • Fiber
  • Phase plates
  • Polarization Manipulation
    • Pockels Cell, Faraday Rotator, Wave plates
  • Apertures
    • Pinholes, Serrated

Whether a fixed classification in group nodes is useful still has to be determined.

Model analysis

Once a model is set up by defining the nodes, assigning specific node parameters, the model is ready to be analyzed / simulated.The model setup also includes creating connections between the input and output ports of the nodes and assigning the propagation distances between connected nodes, which define the optical path through the network. As already discussed in the introduction, the model could be analyzed in very different ways. One might simulate the system using geometric optics. A very simple analysis might only calculate the power / energy flow through the network.In addition, a 3D ray-tracing procedure could give insight into illumination or stray-light scenarios.Besides this “direct” simulation of the model, it is possible to simply export the model into a given format suitable for external simulation software (e.g. ZEMAX or GLAD).

Model analysis is used to simulate the behavior of the optical system and obtain information about light propagation through the model. OPOSSUM provides different analyzers for different simulation goals. Depending on the selected analyzer, different aspects of the optical system can be analyzed and different types of optical information can be calculated.

The available analyzers and their respective analysis methods are described in the Analyzers section.

Analyzers

An analyzer is a module that “orchestrates” an optics simulation. An analyzer defines how the model will be treated. There are basically two types of analyzers: Sequential and Non-Sequential. A sequential analyzer traverses the graph in a defined manner and triggers the corresponding calculation defined inside the nodes. In contrast, the non-sequential analyzer does not actually make use of the graph structure (i.e. the relations between the nodes) but only uses the nodes and their corresponding attributes such as 3D coordinates or mechanical model data.

Note: The use of different analyzers might lead to “contradicting” models. For example, one can model a free-space propagation node between two other elements (e.g. two lenses). It can thus define a given geometric length as an attribute. On the other hand, the two lenses might have 3D coordinates with a different distance to each other than defined in the propagation node. In this case, the sequential analysis would simulate another model situation as the non-sequential analyzer…

Sequential Analyzers

A sequential analyzer uses the node relations defined by the edges of the model graph. It would traverse the graph starting from one or more sources to one or more sink nodes. While traversing, it calls the respective analysis functions of each node. The input data is taken from previously calculated light information stored in the input edges of a node. The node’s analysis result will be stored on the output edges.

The analyzer type also determines the type of data “flowing” between the nodes. For the energy analyzer, the data mainly consists of a light spectrum, while the ray tracing analyzer uses bundles of geometric rays. These rays contain information such as position, direction, wavelength, and other ray properties. Furthermore, each analyzer can have a specific set of configuration parameters that influence the respective analysis algorithm.

The analyzer is also used to configure the properties of source ports.

Depending on the selected analyzer type, different source port configuration options are available.

Each analyzer can be assigned a user-defined name in the GUI. This is particularly useful when a model contains multiple analyzers of the same type (e.g. two Energy analyzers with different source configurations): the name makes them easy to tell apart on the canvas and in reports. If no name is set, the analyzer’s type label (“Energy”, “Ray Tracing”, …) is used as a fallback.

Besides its own configuration, an analyzer carries a list of the pump scenarios it is run in — the operating points at which the model’s amplifying components are driven. It produces one report per listed scenario; an empty list means a single run on the passive model.

The following analyzers are implemented:

  • Energy Analysis

    This is the simplest analyzer. It just calculates the energy spectrum while passing through the optical system. Filter nodes attenuate the spectrum while beam splitter nodes divide the energy spectrum in two arms according to the splitting config. On the other hand, many other nodes such as lenses or gratings do not influence the data during the pass. Hence, this analyzer gives you rather limited information about an optical system. The advantage on the other side is that this analyzer is really fast. The energy analyzer has no further configuration parameters.

    The analyzer is also used to configure the properties of source ports. For the energy analyzer, the source port configuration provides the Energy type, Wavelength, Energy, and Resolution options.

    The Energy type provides two options: Laser lines and From file. The default energy value is 1 Joule, and the default wavelength is 1.054 µm.

  • Ray Tracing Analysis

    The ray tracing analyzer uses bundles of geometric rays. These rays contain information such as position, direction, wavelength, and other ray properties.

    Compared to the energy analyzer, the ray tracing analyzer provides more detailed information about the geometrical behavior of light propagation through the optical system, since individual rays are tracked during the analysis.

    The ray tracing analyzer provides configuration parameters including the maximum number of refractions, maximum number of bounces, minimum ray energy, and missed surface strategy. The maximum number of refractions defines the maximum number of refraction events considered during the analysis. The maximum number of bounces defines the maximum number of reflections considered during the analysis. The missed surface strategy defines how rays are handled that miss a surface, including rays that reach it outside the optic shape of its component. The available options are Stop, the default, which loses such rays, and Ignore, which lets them pass unchanged (see Optic shape). The alignment run that places the components always uses Stop.

    The analyzer is also used to configure the properties of source ports. For the ray tracing analyzer, the source port configuration provides options for the Ray type, Position distribution, Energy distribution, and Spectral distribution. The available ray types are Collimated, Point, and Image.

  • Ghost Focus Analysis

    The ghost focus analyzer can be seen as an extended ray tracing analyzer. In fact, the ghost focus analyzer with the Max bounces parameter set to zero is the basic ray tracing analysis presented above. A ray that misses a surface, e.g. outside the optic shape of its component, always passes it unchanged, as with the Ignore strategy of the ray tracing analyzer.

    The ghost focus analyzer is particularly important for the analysis of high-energy laser systems. In practical optical systems, optical surfaces are not ideal and can generate unintended reflections. Although these reflections may represent only a small fraction of the incident energy, they can become significant in systems operating with pulse energies in the kilojoule (kJ) range. For example, a reflection of only 1% corresponds to several joules of optical energy, which can affect other optical components and the overall optical system.

    The ghost focus analyzer provides the Max bounces configuration parameter. The Max bounces parameter specifies the maximum number of reflections that are considered during the analysis. A value of 1 considers rays that undergo a single reflection. A value of 2 considers rays that undergo two reflections, for example, one reflection at one optical surface followed by a second reflection at another optical surface. Likewise, values of 3 or 4 consider rays that undergo three or four reflections, respectively. Higher values therefore include additional reflection paths that may occur within the optical system. This is particularly important for high-energy laser systems, where even a small reflected fraction of the laser energy can correspond to several joules and may affect optical components and the overall system.If the Max bounces parameter is set to zero, no reflections are considered. However, this mode can still be useful because it allows analyzing the fluence of the primary beam (the main laser beam) on all optical surfaces and, for example, ensures that they all remain within safe limits.

    Additionally, it provides a Fluence Estimator option, which allows selecting the fluence estimator used for the analysis. For further details on the available fluence estimators and their differences,see the Fluence Estimators section.

Pump scenarios

A pump scenario is a named operating point of a model: it states, for every amplifying component, how strongly that component amplifies during one analysis. Scenarios belong to the document, not to any node, and are stored in the .opm file. For the reasoning behind that split see Amplification; for the steps to set one up, see Model an amplifier.

A scenario consists of a name and, per node, a gain model. A node no scenario mentions is analyzed exactly like the passive component it is.

Managing scenarios

Scenarios are created by typing a name in the “New scenario name” field at the top of the pump scenario panel and pressing Add (or Enter). An existing scenario can be duplicated — button with the copy icon (⧉) next to the delete button on the scenario card, or via right-click → Duplicate on the card — which creates a copy of the scenario, including all its node configurations, with “ (copy)“ appended to the name. Both the original and the copy can then be edited independently. Duplicating is undoable.

Gain models

None

No amplification. The default, and what every node not named by the scenario falls back to. A node set to None behaves like the passive optic it is.

Const

A constant energy gain. The energy of the light passing the medium is multiplied by the gain factor, once per traversal of the medium.

gain factor
The factor the energy is multiplied by. Must be finite and non-negative; 1.0 is neutral, so selecting Const does not change a result until the factor is set. The factor does not depend on wavelength, on the path length through the medium, or on how much energy was already extracted — see Amplification for what this model is and is not good for.
Small Signal Gain

A monochromatic, unsaturated gain model. A pump source fills the component’s volume with a spatial gain field; each ray accumulates gain along the actual path it takes through the medium. The gain coefficient g₀ is wavelength-independent — all wavelengths in the beam receive the same gain. For the underlying concepts see Amplification.

grid (n_x × n_y × n_z)
Number of cells in the discretized gain field, along x, y (transversal) and z (longitudinal). The ray traverses each cell exactly (Amanatides–Woo algorithm), so finer grids resolve spatial structure in the pump profile more accurately without any additional step count. All three must be at least 1. Default: 16 × 16 × 16.

Pump source

The pump source defines the spatial distribution of the small-signal gain coefficient g₀ across the medium’s volume.

None

No pumping. The gain field is zero everywhere; the component behaves passively.

Const

A spatially uniform g₀.

peak gain coefficient (g₀)
The small-signal gain coefficient, uniform across the volume. Must be finite. Negative values model an absorbing medium. Unit: m⁻¹ (or cm⁻¹).
Analytic

A spatially profiled g₀, composed of independent transversal and longitudinal factors. The coefficient at each point is g₀ × T(x, y) × L(z), where T and L are each peak-normalized to 1 at the profile center or inlet.

peak gain coefficient (g₀)
The peak value of the profile, at the center of the transversal profile and the inlet of the longitudinal one. Same rules as for Const.

Transversal profile — across the aperture (x–y plane):

Flat

Uniform across the aperture; T(x, y) = 1 everywhere.

Super-Gaussian

A generalized Gaussian, peak-normalized to 1 at the center.

center (x, y)
Center of the profile in the component’s local frame. Unit: length. Default: (0, 0).
sigma (x, y)
1/e² half-widths along x and y. Must be positive.
power
Gaussian order (≥ 1). 1 gives an ordinary Gaussian; higher values give a flatter top with steeper edges (top-hat limit).
theta
Rotation of the ellipse in the transversal plane.
rectangular
If enabled, the profile is the product T_x(x) × T_y(y) instead of an elliptical function of the radial distance — useful for rectangular pump beams.

Longitudinal profile — along the propagation direction (z):

Flat

Uniform along z; L(z) = 1 everywhere.

Lambert-Beer

Exponential absorption of the pump: L(z) = exp(−α × z), where z is measured from the surface the pump enters.

absorption coefficient (α)
Absorption coefficient of the pump light in the medium. Must be positive and finite. Unit: m⁻¹ (or cm⁻¹).
direction
Forward — pump enters from the input surface (z = 0 there). Backward — pump enters from the output surface (z = 0 at the rear face).

Which components can amplify

Only nodes that enclose a volume of material can carry a gain model:

This follows from the node type itself, not from a list maintained in the user interface, so a node type gaining a volume in the future becomes usable as an amplifier without anything else being changed. Other node types do not offer the setting.

Amplifier candidate. Marking a node as an amplifier is bookkeeping for the user interface: it determines which nodes the scenario editor offers a row for and what the canvas shows on the node. It is not what makes a component amplify. The analysis reads the gain model in the scenario and nothing else — worth knowing when a model is built in code, where the marking is optional.

Running an analysis in a scenario

Each analyzer carries a list of the scenarios it is run in, alongside its own configuration (see Analyzers). The list behaves as follows:

  • One report per scenario, produced in the order the scenarios are listed. The report’s analysis type is extended by the scenario’s name, e.g. Energy Analysis - full power, so the reports of one model at different operating points are told apart by their title.
  • An empty list means a single passive run — the behaviour of every analyzer before scenarios existed. This is not an error and needs no scenario to be defined.
  • Every run starts from the same model state, so scenarios do not influence one another regardless of the order they are listed in.
  • Deleting a scenario removes it from the selection of every analyzer that referred to it. An analyzer pointing at a scenario that does not exist is reported as an error before the analysis starts, rather than silently running passively.

Effect on the individual analyses

Const is evaluated in all three analyses:

Energy Analysis
The spectrum passing the component is scaled by the gain factor.
Ray Tracing Analysis
Every ray of the bundle inside the medium is scaled by the gain factor, between the entrance and the exit surface of the component.
Ghost Focus Analysis
As in ray tracing, and applied on every pass — including the reflected paths. A ghost that crosses a pumped medium twice more than the main beam is amplified twice more.

Small Signal Gain is evaluated in ray tracing and ghost focus analysis only:

Energy Analysis
Not supported. The gain depends on the path each ray takes through the medium; an energy flow analysis carries no spatial or geometric information about individual rays and cannot determine it. A model that assigns Small Signal Gain to a component returns an error when an Energy Analysis is run on it.
Ray Tracing Analysis
The gain factor for each ray is computed by integrating g₀ along the ray’s actual path through the medium. Rays that do not intersect the medium’s volume are unaffected.
Ghost Focus Analysis
As in ray tracing, computed independently on every pass — including reflected ghost paths. A ghost that traverses a pumped component picks up gain on each crossing.

Interfacing with external code

The presented project is set up as a simulation platform which means that it only provides the framework / infrastructure to perform complex simulations of optical systems. This can be done in different ways. Once an optical system is modeled as explained before it should basically contain all data necessary to run specific simulation codes. Besides that, the entire network can be exported to files compatible with other simulation systems. This is mostly of interest for closed-source (commercial) software packages such as ZEMAX or GLAD. Fortunately, these software packages have more or less human-readable project files which can be reverse-engineered with not too much effort.

For existing open-source software packages it is important to provide interfaces. So far, two codes could be used as proof-of-principle projects:

  • SHG software (GSI)

    This software simulates the behavior of non-linear crystals for second-harmonic generation. This package is written in Python and could be integrated into an “SHG node”. It should be investigated, how the interfacing could be performed. Some preliminary work has been done in the current “play project” opticplay. The external code was called from Rust using the PyO3 library.

  • HASEonGPU (HZDR)

    This software package is written in C++ and works on graphic CPUs (using CUDA?). If this project provides an external library (DLL) it would be relatively easy to implement. This has to be investigated.