Guide · spectroscopy data in Python

Convert Bruker CSV to Python

You ran your samples, the instrument exported a folder, and now your script, your supervisor, or a homework assignment wants a pandas DataFrame. Here are the three situations you can be in, and the shortest honest path for each.

1. One CSV, one spectrum: plain pandas

A single two-column export (wavenumber or m/z, then intensity) needs two lines. Vendor exports differ in delimiter, comment lines, and decimal marks, so use the sniffing options instead of guessing:

import pandas as pd

df = pd.read_csv("spectrum.csv", sep=None, engine="python")  # sniffs , ; or tab
# common extras: comment="#" for instrument header lines, decimal="," for EU exports
axis = df.iloc[:, 0]
intensity = df.iloc[:, 1]

This works until the folder has more than one layout. Then you are writing a parser per instrument, per export menu, per student. That is the step where most labs lose a week.

2. A whole folder of exports: convert once, load in 3 lines

eQCX converts the folder into the open eQC format: metadata.csv and spectra.csv linked by sample_id, one group per modality. Measured values are untouched by default, and every sample keeps its descriptive columns. The open SDK then loads it anywhere, no vendor tools needed:

import eqc, pandas as pd

groups = eqc.read("my_eqc_output")            # one group per modality
for g in groups:
    print(g.name, g.n_samples, "samples,", g.n_axis_points, "axis points")

g = groups[0]
spectra = pd.DataFrame(g.samples, index=g.axis)   # rows = axis, cols = sample_id
meta = pd.DataFrame(g.metadata)                    # one row per sample

The SDK is pure Python standard library, so it runs on any machine, any cluster, any stuck-offline lab PC. The full format specification is in the wiki, and the same SDK validates what you loaded:

python -m eqc validate my_eqc_output   # 6 conformance checks
python -m eqc verify   my_eqc_output   # recompute the SHA-256 integrity chain

3. The file is not CSV at all: the OPUS .0 case

Bruker's raw binary (OPUS .0), Omnic .spa, Renishaw .wdf, and PE .sp have no reliable public reader, and we will not pretend otherwise. The fix is one export on the instrument PC:

You haveDo onceAfter that
OPUS .0File → Export as CSV or JCAMP-DX (.jdx)Every folder after that converts automatically. JCAMP-DX and SPC are read directly, compressed forms included.
Omnic .spa / Renishaw .wdf / PE .spExport as CSV from the vendor software
Keep the raw binaries. The export is a working copy for analysis; the original measurement file stays the archive copy on the instrument PC.

Which route fits you?

SituationRoute
One spectrum, one script, due tomorrowPlain pandas (route 1)
A real folder: many files, mixed layouts, metadata in sibling fileseQCX folder conversion + the 3-line loader (route 2)
Raw vendor binariesOne-time export to CSV or .jdx (route 3), then route 2

Questions students actually ask

How do I load a Raman or FTIR CSV into pandas?

pd.read_csv(file, sep=None, engine="python") sniffs the delimiter. Add comment="#" for instrument header lines and decimal="," for exports with decimal commas.

How do I combine many spectra CSVs into one dataset?

Convert the folder once with eQCX. The eQC format gives you metadata.csv + spectra.csv linked by sample_id, and the SDK loads it into pandas in three lines.

Python cannot read my .0 file. Is it broken?

No. OPUS .0 is a raw binary with no reliable public reader. Export it once from OPUS as CSV or JCAMP-DX and everything after that is automatic.

Is the result ready for scikit-learn or PyTorch?

Yes. Spectra are float64 on a shared axis per group with no NaN inside the measured range, and every column links back to a sample's metadata row.

Convert the folder once, never write a parser again.

eQCX runs on Windows and processes everything locally. Free with a university email.

Download for Windows

Or check your university's free seats: education program