Skip to content

Commit

Permalink
add AbstractFeatureSeries (NeurodataWithoutBorders#1942)
Browse files Browse the repository at this point in the history
* add AbstractFeatureSeries

* fix location of AbstractFeatureSeries

* fix location of AbstractFeatureSeries

* add AbstractFeatureSeries to intro text
  • Loading branch information
bendichter authored Jul 24, 2024
1 parent fcd7008 commit d453804
Showing 1 changed file with 38 additions and 10 deletions.
48 changes: 38 additions & 10 deletions docs/gallery/domain/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,31 @@
about the subject, the environment, the presented stimuli, or other parts
related to the experiment. This tutorial focuses in particular on the usage of:
* :py:class:`~pynwb.image.OpticalSeries` for series of images that were presented as stimulus
* :py:class:`~pynwb.image.OpticalSeries` and :py:class:`~pynwb.misc.AbstractFeatureSeries` for series of images that
were presented as stimulus
* :py:class:`~pynwb.image.ImageSeries`, for series of images (movie segments);
* :py:class:`~pynwb.image.GrayscaleImage`, :py:class:`~pynwb.image.RGBImage`,
:py:class:`~pynwb.image.RGBAImage`, for static images;
The following examples will reference variables that may not be defined within the block they are used in. For
clarity, we define them here:
"""
# Define file paths used in the tutorial

import os

# sphinx_gallery_thumbnail_path = 'figures/gallery_thumbnails_image_data.png'
from datetime import datetime
import os
from uuid import uuid4

import numpy as np
from dateutil import tz
from dateutil.tz import tzlocal
from PIL import Image

from pynwb import NWBHDF5IO, NWBFile
from pynwb.base import Images
from pynwb.image import GrayscaleImage, ImageSeries, OpticalSeries, RGBAImage, RGBImage
from pynwb.misc import AbstractFeatureSeries

# Define file paths used in the tutorial
nwbfile_path = os.path.abspath("images_tutorial.nwb")
moviefiles_path = [
os.path.abspath("image/file_1.tiff"),
Expand All @@ -55,7 +55,7 @@
nwbfile = NWBFile(
session_description="my first synthetic recording",
identifier=str(uuid4()),
session_start_time=datetime.now(tzlocal()),
session_start_time=session_start_time,
experimenter=[
"Baggins, Bilbo",
],
Expand Down Expand Up @@ -109,6 +109,35 @@
nwbfile.add_stimulus(stimulus=optical_series)

####################
# AbstractFeatureSeries: Storing features of visual stimuli
# ---------------------------------------------------------
#
# While it is usually recommended to store the entire image data as an :py:class:`~pynwb.image.OpticalSeries`, sometimes
# it is useful to store features of the visual stimuli instead of or in addition to the raw image data. For example,
# you may want to store the mean luminance of the image, the contrast, or the spatial frequency. This can be done using
# an instance of :py:class:`~pynwb.misc.AbstractFeatureSeries`. This class is a general container for storing time
# series of features that are derived from the raw image data.

# Create some fake feature data
feature_data = np.random.rand(200, 3) # 200 time points, 3 features

# Create an AbstractFeatureSeries object
abstract_feature_series = AbstractFeatureSeries(
name="StimulusFeatures",
data=feature_data,
timestamps=np.linspace(0, 1, 200),
description="Features of the visual stimuli",
features=["luminance", "contrast", "spatial frequency"],
feature_units=["n.a.", "n.a.", "cycles/degree"],
)

# Add the AbstractFeatureSeries to the NWBFile
nwbfile.add_stimulus(abstract_feature_series)

####################
# Like all :py:class:`~pynwb.base.TimeSeries`, :py:class:`~pynwb.misc.AbstractFeatureSeries` specify timing using
# either the ``rate`` and ``starting_time`` attributes or the ``timestamps`` attribute.
#
# ImageSeries: Storing series of images as acquisition
# ----------------------------------------------------
#
Expand All @@ -118,7 +147,6 @@
#
# We can add raw data to the :py:class:`~pynwb.file.NWBFile` object as *acquisition* using
# the :py:meth:`~pynwb.file.NWBFile.add_acquisition` method.
#

image_data = np.random.randint(low=0, high=255, size=(200, 50, 50, 3), dtype=np.uint8)
behavior_images = ImageSeries(
Expand All @@ -138,21 +166,21 @@
# ^^^^^^^^^^^^^^
#
# External files (e.g. video files of the behaving animal) can be added to the :py:class:`~pynwb.file.NWBFile`
# by creating an :py:class:`~pynwb.image.ImageSeries` object using the
# by creating an :py:class:`~pynwb.image.ImageSeries` object using the
# :py:attr:`~pynwb.image.ImageSeries.external_file` attribute that specifies
# the path to the external file(s) on disk.
# The file(s) path must be relative to the path of the NWB file.
# Either ``external_file`` or ``data`` must be specified, but not both.
#
# If the sampling rate is constant, use :py:attr:`~pynwb.base.TimeSeries.rate` and
# If the sampling rate is constant, use :py:attr:`~pynwb.base.TimeSeries.rate` and
# :py:attr:`~pynwb.base.TimeSeries.starting_time` to specify time.
# For irregularly sampled recordings, use :py:attr:`~pynwb.base.TimeSeries.timestamps` to specify time for each sample
# image.
#
# Each external image may contain one or more consecutive frames of the full :py:class:`~pynwb.image.ImageSeries`.
# The :py:attr:`~pynwb.image.ImageSeries.starting_frame` attribute serves as an index to indicate which frame
# each file contains.
# For example, if the ``external_file`` dataset has three paths to files and the first and the second file have 2
# For example, if the ``external_file`` dataset has three paths to files and the first and the second file have 2
# frames, and the third file has 3 frames, then this attribute will have values `[0, 2, 4]`.

external_file = [
Expand Down

0 comments on commit d453804

Please sign in to comment.