Why this page. Pick practical signals to build one bounded, zero-centric Z_t and extend the lane set with pH and solvation/mixing. The downstream algebra (A_t, Delta_t, Q_t, g_t, RSI_env) stays unchanged. All math is plain ASCII and observation-only.
5.7 Choosing signals (practical mapping)
Rule of thumb (ASCII)
Compute a single, bounded Z_t per study; the rest of the algebra is unchanged. Normalize raw channels to [0,1], fuse into one S_t, extract drift over a short window, compress to [0,1] for Z_t, and derive a slow track A_t.
Examples by domain (copy-ready stubs)
# Lab scale
# Sources: stirrer RPM, torque ripple, inline temperature noise, conductivity pings, UV/Vis drift
lanes_raw := { RPM_ripple, Torque_ripple, T_noise, Cond_ping_var, UVVis_drift }
lanes_norm := normalize_to_01(lanes_raw, declared_recipes)
S_t := w_RPM*RPM_ripple + w_Torq*Torque_ripple + w_T*T_noise
+ w_Cond*Cond_ping_var + w_UV*UVVis_drift
Z_t := compress( drift_extractor(S_t, window=L) ) # e.g., var-log -> Z_raw/(1+Z_raw)
A_t := 1/(1+Z_t) # or smoothed variant
# Field / atmospheric
# Sources: NOx/O3 variability, wind shear, RH/temperature variance, light-intensity swings
lanes_raw := { NOx_var, O3_var, Wind_shear, RH_var, T_var, Light_swings }
lanes_norm := normalize_to_01(lanes_raw, declared_recipes)
S_t := w_NOx*NOx_var + w_O3*O3_var + w_W*Wind_shear
+ w_RH*RH_var + w_T*T_var + w_L*Light_swings
Z_t := compress( drift_extractor(S_t, window=L) )
A_t := 1/(1+Z_t)
# Electrochemistry
# Sources: current ripple, potential noise, impedance residuals
lanes_raw := { I_ripple, V_noise, Zresidual }
lanes_norm := normalize_to_01(lanes_raw, declared_recipes)
S_t := w_I*I_ripple + w_V*V_noise + w_Z*Zresidual
Z_t := compress( drift_extractor(S_t, window=L) )
A_t := 1/(1+Z_t)
Normalization helpers (ASCII)
normalize_to_01(x_raw, recipe):
# choose published recipe per lane: lin01, robust logistic, z-score+clip, MAD scaling, etc.
return clip( (x_raw - lo) / (hi - lo + eps), 0, 1 )
# weights non-negative, sum to 1
S_t = sum_k w_k * lane_k_norm
# choose one extractor and publish:
# "var-log": Z_raw = log(1 + Var_{[t-L,t]}(S))
# "mad": Z_raw = MAD_{[t-L,t]}(S)
# "ewma2": Z_raw = EMA( (S - EMA(S))^2 )
# "band": Z_raw = log(1 + bandpower(S, f_low, f_high))
# compress to [0,1]
Z_t = Z_raw / (1 + Z_raw) # or: 1 - exp(-beta*Z_raw)
A_t = 1/(1+Z_t) # optionally smoothed
Manifest checklist (publish)
- Lane list, meanings, and per-lane normalization recipes (with parameters).
- Weight vector
w_k(non-negative, sums to1) and windowL. - Drift extractor choice and compressor formula/parameters.
- Guards for missing data/outliers and confirmation that
Z_t, A_t in [0,1].
Result
A single, bounded Z_t derived from domain-appropriate lanes makes the gate g_t portable across lab, field, and electrochemical settings without changing the core mathematics.
5.8 Lane extensions (pH, solvation) — bounded maps to S_t (ASCII, observation-only)
Purpose. Add pH and solvation/mixing as first-class, bounded lanes that feed the unified calm gate. We only build S_t in [0,1]; the downstream logic (Z_t, A_t, Delta_t, Q_t, g_t) remains unchanged. When a lane is not relevant, set its weight to 0 (idempotent).
Baseline recap (fusion and renormalization)
# Core lanes (existing): F_t, W_t, V_t, E_t, Sspace_t in [0,1]
# New lanes (this section): P_t (pH lane), M_t (solvation/mixing lane) in [0,1]
S_raw = wF*F_t + wW*W_t + wV*V_t + wE*E_t + wS*Sspace_t + wP*P_t + wM*M_t
W_sum = max(wF + wW + wV + wE + wS + wP + wM, eps)
S_t = clip( S_raw / W_sum , 0, 1 )
pH lane (P_t) — proton availability as a bounded proxy
Choose one canonical map (declare once per reaction family). All return P_t in [0,1], monotone in the intended direction.
# Acid-favored window (linear, bounded)
P_t = clip( (pH_max - pH_t) / (pH_max - pH_min) , 0, 1 )
# Policy: pick [pH_min, pH_max] to cover the active acidic range (e.g., 0..7).
# Base-favored window (linear, bounded)
P_t = clip( (pH_t - pH_min) / (pH_max - pH_min) , 0, 1 )
# Policy: pick [pH_min, pH_max] in the basic range (e.g., 7..14).
# Neutral-band preference (triangular window)
P_t = clip( 1 - abs(pH_t - pH0) / bw , 0, 1 )
# where pH0 ~ 7 and bw > 0 sets half-bandwidth (e.g., bw = 1 gives 6..8 high).
# Soft (logistic) alternative (smooth step)
P_t = 1 / ( 1 + exp( k * (pH_t - pH0) ) ) # acid-favored if k > 0; base-favored if k < 0
# Choose |k| so ~2-3 pH units span ~10-90%.
# Optional shaping (declare once)
P_t := P_t^(eta_pH) # eta_pH >= 1 sharpens; 0 < eta_pH < 1 flattens
Solvation/mixing lane (M_t) — dielectric/ionic/mixing as bounded proxy
Pick measurable proxies, normalize each to [0,1], then fuse with non-negative weights.
# Normalization templates (choose those you can measure)
d_eps = clip( (epsilon_r - eps_min) / (eps_max - eps_min) , 0, 1 ) # dielectric
d_I = clip( (I_t - I_min) / (I_max - I_min) , 0, 1 ) # ionic strength
d_rpm = clip( rpm_t / rpm_cap , 0, 1 ) # stirring/turbulence
d_RT = clip( tau_mix / tau_cap , 0, 1 ) # residence/mixing time fraction
# Fusion (bounded, renormalized)
M_raw = u_eps*d_eps + u_I*d_I + u_rpm*d_rpm + u_RT*d_RT
U_sum = max(u_eps + u_I + u_rpm + u_RT, eps)
M_t = clip( M_raw / U_sum , 0, 1 )
# Optional shaping (declare once)
M_t := M_t^(eta_solv) # eta_solv >= 1 to reward higher solvation/mixing more sharply
Integration with the calm gate (no change downstream)
# drift and slow track
Z_t = compress( drift_extractor(S over [t-L, t]) ) # e.g., Z_raw/(1+Z_raw)
A_t = 1 / (1 + Z_t)
Delta_t = abs( Z_t - A_t )
# calm stock and gate
Q_t = rho * Q_prev + (1 - rho) * clip( A_t - Z_t , 0 , 1 )
g_t = ( 1 / (1 + Z_t + kappa * Delta_t) ) * ( 1 - exp( -mu * Q_t ) )
g_t = clip(g_t, 0, 1)
# condition-aware preference
RSI_env = g_t * RSI
Minimal pseudocode (drop-in)
# inputs: pH_t, epsilon_r, I_t, rpm_t, tau_mix, F_t, W_t, V_t, E_t, Sspace_t
# config:
# pH_map in {acid, base, neutral, logistic}
# pH params: pH_min, pH_max, pH0, bw, k, eta_pH
# solvation weights: u_eps, u_I, u_rpm, u_RT
# caps/ranges: eps_min, eps_max, I_min, I_max, rpm_cap, tau_cap, eta_solv
# fusion weights: wF, wW, wV, wE, wS, wP, wM (non-negative)
P_t = map_pH(pH_t, pH_map, pH_min, pH_max, pH0, bw, k)
P_t = P_t ** eta_pH
d_eps = clip((epsilon_r - eps_min)/(eps_max - eps_min), 0, 1)
d_I = clip((I_t - I_min) /(I_max - I_min), 0, 1)
d_rpm = clip(rpm_t / rpm_cap, 0, 1)
d_RT = clip(tau_mix / tau_cap, 0, 1)
M_raw = u_eps*d_eps + u_I*d_I + u_rpm*d_rpm + u_RT*d_RT
U_sum = max(u_eps + u_I + u_rpm + u_RT, eps)
M_t = clip(M_raw / U_sum, 0, 1)
M_t = M_t ** eta_solv
S_raw = wF*F_t + wW*W_t + wV*V_t + wE*E_t + wS*Sspace_t + wP*P_t + wM*M_t
W_sum = max(wF + wW + wV + wE + wS + wP + wM, eps)
S_t = clip(S_raw / W_sum, 0, 1)
Guards & policy
- Idempotence: set
wP = 0to ignore pH; setwM = 0to ignore solvation/mixing. - Calibration: publish all mins/max/caps and weights; keep them constant within a study.
- Monotonicity: verify
P_tandM_tincrease in the intended direction for the reaction family (unit tests). - Window
L: choose to match process timescale (e.g., minutes for mixing screens). - No hidden tables: any domain heuristics must appear as explicit parameters (no black-box lookups).
Manifest additions (diffs)
wP, pH_map, pH_min, pH_max, pH0, bw, k, eta_pH
wM, u_eps, u_I, u_rpm, u_RT, eps_min, eps_max, I_min, I_max, rpm_cap, tau_cap, eta_solv
W_sum_policy # renorm on; include eps used for guards
Result
pH and solvation/mixing become transparent, auditable lanes that nudge g_t via S_t, without touching stoichiometry or RSI math. The maps are bounded, monotone under declared policies, and fully idempotent when disabled.
Navigation
Previous — Worked micro-flows (how g_t changes outcomes); Minimal pseudocode (reference) (5.5, 5.6)
Next — Diagnostics and plots for calm vs edge; Visual recipes for lanes (5.9, 5.10)
Disclaimer (observation-only). All formulas and results are observation-only—not predictive or operational—and require peer validation and governance before any deployment.