sda.analysis#

sda.analysis — shared pipeline utilities for SDA data analysis scripts.

Modules#

columns

Column-name registries (ENERGY_COLS, VOLTAGE_COLS, …) and row-value helpers (first_value(), concat_notes()).

generators

Generator-name resolution (get_row_generator()).

calibration

E = k·V² calibration and energy inference (K_DEFAULT, calibrate_k(), infer_energy()).

loaders

Supplementary xlsx file loader (load_supplementary_xlsx()).

scorers

Shared score parsers (parse_plasma_homogene()).

viz

Reusable Plotly building-blocks (iso_power_traces(), background_heatmap_trace()).

Submodules#

Attributes#

Functions#

calibrate_k(tests[, voltage_cols, energy_cols, exclude])

Fit k = E / V² per generator from tests that have both columns.

infer_energy(voltage_kv[, k_map, generator])

Compute E = k · V² using the best available k for the given generator.

concat_notes(row, df_cols[, note_cols, keyword_filter])

Concatenate all non-null note/comment fields for hover tooltips.

first_value(row, df_cols, candidates)

Return the first non-null string value from an ordered list of column candidates.

get_row_generator(row, df_cols, test_name, df)

Return the most specific generator name for a single DataFrame row.

load_supplementary_xlsx(test_name[, filename, ...])

Load a supplementary .xlsx from the folder of an SDA test.

parse_plasma_homogene(value)

Convert a 'Plasma homogène' cell to a homogeneity score in [0, 1].

background_heatmap_trace(x_pts, y_pts, z_pts, x_range, ...)

Return a griddata-interpolated go.Heatmap trace, or None.

iso_power_traces(x_min, x_max, y_min, y_max[, ...])

Return (traces, annotations) for iso-power hyperbolas.

Package Contents#

sda.analysis.K_DEFAULT: float = 0.07#
sda.analysis.calibrate_k(tests, voltage_cols=None, energy_cols=None, exclude=frozenset())#

Fit k = E / V² per generator from tests that have both columns.

Parameters:
  • tests (List of SDA test names to scan.)

  • voltage_cols (Column name candidates for voltage.  Defaults to) – VOLTAGE_COLS.

  • energy_cols (Column name candidates for energy.  Defaults to) – ENERGY_COLS.

  • exclude (Test names to skip (e.g. mixed NRP+DC tests whose k is) – not meaningful).

Returns:

  • dict mapping generator name (and ````”default”:py:class:`)` to median k (mJ / kV²).

  • Falls back to :py:class:````{"default": K_DEFAULT}:py:class:``` when no calibration data is found.`

sda.analysis.infer_energy(voltage_kv, k_map=None, generator='default')#

Compute E = k · V² using the best available k for the given generator.

Parameters:
  • voltage_kv (Voltage in kV.)

  • k_map (Dict mapping generator names to k values (from) – calibrate_k()). When None, uses K_DEFAULT.

  • generator (Generator name.  Falls back to :py:class:``”default”:py:class:` when not found`) – in k_map.

Return type:

Energy per pulse in mJ, or np.nan if voltage_kv is not finite.

sda.analysis.ENERGY_COLS: list[str] = ['Energie par pulse (mJ)', 'Energie par pulse mesuré (mJ)', 'Energie déposée par pulse (mJ)',...#
sda.analysis.FREQ_COLS: list[str] = ['Fréquence (kHz)', 'Frequency (kHz)', 'Input frequency [kHz]']#
sda.analysis.GAP_COLS: list[str] = ['Gap (mm)']#
sda.analysis.GEN_COL_PRIORITY: list[str] = ['Generator', 'Générateur', 'Generateur']#
sda.analysis.GEN_GENERIC: frozenset[str]#
sda.analysis.GENERATOR_NAMES: list[str] = ['SOLO2', 'SOLO3', 'SOLO4', 'SOLO5', 'LOCA', 'ROCO', 'NRP', 'DC', 'HYBRIDE']#
sda.analysis.NOTE_COLS: list[str] = ['Notes', 'Notes2', 'Remarks', 'Commentaires', 'Remarques', 'Justification_Zone', 'Objectifs']#
sda.analysis.VOLTAGE_COLS: list[str] = ['Voltage input (kV)', 'Voltage (kV)', 'Input voltage [kV]', 'Tension (kV)']#
sda.analysis.concat_notes(row, df_cols, note_cols=None, *, keyword_filter=None)#

Concatenate all non-null note/comment fields for hover tooltips.

Parameters:
  • row (A single DataFrame row.)

  • df_cols (Column names present in the DataFrame.)

  • note_cols (Ordered list of note column names.  Defaults to) – NOTE_COLS.

  • keyword_filter (If given (e.g. ````”pdc”:py:class:`)`, only include a field when that) – keyword appears in the text (case-insensitive). Pass None to include all non-empty fields.

Return type:

:py:class:``”field1 | field2 | …”:py:class:`` or None when nothing was found.

sda.analysis.first_value(row, df_cols, candidates)#

Return the first non-null string value from an ordered list of column candidates.

Parameters:
  • row (A single DataFrame row (pd.Series).)

  • df_cols (List of column names present in the DataFrame.)

  • candidates (Ordered list of column names to try.)

Return type:

The stripped string value of the first populated column, or None.

sda.analysis.get_row_generator(row, df_cols, test_name, df)#

Return the most specific generator name for a single DataFrame row.

Resolution priority#

  1. First specific (non-generic) value from GEN_COL_PRIORITY.

  2. If only a generic family name (e.g. "SOLO") was found, refine it using "Modèle de générateur" which carries per-row detail (e.g. "SOLO 5").

  3. Keyword scan of filenames / test name.

  4. "unknown".

sda.analysis.load_supplementary_xlsx(test_name, filename=None, glob_patterns=None, sheet=0, label=None)#

Load a supplementary .xlsx from the folder of an SDA test.

Copies the file to a temporary location first so that Windows file locks (e.g. the file is open in Excel) do not prevent reading.

Parameters:
  • test_name (SDA test identifier (e.g. ````”T346”:py:class:`). Used` to resolve) – the folder via sda.api.file_discovery.resolve_local_test_path().

  • filename (Exact filename to load (e.g. ````”T346_analyse_EP.xlsx”:py:class:`).`) – When None, the first file matching glob_patterns is used.

  • glob_patterns (Glob patterns relative to the test folder to search when) – filename is not given. Defaults to ["*analyse*.xlsx", "*EP*.xlsx", "*ep*.xlsx"].

  • sheet (Sheet index or name to parse.  Defaults to 0 (first sheet).)

  • label (Short label for log messages (defaults to) – "<test_name>-sup").

Return type:

pandas.DataFrame — empty on any failure.

sda.analysis.parse_plasma_homogene(value)#

Convert a 'Plasma homogène' cell to a homogeneity score in [0, 1].

Scoring convention (0 = non-homogeneous / lensing, 1 = fully homogeneous):

All other values (empty, , unknown text) → np.nan.

Note

Analysis scripts that need a different mapping (e.g. mapping Oui to a carbon-bridge time score) should implement their own thin wrapper rather than modifying this function.

sda.analysis.background_heatmap_trace(x_pts, y_pts, z_pts, x_range, y_range, colorscale='RdYlGn', zmin=None, zmax=None, grid_size=80, opacity=0.4)#

Return a griddata-interpolated go.Heatmap trace, or None.

Requires at least 3 data points to interpolate; returns None when that threshold is not met.

Parameters:
  • x_pts (Scatter coordinates and values.)

  • y_pts (Scatter coordinates and values.)

  • z_pts (Scatter coordinates and values.)

  • x_range (:py:class:`(min`, :py:class:`max) tuples that define the grid extent.`)

  • y_range (:py:class:`(min`, :py:class:`max) tuples that define the grid extent.`)

  • colorscale (Plotly colorscale name (default ````”RdYlGn”:py:class:`).`)

  • zmin (Color axis limits.  Inferred from *z_pts* when ``None`.`)

  • zmax (Color axis limits.  Inferred from *z_pts* when ``None`.`)

  • grid_size (Number of grid points per axis (default 80).)

  • opacity (Heatmap opacity (default 0.40).)

Return type:

go.Heatmap or None.

sda.analysis.iso_power_traces(x_min, x_max, y_min, y_max, power_candidates=None)#

Return (traces, annotations) for iso-power hyperbolas.

Each power level P (watts, since kHz·mJ = W) is drawn as a faint dotted line with a semi-transparent annotation label. A wide transparent overlay trace carries a detailed hover tooltip without affecting visuals.

Parameters:
  • x_min (Data range for the x-axis (Energy per pulse, mJ).)

  • x_max (Data range for the x-axis (Energy per pulse, mJ).)

  • y_min (Data range for the y-axis (Frequency, kHz).)

  • y_max (Data range for the y-axis (Frequency, kHz).)

  • power_candidates (Power levels in W to consider.  Levels outside the data) – range are skipped automatically.

Returns:

  • traces (List of go.Scatter traces to extend into the figure.)

  • annotations (List of annotation dicts to pass to fig.update_layout.)