Plugins / FLIMKit / Module Reference · edit on GitHub
Module Reference
flimkit.formats - Format Dispatch
The format layer sits behind one interface: every reader returns the same (Y, X, H) decay cube plus metadata, so the fitter, phasor, stitching and GUI never branch on file type.
flim_file.py
FLIMFile(path, ...)- format-agnostic entry point. Sniffs the format and delegates to the matching reader, exposing the same.summed_decay()/.pixel_stack()/.n_bins/.tcspc_resinterface regardless of source.detect_format(path)- identify the format from extension, magic bytes, and sibling files (ISS needs its triplet)file_modality(path)- whether the file is time-domain (fit) or frequency-domain (phasor only)supported_formats(),supported_extensions(),file_dialog_filetypes()- format registry, used to build the GUI file pickers
flimkit.formats.PTU - PicoQuant PTU
reader.py
PTUFile(path, verbose=False)- wraps Christoph Gohlke'sptufileand exposes the FLIMFile interface. Pins the TCSPC bin grid, integrates frames, and selects the photon channel..summed_decay(channel=None)- summed decay histogram.pixel_stack(channel=None, binning=1)- (Y, X, H) histogram stack.raw_pixel_stack(channel=None, binning=1)- (Y, X, H) stack (uint32).n_bins,.tcspc_res,.time_ns- TCSPC metadataread_pck(path)- reads PicoQuant Check / IRF.pckhistograms (ptufileexposes only their tags, so this stays in FLIMKit)
decode.py
get_flim_histogram_from_ptufile()-(Y, X, H)stack + metadata for the tile-stitch pipelinecreate_time_axis()- build time axis from PTU metadata
tools.py
signal_from_PTUFile(path, dtype, binning)- load PTU and return anxarray.DataArraywith labelled dimensions (Y,X,H) andfrequencyattribute
stitch.py
stitch_flim_tiles(xlif_path, ptu_dir, output_dir, ...)- stitch multi-tile PTU data into a mosaic using XLIF metadata. Three-pass phase-correlation registration (Preibisch et al. 2009): column Y drift, row Y residuals, row X backlash. Nearest-centre ownership for canvas assembly.fit_flim_tiles(...)- full fitting pipeline on a stitched mosaic (two-pass: pooled DE fit → per-pixel NNLS)load_flim_for_fitting(output_dir, load_to_memory)- load previously stitched data
flimkit.formats.BH - Becker & Hickl SDT
reader.py
BHFile(path, ...)- wraps Christoph Gohlke'ssdtfileand exposes the FLIMFile interface. Handles block layout, TAC range and repetition rate; auto-selects the populated channel.read_bh(path, binning=1, channel=None, sync_rate=None)-(Y, X, H)cube + metadataget_flim_data(path, ...),get_intensity_image(path, ...)- cube and summed-intensity helperscreate_time_axis(n_bins, tcspc_resolution)- time axis from SDT metadata
writer.py
- Writes
.sdtfiles, used byflimkit.synthfor the--sdtoutput so synthetic ground truth can be opened in SPCImage
flimkit.formats.PS - Photonscore LINCam
reader.py
PSFile(path, ...)- reads the.photonsD7 container viaphotonsfile. Position-sensitive detector, so the image is formed by binning each photon's (x, y) and the decay by histogramming its micro-time.read_ps(path, binning=1, channel=None, pixels=512, n_bins=256, period_ns=None)-(Y, X, H)cube + metadata.pixelssets the spatial binning grid,n_binsthe TCSPC histogram depth.get_flim_data(path, ...),get_intensity_image(path, ...),create_time_axis(...)
flimkit.formats.ISS - ISS FastFLIM / Vista
Experimental: written from ISS specifications and checked only against synthetic files, not real acquisitions (issue #19).
reader.py
ISSFile(path, ...)- time-domain triplet (.TAGTIME/.TAGCHANNEL/.TAGDECAY); all three must sit alongside each otherread_iss(path, binning=1, channel=None)-(Y, X, H)cube + metadataget_flim_data(path, ...),get_intensity_image(path, ...)
fdflim.py
ISSFdFlim(path)- frequency-domain.ifli(VistaFLImage). Already phasor data, so there is no decay to fit.phasor_from_ifli(path, channel=None, harmonic=0, calibrate=True)- per-pixel phase/modulation as phasor coordinates, applying the file's reference calibration
image.py
read_ifi(path, channel=None),get_intensity_image(path, channel=None)- ISS intensity images
flimkit.synth - Synthetic Ground Truth
Generates FLIM data with known parameters, for validation. Driven by synth_cli.py.
generate(out_dir, name='synth', ny=16, nx=16, with_irf=True, sdt=False, **kwargs)- write a sample PTU, matching IRF PTU and truth JSON;sdt=Truealso writes.sdtversionsgenerate_series(out_dir, photon_counts, ...)- a photon-count series from one parameter set, for testing count-dependent biasbuild_decay(tau_ns, amps=None, n_bins=2000, tcspc_res_ns=0.025, ...)- the noiseless expected decay, with optional reflection peak, pile-up and backgroundsample_cube(expected, ny, nx, seed=0)- Poisson-sample the expected decay into a(Y, X, H)cubegaussian_irf(n_bins, center_bin, fwhm_bins)- synthetic IRFwrite_ptu(...),write_sdt(...),write_irf_ptu(...)- file writers
flimkit.FLIM - Reconvolution Fitting
fitters.py
fit_summed(decay, tcspc_res, n_bins, irf_prompt, ...)- fit a summed FLIM decay via reconvolution. Pass 1: Differential Evolution global search → Levenberg-Marquardt polish. Returns(best_params, summary_dict).fit_per_pixel(stack, tcspc_res, n_bins, irf_prompt, global_popt, n_exp, ...)- per-pixel fitting with τ values fixed from the global fit. Uses NNLS - fast, convex, unique solution. Pass 2.
Two-pass model:
y(t) = [IRF(t + Shift_IRF) + Bkgr_IRF] ⊗ [Σ αᵢ·exp(−t/τᵢ) + Bkgr]
Pass 1 (summed): DE → LM polish → fixes τ₁...τₙ
Pass 2 (per-pixel): NNLS fits α₁...αₙ and background with fixed τ values
Primary per-pixel output: tau_mean_amp = Σ(fracᵢ × τᵢ) - amplitude-weighted mean lifetime
assemble.py
assemble_tile_maps(tile_results, canvas_h, canvas_w, n_exp)- assemble per-tile results into a single canvasderive_global_tau(canvas, n_exp)- ROI-level lifetime statistics from the assembled canvassave_assembled_maps(canvas, global_summary, output_dir, roi_name, n_exp, ...)- save canvas as TIFFs and NPY
irf_tools.py
build_machine_irf_from_folder(folder, align_anchor, reducer, ...)- build machine IRF from paired PTU/XLSX files. Aligns to decay peak, aggregates by median, saves as.npy+_meta.json.irf_from_xlsx_analytical(xlsx, ...)- fit the analytical IRF model (Gaussian + exponential tail)gaussian_irf_from_fwhm(n_bins, tcspc_res, fwhm_ns, peak_bin)- generate Gaussian IRF from FWHM
flimkit.phasor - Phasor Analysis
signal.py
return_phasor_from_PTUFile(ptu_file)- compute phasor coordinates from a PTU fileget_phasor_irf(irf_xlsx)- read IRF from FLIM microscope software Excel exportcalibrate_signal_with_irf(signal, real, imag, irf_time_ns, irf_counts, frequency)- phase/modulation correction via IRF phasorcalibrate_signal_with_machine_irf(signal, real, imag, machine_irf_npy, frequency)- calibrate using a machine IRF.npy. Reads companion_meta.jsonfor time resolution; interpolates onto the signal time axis.
filters.py
phasor_filter(real, imag, method, *, mean=None, sigma=1.0, size=3, wavelet='db4', level=1, threshold_mode='soft')- apply a spatial filter to calibrated phasor G/S arrays. Whenmeanis supplied, the phasorpy 0.10 NaN-aware C implementation is used for Gaussian and median; otherwise falls back to scipy. Wavelet denoising uses PyWavelets with a MAD noise estimator. Returns(real_f, imag_f).
interactive.py
phasor_cursor_tool(real_cal, imag_cal, mean, frequency, ...)- interactive phasor cursor widget. Works in Jupyter (ipywidgets) and standalone scripts (matplotlib.widgets). Click-to-place elliptic cursors, adjustable radius/angle, per-cursor τ_φ maps, two-component decomposition, Undo/Peaks/Export/Save.
export.py
savePhasorPlots(session, output_dir, stem, min_photons=0.01, dpi=150)- write<stem>_phasor.png(the phasor histogram on the semicircle with the cursors) and<stem>_phasor_image.png(the image coloured by cursor), each with a legend of cursor pixel counts and median τφ.sessionis the dictload_sessionreturns; its saved filter is re-applied. A point measurement gets only the phasor plot. Returns the paths written, and raisesValueErrorwhen no pixel reachesmin_photons.
peaks.py
find_phasor_peaks(real_cal, imag_cal, mean, frequency, ...)- automatic peak detection on 2-D phasor histograms via Gaussian smoothing and local maxima detection
flimkit.UI - Desktop GUI
gui.py
launch_gui()- entry point for the Tkinter GUIFLIMKitApp- main application class. Tabs: Single FOV Fit, Tile Stitch/Fit, Batch ROI Fit, Machine IRF Builder, Phasor AnalysisFOVPreviewPanel- right-panel widget showing intensity image and summed decay. Switches toPhasorViewPanelwhen the Phasor tab is active. Caches the last fitted IRF prompt (_irf_prompt) so per-ROI fits can reuse it.
roi_tools.py
The region model itself lives in flimkit/utils/roi.py so that headless and web use can reach it without Tkinter. roi_tools re-exports RoiManager and the patch helpers, so existing imports keep working.
RoiAnalysisPanel- tab panel for region drawing, statistics display, and per-ROI fitting.- Drawing modes: Select, Rectangle, Ellipse, Polygon, Freehand
- Per-region stats: τ_mean, τ_median, τ_stdev, photon count (all from the loaded lifetime/intensity maps)
_fit_roi_decay()- shows the Fit Options dialog, builds a union mask for all selected regions, extracts the summed decay, and runsfit_summedin a background thread. On completion writes τ stats back to each merged region and updates the session file._show_roi_fit_result(result)/_view_last_fit_result()- open (or reopen from cache) the dark-themed fit result popup with decay plot, residuals, and summary table.- Export: CSV (including fit columns), GeoJSON (single or all regions), GeoJSON import
_ask_roi_fit_options(params)- modal dialog for overriding n_exp, τ bounds, and cost function before a per-ROI fit. Returns an updated params dict or None if cancelled.
phasor_panel.py
PhasorViewPanel(parent, max_cursors=6)- embedded Tkinter widget withFigureCanvasTkAgg. Top axes: FOV intensity image (colourised once cursors are placed); bottom axes: phasor histogram. Controls: Clear, Undo, Save session, Radius slider, Minor/major slider, spatial filter row (method selector, σ/size spinboxes, Apply, Reset)..set_data(real_cal, imag_cal, mean, frequency, display_image, min_photons)- load phasor data; call on main thread.load_session(session, min_photons)- restore a saved.npzsession.get_session_dict()- export current state for saving
flimkit.image - Image Utilities
tools.py
make_intensity_image(ptu_path, rotate_90_cw, save_image)- 2-D intensity image from PTUmake_cell_mask(intensity_image, flow_threshold, cellprob_threshold, resize_to, gpu, ...)- binary cell mask via Cellpose-SAM segmentation (GPU when available, CPU fallback)apply_intensity_threshold(intensity_image, threshold)- boolean mask for photon-count gatingpick_intensity_threshold(intensity_image)- interactive slider for visual threshold selection
flimkit.utils - Shared Utilities
roi.py
RoiManager- stores region geometry and per-region statistics. Serialises to/from JSON for.roi_session.npzpersistence. No GUI toolkit, so headless scripts and either frontend can use it..add_region(name, tool, coords)- register a new region, returns its integer ID.compute_region_mask(region_id, image_shape)- boolean (H×W) mask for a region.to_json()/.from_json(json_str)- serialise/deserialise for session files.to_geojson(region_ids=None)/.add_geojson(payload, mode='append')- GeoJSON export and import, with self-intersecting polygon repairget_rectangle_patch(...)/get_ellipse_patch(...)/get_polygon_patch(...)- matplotlib patches from region coordinates
display.py
load_zstack_display_slices(group_dir, ptu_dir=None, region=None)- per-slice pixel maps, decays and reference fit for a z-stack output directorycompute_weighted_lifetime(pixel_maps, intensity, n_exp=2, weighting='amplitude')- amplitude- or intensity-weighted mean lifetime mapapply_color_scale(image, vmin=None, vmax=None, gamma=1.0, percentile_auto=(2, 98))- normalise a map for display, with percentile autoscalingget_colormap(name='viridis')- colormap lookup against theCOLORMAPStablecompute_region_stats(lifetime_map, intensity_map, region_mask, full_stats=False)- τ and photon statistics inside a maskmask_to_rgba(mask, color=(1.0, 1.0, 1.0), alpha=0.3)- boolean mask as an RGBA overlay
config_snapshot.py
_C()- cached dict snapshot ofconfigs.py, read by both frontends when building fit arguments
session.py
_reconstruct_dict_from_session(session_data, key)- rebuild a nested dict from the flattened*_jsonand*_arr_*keys in a session NPZ_safe_array_from_json(value)- coerce a session value back to a NumPy array_parse_summary(captured_log)-name = value unitlines from captured fit output as table rows
plotting.py
plot_summed(...)- main summed-fit figure: log-scale decay + model overlay, weighted residuals, parameter tableplot_pixel_maps(...)- per-pixel lifetime and amplitude mapsplot_lifetime_histogram(...)- lifetime distribution histogram
enhanced_outputs.py
save_fit_summary_txt(...)- human-readable fit results text filesave_weighted_tau_images(...)- intensity-weighted and amplitude-weighted τ TIFFs with optional display range clipping
lifetime_image.py
make_lifetime_image(canvas, output_dir, roi_name, tau_min_ns, tau_max_ns, ...)- colourised lifetime image with NaN-aware smoothing and gamma correction
xlsx_tools.py
load_xlsx(path, debug=False)- parse a FLIM microscope FLIM export XLSX. Auto-detects column layout; returnsdecay_t/c,irf_t/c,fit_t/c,res_t/c.
xml_utils.py
parse_xlif_tile_positions(xlif_path, ptu_basename)- tile positions from XLIF (microns)get_pixel_size_from_xlif(xlif_path)- pixel size (m) and pixel countcompute_tile_pixel_positions(tiles, pixel_size_m, tile_size)- convert physical positions to pixel coordinates and compute canvas size