Skip to content

Analysis parameters

This page is for the person running the experiment, not the person maintaining the code. For each parameter it tables, it answers three questions:

  1. What is the default, and where does it live? Every row names the constant or field and the module it is defined in, so you can read the value straight out of the source.
  2. What happens if you change it? Each row states the direction of the trade-off — what you gain and what you lose by raising or lowering the value.
  3. Can you recover it afterwards? Each row says whether the value you used is written into the .tether project file, which is what makes a run reproducible and a methods section honest.

Every default on this page was read out of the code, not out of a specification. Where the frozen spec and the code disagree, the code is what ships and the code is what is printed here.

How to read this page

Column What it means
Parameter The keyword or field you actually set, and the module its default is defined in.
Default The shipped value.
Units Physical units where they exist. Several parameters are dimensionless fractions or frame counts — the difference matters.
Effect on the result What the parameter controls and which way the trade-off runs.
Set via A real surface: a tether CLI flag, a GUI control, or a documented keyword argument. Where a value is not user-settable this is stated explicitly.
Recorded in .tether The store path where the value you used is persisted, or no if it is not recoverable from the project file.

Tether has no settings dialog. Ten of the seventeen ExtractOptions fields are exposed as tether extract flags — --donor-side, --detection-mode, --detection-threshold, --detection-block, --min-separation, --window, --prealign, --pair-tol, --rms-gate and --coloc-distance — and for those the command line is the only surface. The other seven have no flag and no GUI control at all, and are reachable only from Python: the aperture group (disk_radius, ring_inner, ring_outer, bg_window) and the prealign group (prealign_upsample, prealign_low_sigma, prealign_high_sigma). Their rows below say so individually, and all seventeen are recorded alike — the recording is the same whether the value came from a flag or from Python. tether batch deliberately exposes none of them: its flags are --tmap, --tdat, --policy and the sidecar-supervision options, so every movie in a batch is extracted at the ExtractOptions defaults tabled below unless you drive run_batch(extract_options=ExtractOptions(...)) from Python — with one exception. tether batch --tdat applies a shared Deep-LASI detection config to every movie in the run, and importing one replaces detection_mode and detection_threshold with the values decoded from the file before the extraction profile is written, exactly as tether extract --tdat does for a single movie. Under --tdat those two rows below do not describe your run: read the applied values out of /settings/extraction, where the source filename is also recorded as tdat_source. Every other extraction parameter is untouched by --tdat and is still at its default. (--tmap replaces no field, but it does make donor_side inert — see its row.) Downstream stages (photobleaching, corrections, idealization, analysis) are driven from Python, so their "Set via" cells name the keyword argument of the project-level function. Anything with no surface at all is called out as fixed.

Science tunables vs rendering defaults

Not every default is a scientific choice, and the split below is the one the source itself draws: most constants say which kind they are in their own comment, and this page follows that labelling — with three deliberate promotions, named explicitly below.

  • A science tunable changes a reported number. The leakage ceiling, the γ half-window, the bootstrap resample count and the idealization state grid all change what you would publish.
  • A rendering default changes only how a distribution is drawn. The histogram bin count, the transition-density grid resolution and the dwell-time histogram bin count are faithful ports of the corresponding tMAVEN display defaults; the raw-FRET cloud and the anticorrelation event finder are Tether's own presentation choices with no tMAVEN counterpart, and the plot-export settings are Tether's own too — not ports of a tMAVEN display default, though tMAVEN does carry a figure size and a savefig format/DPI of its own (Rendering defaults). Changing any of them redraws a plot; it does not change a fitted value.

The three promotions. Under Analysis and histograms, the frame interval (dt / time_dt), the dwell-fit model and CI level, and the HMM convergence budget (n_iter) are labelled analysis/rendering parameters in their own source comments, but are tabled here as science tunables, because each of them changes a number you would report — most sharply the frame interval, which silently mis-units every published rate.

The distinction is not cosmetic in one direction: halving a bin count will visibly move a peak's apparent position without changing a single fitted state mean. If you are chasing a number, tune the science parameters; if you are chasing a picture, tune the rendering ones. The two groups are tabled separately under Analysis and histograms.

Detection and extraction

Defaults are the fields of ExtractOptions (tether.project.extract), which is the pinned CLI contract. Fifteen of the seventeen fields pin an explicit value rather than passing through to whatever the underlying primitive happens to default to; detection_threshold and min_separation are deliberate None sentinels that defer to each detection mode's own faithful default (tabled below). All seventeen fields are serialised verbatim into the profile_json attribute of /settings/extraction on the first extraction into a project; later movies appended to the same project leave that record untouched, and their aperture/integration parameters are checked against it rather than re-recorded.

Parameter Default Units Effect on the result Set via Recorded in .tether
donor_side
tether.project.extract
left enum left/right Which horizontal half of the frame is the donor channel. Getting it backwards swaps donor and acceptor, which inverts every FRET efficiency. Ignored entirely when a Deep-LASI .tmap is imported, because the channels are then split at the map's own crop geometry. tether extract --donor-side /settings/extraction
detection_mode
tether.project.extract
wavelet enum wavelet/intensity/bandpass Which particle finder runs. wavelet is an à trous multi-scale detector that is robust to smooth background gradients; intensity and bandpass are Crocker-Grier style band-pass finders driven by a brightness threshold. The choice also changes the default minimum separation (see below), so it moves both which spots are found and how close two of them may sit. tether extract --detection-mode; supplied automatically by --tdat /settings/extraction
detection_threshold
tether.project.extract
None (per-mode: 0.5 intensity, 0.98 bandpass) dimensionless fraction of the detection-image maximum How bright a pixel must be to survive. Raising it finds fewer, brighter molecules; lowering it finds more, at the cost of false positives that later have to be curated out. Under bandpass the value is dual-use — it both floors the image and keeps only the top 1 - threshold fraction of band-pass values — so it bites much harder there than under intensity. Recorded but inert under wavelet. tether extract --detection-threshold; supplied automatically by --tdat /settings/extraction
detection_block
tether.project.extract
50 frames Block size of the moving-average max-projection that the detector runs on. Raising it averages away more blinking and shot noise, but the trailing partial block (the T % block remainder frames) is dropped, so a large block silently discards more of the end of the movie. Lowering it lets single-frame spikes into the per-pixel maximum and shifts which spots are found. Movies shorter than one block fall back to a sum projection. tether extract --detection-block /settings/extraction
min_separation
tether.project.extract
None (per-mode: 8.0 wavelet, 3.0 intensity and bandpass) px Non-maximum-suppression radius: two candidates closer than this collapse to one. Raising it merges genuinely distinct molecules and costs recall; lowering it keeps duplicate centroids on a single PSF. Supplying a value overrides the per-mode default for every mode. tether extract --min-separation /settings/extraction
window
tether.project.extract
21 px, odd Side length of the aperture and colocalization crop box. It must be odd and must be at least twice ring_outer. Raising it excludes more molecules near the frame edge (their crop no longer fits); lowering it toward the ring diameter is rejected outright. tether extract --window /settings/extraction
disk_radius
tether.imaging.aperture
3.0 px Radius of the signal disk that is summed per frame — 29 pixels at the default, on the default 21 px window. Raising it captures more of the PSF tail but admits more shot noise and risks a neighbour's PSF; lowering it clips real signal and depresses both channels. ExtractOptions(disk_radius=…) or integrate_traces(disk_radius=…) — no CLI flag, no GUI control /settings/extraction
ring_inner
tether.imaging.aperture
6.0 px Inner radius of the background annulus. The gap between the disk and this radius is a deliberate dead zone that keeps PSF tail out of the background estimate; shrinking it toward disk_radius lets signal leak into the background and biases the integrated intensity down. ExtractOptions(ring_inner=…) or integrate_traces(ring_inner=…) — no CLI flag, no GUI control /settings/extraction
ring_outer
tether.imaging.aperture
8.0 px Outer radius of the background annulus — 84 pixels at the defaults. Raising it averages the background over more pixels (a quieter estimate) but reaches further into neighbouring molecules; it also forces a larger window. ExtractOptions(ring_outer=…) or integrate_traces(ring_outer=…) — no CLI flag, no GUI control /settings/extraction
bg_window
tether.imaging.aperture
10 frames Length of the uniform temporal moving average applied to the crop before the ring mean is taken. Raising it produces a smoother background but lags a genuine background change (for example a slow lamp drift); 1 gives the instantaneous per-frame ring mean, which is noisier and pushes that noise straight into every trace. ExtractOptions(bg_window=…) or integrate_traces(bg_window=…) — no CLI flag, no GUI control /settings/extraction

Not reachable from the pipeline: ExtractOptions carries no field for the à trous scale count (n_scales) or scale pair, the MAD multiplier (k), the band-pass lnoise/lobject lengths (lobject differs per mode — 7 under intensity, 9 under bandpass), the intensity mode's fine_threshold, the border_margin, or the sub-pixel refinement switch (refine). No CLI flag, no batch run and no GUI control can change them; they are the faithful Deep-LASI values. They do remain keyword arguments with those defaults on detect_spots, detect_spots_intensity and detect_spots_bandpass in tether.imaging.detect if you call a detector directly — but a value set that way is not what the pipeline runs and is not recorded in /settings/extraction. Molecule-key quantisation (MOLECULE_KEY_QUANTUM_PX in tether.imaging.extract) is likewise fixed; it is recorded as molecule_key_quantum_px in /settings/extraction because a change to it would break cross-file molecule identity.

Registration and colocalization

Parameter Default Units Effect on the result Set via Recorded in .tether
prealign
tether.project.extract
translation enum translation/similarity Degrees of freedom of the coarse pre-alignment before control points are paired. The default resolves translation only. similarity adds rotation and isotropic scale via a Fourier-Mellin log-polar pass and is reliable only in the near-identity regime (sub-degree rotation, sub-percent scale). Use it when your two channels are genuinely rotated; it costs time and can mislead on large warps. The prealign never enters the fitted map — it only helps the pairing step find partners. tether extract --prealign /settings/extraction
prealign_upsample
tether.imaging.register
10 reciprocal px (shift resolved to 1/upsample px) Sub-pixel resolution of the phase-correlation shift. Raising it refines the prealign at a compute cost; 1 gives whole-pixel alignment only, which can leave true partners outside pair_tol. ExtractOptions(prealign_upsample=…) — no CLI flag, no GUI control /settings/extraction
prealign_low_sigma
tether.imaging.register
3.0 px (Gaussian standard deviation) Low cut of the difference-of-Gaussians band-pass applied before the log-polar pass. Consumed only when prealign is similarity; inert under the default. Raising it strips fine structure the rotation estimate needs. ExtractOptions(prealign_low_sigma=…) — no CLI flag, no GUI control /settings/extraction
prealign_high_sigma
tether.imaging.register
20.0 px (Gaussian standard deviation) High cut of the same band-pass; must be strictly greater than the low cut. Inert under the default translation prealign. Raising it lets saturated background into the FFT magnitude and destabilises the estimate. ExtractOptions(prealign_high_sigma=…) — no CLI flag, no GUI control /settings/extraction
pair_tol
tether.imaging.register
2.0 px (Euclidean, inclusive) Mutual nearest-neighbour gate for accepting a control-point pair. Raising it pairs more points — including spurious ones, which drag the fitted map. Lowering it can leave fewer than the two pairs extraction requires, and the movie fails outright. tether extract --pair-tol /settings/extraction
rms_gate
tether.imaging.calibrate
0.5 px Residual gate on the fitted channel map. A fit whose RMS residual is strictly above the gate is not rejected: the calibration is flagged low-confidence and every molecule it extracts is tagged, so a marginal registration is visible downstream instead of silently dropped. Raising it hides a bad map; lowering it flags more runs for review. tether extract --rms-gate /settings/extraction
over-gate policy
tether.project.batch
warn enum warn/fail What a batch run does with an over-gate movie. warn keeps it, flagged; fail fails that movie's stage so it does not enter the pooled analysis. tether extract on a single movie always warns — only the batch runner can fail. tether batch --policy /settings/batch (policy)
coloc_distance
tether.imaging.coloc
3.0 px (strict <) Nearest-neighbour radius for the informational acceptor_detected flag, and nothing else. Tether is donor-anchored: every in-frame donor spot becomes a molecule and its acceptor intensity is read at the mapped position whether or not an acceptor was independently detected there, so changing this value does not add, remove or re-pair a single molecule (tether.imaging.coloc). It is Deep-LASI's findColoc gate, kept as a diagnostic rather than a filter, because filtering on it discards the low-FRET and acceptor-dark population a FRET histogram must keep. A separation of exactly the threshold is not a match. No downstream stage currently consumes the flag. tether extract --coloc-distance /settings/extraction

Fixed, not settable: the polynomial map degree and the fallback ladder. Six or more control points fit a degree-2 polynomial; two to five fall back to a four-degree-of-freedom similarity; fewer than two is an error. Those thresholds are constants in tether.imaging.calibrate with no user surface.

Photobleaching and the analysis window

Photobleaching is detected per channel with a Bayesian single-step change-point model, and the default analysis window runs from the start of the trace to the first bleach of the summed donor + acceptor intensity. A window that has already been narrowed by hand is a manual override and is never overwritten by a later detection pass — but note that the only surfaces that narrow it are the tMAVEN return-leg reconcile and a legacy-SMD import, not the curation view (see the row below).

Parameter Default Units Effect on the result Set via Recorded in .tether
intensity_quantity
tether.project.photobleach
corrected enum corrected/raw Which trace layer the detector runs on. The model treats the post-bleach segment as mean-zero, which only holds once the background pedestal has been removed. Detection tolerates a modest pedestal, but once the pedestal grows to roughly twice the bleach step the trace stops looking bleached at all and the window silently spans the whole movie — which is what running on raw traces risks. compute_photobleach(intensity_quantity=…) — no CLI flag, no GUI control no
a
PB_PRIOR_A in tether.fret.photobleach
1.0 dimensionless Shape of the inverse-Gamma prior over the per-segment noise variance. At the default the prior is weak and the data dominate on any trace longer than a few frames. Raising it makes the detector more conservative about calling a small step. compute_photobleach(a=…) / detect_photobleach(a=…) — no CLI flag, no GUI control no
b
PB_PRIOR_B in tether.fret.photobleach
1.0 intensity² (same units as the trace, squared) Scale of the same inverse-Gamma prior — effectively an assumed noise floor. It enters only as an additive term alongside the trace's summed squared deviations, so it bites only when raised to something comparable with that sum: on a 200-frame trace with a 1000-count step it is inert from 1e-9 up to about 1e6 and suppresses the step only around 1e8. Lowering it below the default has no practical effect — the data term dominates. compute_photobleach(b=…) / detect_photobleach(b=…) — no CLI flag, no GUI control no
beta
PB_PRIOR_BETA in tether.fret.photobleach
1.0 dimensionless (pseudo-observations) Precision of the Normal prior over the pre-bleach signal level. At 1.0 the prior contributes about one pseudo-observation at mu, so it barely moves a fit on a trace of tens of frames. Raising it pulls the fitted pre-bleach level toward mu and will bias the change point on short or dim traces. compute_photobleach(beta=…) / detect_photobleach(beta=…) — no CLI flag, no GUI control no
mu
PB_PRIOR_MU in tether.fret.photobleach
1000.0 raw detector counts (ADU) of the background-subtracted trace Prior mean of the pre-bleach signal level. This is an absolute intensity, not a normalised one, and the asymmetry matters. A level far above mu is harmless. A level far below it is the dangerous case, and it bites at the default beta — no raised beta needed — because the prior's evidence penalty does not shrink as the trace lengthens. Measured on a 200-frame synthetic trace bleaching at frame 100: levels of 1e6 down to 100 counts all recover frame 100, while a level of 10 counts collapses to the all-bleached hypothesis at frame 0. compute_photobleach then reads that as a dark trace — bleach_frames records the start frame and the analysis window is deliberately left at full extent, because a zero-length window is indistinguishable from "unset" downstream. Setting mu to your own single-molecule level restores detection. Lower mu if your traces are dim. compute_photobleach(mu=…) / detect_photobleach(mu=…) — no CLI flag, no GUI control no
analysis window override auto (start → first bleach of the summed intensity) frames The window the windowed readers slice to: the analysis store behind the FRET histograms and cloud, the anticorrelation/cross-correlation scan, the per-molecule engineered features, the per-molecule exports and idealization each cut a trace to it, falling back to frame_range when it is unset. The correction-factor stages do not read itcompute_leakage_alpha, compute_gamma and compute_corrected_fret slice each trace by its native frame_range and locate their tails from the stored bleach_frames, so narrowing the window does not change α, γ or the corrected traces. Because manual bounds win, re-running detection will not restore the automatic one. There is no in-app curation control for the window — the curation view's window keys report that GUI persistence is unavailable and add no data. apply_reconcile(accept_windows=…) — the standalone-tMAVEN return leg, surfaced as the GUI reconcile dialog — or import_analysis_only_project from a legacy SMD; auto-set by compute_photobleach only where the window is still at the extraction default /molecules (analysis_window, bleach_frames)

Photobleach detection records none of its own inputs. tether.project.photobleach writes the resultsbleach_frames and analysis_window — into /molecules, but it writes no attributes at all: not the priors that produced them, and not the trace layer they were detected on. The layer choice travels only in the transient PhotobleachSummary the call returns. So if you change any of a, b, beta, mu or intensity_quantity, that choice is not recoverable from the project file, and a reader of your .tether cannot tell a default run from a re-prioritised one, nor a corrected pass from a raw one. Record the values yourself in your methods section, or leave them at the defaults so the defaults on this page describe your run. Every other correction stage stamps its own settings; this one does not.

Correction factors

Leakage α and the detection-correction factor γ are estimated per trace and then pooled to a dataset median. Both estimators are deliberately conservative: a trace that does not qualify contributes nothing, and if too few traces qualify the factor is withheld rather than guessed. Corrections are never required — a project with no usable factors degrades to apparent E rather than producing NaNs.

Parameter Default Units Effect on the result Set via Recorded in .tether
intensity_quantity (α and γ)
tether.project.leakage / tether.project.gamma
corrected enum corrected/raw Which /traces layer the per-trace α and γ are measured from: corrected is the background-subtracted layer, raw the pre-background-subtraction one. Measuring on raw leaves the background in the post-bleach tail means and in the acceptor-drop/donor-rise step heights, so it changes the factors themselves and therefore every corrected E computed from them. Unlike the analysis-side argument of the same name, this choice is stamped, so a reader of your project can tell which layer a factor came from. compute_leakage_alpha(intensity_quantity=…), compute_gamma(intensity_quantity=…) — no CLI flag, no GUI control /settings/leakage, /settings/gamma
min_window_frames (α)
DEFAULT_MIN_WINDOW_FRAMES in tether.fret.leakage
20 frames Shortest post-acceptor-bleach tail from which α may be measured. A tail of exactly this length qualifies. Raising it keeps only long, well-averaged tails — fewer contributing traces, a noisier median if you go too far. Lowering it admits short tails whose mean is dominated by shot noise. compute_leakage_alpha(min_window_frames=…) — no CLI flag, no GUI control /settings/leakage
ceiling (α)
LEAKAGE_CEILING in tether.fret.leakage
0.3 dimensionless A per-trace α outside the inclusive range from zero to the ceiling is rejected as unphysical. Raising it admits traces whose "leakage" is really a mis-detected bleach or a contaminating acceptor; lowering it discards real high-leakage dye pairs and can push the dataset below the qualifying count. compute_leakage_alpha(ceiling=…) — no CLI flag, no GUI control /settings/leakage
min_qualifying_traces (α)
DEFAULT_MIN_QUALIFYING_TRACES in tether.fret.leakage
10 molecules How many traces must yield an α before the dataset median is trusted. Exactly this many is enough. Below the bar the factor is withheld and the project falls back to apparent E — a deliberate refusal, not a failure. Lowering it lets a median built from a handful of traces correct an entire condition. compute_leakage_alpha(min_qualifying_traces=…) — no CLI flag, no GUI control /settings/leakage
half_window (γ)
DEFAULT_GAMMA_HALF_WINDOW in tether.fret.gamma
3 frames each side of the acceptor-bleach step How many frames are averaged either side of the step to measure the acceptor drop and the donor rise. Raising it averages away noise but smears a step that is not perfectly sharp, and risks reaching past the donor bleach (the post window is clamped so it cannot). Lowering it makes γ hostage to single-frame noise. compute_gamma(half_window=…) — no CLI flag, no GUI control /settings/gamma
min_window_frames (γ)
DEFAULT_MIN_WINDOW_FRAMES in tether.fret.leakage
20 frames Both the pre-step FRET segment and the post-step donor-only segment must be strictly longer than this — note the difference from the α gate, which is inclusive. Raising it demands longer stable segments and yields fewer, cleaner γ values. compute_gamma(min_window_frames=…) — no CLI flag, no GUI control /settings/gamma
ceiling (γ)
GAMMA_CEILING in tether.fret.gamma
5.0 dimensionless A per-trace γ outside the half-open range above zero up to and including the ceiling is rejected. Raising it admits extreme ratios that usually mean the "step" was not a true acceptor-before-donor bleach; lowering it discards genuinely bright-acceptor dye pairs. compute_gamma(ceiling=…) — no CLI flag, no GUI control /settings/gamma
min_qualifying_traces (γ)
DEFAULT_MIN_QUALIFYING_TRACES in tether.fret.leakage
10 molecules Same contract as for α: below the bar γ is withheld. compute_gamma(min_qualifying_traces=…) — no CLI flag, no GUI control /settings/gamma
alpha_override / gamma_override
tether.project.correct
None dimensionless Substitute a factor measured elsewhere — for example on a dedicated donor-only or acceptor-only sample. An override replaces the dataset median for every molecule and is stamped as such, so the corrected traces are labelled manual rather than corrected. compute_corrected_fret(alpha_override=…, gamma_override=…) — no CLI flag, no GUI control /settings/correction
apparent_e_only
tether.project.correct
False boolean Force apparent E even when factors are available. Use it when you distrust the corrections and want the uncorrected quantity on record; the stamp distinguishes a user choice from unavailable corrections. compute_corrected_fret(apparent_e_only=True) — no CLI flag, no GUI control /settings/correction

Idealization

Idealization runs in an isolated sidecar interpreter. The default model is a variational-Bayes consensus HMM (vbconhmm — the con is consensus): one global HMM fitted across all of the project's molecules, not a model per trace. The state count is chosen automatically by maximising the evidence lower bound over a small grid.

Parameter Default Units Effect on the result Set via Recorded in .tether
model_type
MODEL_TYPE_DEFAULT in tether.project.idealize
vbconhmm enum Which fitter the sidecar runs. Both documented models are population fits, so "pools across traces" is not what separates them: the ebFRET alternative (ebhmm) adds an empirical-Bayes hierarchy — it learns a shared prior across the molecules and keeps per-trace posteriors with per-trace state selection, which makes it more seed-variable and is why it is ratified against its own, looser parity tolerance (see Tolerances and gates). It is a different statistical object, not a tuning knob. Four further keys exist in the sidecar dispatch (vbconhmm_modelselection, ebhmm_modelselection, vbgmm_vbhmm, kmeans_vbhmm) and are accepted but not documented here. idealize_molecules(model_type=…) — no CLI flag; the GUI one-click idealize passes whatever it was constructed with /idealization/<model> (type)
nstates
tether.project.idealize
None (automatic) count Leave it unset and the state count is selected by maximum ELBO over the grid; set it and you are forcing K. Forcing a K larger than the data support splits one state into two noise-separated states and inflates your transition counts; forcing it smaller merges states and hides transitions. idealize_molecules(nstates=…) — no CLI flag /idealization/<model> (nstates, nstates_selected_by)
nstates_grid
NSTATES_GRID_DEFAULT in tether.project.idealize
(1, 2, 3, 4) counts The candidate state counts the automatic selection searches. Widening it lets the ELBO pick a larger K — at the cost of one fit per candidate, so run time scales with the grid. Ties break toward the smaller K. idealize_molecules(nstates_grid=…) — no CLI flag /idealization/<model> (elbo_by_nstates, written when the grid was searched)
intensity_quantity
tether.project.idealize
corrected enum corrected/raw Which trace layer is idealized. Fitting raw traces fits the uncorrected FRET, so the state means are not comparable to a corrected run. idealize_molecules(intensity_quantity=…) — no CLI flag /idealization/<model> (intensity_quantity)
nrestarts
tether.project.idealize
None (tMAVEN's own default) restarts per fit Overrides tMAVEN's modeler.nrestarts preference: how many restarts the variational fitter runs before the best model is kept. Lowering it is faster — its documented use is speeding up tests — and correspondingly more likely to settle in a local optimum. Distinct from max_restarts below, which retries a crashed sidecar and has no effect on the fit. Forwarded to the sidecar but never stamped on the model group. idealize_molecules(nrestarts=…) — no CLI flag no
timeout
DEFAULT_SIDECAR_TIMEOUT in tether.idealize.supervisor
1800.0 seconds per idealization call How long one fit may run before the sidecar is killed. The first fit of a session is dominated by just-in-time compilation and is far slower than the rest, so a short timeout will kill cold runs that would have succeeded. None waits forever. tether batch --sidecar-timeout; idealize_molecules(timeout=…) no
max_restarts
DEFAULT_MAX_RESTARTS in tether.idealize.supervisor
3 restarts per movie How many times a transient sidecar failure (a crash or a timeout) is retried — not to be confused with nrestarts, which is a property of the fit itself. A fit error reported by the sidecar itself is never retried. 0 disables restarts, so one transient crash fails that movie. Raising it can turn a systematically broken environment into a very long batch run. tether batch --max-restarts no
probe_timeout
DEFAULT_PROBE_TIMEOUT in tether.idealize.supervisor
120.0 seconds Budget for the one-shot startup liveness probe that decides whether the sidecar environment works at all. Too short on a cold filesystem and a healthy environment is declared unavailable. SidecarSupervision(probe_timeout=…) — no CLI flag no
defer_if_unavailable
tether.idealize.supervisor
True boolean With the default, a missing sidecar defers idealization for the whole run instead of failing every movie one at a time. Turn it off to make each movie's idealization stage fail in isolation. tether batch --no-defer no

Analysis and histograms

Science tunables

These change a reported number.

Parameter Default Units Effect on the result Set via Recorded in .tether
intensity_quantity
the intensity-layer tether.analysis population functions
corrected enum corrected/raw Which trace layer a population statistic is computed on, and the largest single swing in a reported E on this table. corrected selects the background-subtracted layer (/traces/donor_corrected and /traces/acceptor_corrected); raw selects the pre-background-subtraction layer, whose E values are not comparable to a corrected run. The layer name is all corrected means here: every function that takes this argument computes apparent E from the layer it is handed, and nothing under tether.analysis reads /molecules.alpha or /molecules.gamma, so neither setting yields a leakage/γ-corrected efficiency — do not report one as absolute E. Only the views that read a trace layer take it — the 1-D histograms (including the CI band and the per-condition overlay), the 2-D and post-synchronised heatmaps, the cloud views, the cross-correlation and the anticorrelation finder. The four state-path-derived views — population_dwell_times, population_state_number, population_transition_density and population_transition_prob_histogram — have no intensity_quantity argument at all, because their numbers come from the stored state paths and model means rather than from a trace layer. The same argument, with the same default, also exists on compute_leakage_alpha and compute_gamma, where it decides which layer α and γ are measured from and is recorded — see Correction factors. population_apparent_e_histogram(intensity_quantity=…), the same argument on the other intensity-layer population functions listed above — no CLI flag, no GUI control no
include_first
tether.analysis.dwell
False boolean Whether the first dwell of each trace — which is left-censored, because the molecule was already in that state when the window opened — enters the survival fit. The default excludes it. Turning it on biases the fitted lifetime, and is for auditing the censoring, not for reporting. population_dwell_times(include_first=True) — no CLI flag, no GUI control no
n_resamples
DEFAULT_BOOTSTRAP_RESAMPLES in tether.analysis.histogram
1000 resamples How many molecule-level bootstrap replicates build the confidence band on a population FRET histogram. Lowering it makes the band a coarser estimate of the true interval. It does not make the band jitter run to run: the resampling is seeded (seed, next row but one), so a band is bit-identical on identical data at any resample count — change the seed and a low-resample band visibly moves. Raising it costs time and buys little once the band has stabilised. bootstrap_histogram_ci(n_resamples=…) — no CLI flag, no GUI control no (analysis results are computed on demand, not stored)
ci_level
DEFAULT_CI_LEVEL in tether.analysis.histogram
0.95 probability Coverage of the percentile interval — the default takes the 2.5th and 97.5th percentiles of the replicate distribution. Raising it widens the band. bootstrap_histogram_ci(ci_level=…) — no CLI flag, no GUI control no
seed
DEFAULT_SEED in tether.analysis.histogram
0 seed Fixes the resampling so the band is reproducible run to run. Change it only if you want to demonstrate that the band is insensitive to the draw; report the value you used, because a band computed with a different seed is a different band. bootstrap_histogram_ci(seed=…) — no CLI flag, no GUI control no
per_molecule_equal_weight
tether.analysis.histogram
False boolean With the default, every frame in the population contributes equally, so a long trace counts for more than a short one. Turning it on gives every molecule equal weight, which is the right choice when trace lengths vary systematically between conditions. population_apparent_e_histogram(per_molecule_equal_weight=True) — no CLI flag, no GUI control no
include_rejected
tether.analysis population functions
False boolean Whether curator-rejected molecules enter a population statistic. The default excludes them, which is the whole point of curation. Turning it on is for auditing the effect of curation, not for reporting. population_apparent_e_histogram(include_rejected=True) and the equivalent argument on the other population functions — no CLI flag, no GUI control no
include_stale
the model-derived tether.analysis population functions
False boolean Whether molecules whose idealization has gone stale enter a model-derived statistic. A molecule is stale when the traces or corrections its state path was fitted on have changed since the fit, so the stored path no longer belongs to the signal underneath it — a re-extraction or a recalibration of α or γ is enough. The default excludes them, which is what keeps a transition-density plot, dwell-time fit, transition-probability histogram or state-number count consistent with the traces it is drawn over. Turning it on mixes a state path with signal it was not fitted on; the fix for a stale cohort is reidealize, not this flag. Only these four functions take it: the 1-D histogram, the raw time-versus-signal 2-D heatmap and the cloud views have no idealization to go stale. Two other model-derived views are exceptions to watch, and neither applies a staleness filter of any kind. The post-synchronised A2 heatmap (population_transition_sync_histogram2d) pairs the persisted Viterbi paths with the current traces but takes no include_stale argument, so it can draw a stale path over signal it was not fitted on. Its one guard compares a state path's extent against the width of the whole /traces array — which is zero-padded to the experiment-max frame count, not trimmed per molecule — so it skips a molecule only when that molecule's idealized extent runs past the shared width. A re-extraction that shortens a single molecule is not caught (the vanished frames are read out of that molecule's zero pad), and neither is a recalibration of α or γ; pass molecule_keys=project.live_idealization_keys(model_name) if you need that view restricted to the live cohort. The A1 model-Gaussian overlay (population_model_gaussian_overlay) is the second: it reads the persisted model's means, variances and populations and draws them over the current histogram with no freshness check at all, and it takes no molecule_keys, so there is no in-call restriction available — check project.live_idealization_keys(model_name) yourself, or reidealize, before trusting an overlay drawn after a re-extraction or a recalibration. population_transition_density(include_stale=True), and the same argument on population_dwell_times, population_transition_prob_histogram and population_state_number — no CLI flag, no GUI control no
dt / time_dt
DEFAULT_DWELL_DT in tether.analysis.dwell, DEFAULT_TIME_DT in tether.analysis.histogram, DEFAULT_CLOUD_TIME_DT in tether.analysis.cloud
1.0 seconds per frame Converts frames to physical time. This is the one default that will silently mis-unit a published number. At 1.0 every dwell time is in frames and every fitted rate is per frame, not per second. The frame interval is carried per movie in /movies as frame_time (zero when the source movie declared none), but no analysis function reads it automatically — you must pass it. population_dwell_times(dt=…), time_signal_histogram2d(time_dt=…), raw_fret_cloud(time_dt=…) — no CLI flag, no GUI control no
model / ci_level (dwell fits)
DEFAULT_DWELL_CI_LEVEL in tether.analysis.dwell
single, 0.95 model name, probability Which survival form is fitted to the dwell-time distribution and the coverage of the reported parameter intervals. Moving from a single exponential to a double or stretched form changes the reported rate constants, not just the fit quality; choose the model on physical grounds, and report which you used. population_dwell_times(model=…, ci_level=…) — no CLI flag, no GUI control no
nstates
tether.analysis.kinetics
2 count How many hidden states the shared-parameter Gaussian HMM used for rate-constant estimation is fitted with. Unlike the two rows below, which only govern how the fit terminates, this defines the model. The initialisation is deterministic and derived entirely from K: state means at evenly spaced quantiles of the pooled signal, per-state width scaled as the pooled standard deviation divided by K, a diagonal-dominant transition matrix (0.95 stay probability when K > 1) and a uniform start. Raising K splits one state into two noise-separated states and inflates transition counts; lowering it merges states and hides transitions — the same trade-off as the idealization nstates row above. Because the emissions change, so do the Viterbi paths and every rate constant derived from them. nstates=1 sets the stay probability to 1.0, a model with no transitions at all, so every exit rate degenerates; below 1 it raises ValueError. fit_gaussian_hmm(traces, nstates=…) — no CLI flag, no GUI control. The convenience wrapper two_state_rate_constants hardcodes two states and takes no nstates argument, so a non-two-state model means calling fit_gaussian_hmm / viterbi_paths / pooled_exit_rates yourself. no
n_iter / tol
DEFAULT_HMM_MAX_ITER, DEFAULT_HMM_TOL in tether.analysis.kinetics
200, 1e-6 iterations, relative log-likelihood change Convergence budget of the Gaussian HMM used for rate-constant estimation. They run in opposite directions: n_iter is an iteration cap, tol is the stopping threshold on the relative log-likelihood change (EM stops as soon as the absolute change in the total log-likelihood falls to tol·(1 + its magnitude)). Lowering n_iter or raising tol can return an unconverged fit that still looks plausible; raising n_iter or lowering tol costs time only. fit_gaussian_hmm(n_iter=…, tol=…) — no CLI flag, no GUI control no
var_floor
DEFAULT_HMM_VAR_FLOOR in tether.analysis.kinetics
1e-6 apparent-E units squared (a variance) Lower bound clamped onto every state's fitted emission variance at each M-step of the same Gaussian HMM. It exists to stop a state that has collapsed onto identical values from producing a zero-width Gaussian and dividing by zero; at the default it sits far below any real FRET noise level and never binds. Because the clamped width feeds straight back into the next E-step, raising it toward your actual noise variance does not merely widen a reported σ — it changes the responsibilities, and so the state assignment and every rate estimated from it. Raise it only to rescue a fit that degenerates, and say so if you do. fit_gaussian_hmm(var_floor=…) — no CLI flag, no GUI control no

Rendering defaults

These redraw a plot; none of them changes a fitted value. Two rows are less cosmetic than the rest and say so in place: the transition-sync selection chooses which transitions are drawn rather than how, and the density switch changes the scale a binned view is returned on. Most are faithful ports of the corresponding tMAVEN display defaults and cite the tMAVEN file they came from — the 1-D histogram (data_hist1d.py), the 2-D and post-synchronised heatmaps (data_hist2d.py), the transition-density grid (data_tdp.py), the dwell histogram (survival_dwell.py), the transition-probability view (tm_hist.py) and the state-number bar chart (model_vbstates.py). The last six rows are Tether's own: the raw-FRET cloud, its k-vs-RMSE elbow helper, its α-shape support boundary, the donor–acceptor cross-correlation, the anticorrelation event finder (a QC aid, the pre-idealization counterpart to the HMM's transition list), and the plot-export settings (the three formats are a §7.9 requirement; the DPI and figure size are cosmetic output knobs). None of the six is a port of a tMAVEN display default, but two are not without precedent: tMAVEN carries its own figure width/height as plot preferences (analysis_plots/base.py) and its savefig format and DPI as global matplotlib rcParams set by the trace-plot canvas (trace_plot/multi_plot.py), and it ships k-means as a modelling routine (modeler/kmeans.py, modeler.run_kmeans). The cross-correlation is the only one of the six that targets the same quantity as a named tMAVEN routine, and Tether's is a deliberate divergence rather than a port: tMAVEN's selection.py heuristic is unnormalized — this is not the raw layer of the science-tunable table above, it runs on tMAVEN's own corrected data — as well as gradient-based and lag-zero-only. Most, but not all, carry the rendering-default label in the constant's own comment in the source: the 1-D histogram bins/range and the plot-export constants do not. Not every value tabled here has a constant behind it, either: the cross-correlation's two arguments, the transition-sync selection's three, the density switch, the cloud's time_range and kde, the elbow's k_min and in_grid_only, the α-shape's alpha and in_grid_only, and the state-number chart's states_high are plain keyword defaults. Each Parameter cell names the constant where there is one.

Parameter Default Units Effect on the result Set via Recorded in .tether
bins / value_range
DEFAULT_NBINS, DEFAULT_RANGE in tether.analysis.histogram
151, (-0.25, 1.25) bin count, apparent-E units Resolution and extent of the one-dimensional FRET histogram. The range is deliberately wider than zero to one so that out-of-range values are visible rather than silently clipped. Fewer bins smooth the distribution and can move a peak's apparent position; more bins expose sampling noise. apparent_e_histogram(bins=…, value_range=…) — no CLI flag, no GUI control no
density
a keyword default on the binned tether.analysis functions (no module constant)
True (one-dimensional views), False (two-dimensional views) boolean Whether a binned view is returned as a probability density or as raw (weighted) occupancy counts. At True each bin is divided by its width and by the total in-range mass, so the view integrates to 1 over its range; at False you get the counts themselves. The split is by dimensionality, not by stage: True on the one-dimensional apparent-E histogram, its bootstrap CI band, the per-condition overlay set and the transition-probability histogram; False on the time-versus-signal and post-synchronised two-dimensional heatmaps and on the transition-density plot. The two one-dimensional defaults are faithful tMAVEN ports (data_hist1d.py and tm_hist.py both hard-code density normalisation; Tether makes it a switch), and tMAVEN's two-dimensional views likewise bin raw counts — its hist_normalize / hist_normalizeframe preferences rescale the colour axis and are not this switch. The transform is exact and invertible and moves no peak, so no fitted value changes; but two histograms drawn at different settings are not numerically comparable, and two overlay curves are densities regardless of this switch — the A1 model-Gaussian overlay, which takes no density argument at all, and the transition-probability KDE, which is a gaussian_kde evaluation either way — so drawing either over a density=False histogram puts the two on different scales. The dwell-time histogram is always density-normalised and has no switch at all. population_apparent_e_histogram(density=…) and the same keyword on the other binned population functions — no CLI flag, no GUI control (the GUI histogram's y-axis label does follow it: density versus count) no
time_bins / signal_bins / signal_range
DEFAULT_TIME_BINS, DEFAULT_SIGNAL_BINS, DEFAULT_SIGNAL_RANGE in tether.analysis.histogram
100, 61, (-0.2, 1.2) bin counts, apparent-E units Grid of the time-versus-signal two-dimensional histogram. These intentionally differ from the one-dimensional defaults above, exactly as in tMAVEN; pass the one-dimensional range if you want a shared E axis across the two plots. time_signal_histogram2d(…) — no CLI flag, no GUI control no
sync_preframe
DEFAULT_SYNC_PREFRAME in tether.analysis.histogram
50 time columns before the transition Where the selected transition sits on the post-synchronised plot. At half the time-bin count the transition is centred; lower it to show more of the departure, raise it to show more of the approach. transition_sync_histogram2d(sync_preframe=…) — no CLI flag, no GUI control no
from_state / to_state / single_dwell
keyword defaults on transition_sync_histogram2d in tether.analysis.histogram
-1, -1, True state index, state index, boolean Which transitions the post-synchronised heatmap is built from, and the shape of the window binned around each. -1 matches any state, so the defaults synchronise on every state jump; setting either to a real state index keeps only transitions leaving from_state and entering to_state (tMAVEN's sync_hmmstate_1 / sync_hmmstate_2, whose own defaults are 0 and -1 — transitions leaving state 0, so Tether's -1 / -1 is a deliberate divergence rather than a port), which changes the n_transitions, n_molecules and n_samples reported with the plot as well as the picture. single_dwell=True is tMAVEN's default window: from the end of the previous dwell to the start of the next, so each transition contributes the one dwell either side; False takes a fixed sync_preframe frames before and time_bins - sync_preframe + 1 after every selected transition, whose overlapping windows may double-count a frame, as in tMAVEN. Not cosmetic in the way the rest of this table is — these choose which events are drawn, not how they are drawn — but no fit is involved, and nothing records which selection you used. transition_sync_histogram2d(from_state=…, to_state=…, single_dwell=…) and the same arguments on population_transition_sync_histogram2d — no CLI flag, no GUI control no
nskip / signal_bins / signal_range
DEFAULT_TDP_NSKIP, DEFAULT_TDP_SIGNAL_BINS, DEFAULT_TDP_SIGNAL_RANGE in tether.analysis.tdp
2, 101, (-0.25, 1.25) frames, bin count per axis, apparent-E units Grid of the transition-density plot, and how many frames apart the initial and final points of a transition are read so the transition frame itself is skipped. population_transition_density(…) — no CLI flag, no GUI control no
nbins (dwell histogram)
DEFAULT_DWELL_NBINS in tether.analysis.dwell
51 bins Bin count of the dwell-time distribution view. The survival fit is not binned, so this changes only the picture. DwellTimeAnalysis.histogram(nbins=…) — no CLI flag, no GUI control no
prob_bins / prob_range / kde_bandwidth / kde_points
DEFAULT_TPROB_NBINS, DEFAULT_TPROB_RANGE, DEFAULT_TPROB_KDE_BANDWIDTH, DEFAULT_TPROB_KDE_POINTS in tether.analysis.transition_prob
25, (-0.05, 1.05), 0.25, 100 bin count, probability units, bandwidth, grid points Histogram and kernel-density overlay of per-trace transition probabilities. A wider bandwidth smooths the overlay; it does not change the underlying probabilities. transition_prob_histogram(…) — no CLI flag, no GUI control no
states_low / states_high
DEFAULT_STATE_NUMBER_LOW in tether.analysis.state_number
1, None (derived from the data) state counts (bar-chart x-axis bounds) Extent of the x-axis of the state-number bar chart, which tallies how many distinct states each molecule's Viterbi path actually occupies. 1 is the natural floor because a molecule with a valid idealization occupies at least one state; states_high at None takes the largest occupied count observed, clamped up to states_low so the axis stays valid on an empty or all-below-floor cohort. Narrowing the axis by hand does not silently drop molecules: the result carries n_molecules, n_in_range and n_out_of_range, so anything outside the bars is still counted and visible. A states_high below states_low is rejected outright. population_state_number(states_low=…, states_high=…) — no CLI flag, no GUI control no
cloud grid and contours
DEFAULT_CLOUD_SIGNAL_BINS, DEFAULT_CLOUD_TIME_BINS, DEFAULT_CLOUD_SIGNAL_RANGE, DEFAULT_CLOUD_HDR_COVERAGES, DEFAULT_CLOUD_BW_METHOD in tether.analysis.cloud, plus the time_range and kde keyword defaults there
100, 100, (-0.25, 1.25), (0.5, 0.95), scott, None (the whole cloud), True bin counts, apparent-E units, coverage fractions, rule name, time units (seconds when time_dt is set, frames at its default of 1.0), boolean Resolution of the raw-FRET cloud and the highest-density contours drawn on it. The coverages are the contour levels, not a test; the bandwidth rule controls how smooth the density looks. time_range at None spans 0 to the largest pooled time; passing (lo, hi), which must have hi > lo, does more than crop the axis, because the KDE and its HDR levels are fit on the in-grid points only — a narrowed range changes the fitted density, the Scott bandwidth and the reported n_out_of_range count of finite samples excluded from the fit. The same argument on population_fret_cloud_alpha_shape and population_fret_cloud_state_number_elbow selects which points the support boundary is drawn around and which E values are clustered. kde at True computes the density surface and the contour levels; at False the returned density, hdr_levels and bandwidth are all None and only the raw scatter comes back — which is how the α-shape and elbow store wrappers always call it. raw_fret_cloud(time_range=…, kde=…), population_raw_fret_cloud(…) — no CLI flag, no GUI control no
k-vs-RMSE elbow
the k_min signature default, DEFAULT_ELBOW_K_MAX, DEFAULT_ELBOW_RESTARTS, DEFAULT_ELBOW_SEED in tether.analysis.cloud, then the in_grid_only signature default
1, 8, 10, 0, True cluster-count floor, cluster-count cap, restarts, seed, boolean A k-means sweep over pooled apparent-E that hints at a state count. The bare helper k_rmse_elbow takes none of the grid/contour parameters in the previous row — it clusters the E values it is handed. k_min and k_max are the inclusive floor and cap of the probed k range (k_max is further capped at the number of distinct pooled E values); the elbow is the k furthest from the chord joining the curve's two endpoints, so raising k_min above 1 does not merely shorten the curve, it can move the returned elbow_k. More restarts keep the lowest-distortion codebook and steady the RMSE curve; the seed fixes the initialisation. The store-level entry point population_fret_cloud_state_number_elbow pools from a .tether project and does take the cloud's signal_range (defaulting to the same (-0.25, 1.25) as the previous row), time_range and time_dt: at the default in_grid_only=True only samples inside that range are clustered, so an off-grid bleach or blink excursion cannot raise a spurious extra E band; in_grid_only=False clusters the whole scatter. At the default time_range=None the time span is the whole cloud, so it is the E range and not the time range that does the filtering. It is a pre-idealization hint, not a determination — the state count of record comes from the model view. k_rmse_elbow(k_min=…, k_max=…, restarts=…, seed=…), population_fret_cloud_state_number_elbow(k_min=…, in_grid_only=…) — no CLI flag, no GUI control no
α-shape support boundary
DEFAULT_ALPHA_FACTOR in tether.analysis.cloud, and the alpha / in_grid_only keyword defaults there
2.0, None, True multiplier, dimensionless circumradius threshold, boolean The concave support boundary drawn around the raw-FRET cloud, and the time·E support area reported with it. alpha is a circumradius cut applied after each axis is rescaled to [0, 1] over the cloud's bounding box, so it is dimensionless and comparable across the time and E scales; at None it resolves to DEFAULT_ALPHA_FACTOR times the median finite triangle circumradius, which adapts to the cloud's own density. Raising it keeps more Delaunay triangles, so the boundary relaxes toward the convex hull and the reported area grows; lowering it drops the gap-spanning slivers for a more concave shape, until no triangle survives and an empty boundary is returned rather than a fabricated one. in_grid_only is on the two population_fret_cloud_* entry points only, not on alpha_shape itself: at the default just the points inside the cloud's time_range × signal_range — the same window the density surface is drawn on — bound the shape, so a finite but off-grid bleach/blink outlier stays in the honest scatter without dragging the boundary out to meet it; False bounds the full scatter. Nothing downstream consumes the boundary — it is a QC visualization, not a factor in any fitted value. population_fret_cloud_alpha_shape(alpha=…, in_grid_only=…), alpha_shape(points, alpha=…) — no CLI flag, no GUI control no — but the returned AlphaShape.alpha reports the threshold actually applied, including the auto-selected one
cross-correlation lag axis
max_lag, normalize keyword defaults in tether.analysis.crosscorr
None (the full axis), pearson frames, normalisation name Extent of the donor–acceptor cross-correlation curve. At the default the curve spans every lag the data supports: ±(N − 1) frames for one trace, and for a population the shortest usable molecule's ±(N − 1). Passing max_lag truncates that axis after the full FFT, so it neither saves work nor moves the values that remain — the reported lag0 and lag1_magnitude are unchanged, with the one exception that max_lag=0 drops lag +1 and leaves lag1_magnitude as NaN. normalize is not a choice: "pearson" is the only value accepted and anything else raises, so no run can quietly use a different normalisation. The intensity_quantity and include_rejected arguments behave exactly as in their rows above. population_cross_correlation(max_lag=…), cross_correlation(max_lag=…) — no CLI flag, no GUI control no
anticorrelation event finder
DEFAULT_ANTICORR_WINDOW, DEFAULT_ANTICORR_STEP, DEFAULT_ANTICORR_MIN_MAGNITUDE, DEFAULT_ANTICORR_MIN_WINDOWS in tether.analysis.anticorrelation
15, 1, 0.5, 1 frames, frames, correlation magnitude, consecutive windows Tether's own sliding-window quality-control flagger for anti-phase donor/acceptor behaviour — there is no tMAVEN counterpart. The 0.5 magnitude cut is the classical "clear correlation" threshold, chosen to reject white same-frame shot-noise anticorrelation. Nothing downstream consumes the events, so tuning these changes only what is highlighted for your attention: raise the magnitude or the window count to suppress marginal flags. population_anticorrelation_events(…) — no CLI flag, no GUI control no
plot export
DEFAULT_EXPORT_DPI, DEFAULT_FIGSIZE, DEFAULT_PLOT_FORMATS in tether.analysis.plot_export
200, (6.4, 4.8), ("pdf", "svg", "png") dots per inch, inches, formats Resolution, size and file formats of exported figures. The raster resolution is ignored by the two vector formats. The three formats are a §7.9 requirement rather than a preference; the DPI and figure size are cosmetic output knobs. Purely presentational. export_figure(dpi=…, formats=…) and the render_* functions' figsize= — no CLI flag, no GUI control no

Curation ranker

The quality ranker orders molecules for review. It never drops a molecule: ranking changes the order you see them in, not the population that enters an analysis.

Parameter Default Units Effect on the result Set via Recorded in .tether
intensity_quantity / include_rejected
compute_features in tether.project.features
corrected, True enum corrected/raw, boolean Which trace layer the cached /features/table is computed on, and which molecules get a row in it. The ranker is trained and scored on that table (ranking_dataset reads it), so both settings propagate into every ranking: changing the layer changes all seven trace-derived features, and a molecule with no row cannot be ranked at all. The two spatial features (neighbor_distance, aperture_overlap) are computed from /molecules coordinates and are unaffected by the layer. include_rejected defaults the opposite way here to everywhere else on this page: feature generation keeps rejected molecules by design, because a reject is the ranker's negative training label, whereas the tether.analysis population functions exclude them. Recompute the table after a re-extraction or a recalibration — it is a derived cache, not a record. compute_features(intensity_quantity=…, include_rejected=…) — no CLI flag, no GUI control intensity_quantity yes, as the /features/table attribute of the same name; include_rejected no
w0
DEFAULT_SEED_WEIGHT in tether.ml.weighting
0.3 relative weight Weight of a provisional seed label relative to a human one, which is fixed at 1.0. Seed weight decays as human labels accumulate, so the model leans on the seed only while you have labelled little. Raising it makes a cold-start model trust its own priors longer; lowering it makes early rankings closer to random until you have labelled enough. train_ranker(w0=…), recompute_label_weights(w0=…) — no CLI flag, no GUI control depends on the surface. train_ranker is read-only: it derives the decayed weights in memory for the fit and writes nothing, so a non-default w0 training run leaves no trace in the project. recompute_label_weights is the store-mutating one — it rewrites the resulting per-label weight values into /labels/table. Even then w0 itself is not stamped
learning_rate
RankerHyperparams in tether.ml.gbranker
0.1 dimensionless Gradient-boosting shrinkage. Lower learns more slowly and needs more iterations; higher can overfit a small label set. train_quality_ranker(hyperparams=…), ranker_prequential_uplift(hyperparams=…) — no CLI flag, no GUI control no, and neither surface named to the left writes the value anywhere else: train_quality_ranker returns an in-memory QualityRanker, and ranker_prequential_uplift is read-only and persists no model. A manifest.json carrying the hyper-parameters exists only on the separate portable-model path — train_portable_model or warm_start_retrain in tether.ml.persistence, written out by save_model — so unless you took that path, a non-default hyperparams is recoverable only from your own notes
max_iter
RankerHyperparams in tether.ml.gbranker
100 boosting iterations Number of trees. More capacity, more overfitting risk on the modest label sets this ranker is built for. as above no — as above
max_leaf_nodes
RankerHyperparams in tether.ml.gbranker
15 leaves per tree Tree capacity, deliberately below the library default because a curator's label set is small. Raising it lets the model carve finer distinctions and memorise noise. as above no — as above
min_samples_leaf
RankerHyperparams in tether.ml.gbranker
5 labelled molecules Minimum labels behind any leaf, again lowered from the library default so the model can split on modest label sets. Raising it makes the model refuse to split until you have labelled more. as above no — as above
l2_regularization
RankerHyperparams in tether.ml.gbranker
1.0 dimensionless Guards against overfitting a small sample. as above no — as above
early_stopping
RankerHyperparams in tether.ml.gbranker
False boolean Off by design: enabling it would carve an internal validation split out of an already small label set and make the fit depend on that split. as above no — as above
random_state
RankerHyperparams in tether.ml.gbranker
0 seed Fixes the histogram-binning subsample so a ranking is reproducible. as above no — as above
alpha (drift advisory)
DEFAULT_DRIFT_ALPHA in tether.ml.drift
0.05 family-wise probability Family-wise significance for the per-feature two-sample test that warns when a model trained on one condition is being applied to a visibly different one. It is Bonferroni-corrected across the features actually tested, and the report is advisory — nothing is blocked. Raising it produces more warnings. cross_condition_drift(alpha=…) — no CLI flag, no GUI control no
ship_bar_pts
DEFAULT_SHIP_BAR_PTS in tether.ml.prequential
10.0 percentage points of precision-at-k The uplift over file order, median across videos, at which the prequential evaluation calls the ranker worth using. It is a reporting threshold on an evaluation, not something that changes a ranking. ranker_prequential_uplift(ship_bar_pts=…) — no CLI flag, no GUI control no

Deep trace classifier

The optional GPU add-on has its own defaults; see Deep trace classifier (optional GPU add-on) for setup and usage. None of them affect the base application, and none are recorded in .tether — a trained deep model is a separate artifact.

Parameter Default Units Effect on the result Set via Recorded in .tether
intensity_quantity
tether.project.deep_dataset
corrected enum corrected/raw Which /traces layer supplies the model input. corrected selects the background-subtracted layer (/traces/donor_corrected and /traces/acceptor_corrected); raw selects the pre-background-subtraction layer. This is chosen independently of the layer the engineered features were computed on — the labels and weights are per-molecule and layer-independent. Training on raw changes the model input as much as dropping a channel does, and the per-trace scaling does not undo it: per_trace_total divides both channels by a single shared number, which rescales an additive background pedestal but never removes it, so on raw the pedestal survives into the tensor and inflates the divisor. A model trained on one layer cannot score a dataset built on the other — predict_proba refuses. Only build_deep_dataset reads a layer; assemble_dataset accepts the same argument as a provenance label only, since the caller supplies the arrays. build_deep_dataset(intensity_quantity=…) — no CLI flag, no GUI control no — stamped on the returned TrainedDeepClassifier, which predict_proba and fine_tune both check before scoring or adapting
channels
DEFAULT_DEEP_CHANNELS in tether.ml.deep.dataset
("donor", "acceptor") channel names Which measured channels are stacked, in order, as the model input. The tuple is axis 1 of the tensor and therefore the input channel count of the first convolution, so a donor-only or acceptor-only set trains a different classifier on strictly less of the trace. Only a non-empty, duplicate-free subset of ("donor", "acceptor") is accepted. Dropping a channel does not change the scaling: the shared per-trace scale is still computed from donor plus acceptor. build_deep_dataset(channels=…) or assemble_dataset(channels=…) — no CLI flag, no GUI control no — stamped on the returned TrainedDeepClassifier, which predict_proba checks before scoring
window_length
DEFAULT_WINDOW_LENGTH in tether.ml.deep.dataset
500 frames Fixed length every trace is cropped or zero-padded to. Shorter windows discard the tail of long traces — real data thrown away. Longer ones only cost compute: a boolean mask marks the real frames, the convolutional stack is length-preserving, and the LSTM is packed against the per-trace valid lengths, so padded frames never reach the recurrent summary or the classification head. assemble_dataset(window_length=…) — no CLI flag, no GUI control no
normalization
DEFAULT_NORMALIZATION in tether.ml.deep.dataset
per_trace_total enum Per-trace scaling of the two channels by their combined total, which preserves the donor/acceptor ratio while removing absolute brightness. none keeps absolute counts, which makes the model sensitive to gain and exposure. assemble_dataset(normalization=…) — no CLI flag, no GUI control no
val_fraction / split_seed / stratify
DEFAULT_VAL_FRACTION, DEFAULT_SPLIT_SEED in tether.ml.deep.dataset; stratify is a keyword default there, with no constant behind it
0.2, 0, True fraction, seed, boolean Size, reproducibility and class balance of the held-out split only — the same DEFAULT_SPLIT_SEED constant also supplies the training seed, which is a different job; see the training seed row below. A smaller validation fraction leaves more data for training and a noisier estimate of how well it worked. At the default the split is drawn within each label class, so the accept/reject ratio is preserved on both sides and a class of two or more rows never empties out of either side. stratify=False draws the validation rows from one global pool instead, so the held-out class balance is free to drift away from the training one — a held-out score reported from a non-stratified split is not comparable with one from the default. train_val_split(val_fraction=…, seed=…, stratify=…), DeepTraceDataset.split(…) — no CLI flag, no GUI control no
epochs / batch_size / learning_rate
DEFAULT_EPOCHS, DEFAULT_BATCH_SIZE, DEFAULT_LEARNING_RATE in tether.ml.deep.model
20, 32, 0.001 epochs, traces, dimensionless Training budget. Too few epochs underfits; too many overfits a small label set with no early stopping to catch it. train_classifier(…) and fine_tune(…), which take the same batch_size default; predict_proba(…) and rank_by_deep_model(…) take it too, but there it only chunks the scoring pass — no CLI flag, no GUI control no
training seed
DEFAULT_SPLIT_SEED in tether.ml.deep.dataset, reused as the signature default of train_classifier and fine_tune in tether.ml.deep.model
0 seed The training RNG — the same constant as the split seed two rows up, but a different job. It is passed to torch.manual_seed before the weights are initialised and it seeds the DataLoader shuffle generator, so two runs that differ only in seed produce different trained classifiers and different per-trace scores. Report the seed you trained at. The source claims determinism for a fixed seed on CPU; a CUDA run is not promised to be bit-reproducible. train_classifier(seed=…), fine_tune(seed=…) — no CLI flag, no GUI control no — stamped as seed in the returned TrainedDeepClassifier's hyperparameters
num_conv_layers / conv_channels / kernel_size / lstm_hidden / bidirectional / dropout
DEFAULT_NUM_CONV_LAYERS, DEFAULT_CONV_CHANNELS, DEFAULT_KERNEL_SIZE, DEFAULT_LSTM_HIDDEN, DEFAULT_BIDIRECTIONAL, DEFAULT_DROPOUT in tether.ml.deep.model
2, 32, 5, 32, True, 0.0 layers, channels, frames, units, boolean, probability Network shape. Larger capacity fits more complex trace morphologies and overfits sooner; dropout above zero trades training fit for generalisation. train_classifier(…) — no CLI flag, no GUI control no
fine-tuning epochs / learning_rate / freeze_conv
DEFAULT_FINE_TUNE_EPOCHS, DEFAULT_FINE_TUNE_LEARNING_RATE, DEFAULT_FREEZE_CONV in tether.ml.deep.model
10, 0.0001, False epochs, dimensionless, boolean Transfer of a trained model to a new condition. The low fine-tuning rate is what keeps the transferred model from forgetting the source condition; freezing the convolutional stack restricts adaptation to the recurrent head, which helps when the new condition has very few labels. fine_tune also takes batch_size, at the training default of 32 — it is stamped into the fine-tuned model's hyperparameters alongside the fine-tune values, so report it if you changed it. fine_tune(…) — no CLI flag, no GUI control no
device
DEFAULT_DEVICE in tether.ml.deep.model
cpu on train_classifier; None on fine_tune and predict_proba device string Where training runs. Not a scientific parameter, but it is the one you will change first. The cpu default is train_classifier's. fine_tune and predict_proba take device=None instead and resolve it from the model they are handed — fine_tune from base.hyperparameters['device'], predict_proba from the trained classifier's — falling back to DEFAULT_DEVICE when the model records no device, which is also what a bare nn.Module handed to predict_proba gets. So a classifier trained on CUDA fine-tunes and scores on CUDA unless you pass device yourself; rank_by_deep_model takes no device argument at all and always inherits. train_classifier(device=…), fine_tune(device=…), predict_proba(device=…) — no CLI flag, no GUI control no — but the device actually used is stamped as device in the returned TrainedDeepClassifier's hyperparameters, which is the record the fine-tune and scoring paths inherit from

Tolerances and gates

Some numbers in Tether are not really knobs: they are acceptance thresholds that decide whether a result is trustworthy. Their values are deliberately not restated here, because the evidence that justifies each one lives with the decision record that set it, and a second copy would drift. Use this section to find the authority for each, then read the value from there. Where one of them is settable per call, the row says so.

For the gates that were measured rather than chosen, Validation & benchmarks carries the evidence: the frozen numbers, what produced them, and — stated explicitly — which direction of change CI does and does not catch.

Gate Where the value lives What it decides
Registration RMS residual DEFAULT_RMS_GATE_PX in tether.imaging.calibrate; rationale in ADR-0014 Whether a channel map is flagged low-confidence, and — under tether batch --policy fail — whether the movie is failed. Settable as --rms-gate; the policy is the gate.
Leakage α acceptance range LEAKAGE_CEILING in tether.fret.leakage; estimator rationale in ADR-0027 Which per-trace α values enter the dataset median.
γ acceptance range GAMMA_CEILING in tether.fret.gamma; estimator rationale in ADR-0028 Which per-trace γ values enter the dataset median.
Idealization parity tolerance schema/parity_tolerance.json, loaded by load_frozen_tolerance in tether.idealize.parity; rationale in ADR-0009 and ADR-0043; measured spreads and re-freeze recipe in Validation & benchmarks Whether Tether's idealization is accepted as matching the reference implementation. The file carries a per-method row: the empirical-Bayes model is ratified against its own, looser tolerance, not the default one. Read the method's own row, not the top-level one.
Bleach-frame agreement asserted directly in tests/test_fret_photobleach.py How closely the detector must recover a known bleach frame. It exists only as a test assertion — there is no module constant, and therefore nothing to set.
Photobleach window default rationale in ADR-0026 How the automatic analysis window is derived and why a manual window always wins.
Per-trace interaction budget PER_TRACE_LATENCY_BUDGET_S in tether.project.perf A performance budget, not a scientific one: how long one molecule may take to render and advance.
Lock staleness DEFAULT_STALENESS_TIMEOUT_S in tether.project.lock When another process's write lock on a project is treated as abandoned. Unlike the other rows here it is settable per call — Project.acquire_lock(timeout_s=…) and Project.write_lock(timeout_s=…) both accept it — but the value you used is not persisted.
Return-leg identity match DEFAULT_MATCH_ATOL / DEFAULT_MATCH_RTOL in tether.project.handoff; rationale in ADR-0025 Which traces coming back from standalone tMAVEN are recognised as the store molecules they left as, and therefore whether an accepted window edit, class change or imported model reaches them at all — an unrecognised trace is reported unmatched and dropped, never mis-attributed. It is an equality guard rather than a tunable: tMAVEN preserves the SMD raw array unchanged across a save, so the correct test is equality with a float guard. Like the row above it is settable per call, but only on the module-level tether.project.handoff.read_return_leg / apply_reconcile — the same-named Project methods and the GUI reconcile dialog do not forward it, and no CLI flag exposes it.

Recording parameters in a methods section

If you ran everything at the defaults, this page describes your run and you can cite it. If you changed anything, what you can recover afterwards depends on the stage:

  • Extraction and registration — fully recoverable for the one-movie project tether extract and tether batch produce. Read /settings/extraction: the aperture and integration parameters are attributes, and the profile_json attribute holds every field of ExtractOptions as it was applied. The two Deep-LASI legacy-import paths — reconstruct_project and import_analysis_only_project, the two legs the GUI's Deep-LASI wizard drives — are not that, and neither ever had an ExtractOptions. A reconstruction writes the group, but its five aperture and integration attributes are fixed module constants describing the provenance of the pre-integrated legacy traces rather than an integration the import performed, and profile_json holds a short provenance dict instead. An analysis-only import (a coordinate-less SMD or .txt, no movie) writes no /settings/extraction group at all. The group is stamped by the first extraction into a project and never rewritten, and a later movie is only checked for consistency on window, disk_radius, ring_inner, ring_outer and bg_window. So if you appended several movies into one project from Python (write_extraction — no CLI or GUI command does this), /settings/extraction describes the first movie only: a later movie's detection_mode, prealign, pair_tol, rms_gate or coloc_distance is neither rejected nor recorded, and you must state those yourself.
  • Batch policy — recoverable from /settings/batch. The sidecar supervision settings (timeout, restarts) are not recorded. A batch run has no extraction flags, so its /settings/extraction is the shipped ExtractOptions defaults unless the run was driven from Python with an explicit extract_options — or --tdat was passed, which replaces the detection mode and threshold for every movie in the run. That case is still fully recoverable: /settings/extraction holds the values actually applied and names the file they came from in tdat_source.
  • Corrections — fully recoverable. /settings/leakage and /settings/gamma record the window, ceiling and qualifying-count thresholds actually used, along with the resulting factor and how many molecules qualified; /settings/correction records any overrides and whether apparent E was forced.
  • Idealization — the model type, the selected state count and how it was selected are recorded on the /idealization/<model> group, together with the per-K evidence whenever the state count was chosen automatically. The sidecar timeout and restart budget are not, and neither is nrestarts — if you overrode the fitter's restart count, write it down.
  • Photobleaching — the results are recorded, the inputs are not: neither the priors nor the intensity_quantity trace layer detection ran on. If you changed either, write it down yourself.
  • Analysis — nothing is recorded, because analysis outputs are computed on demand rather than stored. Any bin count, bootstrap setting, trace layer or frame interval you passed must be stated in your methods section. The frame interval is the one to check first: at the default, dwell times and rates come out per frame, not per second. State the intensity_quantity too — a histogram computed on raw traces is not comparable to one computed on corrected, and nothing in the project file records which you used.
  • Curation ranking — the trace layer the cached feature table was built on is recoverable, as the intensity_quantity attribute of /features/table. Whether rejected molecules were featured is not, and neither are the ranker's own hyper-parameters. They are written down only if you took the separate portable-model path — train_portable_model or warm_start_retrain, saved with save_model — which stamps them into the artifact's manifest.json. The two surfaces that accept a hyperparams override, train_quality_ranker and ranker_prequential_uplift, produce no artifact at all, and the project-level train_ranker takes no override and always fits at DEFAULT_HYPERPARAMS. So a non-default hyper-parameter outside the portable-model path has to be stated in your methods section.