quadstar: For Quadstar MS data

An extractors for data files produced by Quadstar mass spectrometers.

yadg.extractors.quadstar.sac module

The sac2dat.c code from Dr. Moritz Bubek was a really useful stepping stone for this Python file parser.

Usage

Available since yadg-4.0.

pydantic model dgbowl_schemas.yadg.dataschema_6_0.filetype.Quadstar_sac
Config:
  • extra: str = forbid

Validators:

field filetype: Literal['quadstar.sac'] [Required]

Schema

xarray.DataTree:
  {{ trace_index }}:
    coords:
      uts:              !!float               # Unix timestamp
      mass_to_charge:   !!float               # M/Z ratio
    data_vars:
      fsr:              (None)                # Full scale range
      y:                (uts, mass_to_charge) # Signal data

Metadata

The “info_position” section in the below structure is stored as metadata for every trace, without further processing.

Notes on file structure

Pretty much the entire file format has been reverse engineered. There are still one or two unknown fields.

0x00 "data_index"
0x02 "software_id"
0x06 "version_major"
0x07 "version_minor"
0x08 "second"
0x09 "minute"
0x0a "hour"
0x0b "day"
0x0c "month"
0x0d "year"
0x0f "author"
0x64 "n_timesteps"
0x68 "n_traces"
0x6a "timestep_length"
...
# Not sure what sits from 0x6e to 0xc2.
...
0xc2 "uts_base_s"
0xc6 "uts_base_ms"
# Trace header. Read these 9 bytes for every trace (n_traces).
0xc8 + (n * 0x09) "type"
0xc9 + (n * 0x09) "info_position"
0xcd + (n * 0x09) "data_position"
...
# Trace info. Read these 137 bytes for every trace where type != 0x11.
info_position + 0x00 "data_format"
info_position + 0x02 "y_title"
info_position + 0x0f "y_unit"
info_position + 0x1d "x_title"
info_position + 0x2a "x_unit"
info_position + 0x38 "comment"
info_position + 0x7a "first_mass"
info_position + 0x7e "scan_width"
info_position + 0x80 "values_per_mass"
info_position + 0x81 "zoom_start"
info_position + 0x85 "zoom_end"
...
# UTS offset. Read these 6 bytes for every timestep (n_timesteps).
0xc2 + (n * timestep_length) "uts_offset_s"
0xc6 + (n * timestep_length) "uts_offset_ms"
# Read everything remaining below for every timestep and every trace
# where type != 0x11.
data_position + (n * timestep_length) + 0x00 "n_datapoints"
data_position + (n * timestep_length) + 0x04 "data_range"
# Datapoints. Read these 4 bytes (scan_width * values_per_mass)
# times.
data_position + (n * timestep_length) + 0x06 "datapoints"
...

Uncertainties

Uncertainties in mass_to_charge are set to one step in M/Z spacing.

Uncertainties in the signal y are either based on the analog-to-digital conversion (i.e. using the full scale range), or from the upper limit of contribution of neighboring M/Z points (50 ppm).

Code author: Nicolas Vetsch

yadg.extractors.quadstar.sac.extract(*, fn: str, **kwargs: dict) DataTree