Overview
CAFE (Chemical Affinity & Fitting Engine) is a GUI dialog for Chemical
Shift Perturbation (CSP) mapping and Kd (binding dissociation constant) fitting, absorbing
the capabilities of two older, still-separately-available tools: NMR Perturbation
Plot (accelerator np, npdplot.py) and
NMR Titration Plot (accelerator ni,
ntdplot.py). CAFE tracks a whole titration series in one pass, plots directly
in an embedded matplotlib canvas, and adds real Kd curve fitting that neither older tool had.
Peaks are matched across spectra by assignment label, not by position β important for titration data, since peaks move as ligand is added. This means peaks must already be assigned/tracked in every spectrum of a series before running CAFE, the same way peak assignment normally works in POKY.
Double-clicking any row in either tab's results table centers the corresponding spectrum view on that peak (the perturbed spectrum for CSP, the reference spectrum for Titration & Kd), the same jump-to-peak convention used elsewhere in POKY.
CSP (Pairwise)
Computes the classic Chemical Shift Perturbation distance between a reference (apo/unperturbed) spectrum and a single perturbed spectrum, for every residue assigned in both:
- CSP = β[ (ΞΞ΄H)Β² + (ΞΞ΄X / B)Β² ]
where X is whichever heteroatom (15N or 13C) is bonded to the observed proton, identified from the spectrum's nucleus list rather than assumed from axis order. CSP weighting reconciles three different conventions that existed independently elsewhere in POKY into one selectable preset:
| Preset | B (non-Gly) | B (Gly) | Source |
|---|---|---|---|
| POKY classic | 5.0 | 6.4 | npdplot.py (np) |
| Williamson/Becker | 7.14 | 5.0 | calculate_Kd_script.py (Ξ±=0.14/0.2, inverted to B=1/Ξ±) |
| Nucleus-based | 6.0 (15N) / 8.0 (13C) | same as non-Gly | plot_CSP_script.py |
| PseudoShift | 5.0 | 5.0 | sputil.pseudoshift() |
B and Gly-B remain fully editable after applying a preset. Results are shown as a bar chart with mean+1SD and mean+2SD reference lines, the usual significance-threshold convention for CSP plots, alongside a per-residue table.
The Observable dropdown selects what's actually compared between the two
spectra β the default, CSP (auto N/C, standard), is the formula above and
needs no further explanation. Selecting anything else switches to npdplot.py's
full pairwise comparison list (ported in for complete parity with that older tool, which CAFE
otherwise replaces):
- Individual atom shifts β H, N, C, CA, CB, HA/HA2, HA/HA3, HB/HB2, HB/HB3 (Ξppm between the two spectra)
- Line width, data height, fit height, volume, and signal-to-noise β each as %, ratio, or (for data/fit height) ratio with a propagated error estimate from both spectra's noise
- The remaining CSP-formula variants: choose 15N- or 13C-based
weighting explicitly (rather than auto-detected), with or without the
/2divisor, and either the standard CSP-of-the-delta or the more unusual delta-of-magnitudes form
Use absolute values (also from npdplot.py) takes the absolute
value of whatever's selected β mainly useful for the plain shift-delta and line-width
observables, which can otherwise be negative.
Titration & Kd new
Kd fitting is new in CAFE β neither np nor ni implements it. A
full titration series is selected in one multi-select dialog (rather than ni's
one-spectrum-at-a-time "Append" workflow), each spectrum's ligand ratio or concentration is
entered in a small table (auto-filled from the first number in the spectrum name where
possible), and every residue's response is fit to the standard single-site (1:1) quadratic
binding isotherm (Becker et al., ported from poky/misc/calculate_Kd_script.py):
- ΞΞ΄(Lt) = ΞΞ΄max Β· [(NΒ·Pt+Lt+Kd) β β((NΒ·Pt+Lt+Kd)Β² β 4Β·NΒ·PtΒ·Lt)] / (2Β·NΒ·Pt)
The quantity fit can be the CSP (using the same weighting presets as the CSP tab), an intensity ratio, or a volume ratio (each expressed as 1 β ratio, so it starts at 0 for the apo point like a CSP does). Unlike the original script, which fixed the amplitude ΞΞ΄max to the maximum observed value, CAFE fits it as a free parameter alongside Kd for every residue.
An optional global fit shares a single Kd across every residue in the dataset (with an independent amplitude per residue) β a more robust estimate when many residues report on the same binding event, recommended once individual per-residue fits look reasonably consistent. A per-residue titration-curve view (data + fit overlay, selectable from the results table) sits alongside summary plots of Kd, ΞΞ΄max, or ΟΒ² versus residue number.
Two further per-residue views round out feature parity with ntdplot.py
(select a row in the results table first):
- Lineshape stack (Plot dropdown): samples the actual 1D lineshape around the tracked peak's 1H position in every spectrum of the series (holding the heteroatom dimension fixed at that spectrum's own peak position), and plots the normalized traces stacked by titration point β a direct way to see peak movement or exchange broadening across the series, 2D spectra only.
- Export to ndpplot... (button): opens the selected residue's titration
curve (data + fit) in the standalone
ndpplotviewer, the same external toolntdplot.py(ni) uses β handy for a quick screenshot or for anyone already used to that viewer.
Excel & PyMOL Export
Both tabs export their per-residue table to an Excel workbook (via openpyxl)
with a ready-made scatter chart, and can generate a PyMOL .pml coloring script
mapping residue values onto a loaded structure β CSP magnitude (high CSP flagged, the usual
"hot spot" convention) or Kd (low Kd, i.e. the tightest binders,
flagged) β either a hard threshold (residues past a limit shown as red spheres) or a smooth
red-gradient coloring, with the run command copied to the clipboard for pasting
straight into PyMOL's command line.
PCA new
The PCA tab provides Principal Component Analysis for comparing sets of NMR spectra β useful for detecting correlated changes across a titration series, a mutant panel, or different sample conditions. At least three spectra are required. The output is a PC1 vs. PC2 score plot with labeled points and (in Assigned Peaks mode) loading arrows for each spectrum, alongside a per-sample table of PC1 and PC2 scores.
Both modes require scikit-learn (pip install scikit-learn);
Raw Spectra mode additionally requires nmrglue
(pip install nmrglue).
After running PCA, use the Plot selector and Redraw button to switch between two display modes without re-running the analysis:
| Plot mode | X axis | Y axis | Best for |
|---|---|---|---|
| PC1 vs PC2 | PC1 | PC2 | Exploring which samples cluster together |
| Molar ratio vs PC1 | Molar ratio (entered per spectrum) | PC1 | Tracking the dominant spectral change along a titration |
The X-axis label field customizes the axis title for the ratio plot (e.g., "Molar Ratio", "Ligand (ΞΌM)", "pH"). Molar ratio values are auto-filled from the first number in each spectrum name and can be edited before clicking Redraw.
Assigned Peaks (POAP)
Each residue is a sample; each spectrum is a feature. Only peaks assigned in all selected spectra are used. Gyromagnetic-ratio scaling is applied first to make 1H, 15N, and 13C shifts comparable (NΓ0.20, CΓ0.25 by default, both editable).
Combine two dimensions (on by default): the two spectral frequencies for each residue are collapsed into a single Euclidean distance from the reference-spectrum position β equivalent to a CSP-like scalar per condition. When off, each nucleus is treated as an independent variable, doubling the number of features.
The score plot shows residues as labeled points in PC1/PC2 space; red arrows (loadings) indicate which spectra/conditions drive the separation. A peak selection in the reference spectrum restricts the analysis to the selected subset.
In Molar ratio vs PC1 mode, the Y axis shows each spectrum's PC1 loading (how strongly that condition contributes to the first principal component), plotted against its molar ratio β useful for tracking how the dominant source of chemical-shift variation evolves along a titration.
Raw Spectra (PORS)
Each spectrum is a sample; raw intensity values (the full spectral data array flattened to a vector) are the features. No peak assignments are needed β useful for exploratory analysis or when assignments are incomplete.
If a single peak is selected in the session before clicking Run and the Normalize to reference peak checkbox is checked, all spectra are scaled to that peak's height before preprocessing β useful when spectra were acquired at different receiver gains. Otherwise each spectrum is minβmax normalized independently. The score plot shows spectra as labeled points; loading arrows are omitted (pixel indices are not meaningful labels).
In Molar ratio vs PC1 mode, the Y axis shows each spectrum's PC1 score β the position of that spectrum along the first principal component β plotted against its molar ratio. This is the raw-spectra equivalent of tracking the dominant state change vs. ligand concentration, and does not require any peak assignments.