This repository provides a minimal, dependency-light tools to handle NMR data. Makeshift reads NMR-STAR format files from the Biological Magnetic Resonance Bank (BMRB). It extracts sample metadata and measurements into Python dictionaries and pandas DataFrames.
Implementation details and validation of makeshift are described in our preprint: El Nesr & Wayment-Steele, Makeshift: a lightweight software for accessing and analyzing NMR data and protein dynamics (bioRxiv, 2026). doi:10.64898/2026.08.17.745346.
- Parse
.strfiles into nested Python dictionaries - Re-reference, calculate CSI, and more in
python - Extract polymer sequences, sample compositions, and chemical shifts
- Built using Python standard library +
pandas
pip install makeshift-nmrOr clone and install in editable mode (useful if you want to modify the code):
git clone https://github.com/WaymentSteeleLab/makeshift.git
cd makeshift
pip install -e .To also install dependencies for running the demo notebooks (seaborn, matplotlib, jupyter):
pip install -e ".[demos]"import makeshift as ms
# Download an NMR-STAR file from BMRB
ms.fetch_nmrstar_file(5363) # saves as bmr5363_3.str
# Parse the file
entry = ms.parse_nmr_star('bmr5363_3.str')
# Extract useful information
seq = ms.get_sequences(entry)
samples = ms.get_sample_info(entry)
cs = ms.get_chem_shifts(entry)Two lightweight re-referencing implementations are available:
panav: This code implements the core idea described in Wang & Wishart 2005. The idea is to use HA atoms, hydrogens being rarely mis-referenced, to estimate secondary structure from curated shift distributions from Wang & Jardetsky 2002. The method then minimizes the difference in distribution for N, CA, CB atoms between the current distribution and the curated shift distribution.
lacs: This code implements the core idea described in Wang & Markley 2009. The idea is to enforce that the chemical shift index (CSI) of the i-1 Carbon and the i Nitrogen intercepts at (0,0), essentially setting the "random coil" regime of each protein to be there.
Note: these two methods have not yet been extensively compared.
ms.fetch_nmrstar_file(4527)
cs = ms.get_chem_shifts(ms.parse_nmr_star('bmr4527_3.str'))
df, check, offsets = ms.reref(cs, method='panav') # or method='lacs'
print(offsets) # {'N': ..., 'CA': ..., 'CB': ..., 'C': ...}Entry 4527 is an example entry that is correctly referenced. Entries 6586 and 4150 are both entries described previously in literature as needing re-referencing.
NMR-STAR files are organised around saveframes. Each saveframe belongs to a category (e.g. assigned_chemical_shifts, entity, sample) and contains key-value pairs plus data loops.
The three concepts you’ll interact with most:
Entry — a single BMRB deposition. One .str file, one entry.
Entity — a distinct molecular species (protein, DNA strand, ligand, etc.). Multi-component complexes have multiple entities, each with its own Entity_ID.
Chemical shift list — the _Atom_chem_shift loop inside an assigned_chemical_shifts saveframe. One row per observed shift, keyed by Entity_ID, Seq_ID, Comp_ID, and Atom_ID.
| Function | Description |
|---|---|
fetch_nmrstar_file(bmrb_id) |
Download the NMR-STAR v3 file for a BMRB entry and save it locally. |
parse_nmr_star(file_path) |
Parse a .str file into a nested dict keyed by saveframe category. |
| Function | Description |
|---|---|
get_sequences(parsed) |
DataFrame of entities: ID, polymer type, one-letter sequence. |
get_sample_info(parsed) |
DataFrame of sample components: name, labeling, concentration. |
get_chem_shifts(parsed, calc_CSI=False) |
Tidy DataFrame of assigned shifts — one row per observation. Pass calc_CSI=True to add csi_raw and csi columns. |
| Function | Description |
|---|---|
reref(df, method) |
Correct backbone referencing errors. method is ’panav’ or ’lacs’. Returns (df, check, offsets). |
reref return values:
df— corrected shifts;origcolumn holds the pre-correction valuescheck—{atom: bool}indicating which atom types convergedoffsets—{atom: float | None}total offset applied per atom type
MIT License.
Note that makeshift.talosn downloads and runs the TALOS-N binary,
which is distributed separately by NIH under its own
Terms of Use; those terms
govern the downloaded software, not this wrapper.
- The Biological Magnetic Resonance Bank (BMRB) for maintaining and sharing NMR data.
- The Bax lab at NIH for TALOS-N.
If you use makeshift, please cite:
@article{makeshift2026,
title = {Makeshift: a lightweight software for accessing and analyzing NMR data and protein dynamics},
author = {El Nesr, Gina and Wayment-Steele, Hannah K.},
journal = {bioRxiv},
year = {2026},
doi = {10.64898/2026.08.17.745346},
url = {https://doi.org/10.64898/2026.08.17.745346}
}If you use the relaxation-dispersion processing, please also cite:
@article {dyna1,
author = {Wayment-Steele, Hannah K. and El Nesr, Gina and Hettiarachchi, Ramith and Ojoawo, Adedolapo and Kariyawasam, Hasindu and Ovchinnikov, Sergey and Kern, Dorothee},
title = {Learning millisecond protein dynamics from what is missing in NMR spectra},
year = {2026},
doi = {10.1038/s41586-026-10989-4},
journal = {Nature}
}