Technical Reference

Neuro-1 FIF Format Reference

How the Neuro-1 Control Center writes its .fif data files, and how to read them in your own analysis pipeline.

Applies to Control Center 1.78 and later (notes cover files from 1.74) Format: FIFF (.fif) Tested with MNE-Python 1.10

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
FileProduced byContents
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–630–127X1…magTX-axis field of each sensor
64–127128–255Y1…magTY-axis field of each sensor
128–191256–383Z1…magTZ-axis field of each sensor
192–202384–394D0…D10stim0 / 1Digital inputs
203–218395–410AI 0…AI 15stimVAnalog 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: D0 is DAQ input DI_1 and D10 is DI_11; AI 0 is AI_1 and AI 15 is AI_16.
  • Counters. MUX_Counter1/2 increment with each sample sent from the array electronics (MUX) to the DAQ, and DAQ_Counter1 with each data set sent from the DAQ to the computer; a jump means data were lost on that link. Data_Drop1/2 are 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 STS status 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.

Files from earlier versions

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.

FieldTypeMeaning
ACT0/11 = sensor active to commands
LLS0/11 = laser locked
SLS0/11 = slow lock active
FLS0/11 = fast lock active
TLS0/11 = temperature locked
CNT0/11 = channel receiving data
CBS0/11 = calibration applied
DIS0/11 = channel disabled
STS32-bit integerStatus word (below)
BFX, BFY, BFZnumberField applied by the sensor on each axis, nT
CLX, CLY, CLZnumberFast-lock closed-loop value per axis (DAC units)
LTC, CTC, CTEnumberLaser temperature control, cell temperature control, and cell temperature error (DAC units)
PDX, PDZnumberPhotodiode DC levels
CBX, CBY, CBZnumberThe 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).

BitSet (1)Clear (0)
0Triaxial modeDual-axis mode
1Light check passedLight check not passed
2Auto-start procedure activeNot active
3Auto-start completedNot completed
4Field zero activeNot active
5Fields applied from the field-zero processNot applied
6Calibration procedure activeNot active
7Calibration applied and within the normal rangeNot applied, or outside the normal range
8X-axis modulation on (axis recorded)Off; the X channel holds the 999 pT placeholder
9Y-axis modulation on (axis recorded)Off; the Y channel holds the 999 pT placeholder
10Z-axis modulation on (axis recorded)Off; the Z channel holds the 999 pT placeholder
11Slow closed loop onOff
12X slow lock onOff
13Y slow lock onOff
14Z slow lock onOff
15X fast lock onOff
16Y fast lock onOff
17Z fast lock onOff
18High-dynamic-range field zero onDefault field-zero range
19Modified modulationDefault modulation
20Gen4 (G4) mode onOff
21–23Reserved for future status information—
24–31Error 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}}
EntryMeaning
applied_at, softwareWhen the file was made (computer’s local time) and by which program
measurement, outputThe raw recording it was made from, and this calibrated file’s name
version1 for _calibrated.fif, 2 for _v2_calibrated.fif, and so on
appliedWhether positions and calibration factors were applied, and how many channels, HALO coils and head points
localizationThe 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
framealignOnly 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)
penOnly when HPI Pen head points were added: their file (paths and SHA-256), the pen recording, the frame, and the number of points
hfcOnly 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 loc is set to [r0, ex, ey, ez]. r0 is the sensor position in meters (the same for a sensor’s X, Y, and Z channels), and ez is 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. ex and ey complete a right-handed frame around ez and 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 modes must match

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 kindCountContents
HPI (FIFFV_POINT_HPI, 2)16HALO coil positions, numbered 1–16.
Extra (FIFFV_POINT_EXTRA, 4)variesHead 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_types leaves out channels marked bad, such as unused axes in a calibrated file. In a raw file no channels are marked, so check STS or 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.
Compatibility

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.

Questions?

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).