Probe Timecourse Fitting
Time-course probing captures RNA reactivity at multiple reaction times (e.g., 15 s, 30 s, …). Each time point is a quenched sample whose reactivity (fmod, modrate, or related metrics) is tracked per nucleotide. NERD’s timecourse engine converts those trajectories into kinetic parameters that summarize how quickly each nucleotide reacts.
- Inputs: per-nucleotide reactivity values across time points (often
modratefrom mutational counting). - Outputs:
k_obs(composite rate),k_deg, and baseline offsets (fmod0) stored in the SQLite database and JSON artifacts.
A separate guide covers how reactivity values are computed; this page focuses on the fitting workflow.
Kinetic Model
Every nucleotide is fit to the standardized equation:
[ r(t) = 1 - \exp!\left[-\frac{k_{\text{obs}}}{k_{\text{deg}}} \left(1 - e^{-k_{\text{deg}} t}\right)\right] + r_0 ]
where:
- (r(t)) is the observed reactivity at time (t).
- (k_{\text{obs}}) is the composite rate (\left(\frac{K}{K+1} \cdot \frac{k_{\text{add}} [P]0}{k{\text{deg}}}\right)).
- (k_{\text{deg}}) is the degradation rate of the probe (shared across nucleotides within a molecule).
- (r_0) (
fmod0in code) is a baseline offset capturing background signal.
The free round fits all three parameters per nucleotide; subsequent rounds constrain (k_{\text{deg}}) to enforce consistency.
Three-Round Workflow
| Round | Purpose | Key Details |
|---|---|---|
| Round 1 – Free | Fit each nucleotide independently. | Provides initial estimates of (k_{\text{obs}}), (k_{\text{deg}}), (r_0); caches results for reuse. |
| Round 2 – Global | Share (k_{\text{deg}}) across the molecule. | Combines the best free fits (default R² cutoff ≈ 0.8) and performs a global nonlinear regression. |
| Round 3 – Constrained | Refit all nucleotides with (k_{\text{deg}}) fixed. | Produces the final parameter set used downstream. |
Why so many rounds?
- Stability: Free fits bootstrap good starting points and flag problematic traces.
- Physical consistency: Within the same molecule and condition, degradation should be common. The global round enforces that intuition.
- Final reporting: Constrained fits yield a clean, per-nucleotide parameter set with a shared (k_{\text{deg}}).
You can request one or more rounds in the config (rounds: [round1_free, round3_constrained]), but the full sequence is most common.
Engines & Extensibility
NERD ships with a Python baseline engine (python_baseline) that uses lmfit. Other engines are available or planned:
r_integration(experimental): delegates fitting to R/NLME.- Custom engines: register new backends by extending the
TimecourseEngineinterface.
Each engine plugs into the same CLI interface, so swapping is as simple as changing engine: r_integration in the config.
Configuration Example
run:
label: tc_fit_4U
output_dir: outputs
probe_timecourse:
engine: python_baseline
rounds: [round1_free, round2_global, round3_constrained]
rg_ids: [42] # Reaction group IDs from `create`
valtype: modrate # or fmod, etc.
min_points: 3 # Require at least three time points
engine_options:
r2_threshold: 0.8 # Minimum R² to include in global round
Key fields:
rg_ids: which reaction groups to fit.valtype: the reactivity metric to use. Defaults tomodrate.engine_options.r2_threshold: filter for global fits (Tuning this is important for challenging data).rounds: any subset ofround1_free,round2_global,round3_constrained.
The task reads per-nucleotide time series from the database (loaded by mut_count and create tasks) and submits them to the engine.
Outputs & Interpretation
Each round generates:
nucleotides/<round>/...entries in the JSON artifact with parameters and diagnostics.- Database inserts into
probe_tc_fit_runs(one row per round + nucleotide set) andprobe_tc_fit_params(per-parameter rows forkobs,kdeg,fmod0, errors, QC metrics).
To inspect results:
- Open the JSON artifact under
outputs/<label>/probe_timecourse/.../results. - Query SQLite:
sql SELECT rg_id, nt_id, param_name, param_numeric FROM probe_tc_fit_params WHERE param_name IN ('kobs', 'kdeg') AND fit_run_id IN ( SELECT id FROM probe_tc_fit_runs WHERE fit_kind = 'round3_constrained' ); - Join with
meta_nucleotidesorprobe_reactionsto annotate constructs, positions, or conditions.
Remember: the headline metric is one (k_{\text{obs}}) per nucleotide per reaction group. These composite rates feed directly into downstream analyses such as temperature-gradient fits or global kinetic comparisons.
Best Practices
- Use derived samples (subsampling, filtering) to generate cleaner mutational profiles before fitting.
- Inspect free-fit diagnostics (
r2,chisq) to spot nucleotides with noisy or non-monotonic traces. - Provide prior knowledge when available:
- Seed
log_kdeg_initialin the config if degradation rates are known. - Restrict
nt_idsorvaltypeto focus on specific bases. - Consider running alternate engines (Python vs R) to validate difficult datasets.
With a consistent modeling approach, time-course fits become a reliable bridge from raw reactivities to interpretable kinetic fingerprints of your RNA construct.