Operate a Bruker NMR spectrometer via TopSpin software. Covers 1H-NMR acquisition and processing (1D). 13C-NMR and 2D experiments (COSY, HSQC, HMBC) supported for acquisition only — processing pipeline is 1D 1H. Process FID data, pick peaks, analyze chemical shifts, identify compounds.
Read SOUL.md for NMR personality, spectroscopic quirks, and solvent knowledge before first use.
You are operating a Bruker NMR spectrometer through TopSpin 5.x software. This skill gives you three ways to control the instrument and a complete data processing pipeline.
NMR spectrometers have a superconducting magnet that is ALWAYS energized:
Safety level: normal
| Mode | When to use | Requirements |
|---|---|---|
| Offline | Process existing FID data without TopSpin running | nmrglue, numpy |
| API | Programmatic control of a running TopSpin instance (processing only — see note below) | TopSpin running, gRPC port 3081 |
| GUI | Visual automation of TopSpin window via Computer Use | TopSpin visible, ANTHROPIC_API_KEY |
Always start with Offline mode unless you specifically need live instrument control.
# Note: Directory is 'bruker-topspin' on disk but imports use underscores
from devices.bruker_topspin.adapter import TopSpinAdapter
from devices.bruker_topspin.processor import TopSpinProcessor
from devices.bruker_topspin.visualizer import plot_spectrum
# 1. Connect in offline mode (default)
adapter = TopSpinAdapter(mode="offline")
adapter.connect()
# 2. List available datasets
datasets = adapter.list_datasets()
# Each entry: {"path": str, "sample": str, "expno": int, "title": str}
# 3. Process a dataset (FID -> spectrum with peaks)
spectrum = adapter.process(data_path="/opt/topspin5.0.0/examdata/exam_CMCse_1/1")
# Returns NMRSpectrum with: data, ppm_scale, peaks, nucleus, solvent, frequency_mhz
# 4. Inspect peaks
for peak in spectrum.peaks[:10]:
print(f" {peak.ppm:.3f} ppm (intensity: {peak.intensity:.1f})")
# 5. Plot
plot_spectrum(spectrum, output_path="spectrum.png", annotate_peaks=True)
The central data object returned by all processing paths:
data (np.ndarray) -- processed spectrum intensitiesppm_scale (np.ndarray) -- chemical shift axispeaks (list[NMRPeak]) -- detected peaks, sorted high-to-low ppmnucleus (str) -- e.g. "1H"solvent (str) -- e.g. "CDCl3"frequency_mhz (float) -- spectrometer frequencytitle, sample_name (str) -- metadata from datasetppm (float) -- chemical shift positionintensity (float) -- peak heightwidth_hz (float) -- line widthmultiplicity (str) -- splitting patternintegral (float) -- relative areaThe processor runs the standard NMR pipeline: digital filter removal, zero-fill, apodization, FFT, phase correction, baseline correction, peak picking.
processor = TopSpinProcessor(line_broadening=0.3)
dic, fid = processor.read_bruker("/path/to/dataset/1")
spectrum = processor.process_1d(dic, fid, dataset_path="/path/to/dataset/1")
Processing steps (automatic):
Note: _acquire_api() is not yet implemented (raises NotImplementedError). Use API mode for processing only (adapter.process()), not acquisition.
adapter = TopSpinAdapter(mode="api")
if adapter.connect(): # connects to gRPC port 3081
spectrum = adapter.process(data_path="/path/to/dataset/1")
# TopSpin runs: efp (FT+phase) -> apbk (baseline) -> ppf (peak pick)
# Then reads processed pdata back via nmrglue
adapter = TopSpinAdapter(mode="gui")
if adapter.connect(): # detects TopSpin window
spectrum = adapter.process(data_path="/path/to/dataset/1")
# Types commands into TopSpin command line: efp, apbk, ppf
from devices.bruker_topspin.brain import TopSpinBrain
brain = TopSpinBrain() # needs ANTHROPIC_API_KEY or uses cached demos
interpretation = brain.interpret_spectrum(spectrum, molecular_formula="C9H8O4")
# Returns markdown: Peak Analysis, Proposed Structure, Confidence, Next Steps
# Streaming variant
for chunk in brain.interpret_spectrum(spectrum, stream=True):
print(chunk, end="")
# Suggest follow-up experiments
suggestion = brain.suggest_next_experiment(spectrum, hypothesis="aspirin")
from devices.bruker_topspin.library import SpectralLibrary
lib = SpectralLibrary.from_examdata() # loads all TopSpin example data
matches = lib.match(unknown_spectrum, top_k=3)
for m in matches:
print(f" {m.entry.name}: score={m.score:.2f} ({m.matched_peaks} peaks matched)")
from devices.bruker_topspin.driver import TopSpinDriver
driver = TopSpinDriver(config={"mode": "offline"})
await driver.connect()
await driver.write({"action": "process", "path": "/path/to/dataset/1"})
result = await driver.read() # returns dict with peaks, metadata
This skill includes 525 command reference files in docs/commands/. Do NOT try to load them all. Instead, search by topic:
# Find commands related to a topic
grep -ril "phase correction" devices/bruker-topspin/docs/commands/
grep -ril "baseline" devices/bruker-topspin/docs/commands/
grep -ril "peak pick" devices/bruker-topspin/docs/commands/
grep -ril "2D" devices/bruker-topspin/docs/commands/
Files are named by command (e.g., efp.md, apk.md, ppf.md). Read a specific file when you need details about a command.
| Command | Purpose |
|---|---|
efp | Exponential multiply + Fourier transform + phase correction |
apk | Automatic phase correction |
apbk | Auto phase + baseline (neural-net algorithm) |
absn | Baseline correction |
ppf | Peak picking (find peaks) |
re | Open/load a dataset |
zg | Start acquisition (go) |
rga | Receiver gain adjustment |
lock | Lock on solvent signal |
topshim | Automatic shimming |
Note: Processor currently handles 1D 1H only. 2D data can be acquired but must be processed in TopSpin.
For a typical 1D 1H spectrum, the command sequence is:
re <dataset_path> # open dataset
efp # FT + phase
apbk -n # neural-net auto phase + baseline
ppf # peak picking
Each experiment is a directory tree:
<sample_name>/
<expno>/ # experiment number (1, 2, 3...)
fid # raw Free Induction Decay
acqus # acquisition parameters
acqu2s # 2D acquisition parameters (if 2D)
pdata/
1/ # processing number
1r, 1i # processed real/imaginary data
procs # processing parameters
title # experiment title
peaklist.xml # peak list (after ppf)
Default examdata location: /opt/topspin5.0.0/examdata/
Read SOUL.md for chemical shift interpretation, solvent peaks, and NMR personality.
Instance-specific operational data in user/:
| Path | When to read |
|---|---|
MEMORY.md | Before any session — check calibration dates, known issues |
user/system_config.md | When configuring acquisition parameters |
user/calibration_log.md | Before quantitative measurements |
user/protocols/ | When running standard experiment protocols |
user/findings/ | When reviewing previous analysis results |
| File | Purpose |
|---|---|
adapter.py | TopSpinAdapter -- main entry point, 3 control modes |
processor.py | TopSpinProcessor -- offline FID processing, NMRSpectrum, NMRPeak |
brain.py | TopSpinBrain -- Claude-powered spectrum interpretation |
driver.py | TopSpinDriver -- async driver for labclaw integration |
library.py | SpectralLibrary -- fingerprint matching against known compounds |
visualizer.py | plot_spectrum() -- publication-quality spectrum plots |
gui_automation.py | GUI mode helper — use when PrairieView-style visual automation is needed |
demo_cache.py | Offline demo data — used when no spectrometer available |
skill.yaml | Device manifest (capabilities, modes, dependencies) |
SOUL.md | Device identity, NMR personality, quirks, safety |
docs/commands/ | 525 TopSpin command reference files (search, don't load all) |