Example code
One phosphorylation reactor can rest or oscillate at the same rates and totals. A kinase adds phosphate groups; a phosphatase removes them. Their six substrate complexes compete for shared enzyme pools, coupling the three sites without an added feedback reaction.
The example reconstructs the full twelve-species mass-action model and its conserved totals. It computes the stable resting state, an attracting oscillation and an inner unstable cycle, then applies a temporary change to one rate. Reaction rates, pulse settings and physical reference units are editable; reusable reactor, signal, shooting and switching components support further experiments.


The default oscillation has period 28.69124 model units and fully phosphorylated-pool range 2.34593. A three-period, at-most-ten-percent association-rate pulse numerically activates the rhythm. A differently phased pulse, triggered when the trajectory crosses a specified reference section, returns it toward rest. Recovery is slow: the residual ripple after OFF takes many periods to decay.
The interval checks for the local onset of coexisting rest and oscillation and for control through each individual rate are freshly replayed. The finite-orbit proof is included as an explicitly imported certificate; the displayed trajectories and finite-witness switching are numerical. The local theorem does not certify these particular pulses, phase-blind OFF, or a numerical tolerance for switching errors. The model and outputs keep those distinctions visible.
Python source
"""Rest and rhythm in one phosphorylation reactor, with single-rate actuation."""
# EDITABLE INPUTS. Exact source concentrations/currents are in the named JSON.
SOURCE_FILE = 'finite_source_exact.json'
ORBIT_SEEDS_FILE = 'orbit_seeds.json' # Supply new guesses/section for substantially changed sources.
RATE_MULTIPLIERS = {} # e.g. {'alpha1': 1.001}; exploratory, no inherited certificate.
ACTUATED_RATE = 'alpha1' # Any one of eighteen names; published pulse uses alpha1.
PULSE_AMPLITUDE = .1
PULSE_PERIODS = 3
ON_PHASE_PI = 1.
OFF_PHASE_PI = 1/3
WAIT_AFTER_ON_PERIODS = 14
ON_SETTLING_PERIODS = 400
OFF_SETTLING_PERIODS = 600
CONCENTRATION_UNIT_MICROMOLAR = .1
TIME_UNIT_SECONDS = 100.
OBSERVATION_GAP = .5 # Model units; readout diagnostic, not a noise certificate.
OBSERVATION_ERROR = .01 # Absolute readout units per sample.
from pathlib import Path
import argparse,csv,hashlib,json,platform
import numpy as np
import scipy
import sympy as sp
from mpmath import mp
from clock import finite_model,patch_model,rate_list,RATE_NAMES,GH_CENTER,mp_JB,critical_pair,normal_form
from phos import Model,certify_hopf,bounds
from reactor import MassActionReactor,SwitchingExperiment
import local_certificate,input_rank
MANUSCRIPT_SHA256='efe1d3ed4fc2b556aed9c0eb6b3b62957ffeb32c9cfbf1edf67d93e11728a266'
def main():
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--output',type=Path,default=Path('outputs'));out=parser.parse_args().output;out.mkdir(parents=True,exist_ok=True)
def dump(name,value):(out/name).write_text(json.dumps(value,indent=2,default=lambda v:v.tolist() if isinstance(v,np.ndarray) else str(v))+'\n')
def table(name,rows):
with (out/name).open('w',newline='') as f:w=csv.DictWriter(f,fieldnames=list(rows[0]));w.writeheader();w.writerows(rows)
here=Path(__file__).parent;data=json.loads((here/SOURCE_FILE).read_text());x=list(map(sp.Rational,data['xstar']));q=list(map(sp.Rational,data['currents']));r=sp.Rational(data['r'])
if len(x)!=12 or len(q)!=3 or min(*x,*q,r)<=0:raise ValueError('The three-site source needs twelve positive concentrations, three positive currents and a positive reverse ratio.')
model=Model(3,x,q,[sp.Rational(1,100)]*3,[r,sp.Rational(1,100),sp.Rational(1,100)])
rates=list(map(float,rate_list(model)))
for name,multiplier in RATE_MULTIPLIERS.items():
if name not in RATE_NAMES or not np.isfinite(multiplier) or multiplier<=0:raise ValueError('Each rate multiplier must be named, finite and positive.')
rates[RATE_NAMES.index(name)]*=multiplier
reactor=MassActionReactor(model,rates,ACTUATED_RATE)
dump('exact_source.json',dict(concentrations=list(map(str,x)),currents=list(map(str,q)),rates=dict(zip(RATE_NAMES,map(str,rate_list(model)))),totals=list(map(str,model.totals())),configured_rates=dict(zip(RATE_NAMES,rates)),configured_equilibrium_residual=float(max(abs(reactor.f(0,np.zeros(9))))),scope='The exact reconstruction fixes a baseline equilibrium. Independent rate multipliers generally move it; reference certificates below apply to the published source only.'))
rest_state,rest_residual=reactor.equilibrium()
assert all(v==0 for v in model.field()) and model.Rm*model.P==sp.eye(9)
eig=np.linalg.eigvals(reactor.jac(0,rest_state));dump('rest_stability.json',dict(equilibrium_chart=rest_state,equilibrium_residual=rest_residual,eigenvalues=[str(v) for v in eig],largest_real=float(max(eig.real)),e_folding_model_time=float(-1/max(eig.real)),scope='Numerical restricted Jacobian at the configured rates and totals; modified rates require a newly located rest state.'))
print('Computing fresh generalized-Hopf interval certificate and all input ranks.',flush=True)
gh=local_certificate.certify();dump('generalized_hopf_certificate.json',gh);dump('all_input_rank_certificate.json',input_rank.certify(gh))
mp.dps=45;J,B=mp_JB(patch_model(sp.Rational(GH_CENTER[0]),sp.Rational(GH_CENTER[1])));lam,qq,ll,_=critical_pair(J,mp.mpf(GH_CENTER[2]));coeff,_=normal_form(J,B,lam,qq,ll)
dump('independent_normal_form.json',dict(eigenvalue=str(lam),cubic=str(coeff[1]),quintic=str(coeff[2]),l2=str(mp.re(coeff[2])/mp.im(lam)),scope='Independent high-precision numerical recurrence; fresh directed certificate is stored separately.'))
hc=certify_hopf(lambda rr:finite_model(rr));dump('finite_family_hopf.json',{k:bounds(hc[k]) for k in ('r','omega','l1','crossing')})
imported=json.loads((here/'imported_orbit_certificate.json').read_text());dump('orbit_proof_status.json',dict(status='imported_not_rerun',source_sha256=hashlib.sha256((here/'imported_orbit_certificate.json').read_bytes()).hexdigest(),period=imported['T_interval'],readout=imported['readout_p2p'],gershgorin=imported['gershgorin'],scope='The manuscript independently validates the finite orbit. This run freshly solves numerical shooting and variational equations; it does not rerun the multiple-shooting interval proof or the Fourier proof.'))
seeds=json.loads((here/ORBIT_SEEDS_FILE).read_text());orbits=[];curves=[]
for name in ['stable','unstable']:
orbit=reactor.shoot(seeds[name+'_y0'],seeds[name+'_T']);run=reactor.integrate(orbit['anchor'],orbit['period'],ledger=True,samples=2001)
readout=run['species'][3]+run['species'][11];orbit.update(case=name,readout_range=float(np.ptp(readout)),min_species=run['minimum_concentration'],conservation_drift=run['conservation_drift'],kinase_turnover=float(sum(run['ledger'][[2,5,8]])),phosphatase_turnover=float(sum(run['ledger'][[11,14,17]])))
orbits.append(orbit);curves.append((name,run));table(name+'_orbit.csv',[dict(time=t,**{f'x{i}':run['species'][i,j] for i in range(12)},readout=readout[j]) for j,t in enumerate(run['time'])])
print(name,'period',orbit['period'],'range',orbit['readout_range'],'leading nontrivial multiplier',orbit['largest_nontrivial'],flush=True)
if max(eig.real)>=0 or orbits[0]['largest_nontrivial']>=1:raise RuntimeError('Configured numerical rest/rhythm pair is not attracting; do not classify this as bistability.')
dump('numerical_orbits.json',[{**o,'multipliers':[str(v) for v in o['multipliers']]} for o in orbits]);T=orbits[0]['period']
experiment=SwitchingExperiment(reactor,T,seeds['XI'],seeds['ZETA'],PULSE_AMPLITUDE,PULSE_PERIODS)
segments,on,off=experiment.run(np.pi*ON_PHASE_PI,np.pi*OFF_PHASE_PI,WAIT_AFTER_ON_PERIODS,rest_state)
# Independent stiff solver cross-checks only the finite pulse endpoints.
cross_on=experiment.pulse(on['chart'][:,0],np.pi*ON_PHASE_PI,method='Radau');cross_off=experiment.pulse(off['chart'][:,0],np.pi*OFF_PHASE_PI,method='Radau')
on_fate=experiment.terminal_window(on['endpoint'],ON_SETTLING_PERIODS,rest_state);off_fate=experiment.terminal_window(off['endpoint'],OFF_SETTLING_PERIODS,rest_state)
dump('switching_diagnostics.json',dict(actuated_rate=ACTUATED_RATE,amplitude=PULSE_AMPLITUDE,pulse_periods=PULSE_PERIODS,on=on_fate,off=off_fate,LSODA_Radau_on_difference=float(max(abs(on['endpoint']-cross_on['endpoint']))),LSODA_Radau_off_difference=float(max(abs(off['endpoint']-cross_off['endpoint']))),minimum_concentration=min(s['minimum_concentration'] for s in segments),conservation_drift=max(s['conservation_drift'] for s in segments),scope='Numerical finite-witness switching with a phase-triggered OFF pulse. Neither arbitrary-phase OFF nor finite error tolerance is certified.'))
records=[];offset=0
for i,s in enumerate(segments):
for j,t in enumerate(s['time']):records.append(dict(segment=i,time=offset+t,periods=(offset+t)/T,readout=s['species'][3,j]+s['species'][11,j],relative_modulation=s['control'][j]))
offset+=s['elapsed']
table('switching_trace.csv',records)
units=physical_reading(model,reactor,orbits[0],eig,T,rest_state);dump('physical_interpretation.json',units)
# The normal-form scaling is a leading-order model, not a parameter sweep
# of the full reactor or a guaranteed control-amplitude formula.
d=.0444275025;b0=.012;a0=b0*b0/(8*d);scaling=[]
for eps in [1.,.5,.25,.125,.0625]:
a=-eps**2*a0;b=eps*b0;disc=np.sqrt(b*b+4*d*a);rp=np.sqrt((b+disc)/(2*d));rm=np.sqrt((b-disc)/(2*d))
scaling.append(dict(epsilon=eps,inner_radius=rm,outer_radius=rp,coexistence_width=b*b/(4*d),sink_recovery_time=-1/a,cycle_recovery_time=1/(2*rp*rp*disc),relative_control_amplitude_scale=np.sqrt(eps)))
table('leading_order_tradeoff.csv',scaling);plot(out,curves,records,scaling,reactor,T,rest_state)
print('Switching final readout ranges:',on_fate['range'],off_fate['range'],flush=True)
print('All rates and totals remain fixed between pulses; one rate alone is modulated during each pulse. Generalized-Hopf and rank certificates freshly replayed. Finite-orbit proof imported; switching numerical; Lean not rerun.',flush=True)
digest=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
dump('run_metadata.json',dict(manuscript_sha256=MANUSCRIPT_SHA256,source_sha256=digest(Path(__file__)),python=platform.python_version(),numpy=np.__version__,scipy=scipy.__version__,module_sha256={p.name:digest(p) for p in sorted(here.glob('*.py')) if p.name not in ['example.py','test_example.py']},input_sha256={p.name:digest(p) for p in sorted(here.glob('*.json')) if p.name!='release.json'},output_sha256={p.name:digest(p) for p in sorted(out.iterdir()) if p.is_file() and p.name!='run_metadata.json'}))
def physical_reading(model,reactor,orbit,eig,T,rest_state):
c=CONCENTRATION_UNIT_MICROMOLAR;tau=TIME_UNIT_SECONDS
if min(c,tau)<=0 or OBSERVATION_GAP<0 or OBSERVATION_ERROR<0:raise ValueError('Positive physical units and nonnegative observation errors required.')
sampled=reactor.integrate(orbit['anchor'],T,samples=2001);slope=max(abs(reactor.f(t,sampled['chart'][:,i])[2]) for i,t in enumerate(sampled['time']))
return dict(concentration_unit_micromolar=c,time_unit_seconds=tau,totals_micromolar=[float(v)*c for v in model.totals()],period_minutes=T*tau/60,readout_range_micromolar=orbit['readout_range']*c,cycle_recovery_periods=-1/np.log(orbit['largest_nontrivial']),sink_recovery_periods=-1/max(eig.real)/T,bound_phosphatase_fraction_at_rest=float(1-reactor.species(rest_state)[5]/float(model.totals()[1])),cycle_kinase_events=orbit['kinase_turnover'],rest_kinase_events=float(sum(reactor.flux(reactor.species(rest_state))[2:9:3]))*T,numerical_readout_slope_max=float(slope),sampling_range_diagnostic=orbit['readout_range']-slope*OBSERVATION_GAP-2*OBSERVATION_ERROR,scope='Uncalibrated dimensional interpretation. Slope maximum is sampled numerically, so the sampled-range calculation is diagnostic. Recovery e-folding times are not settling guarantees; no stochastic retention claim.')
def plot(out,curves,records,scaling,reactor,T,rest_state):
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig,axs=plt.subplots(1,2,figsize=(11,4),layout='constrained')
for name,run in curves:
rd=run['species'][3]+run['species'][11];axs[0].plot(run['time'],rd,label=name+' cycle (numerical)');axs[1].plot(run['species'][5],rd,label=name+' cycle')
rest=reactor.species(rest_state)[3]+reactor.species(rest_state)[11];axs[0].axhline(rest,color='black',ls=':',label='Stable rest');axs[1].plot(reactor.species(rest_state)[5],rest,'ko',label='Stable rest')
axs[0].set(xlabel='Model time',ylabel='Fully phosphorylated pool S3 + D3',title='Steady and oscillating states at fixed\nrates and totals');axs[1].set(xlabel='Free phosphatase F',ylabel='Fully phosphorylated pool S3 + D3',title='Coexisting steady state and periodic\ntrajectories')
for a in axs:a.legend(fontsize=8);a.grid(alpha=.2)
fig.savefig(out/'coexisting_rest_rhythm.png',dpi=180);fig.savefig(out/'coexisting_rest_rhythm.svg');plt.close(fig)
fig,axs=plt.subplots(2,1,figsize=(11,5),sharex=True,layout='constrained',gridspec_kw={'height_ratios':[3,1]})
axs[0].plot([r['periods'] for r in records],[r['readout'] for r in records]);axs[0].axhline(rest,color='gray',ls=':');axs[0].set(ylabel='S3 + D3',title='Single-rate ON and phase-triggered OFF (numerical)')
axs[1].plot([r['periods'] for r in records],[r['relative_modulation'] for r in records]);axs[1].set(xlabel='Time / autonomous cycle period',ylabel='Relative input')
for a in axs:a.grid(alpha=.2)
fig.savefig(out/'single_rate_switching.png',dpi=180);fig.savefig(out/'single_rate_switching.svg');plt.close(fig)
if __name__=='__main__':main()
Run output
Computing fresh generalized-Hopf interval certificate and all input ranks. stable period 28.691242741624432 range 2.3459339732732474 leading nontrivial multiplier 0.9298626626726679 unstable period 26.509979771442666 range 1.0276042081078458 leading nontrivial multiplier 1.0160413081288544 Switching final readout ranges: 2.345921198012501 0.00030471730745729175 All rates and totals remain fixed between pulses; one rate alone is modulated during each pulse. Generalized-Hopf and rank certificates freshly replayed. Finite-orbit proof imported; switching numerical; Lean not rerun.