- Field units
- Tesla (T), stored as 32-bit floating point
- Sampling rate
- 375, 750, or 1,500 Hz, as selected for the session
- Channels
- 224 with one sensor array, 416 with two
- Sensor model
- FIFF coil type 8002, MNE’s QuSpin OPM
- Raw files
- Field data and status metadata; no sensor positions
- Calibrated files
- Add sensor positions and orientations, calibration, and HALO coil and head points
Format overview
The Neuro-1 Control Center records magnetometer data in the FIFF file format
(.fif), the open MEG data format originally developed for Neuromag systems. Files
are written with the MNE-Python library’s FIFF routines,
so they open directly in MNE-Python with no conversion step.
Every recording carries a complete measurement header: channel names, types, and units; the sampling rate; the measurement date in UTC; and a snapshot of the sensor-array status taken when the recording started (see Embedded status metadata).
Files and folders
Each recording is saved in its own folder, named after the file (without the
_raw.fif ending). Processed files are written into the same folder:
<recording folder>\
N1_Measurement_20261009_113629\
N1_Measurement_20261009_113629_raw.fif
N1_Measurement_20261009_113629_calibrated.fif
N1_Measurement_20261009_113629_calibrated_hfc_corrected.fif | File | Produced by | Contents |
|---|---|---|
N1_Measurement_<date>_<time>_raw.fif | Measurement recording | Raw magnetometer and auxiliary data. |
N1_HALO_<date>_<time>_raw.fif | HALO recording | Raw data for a HALO sensor-localization run. |
N1_HPI_Pen_<date>_<time>_raw.fif | HPI Pen recording | Raw data for a head-point digitization run. |
<name>_calibrated.fif | Apply Localization | Copy of a measurement with sensor positions and orientations embedded and the field data calibrated (see Processed files). |
<name>_calibrated_hfc_corrected.fif | Apply HFC | Copy of the calibrated file with homogeneous field correction applied to the data. |
Applying again never replaces earlier output. The first Apply Localization writes
<name>_calibrated.fif, the next ones
<name>_v2_calibrated.fif, <name>_v3_calibrated.fif, and
so on, each with its own _hfc_corrected copy. All of them end in
_calibrated.fif (or _calibrated_hfc_corrected.fif), and each records
which files it was made from (see Source record).
The N1_Measurement, N1_HALO, and N1_HPI_Pen prefixes
are the default file names; you can change the name in Recording Settings (for example
N1_Measurement_Gamma). The _<date>_<time> part
(YYYYMMDD_HHMMSS, computer’s local time) is added when Append
Timestamp is checked, which is the default. In the table, <name> is the
recording’s file name without _raw.fif.
Channel layout
Channels are ordered in axis blocks (all X channels, then all Y, then all Z), followed by one
set of auxiliary channels. Sensors are numbered sequentially across arrays: with one 64-sensor
array the magnetometer channels are X1–X64,
Y1–Y64, and Z1–Z64; with two
arrays they run 1–128 per axis (array 1 is 1–64, array 2 is
65–128). Within each array, sensor numbers map to slots
A1…H8 in row order (1 = A1, 8 = A8,
9 = B1, … 64 = H8; for array 2, 65 = A1 …
128 = H8).
| Index, 1 array | Index, 2 arrays | Names | MNE type | Unit | Description |
|---|---|---|---|---|---|
| 0–63 | 0–127 | X1… | mag | T | X-axis field of each sensor |
| 64–127 | 128–255 | Y1… | mag | T | Y-axis field of each sensor |
| 128–191 | 256–383 | Z1… | mag | T | Z-axis field of each sensor |
| 192–202 | 384–394 | D0…D10 | stim | 0 / 1 | Digital inputs |
| 203–218 | 395–410 | AI 0…AI 15 | stim | V | Analog inputs |
| 219–223 | 411–415 | MUX_Counter1, MUX_Counter2, DAQ_Counter1, Data_Drop1, Data_Drop2 | misc | — | Data-integrity counters (below) |
The auxiliary channels are stored once. The DAQ sends the same auxiliary data with each array, so with two arrays only the first copy is kept.
Magnetometer channels have FIFF coil type 8002
(FIFFV_COIL_QUSPIN_ZFOPM_MAG2), MNE’s model of a QuSpin OPM sensor: a small
vapor cell that behaves as a point sensor in forward models. Files recorded before
version 1.78 carry coil type 3024, the 25.8 mm square Vectorview magnetometer; Apply
Localization and Apply HFC set 8002 in the files they write, also when the input is an older
recording.
- Input names. The DAQ labels its inputs from 1, and the Control Center and
the files count from 0:
D0is DAQ input DI_1 andD10is DI_11;AI 0is AI_1 andAI 15is AI_16. - Counters.
MUX_Counter1/2increment with each sample sent from the array electronics (MUX) to the DAQ, andDAQ_Counter1with each data set sent from the DAQ to the computer; a jump means data were lost on that link.Data_Drop1/2are 0 for a valid sample and 1 for a sample that is not valid. - Unused axes. In dual-axis and single-axis sensor modes the channels of the
axes that are switched off are still written, so the channel layout never changes. They hold
a constant placeholder of 999 pT (9.99 × 10−10 T);
ignore them in your analysis. The
STSstatus word tells which axes each sensor uses (see Embedded status metadata), and Apply Localization marks the unused axes as bad.
Units and calibration
Magnetometer samples are stored in tesla as 32-bit floating-point values,
with each channel’s cal and range factors set to 1.0. FIFF
readers therefore return the stored values directly in tesla; multiply by
1012 for picotesla. Analog inputs are in volts, digital inputs are 0 or 1, and the
counters are plain counts.
Raw files recorded with Control Center versions before 1.78 carry a unit-multiplier field
(unit_mul) of −12 in the magnetometer channel records. It does not
describe the stored values, which are tesla in every version. MNE-Python does not apply this
field, so it reads all versions correctly; if you read older files with other software,
check that magnetometer values come out in tesla (a 100 pT field reads as
1 × 10−10) and do not apply the multiplier. From version
1.78, new recordings have unit_mul = 0, and Apply Localization and Apply HFC set
it to 0 in the files they write, also when the input is an older recording.
The sampling rate in the header is the DAQ acquisition rate chosen for the session: 375, 750, or 1,500 Hz. At the lower rates the DAQ averages the data down from the full rate.
Raw files hold the field values exactly as the sensors reported them.
Calibrated files hold the raw values multiplied by each channel’s
calibration factor from the HALO localization (raw × factor = calibrated
field). The factor is applied to the stored data, and cal and range
stay at 1.0, so any FIFF reader returns calibrated values without further steps. The factors
that were applied are listed in the file header (see
Embedded status metadata).
Embedded status metadata
The FIFF description field (raw.info["description"] in MNE-Python) holds
a JSON snapshot of the system status, taken when the recording started. Abbreviated:
{"sensor_status": {
"timestamp": "2026-10-09T11:36:30.207337",
"sensors": [
{"id": 0, "slot": "A1", "status_string": "#(YC) 0.69 (ZC) 0.70",
"ACT": 1, "LLS": 0, "SLS": 0, "FLS": 0, "TLS": 0,
"CNT": 1, "CBS": 1, "DIS": 0, "STS": 1574560,
"BFX": 26.9174, "BFY": -4.1233, "BFZ": -21.333, ...},
...]},
"system_status": {
"timestamp": "2026-10-09T11:36:30.208336",
"text_rows": ["Data Acquisition Rate:375.000 Hz", ...]}}
There is one entry in sensors per sensor, in channel order: id 0 is
sensor 1 (channels X1, Y1, Z1),
slot is its slot label, and status_string is the sensor’s last
status message. With one array the slot labels are A1…H8;
with two arrays they are A1-1…H8-1 and
A1-2…H8-2, the same names as the Sensor column of
the localization results. (Two-array files recorded before version 1.78 label array 1
A1…H8 and array 2 ?64…?127;
use id for those.) The timestamps are the recording computer’s local time
(the header’s measurement date is the UTC equivalent). system_status.text_rows
holds the DAQ’s system-status lines as text: acquisition rate, power supply readings,
array connections, firmware versions, and similar.
| Field | Type | Meaning |
|---|---|---|
ACT | 0/1 | 1 = sensor active to commands |
LLS | 0/1 | 1 = laser locked |
SLS | 0/1 | 1 = slow lock active |
FLS | 0/1 | 1 = fast lock active |
TLS | 0/1 | 1 = temperature locked |
CNT | 0/1 | 1 = channel receiving data |
CBS | 0/1 | 1 = calibration applied |
DIS | 0/1 | 1 = channel disabled |
STS | 32-bit integer | Status word (below) |
BFX, BFY, BFZ | number | Field applied by the sensor on each axis, nT |
CLX, CLY, CLZ | number | Fast-lock closed-loop value per axis (DAC units) |
LTC, CTC, CTE | number | Laser temperature control, cell temperature control, and cell temperature error (DAC units) |
PDX, PDZ | number | Photodiode DC levels |
CBX, CBY, CBZ | number | The sensor’s own calibration factor per axis (not the HALO calibration applied by Apply Localization) |
The STS status word packs mode and state flags into one 32-bit integer. Bit 0 is
the least significant bit. For analysis, the most useful are bit 0 (sensor mode), bits
8–10 (which axes the sensor records), and bits 5 and 7 (field zero and calibration
applied).
| Bit | Set (1) | Clear (0) |
|---|---|---|
| 0 | Triaxial mode | Dual-axis mode |
| 1 | Light check passed | Light check not passed |
| 2 | Auto-start procedure active | Not active |
| 3 | Auto-start completed | Not completed |
| 4 | Field zero active | Not active |
| 5 | Fields applied from the field-zero process | Not applied |
| 6 | Calibration procedure active | Not active |
| 7 | Calibration applied and within the normal range | Not applied, or outside the normal range |
| 8 | X-axis modulation on (axis recorded) | Off; the X channel holds the 999 pT placeholder |
| 9 | Y-axis modulation on (axis recorded) | Off; the Y channel holds the 999 pT placeholder |
| 10 | Z-axis modulation on (axis recorded) | Off; the Z channel holds the 999 pT placeholder |
| 11 | Slow closed loop on | Off |
| 12 | X slow lock on | Off |
| 13 | Y slow lock on | Off |
| 14 | Z slow lock on | Off |
| 15 | X fast lock on | Off |
| 16 | Y fast lock on | Off |
| 17 | Z fast lock on | Off |
| 18 | High-dynamic-range field zero on | Default field-zero range |
| 19 | Modified modulation | Default modulation |
| 20 | Gen4 (G4) mode on | Off |
| 21–23 | Reserved for future status information | — |
| 24–31 | Error code, 8 bits (bit 24 is error bit 0, the least significant) | — |
For example, the STS of 1574560 above has bits 5, 7, 9, 10, 19, and 20 set: a
dual-axis sensor (bit 0 clear) recording its Y and Z axes, with field-zero fields and
calibration applied, modified modulation, and Gen4 mode.
Bits 0–17 and 24–31 are also described in the
Neuro-1 TCP/IP Connection Info document (PDF), which covers the
same status word in the live data stream; bits 18–20 are later sensor-firmware additions
and are not in it yet. STS is present only when the sensor firmware reports it.
The Control Center shows bit 0 in the color of the CNT LED row, bit 18 in the ACT
row, and bit 19 in the LLS row; the N1 Data Viewer decodes all of them under
Show Status Info.
Calibrated files add a plain-text block after the JSON, titled QuSpin Applied
Calibration Factors, listing the factor applied to each calibrated channel (for
example Y1: 0.6994, Y2: 0.7276, …). Channels without an applied factor are
not listed. The N1 Data Viewer, installed with the Control Center, shows all of this metadata under Show Status
Info.
Source record (calibrated and HFC-corrected files)
From version 1.78, Apply Localization adds a localization_applied object to the
JSON, next to sensor_status and system_status. It records what was
applied and from which files, so a calibrated file can always be traced back to its
localization. Abbreviated:
"localization_applied": {
"applied_at": "2026-10-25T11:21:48",
"software": "Neuro-1 Control Center V1.78",
"measurement": "N1_Measurement_20261025_112036_raw.fif",
"output": "N1_Measurement_20261025_112036_calibrated.fif",
"version": 1,
"applied": {"positions": true, "calibrations": true,
"channels_positioned": 192, "channels_calibrated": 192,
"halo_coils": 16, "pen_points": 0},
"localization": {
"file": "C:\\N1 Recordings\\...\\Localization_Results_2026-10-25_11-20-10.csv",
"relative": "..\\N1_HALO_20261025_111954\\N1 HALO Localization Results\\...",
"halo_run": "N1_HALO_20261025_111954", "method": "standard",
"frame": "device", "results_time": "2026-10-25T11:20:10",
"sha256": "86435fa7..."},
"hfc": {"output": "N1_Measurement_20261025_112036_calibrated_hfc_corrected.fif",
"from": "N1_Measurement_20261025_112036_calibrated.fif",
"channels_corrected": 192, "power_reduction_pct": 91.56}} | Entry | Meaning |
|---|---|
applied_at, software | When the file was made (computer’s local time) and by which program |
measurement, output | The raw recording it was made from, and this calibrated file’s name |
version | 1 for _calibrated.fif, 2 for _v2_calibrated.fif, and so on |
applied | Whether positions and calibration factors were applied, and how many channels, HALO coils and head points |
localization | The localization results file: full path, path relative to this file’s folder (still valid after the session folder is moved), the HALO recording it came from, the localization method, the coordinate frame (device, or head after FrameAlign), the results’ time, and the file’s SHA-256 checksum |
framealign | Only when the results were aligned to a head model: the FrameAlign transform file (paths and SHA-256) and the transform itself (linear_3x3, translation in meters) |
pen | Only when HPI Pen head points were added: their file (paths and SHA-256), the pen recording, the frame, and the number of points |
hfc | Only in an HFC-corrected file: its name, the calibrated file it was made from, the number of corrected channels, and the interference power removed (percent) |
The SHA-256 checksums identify the exact input files even after they are renamed or copied. Files applied with versions before 1.78 have no source record. The N1 Data Viewer shows the record under Show Status Info.
Processed files
Apply Localization → _calibrated.fif
Combines a measurement recording with the results of a HALO localization (the
Localization_Results_<date>_<time>.csv file in the HALO
recording’s N1 HALO Localization Results folder) and, optionally, the head
points from an HPI Pen localization. The original _raw.fif is not changed, and
neither is any earlier output: a second apply writes _v2_calibrated.fif (see
Files and folders). In the new file:
- Positions and orientations. Each magnetometer channel’s 12-element
locis set to[r0, ex, ey, ez].r0is the sensor position in meters (the same for a sensor’s X, Y, and Z channels), andezis the unit vector of that channel’s sensitive axis. Each axis direction is measured separately, so the three axes of a sensor are generally not exactly orthogonal.exandeycomplete a right-handed frame aroundezand carry no measured information. - Calibration. The field data are multiplied by each channel’s calibration factor from the localization results (see Units and calibration).
- Bad channels. Magnetometer channels that have no position or orientation (axes the sensors were not recording, or sensors the localization could not solve) are marked bad. They stay in the file.
- Digitization points. The 16 HALO coil positions and any HPI Pen head points are added to the header (see Coordinates and digitization points).
- Source record. Which localization results, FrameAlign transform and head points were applied, with their checksums (see Source record).
Sensor orientations and calibration factors depend on the sensor mode (triaxial, dual-axis, or single-axis). Run the HALO localization in the same mode as the measurement; the Control Center warns when they differ.
Apply HFC → _hfc_corrected.fif
Applies first-order homogeneous field correction (HFC) to a calibrated file. HFC models
ambient interference as a spatially uniform field and removes it from the magnetometer
channels, using the sensor orientations embedded by Apply Localization. The result is
equivalent to MNE’s compute_proj_hfc(order=1) on the same channels, but the
correction is applied to the stored data instead of being stored as a projector, so every
reader sees corrected values.
Channels without an embedded orientation, and channels whose localization did not pass QuSpin’s quality check, are not used and are left uncorrected. They are marked bad in the corrected file, so analysis tools skip them, and the Control Center lists them in the processing log (Show Log). (Before version 1.78, channels that failed the quality check were left uncorrected without being marked bad; check the log of older runs.)
Coordinates and digitization points
All geometry in a calibrated file is expressed in one coordinate frame, in meters: the frame of the localization results that were applied. By default that is the HALO’s own frame. When the results were first aligned to a head model in QuSpin FrameAlign, it is the head-model frame, and the HALO coil positions are moved with the sensors. Select HPI Pen head points from the same frame: FrameAlign’s Apply Transform writes transformed copies of both the localization results and the head points.
In FIFF terms, channel positions are stored in the device frame and digitization
points in the head frame, with an identity device-to-head transform
(dev_head_t). The coordinates of both are therefore directly comparable, and
MNE’s head coordinates are the localization coordinates.
| Digitization kind | Count | Contents |
|---|---|---|
HPI (FIFFV_POINT_HPI, 2) | 16 | HALO coil positions, numbered 1–16. |
Extra (FIFFV_POINT_EXTRA, 4) | varies | Head points digitized with the HPI Pen, when a pen localization was selected during Apply Localization. |
The files contain no anatomical landmarks (nasion and preauricular points). Raw recordings contain no geometry at all: their channel positions are undefined (NaN) until Apply Localization is run.
Large recordings and file splits
The FIFF format limits a single file to 2 GB. During recording, data are written to disk
in 10-second blocks; once a file passes about 1.9 GB the recording continues in a linked
split file (<name>_raw-1.fif, <name>_raw-2.fif,
…) with no gap. At 1,500 Hz a split occurs about every 23 minutes with one
array and every 12 minutes with two (four times longer at 375 Hz). The files
reference each other with standard FIFF links, so MNE-Python opens the first file and reads
the whole recording. Processed files larger than 2 GB are split the same way.
Reading the files
With MNE-Python:
import json
import mne
from mne.io.constants import FIFF
raw = mne.io.read_raw_fif("N1_Measurement_20261009_113629_calibrated.fif",
preload=True)
# Magnetometer data in tesla (channels marked bad are left out)
picks = mne.pick_types(raw.info, meg=True)
data, times = raw[picks]
# Trigger events from a digital input (D0 = DAQ input DI_1)
events = mne.find_events(raw, stim_channel="D0")
# Sensor status snapshot: the JSON part of the description
desc = raw.info["description"]
meta = json.loads(desc[:desc.rfind("}") + 1])
sensor = meta["sensor_status"]["sensors"][0] # sensor A1
sts = sensor.get("STS", 0)
triaxial = bool(sts & 1) # bit 0
active_axes = [ax for ax, bit in zip("XYZ", (8, 9, 10)) if sts >> bit & 1]
modified_modulation = bool(sts >> 19 & 1) # bit 19
# Source record (calibrated files from version 1.78): what was applied
record = meta.get("localization_applied") # None in raw files
if record:
print(record["localization"]["file"], record["localization"]["sha256"])
# Embedded geometry (calibrated files)
ch = raw.info["chs"][raw.ch_names.index("Z1")]
position = ch["loc"][0:3] # meters
sensitive_axis = ch["loc"][9:12] # unit vector
coils = [d["r"] for d in raw.info["dig"] if d["kind"] == FIFF.FIFFV_POINT_HPI]
head_points = [d["r"] for d in raw.info["dig"] if d["kind"] == FIFF.FIFFV_POINT_EXTRA] -
pick_typesleaves out channels marked bad, such as unused axes in a calibrated file. In a raw file no channels are marked, so checkSTSor the 999 pT placeholder to find unused axes. -
Analog inputs are stored in volts. To detect triggers on an analog input, threshold the
signal yourself instead of using
find_events. - Analyses that need sensor positions (sensor plots, source modeling, HFC) need a calibrated file.
No QuSpin-specific reader is required. The files follow the standard FIFF structure and are tested with MNE-Python. Other FIFF-based tools, such as FieldTrip and Brainstorm, use the same structure; if you use one of them, check that magnetometer values come out in tesla (see Units and calibration). The JSON metadata is stored in a standard text field that other tools ignore.
Contact QuSpin support for help integrating Neuro-1 recordings into your pipeline. The live data stream and the full status-word table are covered in the Neuro-1 TCP/IP Connection Info document (PDF).