phenotypic.analysis.LinearSoftplusModel#

class phenotypic.analysis.LinearSoftplusModel(on: str, groupby: List[str], time_label: str = 'Metadata_Time', agg_func: Callable | str | list | dict | None = 'mean', *, smax: float | None = None, beta: float = 10, stderr_label: str | None = None, inoc_size_label: str | None = None, prune_saturated: bool = True, saturation_threshold: float = 0.05, saturation_buffer: int = 2, v_upper: float = 50.0, num_workers: int = 1, loss: Literal['linear'] = 'linear', verbose: bool = False)[source]

Bases: ModelFitter

Linear-with-softplus lag-phase growth fitter.

The model combines a linear post-lag growth phase with a softplus lag transition and an optional softplus saturation ceiling:

\[s(t) = \frac{v}{\alpha}\, \ln\!\bigl(1 + e^{\alpha(t-\lambda)}\bigr) + s_0\]

When smax is provided (or inferred per-group as the observed maximum), a second softplus clamps the curve to the saturation ceiling:

\[s(t) = s_{\max} - \frac{1}{\beta}\,\ln\!\bigl(1 + e^{\beta(s_{\max} - s_{\text{unclamped}}(t))}\bigr)\]
Parameters:
  • on (str)

  • groupby (List[str])

  • time_label (str)

  • agg_func (Callable | str | list | dict | None)

  • smax (float | None)

  • beta (float)

  • stderr_label (str | None)

  • inoc_size_label (str | None)

  • prune_saturated (bool)

  • saturation_threshold (float)

  • saturation_buffer (int)

  • v_upper (float)

  • num_workers (int)

  • loss (Literal['linear'])

  • verbose (bool)

smax

Fixed carrying capacity. None falls back to per-group observed maximum.

Type:

float | None

beta

Saturation transition sharpness.

Type:

float

stderr_label

Column providing per-timepoint standard errors used as weights in the fit. When None, the fit auto-derives a replicate-SE column during aggregation.

Type:

str | None

inoc_size_label

Column of per-row inoculum size measurements. When supplied, per-group mean and sample std are computed automatically and used as an informative Gaussian prior on s0; when None, no prior is applied (appropriate for yeast where inoculum size is not imaged).

Type:

str | None

prune_saturated

Whether to drop post-saturation timepoints before fitting.

Type:

bool

saturation_threshold

Fraction of peak ds/dt below which the curve is considered saturated.

Type:

float

saturation_buffer

Extra rows past the saturation index kept so the fit still sees some plateau evidence.

Type:

int

v_upper

Upper bound on v in the optimizer.

Type:

float

Methods

__init__

Initialize the linear-softplus fitter.

analyze

Fit the model to every group of data.

dash

Interactive Plotly version of show().

model_func

Linear-softplus growth curve with optional saturation ceiling.

results

Return the most recent fit results produced by analyze().

show

Plot model predictions alongside measurements with optional filtering.

__init__(on: str, groupby: List[str], time_label: str = 'Metadata_Time', agg_func: Callable | str | list | dict | None = 'mean', *, smax: float | None = None, beta: float = 10, stderr_label: str | None = None, inoc_size_label: str | None = None, prune_saturated: bool = True, saturation_threshold: float = 0.05, saturation_buffer: int = 2, v_upper: float = 50.0, num_workers: int = 1, loss: Literal['linear'] = 'linear', verbose: bool = False)[source]

Initialize the linear-softplus fitter.

Parameters:
  • on (str) – Target column (size measurement) to fit.

  • groupby (List[str]) – Columns defining the per-fit grouping structure.

  • time_label (str) – Column name representing time. Defaults to "Metadata_Time".

  • agg_func (Callable | str | list | dict | None) – Aggregation function for the on column when stderr_label is provided. Ignored when stderr_label is None because the fitter uses pandas named aggregation to derive mean and SE together. Defaults to "mean".

  • smax (float | None) – Fixed carrying capacity for every group. When None, each group uses its own post-pruning observed maximum of on.

  • beta (float) – Saturation transition sharpness.

  • stderr_label (str | None) – Column providing per-timepoint standard errors used as weights. When None, replicate SE is computed automatically during aggregation.

  • inoc_size_label (str | None) – Optional column providing per-row inoculum size measurements (typically available for filamentous fungi from the t=0 image, absent for yeast). When supplied, per-group mean and sample standard deviation of the column are computed automatically via groupby.transform and fed into a single virtual Gaussian residual on s0 (spec §5.3). When None (the default, appropriate for yeast), the inoculum prior is omitted from the residual vector entirely.

  • prune_saturated (bool) – Whether to drop post-saturation timepoints before fitting.

  • saturation_threshold (float) – Fraction of peak ds/dt below which the curve is considered saturated.

  • saturation_buffer (int) – Extra rows past the saturation index retained so the fit still sees plateau evidence.

  • v_upper (float) – Upper bound on v.

  • num_workers (int) – Number of parallel workers for per-group fits.

  • loss (Literal['linear']) – Loss method passed through to scipy.optimize.least_squares(). Defaults to "linear".

  • verbose (bool) – If True, enables optimizer verbose output.

static model_func(t: np.ndarray | float, v: float, s0: float, lam: float, alpha: float, smax: float | None = None, beta: float = 10) float | np.ndarray[source]

Linear-softplus growth curve with optional saturation ceiling.

Parameters:
  • t (np.ndarray | float) – Time (scalar or array).

  • v (float) – Post-lag growth rate.

  • s0 (float) – Initial size.

  • lam (float) – Lag duration.

  • alpha (float) – Lag transition sharpness.

  • smax (float | None) – Optional carrying capacity. When None, the curve grows linearly forever past the lag.

  • beta (float) – Saturation transition sharpness.

Returns:

Predicted size at t; scalar when t is scalar, otherwise an array.

Return type:

float | np.ndarray

analyze(data: pandas.DataFrame) pandas.DataFrame[source]

Fit the model to every group of data.

Pre-computes two broadcasted helper columns on the raw data before delegating to the base-class aggregation pipeline:

  • When stderr_label is None, a replicate-SEM column derived via groupby.transform("sem") so the weighted loss can downweight noisy timepoints automatically.

  • When inoc_size_label is set, per-group mean and sample std of the inoculum-size column via groupby.transform — these feed the optional Gaussian prior on s0 (_inoc_stats()).

Each helper is constant within its group, so the base-class dict-style aggregation carries it through as a flat column without MultiIndex juggling.

Parameters:

data (pandas.DataFrame)

Return type:

pandas.DataFrame

dash(tmax: int | float | None = None, criteria: Dict[str, Any | List[Any]] | None = None, figsize=(6, 4), cmap: str | None = 'tab20', legend: bool = True, **kwargs) go.Figure

Interactive Plotly version of show().

Hover tooltips are populated from _hover_fields so subclasses can expose whichever fitted parameters and metrics are most meaningful for their model.

Raises:

ImportError – If plotly is not installed.

Parameters:
  • tmax (int | float | None)

  • criteria (Dict[str, Union[Any, List[Any]]] | None)

  • cmap (str | None)

  • legend (bool)

Return type:

go.Figure

results() pandas.DataFrame

Return the most recent fit results produced by analyze().

Return type:

pandas.DataFrame

show(tmax: int | float | None = None, criteria: Dict[str, Any | List[Any]] | None = None, figsize=(6, 4), cmap: str | None = 'tab20', legend: bool = True, ax: plt.Axes | None = None, **kwargs) Tuple[plt.Figure, plt.Axes]

Plot model predictions alongside measurements with optional filtering.

Parameters:
  • tmax (int | float | None) – Upper bound of the prediction curve. If None, uses the maximum observed time.

  • criteria (Dict[str, Union[Any, List[Any]]] | None) – Column/value filter applied to both fitted results and raw measurements before plotting.

  • figsize – Matplotlib figure size. Used only when ax is None.

  • cmap (str | None) – Matplotlib colormap name, a single color string, or None for matplotlib’s default color cycle.

  • legend (bool) – Whether to render a legend (auto-removed if larger than the axes).

  • ax (plt.Axes | None) – Existing axes to draw into. A new figure is created when omitted.

  • **kwargs – Styling overrides — dpi, facecolor, edgecolor, line_width, marker_size, elinewidth, capsize, legend_loc, legend_fontsize, label.

Returns:

A (Figure, Axes) pair.

Return type:

Tuple[plt.Figure, plt.Axes]