Analysis

class ledsa.analysis.ExtinctionCoefficients.ExtinctionCoefficients(experiment, reference_property='sum_col_val', num_ref_imgs=10, ref_img_indices=None, average_images=False)[source]

Bases: ABC

Parent class for the calculation of the Extinction Coefficients.

Variables:
  • coefficients_per_image_and_layer (list[np.ndarray]) – List of coefficients for each image and layer.

  • experiment (Experiment) – Object representing the experimental setup.

  • reference_property (str) – Reference property to be analysed.

  • num_ref_imgs (int) – Number of reference images. # TODO: create test for this

  • ref_img_indices (list[int] or None) – Indices of reference images to use. If None, use num_ref_imgs.

  • calculated_img_data (pd.DataFrame) – DataFrame containing calculated image data.

  • distances_per_led_and_layer (np.ndarray) – Array of distances traversed between camera and LEDs in each layer.

  • ref_intensities (np.ndarray) – Array of reference intensities for all LEDs.

  • cc_matrix (np.ndarray or None) – Color correction matrix.

  • average_images (bool) – Flag to determine if intensities are computed as an average from two consecutive images.

  • solver – Indication whether the calculation is to be carried out numerically or analytically.

apply_color_correction(cc_matrix, on='sum_col_val', nchannels=3) None[source]

Apply color correction on channel values based on color correction matrix.

Parameters:
  • cc_matrix (np.ndarray) – Color correction matrix.

  • on (str) – Reference property to apply the color correction on.

  • nchannels (int) – Number of channels.

calc_and_set_coefficients() None[source]

Serial calculation of extinction coefficients for every image

calc_and_set_coefficients_mp(cores=4) None[source]

Uses multiprocessing to calculate and set extinction coefficients.

Parameters:

cores (int) – Number of cores to use.

calc_and_set_ref_intensities() None[source]

Calculate and set the reference intensities for all LEDs based on the reference images.

abstractmethod calc_coefficients_of_img(rel_intensities: ndarray) ndarray[source]

Calculate the extinction coefficients for a single image. Needs to be implemented by the child class.

Parameters:

rel_intensities – Array of relative change in intensity of every LED.

Returns:

Array of the computed extinction coefficients

Return type:

np.ndarray

calc_distance_array() ndarray[source]

Calculate the distances traversed between camera and LEDs in each layer.

Returns:

Array of distances traversed between camera and LEDs in each layer.

Return type:

np.ndarray

load_img_data() None[source]

Load processed image data from binary file

save() None[source]

Save the computed extinction coefficients to a file.

set_all_member_variables(save_distances: bool = True) None[source]

Calculate distance traveled per layer, for every led, load image data from binary file and calculate reference intensities for each LED

Parameters:

save_distances (bool) – If True, write the distance matrix to a text file in the current working directory. Pass False when calling from a stacked context that manages its own distance file.

ledsa.analysis.ExtinctionCoefficients.multiindex_series_to_nparray(multi_series: pandas.Series) ndarray[source]

Convert a multi-index series to a NumPy array.

Parameters:

multi_series (pd.Series) – Series with multi-index to convert.

Returns:

Converted array.

Return type:

np.ndarray

class ledsa.analysis.ExtinctionCoefficientsLinear.ExtinctionCoefficientsLinear(experiment, reference_property='sum_col_val', num_ref_imgs=10, average_images=False, ref_img_indices=None, lambda_reg=0.001)[source]

Bases: ExtinctionCoefficients

ExtinctionCoefficientsLinear computes the extinction coefficients by linearizing the Beer–Lambert law. Specifically, using the transformation:

-ln(I_e / I_0) = sum_i (sigma_i * Delta s_{i})

the problem is recast as a linear least squares system that can be solved efficiently. A Tikhonov regularization is added via a finite-difference operator to enforce smoothness in the solution.

Variables:

solver (str) – Type of solver (linear or nonlinear).

calc_coefficients_of_img(rel_intensities: ndarray) ndarray[source]

Calculate the extinction coefficients for a single image using a linearized approach. This method solves the linear system derived from the Beer-Lambert law using non-negative least squares with Tikhonov regularization.

Parameters:

rel_intensities (np.ndarray) – Array of relative (normalized) LED intensities (I_e/I_0).

Returns:

Array of the computed extinction coefficients (sigmas).

Return type:

np.ndarray

class ledsa.analysis.ExtinctionCoefficientsNonLinear.ExtinctionCoefficientsNonLinear(experiment, reference_property='sum_col_val', num_ref_imgs=10, ref_img_indices=None, average_images=False, weighting_curvature=1e-06, weighting_preference=-0.006, num_iterations=200)[source]

Bases: ExtinctionCoefficients

ExtinctionCoefficientsNonLinear computes the extinction coefficients by directly minimizing the difference between observed and predicted intensities using the Beer-Lambert law:

I_e = I_0 * exp(-sum_i (sigma_i * Delta s_{i}))

A numerical optimization approach is used with regularization terms to enforce smoothness in the solution.

Variables:
  • bounds (list[tuple]) – Bounds for each layer.

  • weighting_preference (float) – Weighting factor for the preference to push the numerical solver to high or low values for the extinction coefficients.

  • weighting_curvature (float) – Weighting factor for the smoothness of the solution.

  • num_iterations (int) – Maximum number of iterations of the numerical solver.

  • solver – Type of solver (linear or nonlinear).

calc_coefficients_of_img(rel_intensities: ndarray) ndarray[source]

Calculate the extinction coefficients for a single image based on a minimization procedure.

Parameters:

rel_intensities – Array of relative (normalized) LED intensities (I_e/I_0).

Returns:

Array of the computed extinction coefficients (sigmas)

Return type:

np.ndarray

calc_intensities(sigmas: ndarray) ndarray[source]

Calculate the intensities from a given set of extinction coefficients. This implements the Beer-Lambert law and is called during the minimization of the cost function.

Parameters:

sigmas (np.ndarray) – An array of extinction coefficients (sigma values).

Returns:

An array of the calculated relative intensities (I_e/I_0).

Return type:

np.ndarray

cost_function(sigmas: ndarray, target: ndarray) float[source]

Calculate the cost based on the difference between the computed intensities and target intensities. The cost function aims to minimize the root mean square error (rmse) between the computed and target intensities, while also considering the smoothness of the solution (curvature) and boundaries of the coefficients (preference).

Parameters:
  • sigmas (np.ndarray) – Extinction coefficients (sigma values).

  • target (np.ndarray) – Target relative intensities (I_e/I_0).

Returns:

Computed cost.

Return type:

float

class ledsa.analysis.Experiment.Camera(pos_x: float, pos_y: float, pos_z: float)[source]

Bases: object

Contains a camera’s position in 3D space.

Variables:
  • pos_x (float) – The x-coordinate of the camera

  • pos_y (float) – The y-coordinate of the camera

  • pos_z (float) – The z-coordinate of the camera

pos_x: float
pos_y: float
pos_z: float
class ledsa.analysis.Experiment.Experiment(layers: Layers, led_array: int, camera: Camera, path=PosixPath('.'), channel=0, merge_led_arrays=False)[source]

Bases: object

Represents an experimental setup involving layers, an LED array, and a camera.

Variables:
  • layers (Layers) – The spatial layers involved in the experiment.

  • led_array (int) – The identifier for the LED array.

  • camera (Camera) – The camera involved in the experiment.

  • leds (List[LED]) – List of LED light sources.

  • led_number (int) – Number of LEDs on LED array.

  • path (Path) – File path for experiment data.

  • channel (int) – The camera channel to be analysed.

  • merge_led_arrays (bool) – Whether to merge LED arrays.

calc_traversed_dist_in_plane(led: LED) ndarray[source]

Calculate the distance traversed by light from an LED in a plane to the camera.

Parameters:

led (LED) – The LED light source

Returns:

Array of distances traversed in each layer within the plane

Return type:

np.ndarray

calc_traversed_dist_per_layer(led: LED) ndarray[source]

Calculate the distance traversed by light from an LED through each layer to the camera.

Parameters:

led (LED) – The LED light source

Returns:

Array of distances traversed in each layer

Return type:

np.ndarray

calc_traversed_dist_per_layer_with_nonzero_alpha(alpha: float, led: LED) ndarray[source]

Calculate the distance traversed by light from an LED through each layer to the camera, taking into account a non-zero angle of incidence.

Parameters:
  • alpha (float) – The angle of incidence

  • led (LED) – The LED light source

Returns:

Array of distances traversed in each layer considering the angle

Return type:

np.ndarray

calc_traversed_height_in_layer(led_height: float, layer_bot: float, layer_top: float) float[source]

Calculate the vertical distance (height) traversed by light from an LED within a layer.

Parameters:
  • led_height (float) – The z-coordinate of the LED

  • layer_bot (float) – The z-coordinate of the bottom of the layer

  • layer_top (float) – The z-coordinate of the top of the layer

Returns:

The vertical distance traversed within the layer

Return type:

float

distance_calculation_is_consistent(distance_per_layer: ndarray, led: LED, silent=True) bool[source]

Check if the computed distance values for each layer are consistent with the Euclidean distance.

Parameters:
  • distance_per_layer (np.ndarray) – Array of distances traversed in each layer

  • led (LED) – The LED light source

  • silent (bool, optional) – If set to False, prints out debugging information, defaults to True

Returns:

True if computations are consistent, False otherwise

Return type:

bool

get_led_ids() ndarray[source]

Retrieve the IDs for the LEDs involved in the experiment.

Returns:

Array of LED IDs

Return type:

np.ndarray

get_led_positions(ids: ndarray) List[ndarray][source]

Retrieve the 3D positions for a set of LEDs.

Parameters:

ids (np.ndarray) – Array of LED identifiers

Returns:

List of arrays containing x, y, and z coordinates for each LED

Return type:

List[np.ndarray]

set_leds() None[source]

Initialize the LED instances involved in the experiment based on loaded data.

class ledsa.analysis.Experiment.LED(id: int, pos_x: float, pos_y: float, pos_z: float)[source]

Bases: object

Represents a LED light source in 3D space.

Variables:
  • id (int) – The identifier for the LED

  • pos_x (float) – The x-coordinate of the LED

  • pos_y (float) – The y-coordinate of the LED

  • pos_z (float) – The z-coordinate of the LED

id: int
pos_x: float
pos_y: float
pos_z: float
class ledsa.analysis.Experiment.Layer(bottom_border: float, top_border: float)[source]

Bases: object

Represents a spatial layer with a bottom and top border.

Variables:
  • bottom_border (float) – The z-coordinate of the bottom border of the layer

  • top_border (float) – The z-coordinate of the top border of the layer

bottom_border: float
top_border: float
class ledsa.analysis.Experiment.Layers(amount: int, bottom_border: float, top_border: float)[source]

Bases: object

Represents a collection of spatial layers.

Variables:
  • amount (int) – The number of layers

  • bottom_border (float) – The z-coordinate of the bottom-most border of the layers

  • top_border (float) – The z-coordinate of the top-most border of the layers

amount: int
borders: ndarray
bottom_border: float
layers: [<class 'ledsa.analysis.Experiment.Layer'>]
top_border: float
class ledsa.analysis.ExperimentData.ExperimentData(load_config_file=True)[source]

Bases: object

Dataclass containing the data for the extinction coefficient calculation from the experiment_data.txt input file.

Variables:
  • config – Configuration data.

  • config_analysis – Analysis configuration data.

  • camera – Camera data.

  • layers – Layer data.

  • channels – List of channels.

  • led_arrays – List of LED arrays.

  • n_cpus – Number of CPUs.

  • weighting_preference – Weighting preference for nonlinear solver.

  • weighting_curvature – Weighting curvature for nonlinear solver.

  • num_iterations – Number of iterations.

  • num_ref_images – Number of reference images.

  • ref_img_indices – Indices of reference images to use. If None, use num_ref_imgs.

  • reference_property – Reference property to be analysed.

  • merge_led_arrays – Merge LED arrays option.

  • lambda_reg – Regularization parameter for linear solver.

load_config_parameters() None[source]

Load experiment data from configuration file.

request_config_parameters() None[source]

Prompts the user to input missing parameters of analysis configuration and updates the configuration.

Stacked Multi-Camera Analysis

Stacked extinction coefficient computation across multiple cameras/LEDSA runs.

Usage example:

from ledsa.analysis.ConfigDataStacked import ConfigDataStacked
from ledsa.analysis.StackedExtinctionCoefficients import StackedExtinctionCoefficients

cfg = ConfigDataStacked()                    # reads config_stacked.ini

for arr_id in cfg.get_led_array_ids():
    for channel in cfg.camera_channels:
        sec = StackedExtinctionCoefficients(cfg, arr_id, channel)
        sec.calc_and_set_coefficients()
        sec.save()
class ledsa.analysis.StackedExtinctionCoefficients.StackedExtinctionCoefficients(config: ConfigDataStacked, led_array_id: int, channel: int)[source]

Bases: object

Joint inversion of extinction coefficients using ray data stacked across multiple cameras (LEDSA simulation directories).

For a given virtual LED-array ID and colour channel the class:

  1. Builds one Experiment per (simulation, led_array_id) pair.

  2. Constructs a stacked system matrix by vertically concatenating the per-experiment distance-per-layer matrices and writes it once per virtual array (channel-independent) to <output_path>/.

  3. Computes the common time axis across all simulations, writes a time-alignment report to <output_path>/, and stores it for reuse.

  4. Solves the augmented Beer–Lambert system with the configured solver.

  5. Writes extinction coefficient CSVs to <output_path>/analysis/extinction_coefficients/<solver>/.

Variables:
  • config (ConfigDataStacked) – Stacked-analysis configuration.

  • led_array_id (int) – Virtual LED-array ID (integer key in [led_arrays]).

  • channel (int) – Colour channel index.

  • layers (Layers) – Shared layer discretisation.

  • led_array_mapping (dict[int, int]) – {sim_idx: led_array_id} for this virtual array.

  • sub_experiments (list[Experiment]) – Per-simulation Experiment objects.

  • distances_per_led_and_layer (np.ndarray) – Stacked distance matrix (n_leds_total × n_layers).

  • ref_intensities (np.ndarray) – Stacked reference intensities (n_leds_total,).

  • coefficients_per_image_and_layer (list[np.ndarray]) – Computed extinction coefficients.

  • common_times (np.ndarray or None) – Experiment times [s] shared by all simulations.

calc_and_set_coefficients() None[source]

Compute extinction coefficients for all time-aligned images.

Populates coefficients_per_image_and_layer and common_times.

calc_and_set_coefficients_mp(cores: int | None = None) None[source]

Parallel computation using multiprocessing.

Parameters:

cores (int or None) – Number of worker processes. Defaults to config.num_cores.

save() None[source]

Write computed extinction coefficients to CSV.

Output path:

<output_path>/analysis/extinction_coefficients/<solver>/
extinction_coefficients_<solver>_channel_<ch>_<ref_prop>_led_array_<id>.csv