Skip to content

carlocamilloni/Aging

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

63 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AgIng

A 1D Ising-like Monte Carlo simulation of protein aggregation, running live in the browser.

Each site on a linear chain represents a protein that can exist in one of three states: Monomer, Disordered Oligomer, or Fibril. The system evolves via the Metropolis algorithm, and you can watch nucleation, aggregation, and phase-like transitions unfold in real time.

Live Demo

πŸ‘‰ carlocamilloni.github.io/Aging


The Model

States

State Colour Description
Monomer (M) πŸ”΅ Sky blue Free, soluble protein
Disordered Oligomer (D) 🟠 Orange Loosely associated, unstructured aggregate
Fibril (F) 🩷 Pink-violet Ordered amyloid-like aggregate β€” stabilised by cooperative interactions

Hamiltonian

H = Ξ£α΅’ Ξ΅β‚›α΅’
  βˆ’ J_D  Σ⟨i,j⟩  Ξ΄(D,D)
  βˆ’ J_F  Σ⟨i,j⟩  Ξ΄(F,F) Β· πŸ™[run β‰₯ minRun]
  βˆ’ h_FF Β· N_F   Β· πŸ™[βˆƒ active run]
  • Ξ΅β‚› β€” intrinsic energy of each state (eM, eD, eF)
  • J_D β€” disordered nearest-neighbour coupling: two adjacent D sites lower energy
  • J_F β€” fibril nearest-neighbour coupling: active only when both sites belong to a contiguous run of length β‰₯ minRun (cooperative nucleation)
  • h_FF β€” background field that lowers the energy of every fibril site once at least one active run exists anywhere on the chain (secondary nucleation / seeding)

Key physics

Competition between aggregation pathways β€” disordered oligomers form freely at any size, while fibril coupling is gated by a minimum run length. At intermediate temperatures the system can become trapped in a disordered phase rather than reaching the fibril state, reflecting the experimental observation that disordered aggregates can kinetically compete with amyloid formation.

Cooperative fibril nucleation β€” isolated fibril sites gain no stabilisation from J_F, so nucleation requires assembling a critical seed of size minRun before the fibril state becomes thermodynamically favourable.

Catalytic background field β€” once any active run forms, h_FF lowers the energy of every fibril site regardless of local context. This captures secondary nucleation and seeding: an established fibril template changes the free-energy landscape for the whole chain. The field is O(N) and avoids the O(NΒ²) cost of explicit pairwise long-range couplings.

Irreversible fibril mode β€” an optional toggle locks any fibril site once it joins an active run, preventing reversion. This captures kinetic trapping of mature amyloid cores.


Parameters

All energy parameters share the range 0–8.

Parameter Description
Chain length N Number of monomers (10–10000)
k_B T Temperature β€” controls the scale of thermal fluctuations
E_Monomer Intrinsic energy of the monomer state
E_Disordered Intrinsic energy of the disordered oligomer state
E_Fibril Intrinsic energy of the fibril state
J_Disordered Disordered–disordered nearest-neighbour coupling
J_Fibril Short-range fibril–fibril coupling (nearest neighbours, run β‰₯ minRun)
h_FF background Background field on all F sites once an active run exists
Min Fibril Run Minimum run length to activate fibril coupling and the background field

Trajectory export

Clicking Save (n) downloads a JSON file containing every recorded snapshot:

{
  "metadata": {
    "created": "2026-03-13T10:23:00.000Z",
    "software": "Aging",
    "n": 80,
    "totalSteps": 342,
    "snapshots": 342,
    "params": { "eM": 0, "eD": 1.5, "eF": 3.0, "jD": 1.2, "jF": 2.5, "hFF": 0.5, "minRun": 3, "T": 1.0 }
  },
  "trajectory": [
    { "step": 1, "chain": [0, 0, 2, 0, 1], "E": 12.4 },
    { "step": 2, "chain": [0, 1, 2, 0, 1], "E": 11.1 }
  ]
}

Each entry contains the step index, the full chain as an integer array (0 = Monomer, 1 = Disordered, 2 = Fibril), and the instantaneous energy. The buffer is cleared on Reset.


Running locally

You need Node.js v18 or later.

git clone https://github.com/carlocamilloni/Aging.git
cd Aging
npm install
npm run dev

Then open http://localhost:5173.

On macOS with MacPorts

sudo port install nodejs22 npm10

Command-line interface

The simulation can be run headlessly from the terminal, writing the time trace and full trajectory to TSV files incrementally.

node aging-cli.js [options]
Flag Default Description
--steps N 1000 Number of MC steps
--n N 100 Chain length
--seq MMMFFF... β€” Starting conformation string (overrides --n)
--T N 1.0 Temperature k_BT
--eM N 0 Intrinsic energy β€” Monomer
--eD N 1.4 Intrinsic energy β€” Disordered
--eF N 6.0 Intrinsic energy β€” Fibril
--jD N 1.0 J_Disordered coupling
--jF N 3.5 J_Fibril coupling
--hFF N 3.5 h_FF background field
--minRun N 3 Min fibril run length
--irreversible off Enable irreversible fibril locking
--stopOnFibril F off Stop when fibril fraction reaches F ∈ (0, 1] (default 1.0 if flag given without value)
--trace FILE trace.tsv Time trace output file
--traj FILE trajectory.tsv Trajectory output file
--help β€” Show usage

Both output files are written incrementally β€” safe to inspect mid-run with tail -f.

trace.tsv β€” one row per step:

step  fM      fD      fF      fActiveF  E        avgE
0     1.0000  0.0000  0.0000  0.0000    80.0000  80.0000
1     0.9875  0.0125  0.0000  0.0000    79.5000  79.7500

trajectory.tsv β€” one row per step, chain encoded as a string of M/D/F characters:

step  chain           E
0     MMMMMMMM...     80.0000
1     MMDMMMMD...     79.5000

Examples:

# Run 5000 steps at low temperature
node aging-cli.js --steps 5000 --n 100 --T 0.5 --jF 3.0 --hFF 1.0

# Stop as soon as 80% of sites are fibril
node aging-cli.js --steps 10000 --stopOnFibril 0.8

# Stop at 100% fibril (shorthand)
node aging-cli.js --steps 10000 --stopOnFibril

# Via npm
npm run cli -- --steps 5000 --T 0.5

Tests

The model and MC engine are covered by a regression suite using Vitest. All tests use hand-verified expected values β€” deterministic, no MC randomness except the low-temperature energy test.

npm test

Tests in tests/aging.test.js cover:

  • fibrilRunLength β€” boundary cases, run detection, non-fibril sites
  • computeEnergy β€” intrinsic energies, D-D coupling, F-F short-range coupling, h_FF background field (firing conditions, sub-threshold sites, two-run cases)
  • buildRunLen β€” correct lengths for all-monomer, single fibril, contiguous runs, and multiple runs
  • countActiveRuns β€” threshold detection including sub-threshold runs
  • updateRunLen β€” correctness after split, merge, extension, shrink, and long-run cases
  • deltaEnergyFast β€” exact consistency with computeEnergy for 17+ flip cases covering M↔D, M↔F, D↔F, boundary conditions, and h_FF transitions
  • mcStep β€” chain length preservation, irreversible locking, energy non-increase at low temperature

The CI workflow (.github/workflows/test.yml) runs the suite on every push and pull request.


Building for production

npm run build

The static output lands in dist/ and can be served from any static host.


Deployment

Pushes to main deploy automatically to GitHub Pages via GitHub Actions. See .github/workflows/deploy.yml.

After cloning, enable Pages in your repo under Settings β†’ Pages β†’ Source β†’ GitHub Actions.


Project structure

Aging/
β”œβ”€β”€ .github/workflows/
β”‚   β”œβ”€β”€ deploy.yml       # deploy to GitHub Pages on push to main
β”‚   └── test.yml         # run test suite on push and pull request
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ model.js         # Hamiltonian, energy functions, runLen cache
β”‚   β”œβ”€β”€ simulation.js    # MC engine (mcStep), chain helpers, constants
β”‚   β”œβ”€β”€ worker.js        # Web Worker owning the MC loop
β”‚   β”œβ”€β”€ aging.jsx        # React UI
β”‚   └── main.jsx         # entry point
β”œβ”€β”€ tests/
β”‚   └── aging.test.js    # Vitest regression suite
β”œβ”€β”€ aging-cli.js         # headless CLI runner
β”œβ”€β”€ index.html
β”œβ”€β”€ package.json
β”œβ”€β”€ vite.config.js       # Vite + Vitest config
└── README.md

Stack

  • React 18 β€” UI and state management
  • Vite 5 + Vitest 1 β€” build tooling and testing
  • Vanilla JS β€” MC engine (no runtime dependencies)

Acknowledgements

This codebase was developed with the assistance of Claude Sonnet 4.6 (Anthropic), which contributed to the model design, implementation, refactoring, and test suite.


License

MIT Β© The Authors

About

A 1D ising model for protein aggregation

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors