Outputs

The FaceIt pipeline generates multiple outputs stored in .npz and .nwb files, plus visualization images. This page describes what each file contains and how to read them safely.

Outputs Overview

.npz file (compressed data archive)

Saved as faceit.npz. It may include the following arrays (keys):

  • pupil_center: Pupil center (per-frame; typically 1D or structured).

  • pupil_center_X, pupil_center_y: X and Y coordinates of the pupil center.

  • pupil_dilation_blinking_corrected: Pupil area/dilation after blink correction.

  • pupil_dilation: Raw pupil area/dilation.

  • X_saccade, Y_saccade: Saccade matrices (often 2×T or heatmap-like overlays).

  • pupil_distance_from_corner: Distance of pupil center to eye corner (per frame).

  • width, height: Fitted ellipse dimensions (per frame).

  • motion_energy: Whisker pad (face) motion energy (per frame).

  • motion_energy_without_grooming: Motion energy with grooming filtered out.

  • grooming_ids: Frame indices flagged as grooming.

  • grooming_threshold: Grooming threshold value(s).

  • blinking_ids: Frame indices flagged as blinks.

  • angle: Fitted pupil ellipse angle (per frame).

  • Face_frame, Pupil_frame: Frame reference values (scalar/short arrays).

Note

Keys are snake_case with underscores (e.g., grooming_ids, not "grooming ids").

.nwb file (Neurodata Without Borders)

Saved as faceit.nwb if the “Save NWB” option is checked. TimeSeries are stored under a ProcessingModule named eye_facial_movement. The series mirror the .npz content:

TimeSeries (typical keys): - pupil_center, pupil_center_X, pupil_center_y - pupil_dilation_blinking_corrected, pupil_dilation - X_saccade, Y_saccade - pupil_distance_from_corner - width, height - motion_energy, motion_energy_without_grooming - grooming_ids, grooming_threshold - blinking_ids - pupil_angle - Face_frame, Pupil_frame

Note

Each TimeSeries uses timestamps sized to its own length.

Visualization images (.png)

The pipeline saves quick-look plots in the save directory:

  • blinking_corrected.png — blink-corrected pupil area

  • pupil_area.png — raw pupil area/dilation

  • motion_energy.png — motion energy (with grooming threshold line if available)

  • facemotion_without_grooming.png — motion energy with grooming removed

Access to data

Example: read ``.nwb``

from pathlib import Path
import numpy as np
from pynwb import NWBHDF5IO

nwb_path = Path("path/to/faceit.nwb")

with NWBHDF5IO(str(nwb_path), "r") as io:
    nwb = io.read()
    mod = nwb.processing["eye_facial_movement"]

    # List series names:
    print(list(mod.data_interfaces.keys()))

    # Read common series
    pupil_dilation = np.asarray(mod.data_interfaces["pupil_dilation"].data)
    pupil_dilation_blinking_corrected = np.asarray(
        mod.data_interfaces["pupil_dilation_blinking_corrected"].data
    )
    blinking_ids = np.asarray(mod.data_interfaces["blinking_ids"].data)
    pupil_center = np.asarray(mod.data_interfaces["pupil_center"].data)
    pupil_center_X = np.asarray(mod.data_interfaces["pupil_center_X"].data)
    pupil_center_y = np.asarray(mod.data_interfaces["pupil_center_y"].data)
    X_saccade = np.asarray(mod.data_interfaces["X_saccade"].data)
    Y_saccade = np.asarray(mod.data_interfaces["Y_saccade"].data)
    pupil_width = np.asarray(mod.data_interfaces["width"].data)
    pupil_height = np.asarray(mod.data_interfaces["height"].data)
    motion_energy = np.asarray(mod.data_interfaces["motion_energy"].data)
    motion_energy_without_grooming = np.asarray(
        mod.data_interfaces["motion_energy_without_grooming"].data
    )
    grooming_ids = np.asarray(mod.data_interfaces["grooming_ids"].data)
    grooming_threshold = np.asarray(mod.data_interfaces["grooming_threshold"].data)
    pupil_distance_from_corner = np.asarray(
        mod.data_interfaces["pupil_distance_from_corner"].data
    )
    pupil_angle = np.asarray(mod.data_interfaces["pupil_angle"].data)

Example: read ``.npz``

from pathlib import Path
import numpy as np

npz_path = Path("path/to/faceit.npz")

with np.load(npz_path, allow_pickle=True) as z:
    print("Keys:", list(z.files))

    pupil_center = z["pupil_center"]
    motion_energy = z["motion_energy"]
    pupil_dilation = z["pupil_dilation"]
    pupil_dilation_blinking_corrected = z["pupil_dilation_blinking_corrected"]
    pupil_center_X = z["pupil_center_X"]
    pupil_center_y = z["pupil_center_y"]
    X_saccade = z["X_saccade"]
    Y_saccade = z["Y_saccade"]
    pupil_width = z["width"]
    pupil_height = z["height"]
    motion_energy_without_grooming = z["motion_energy_without_grooming"]
    grooming_ids = z["grooming_ids"]
    grooming_threshold = z["grooming_threshold"]
    blinking_ids = z["blinking_ids"]
    pupil_distance_from_corner = z["pupil_distance_from_corner"]
    angle = z["angle"]
    Face_frame = z["Face_frame"]
    Pupil_frame = z["Pupil_frame"]

Tips & Requirements

  • Install: - NumPy to read .npz. - PyNWB (and dependencies like h5py) to read .nwb.

  • Keys and names are case- and underscore-sensitive: - Use pupil_center_y (lowercase y), not pupil_center_Y. - Use grooming_ids / blinking_ids, not names with spaces.