Fitting fluorescence correlation spectroscopy (FCS) data in Julia
FluorescenceCorrelationFitting provides a lightweight, composable toolkit for modelling and fitting FCS correlation curves. Optional package extensions enable file I/O, tables, and publication‑quality plots.
- Generic 2D/3D diffusion models with optional anomalous diffusion (α) and multi‑component mixtures
- Additive dynamic terms (e.g., exponential kinetic terms) and optional baseline offset
- Parameter scaling and bounds handling for numerically stable fits
- Global fitting of diffusion coefficients and beam waists between multiple correlation curves
- Optional extensions for:
- Reading delimited text files (
DelimitedFiles.jl) - Pretty tabular summaries of fits (
PrettyTables.jl) - Interactive/publication plots (
CairoMakie.jl&LaTeXStrings.jl)
- Reading delimited text files (
Until the package is registered, install by adding the package from a local directory or via the Git URL.
julia> ]
pkg> activate --shared fcs
pkg> add CairoMakie LaTeXStrings DelimitedFiles PrettyTables IJulia
pkg> add /absolute/path/to/FluorescenceCorrelationFitting.jl
pkg> precompilejulia> ]
pkg> activate --shared fcs
pkg> add CairoMakie LaTeXStrings DelimitedFiles PrettyTables IJulia
pkg> add git@github.com:LabGradinaru/FluorescenceCorrelationFitting.jl.git # or https
pkg> precompileTip: use
dev(instead ofadd) to track local changes during development.
If you use Jupyter, it’s convenient to create a dedicated kernel for notebooks such as that in examples/fitting.ipynb to run in.
We will assume a global environment named fcs has been created, as above.
- Install a Jupyter kernel that points at this env
julia> using IJulia
julia> IJulia.installkernel("Julia (@fcs)"; env=Dict("JULIA_PROJECT" => "@fcs"))- Select the kernel in VS Code:
Ctrl+Shift+P→ Notebook: Select Notebook Kernel → Select Another Kernel… → Jupyter Kernels → Julia (@fcs).
using FluorescenceCorrelationFitting
# Example: 3D normal diffusion with one kinetic (exponential) term and an offset.
diffusivity = 5e-11 # m^2/s
offset = 0.0
spec = FCSModelSpec(dim = d3, anom = none, offset = offset, diffusivity = diffusivity)
# Synthetic example parameters: [g0, n_exp_terms, τD, τ_dyn, K_dyn]
initial_parameters = [1.0, 5.0, 2e-7, 1e-7, 0.1]
lower_bounds = [0.9, 1.0, 1e-8, 1e-8, 0.0]
upper_bounds = [1.1, 20.0, 1e-6, 1e-4, 0.5]
# t: lag‑time vector (s); g: experimental correlation values
# Example stub (replace with real data):
t = range(1e-7, 1e-1; length=256)
g = model(spec, initial_parameters, t) .+ 0.02 .* randn(length(t))
# Store output from fit in a `FCSFitResults` container
fit = fcs_fit(spec, t, g, initial_parameters; lower = lower_bounds, upper = upper_bounds)
println(fit)using FluorescenceCorrelationFitting
diff_time = τD(spec, fit; scale="m") # diffusion time [ms]
confocal_volume = Veff(spec, fit; scale="n") # confocal volume [nm^3]
conc = concentration(spec, fit; scale="n") # effective concentration in nM
rh = hydrodynamic(diffusivity; scale="A") # hydrodynamic radius [Angstroms]using FluorescenceCorrelationFitting
# different molecules, same PSF → shared w₀
spec1 = FCSModelSpec(dim=d2, anom=none, offset=0.0, diffusivity=D1)
spec2 = FCSModelSpec(dim=d2, anom=none, offset=0.0, diffusivity=D2)
gfit = fcs_fit([spec1, spec2], [τ1, τ2], [G1, G2], [p0_1, p0_2]; shared=:w0)
fit1 = channel_result(gfit, 1)
println(fit1)If your data live in a delimited file (CSV/TSV), load DelimitedFiles before FluorescenceCorrelationFitting to enable the extension. The files are assumed to be in the order (column-wise): lag times, data, standard deviations (optional), which is then organized into FCSChannel objects:
using DelimitedFiles, FluorescenceCorrelationFitting
data = read_fcs(filepath; start_idx = 20, end_idx = 300);
fit = fcs_fit(spec, data.channel[1].τ, data.channel[1].G, initial_parameters; lower = lower_bounds, upper = upper_bounds)using CairoMakie, LaTeXStrings, FluorescenceCorrelationFitting
channel = FCSChannel("sample", t, g, nothing)
fig, fit = fcs_plot(spec, channel, initial_parameters)
save("corr1.png", fig)FCSModelSpec declares model structure; numerical values are supplied via the parameter vector. The intended order for the parameter vector arguments can be accessed via
using FluorescenceCorrelationFitting
coarse_parameter_order = expected_parameter_names(spec)
precise_parameter_order = expected_parameter_names(spec, initial_parameters)which returns a Vector{String} containing the intended argument order. In general, the order should be
- Current correlation,
$G (0)$ - (Optional) Correlation offset,
$G (\infty)$ - (If
dim=:d3) Structure factor,$\kappa$ - Characteristic diffusion times,
$\tau_{D,i} = w_{0,i}^2 / 4D_i$ (OR the beam width$w_{0,i}$ if the diffusivity is provided) - (If
spec.anom != :none) Anomalous exponents,$\alpha_i$ - (If
spec.n_diff > 1) Diffusion population fractions,$f_i$ - Dynamic lifetimes,
$\tau_{\mathrm{dyn}, j}$ - Dynamic population fractions,
$T_j$
The generic form of the model being fit is
ics parameter of FCSModelSpec.
For instance, if you wish to have two independent dynamic processes, each with one state, one would set ics=[1,1], amounting to a dynamic contribution
ics = [2] such that the contribution is now
- MethodError on model spec: check that your parameter vector matches the model’s expected ordering.
- Slow/unstable fits:
(a) provide reasonable bounds;
(b) use
scaleoutput fromfcs_fitfor diagnostics; (c) reduce parameter correlations by fixing known values if possible; (d) ensure none of your data containsNaNorInfvalues. - Pkg can’t find the repo: double‑check the path/URL and that you have permission to the private repository.