Install any skill in seconds. Free to start, no credit card required.
Get Started Free →brycewang-stanford/spectroscopy-analysis-guide
Spectral data analysis for NMR, IR, mass spectrometry, and UV-Vis
Passed 18 of 24 test cases with the skill, and 11 of 24 without it.
and 8 more in the full report
7 fixed11 passed either way6 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 7 test cases the skill fixed. Same model, same prompt, with and without the skill.
In infrared (IR) vibrational spectroscopy, a general model might confuse double bond stretches (~1650 cm-1) or single bond stretches with triple bonds. What wavenumber range in cm-1 is defined for triple bond stretching vibrations, including nitriles (C≡N) and alkynes (C≡C)?
| Checked | Without skill | With skill |
|---|---|---|
| The triple bond stretch range is defined as 2100 to 2260 cm-1. | Missed | Passed |
The instructions your model reads when the skill loads.
A skill for processing and interpreting spectroscopic data in chemistry research. Covers NMR, IR, mass spectrometry, and UV-Vis spectroscopy including data formats, baseline correction, peak detection, spectral matching, and structure elucidation workflows.
| Format | Spectroscopy | Description |
|---|---|---|
| JCAMP-DX (.jdx, .dx) | All types | IUPAC standard exchange format |
| Bruker (1r, fid, acqu) | NMR | Raw and processed Bruker data |
| mzML / mzXML | MS | Open mass spectrometry format |
| SPC (.spc) | IR, UV-Vis | Galactic/Thermo spectral format |
| CSV / TXT | All | Simple x,y pairs (wavelength/wavenumber, intensity) |
import numpy as np
from scipy.signal import find_peaks, savgol_filter
def read_jcamp(filepath: str) -> dict:
"""
Read a JCAMP-DX spectral file.
Returns x (wavenumber/chemical shift/m/z) and y (intensity) arrays.
"""
x_data, y_data = [], []
metadata = {}
with open(filepath, "r") as f:
for line in f:
line = line.strip()
if line.startswith("##"):
key_val = line[2:].split("=", 1)
if len(key_val) == 2:
metadata[key_val[0].strip()] = key_val[1].strip()
elif line and not line.startswith("$$"):
parts = line.split()
try:
test cases passed, vs 11 / 24 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.