spacr.timelapse

Time-series tracking, motility analysis, and trajectory utilities.

Functions

analyze_calcium_oscillations(db_loc[, measurement, ...])

Detect and summarise per-cell calcium oscillation peaks from a measurements DB.

automated_motility_assay(settings)

End-to-end merged-npy pipeline for cell/pathogen motility and infection QC.

create_results_figure()

Create the standard 3-panel QC results figure layout.

exponential_decay(x, a, b, c)

Return a * exp(-b * x) + c for curve fitting.

infected_vs_noninfected(result_df, measurement)

Plot per-well mean delta_<measurement> for infected vs uninfected cell groups.

link_by_iou(mask_prev, mask_next[, iou_threshold])

Match labels between two consecutive frames using IoU and Hungarian assignment.

plot_data(measurement, group, ax, label[, marker, ...])

Plot delta_<measurement> vs time for one grouped subset onto ax.

preprocess_pathogen_data(pathogen_df)

Aggregate a per-parasite table to one row per host cell with a parasite count.

save_figure(fig, src, figure_number)

Save fig as figure_<figure_number> inside a sibling results folder.

save_results_dataframe(df, src, results_name)

Save df as <results_name>.csv inside a sibling results folder.

summarize_per_well(peak_details_df)

Aggregate per-object peak details to one summary row per well.

summarize_per_well_inf_non_inf(peak_details_df)

Aggregate per-object peak details per well, split by infection status.

Module Contents

spacr.timelapse.analyze_calcium_oscillations(db_loc, measurement='cell_channel_1_mean_intensity', size_filter='cell_area', fluctuation_threshold=0.25, num_lines=None, peak_height=0.01, pathogen=None, cytoplasm=None, remove_transient=True, verbose=False, transience_threshold=0.9)[source]

Detect and summarise per-cell calcium oscillation peaks from a measurements DB.

Loads the cell (and optionally pathogen/cytoplasm) tables, filters transient tracks, detects peaks on the chosen intensity trace, and writes the per-peak, per-cell and per-well tables to CSV in a results folder beside the database.

Parameters:
  • db_loc – path to the measurements SQLite database.

  • measurement – intensity column analysed for oscillations.

  • size_filter – object-size column used for gating.

  • fluctuation_threshold – maximum coefficient of variation (std / mean) of size_filter within a track; more variable tracks are dropped.

  • num_lines – cap on the number of traces to plot; plots all when None.

  • peak_height – minimum absolute peak height, passed to scipy.find_peaks(height=...) on the delta trace.

  • pathogen – optional pathogen table name to join for infection status.

  • cytoplasm – optional cytoplasm table name to join.

  • remove_transient – drop tracks shorter than the transience threshold.

  • verbose – print diagnostic information.

  • transience_threshold – fraction of timepoints a track must span to be retained.

Returns:

tuple (result_df, peak_details_df, fig) – the photobleach-corrected per-cell traces, the per-peak details and the summary matplotlib Figure. The per-well summaries are only written to CSV. Returns None when the database has no time axis, the decay fit fails, or no cells pass the filters.

spacr.timelapse.automated_motility_assay(settings)[source]

End-to-end merged-npy pipeline for cell/pathogen motility and infection QC.

Reads merged/*.npy frames, builds per-cell measurements, cleans and persists them to SQLite, computes per-track velocities, generates intensity + motility QC panels (mask-based and, optionally, XGBoost / histogram / PCA / UMAP / t-SNE adjusted labels), and writes a well-level motility summary.

Parameters:

settings – dict of assay settings; see get_automated_motility_assay_default_settings for keys including src, db_table_name, n_jobs, max_displacement, zscore_thresh, infection_intensity_qc, infection_intensity_strategy, infection_intensity_mode, infection_xgb_drop_ambiguous, infection_xgb_ambiguous_low, infection_xgb_ambiguous_high, infection_xgb_proba_column, infection_hist_percentile, make_mask_panel, make_adjusted_panel, motility_xlim, motility_ylim, motility_origin_xlim, motility_origin_ylim, and reuse_existing_measurements.

Returns:

the per-cell measurements DataFrame carrying the final (QC-adjusted) labels. Measurements and summary tables are also written to measurements/measurements.db and the QC panels saved under src.

Raises:

ValueError – when settings['db_table_name'] names a spaCR-owned table; see _validate_db_table_name().

spacr.timelapse.create_results_figure()[source]

Create the standard 3-panel QC results figure layout.

Arrangement is PCA (top-left), XGBoost (top-right) and Histogram (bottom spanning both columns).

Returns:

tuple (fig, ax_pca, ax_xgb, ax_hist).

spacr.timelapse.exponential_decay(x, a, b, c)[source]

Return a * exp(-b * x) + c for curve fitting.

The photobleaching model analyze_calcium_oscillations() fits with scipy.optimize.curve_fit, which reads the three arguments after x as the free parameters to solve for.

Parameters:
  • x – time points, as a scalar or a NumPy array / pandas Series; a Series comes back as a Series on the same index, which is what lets the caller’s df[measurement] / exponential_decay(...) align by label.

  • a – amplitude of the decaying term. At x == 0 the result is a + c, not a; a == 0 flattens the curve to the constant c.

  • b – decay rate. The sign is not checked – a negative b grows instead of decaying, and a large -b * x overflows to inf with a RuntimeWarning rather than raising.

  • c – additive offset, and the asymptote as x grows. Nothing keeps the curve positive, so a fit with c < 0 crosses zero and the caller’s division by this curve flips sign across the crossing.

Returns:

numpy.float64 for scalar x, otherwise the array type of x.

Raises:

TypeError – when x is a plain list and b is a float, because -b * x is then list arithmetic. An integer b does not raise: it silently returns an empty array for b >= 0.

spacr.timelapse.infected_vs_noninfected(result_df, measurement)[source]

Plot per-well mean delta_<measurement> for infected vs uninfected cell groups.

Parameters:
  • result_df – per-cell/time DataFrame keyed by the composed plate_row_column_field_object column, with time, parasite_count and the delta_<measurement> column.

  • measurement – base measurement column name to plot (the delta_ variant is drawn).

Returns:

None.

Match labels between two consecutive frames using IoU and Hungarian assignment.

Parameters:
  • mask_prev – labelled mask from the previous frame.

  • mask_next – labelled mask from the next frame.

  • iou_threshold – minimum IoU required to accept a match. Default 0.1.

Returns:

list of (label_prev, label_next) matches above the threshold.

spacr.timelapse.plot_data(measurement, group, ax, label, marker='o', linestyle='-')[source]

Plot delta_<measurement> vs time for one grouped subset onto ax.

Parameters:
  • measurement – base measurement name; the delta_ prefix is added when reading the column.

  • group – DataFrame subset for a single group.

  • ax – matplotlib axis to draw onto.

  • label – legend label for this series.

  • marker – matplotlib marker. Default 'o'.

  • linestyle – matplotlib line style. Default '-'.

Returns:

None.

spacr.timelapse.preprocess_pathogen_data(pathogen_df)[source]

Aggregate a per-parasite table to one row per host cell with a parasite count.

Keys on the column names the measurement writer actually emits: columnID (not column_name), timeID (not timeid, and absent altogether outside a timelapse run) and cell_id – the child table’s link to its host cell – not pathogen_cell_id, which no writer has ever produced. Under the old names every call died with KeyError.

Parameters:

pathogen_df – per-parasite measurements DataFrame with plate/well/field/time/cell identifiers.

Returns:

DataFrame aggregated to (plate, row, column, field, time, host cell) with a parasite_count column.

spacr.timelapse.save_figure(fig, src, figure_number)[source]

Save fig as figure_<figure_number> inside a sibling results folder.

The .pdf extension built here is only a proposal: spacr.plot.save_figure() rewrites it to the configured figure format. That preference defaults to pdf, so the file on disk is figure_1.pdf unless another format has been selected.

Parameters:
  • fig – matplotlib Figure to persist.

  • src – reference path used to derive the parent directory.

  • figure_number – integer/string suffix embedded in the filename.

Returns:

None; the written path is printed.

spacr.timelapse.save_results_dataframe(df, src, results_name)[source]

Save df as <results_name>.csv inside a sibling results folder.

Parameters:
  • df – DataFrame to write.

  • src – reference path used to derive the parent directory.

  • results_name – filename stem (no extension).

Returns:

None.

spacr.timelapse.summarize_per_well(peak_details_df)[source]

Aggregate per-object peak details to one summary row per well.

Parameters:

peak_details_df – per-object peak DataFrame with an ID column encoding plate_row_column_field_object and peak metrics.

Returns:

DataFrame with one row per well including peak counts, unique cell counts, and per-well means of the numeric metrics.

Raises:

spacr.schema.KeyParseError – when an ID is not an object key.

spacr.timelapse.summarize_per_well_inf_non_inf(peak_details_df)[source]

Aggregate per-object peak details per well, split by infection status.

Parameters:

peak_details_df – per-object peak DataFrame with an ID column encoding plate_row_column_field_object, peak metrics, and an infected column whose positive values mark infected objects.

Returns:

DataFrame with one row per well and infection status (so one row for a well seen in a single status) of peak counts, cell counts, and per-well means of numeric metrics.

Raises:
  • spacr.schema.KeyParseError – when an ID is not an object key.

  • KeyError – when the frame has no infected column; the pathogen count must be carried under exactly that name.