ndx-ophys-devices


Namendx-ophys-devices JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryThis is an NWB extension for storing metadata of devices used in optical experimental setup (microscopy, fiber photometry, optogenetic stimulation etc.)
upload_time2025-09-17 16:38:12
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseBSD-3
keywords nwb neurodatawithoutborders ndx-extension nwb-extension
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ndx-ophys-devices Extension for NWB

This is an NWB extension for storing metadata of devices used in optical experimental setup (microscopy, fiber photometry, optogenetic stimulation etc.)

This extension consists of neurodata types in the following categories:

**Container Classes:**
- **ViralVector** extends NWBContainer to hold metadata on viral vectors used for gene delivery.
- **ViralVectorInjection** extends NWBContainer to hold metadata on viral vector injection procedures.
- **Indicator** extends NWBContainer to hold metadata on the fluorescent indicator.
- **Effector** extends NWBContainer to hold metadata on the effector/opsin.
- **LensPositioning** extends NWBContainer to hold metadata on the positioning of a lens relative to the brain.
- **FiberInsertion** extends NWBContainer to hold metadata on the insertion of a fiber into the brain.

**Model Classes:**
- **OpticalFiberModel** extends DeviceModel to hold metadata on the optical fiber model.
- **ExcitationSourceModel** extends DeviceModel to hold metadata on the excitation source model.
- **PhotodetectorModel** extends DeviceModel to hold metadata on the photodetector model.
- **DichroicMirrorModel** extends DeviceModel to hold metadata on the dichroic mirror model.
- **OpticalFilterModel** extends DeviceModel to hold metadata on a general optical filter model.
- **BandOpticalFilterModel** extends OpticalFilterModel to hold metadata on any bandpass or bandstop optical filter models.
- **EdgeOpticalFilterModel** extends OpticalFilterModel to hold metadata on any edge optical filter models.
- **OpticalLensModel** extends DeviceModel to hold metadata on the optical lens model.

**Device Classes:**
- **OpticalFiber** extends Device to hold metadata on optical fibers.
- **ExcitationSource** extends Device to hold metadata on excitation sources.
- **PulsedExcitationSource** extends ExcitationSource to hold metadata on pulsed excitation sources.
- **Photodetector** extends Device to hold metadata on photodetectors.
- **DichroicMirror** extends Device to hold metadata on dichroic mirrors.
- **OpticalFilter** extends Device to hold metadata on general optical filters.
- **BandOpticalFilter** extends OpticalFilter to hold metadata on bandpass or bandstop optical filters.
- **EdgeOpticalFilter** extends OpticalFilter to hold metadata on edge optical filters.
- **OpticalLens** extends Device to hold metadata on optical lenses.

Note that the container classes cannot be directly added to the NWB file, but instead require extending `LabMetaData` to
contain one or more of these container classes in a separate extension. 
For example, see [ndx-optogenetics](https://github.com/rly/ndx-optogenetics). 

## Installation
To install the latest stable release through PyPI,
```bash
pip install ndx-ophys-devices
```

## Usage

```python
import datetime
import numpy as np
from pynwb import NWBFile
from ndx_ophys_devices import (
    # Container classes
    ViralVector,
    ViralVectorInjection,
    Indicator,
    Effector,
    LensPositioning,
    FiberInsertion,
    
    # Model classes
    OpticalFiberModel,
    ExcitationSourceModel,
    PhotodetectorModel,
    DichroicMirrorModel,
    OpticalFilterModel,
    BandOpticalFilterModel,
    EdgeOpticalFilterModel,
    OpticalLensModel,
    
    # Device classes
    OpticalFiber,
    ExcitationSource,
    PulsedExcitationSource,
    Photodetector,
    DichroicMirror,
    OpticalFilter,
    BandOpticalFilter,
    EdgeOpticalFilter,
    OpticalLens,
)

nwbfile = NWBFile(
    session_description='session_description',
    identifier='identifier',
    session_start_time=datetime.datetime.now(datetime.timezone.utc)
)

# Create container objects
viral_vector = ViralVector(
    name="viral_vector",
    description="AAV viral vector for optogenetic stimulation",
    construct_name="AAV-EF1a-DIO-hChR2(H134R)-EYFP",
    manufacturer="Vector Manufacturer",
    titer_in_vg_per_ml=1.0e12,
)

viral_vector_injection = ViralVectorInjection(
    name="viral_vector_injection",
    description="Viral vector injection for optogenetic stimulation",
    location="Hippocampus",
    hemisphere="right",
    reference="Bregma at the cortical surface",
    ap_in_mm=2.0,
    ml_in_mm=1.5,
    dv_in_mm=-3.0,
    pitch_in_deg=0.0,
    yaw_in_deg=0.0,
    roll_in_deg=0.0,
    stereotactic_rotation_in_deg=0.0,
    stereotactic_tilt_in_deg=0.0,
    volume_in_uL=0.45,
    injection_date="1970-01-01T00:00:00+00:00",
    viral_vector=viral_vector,
)

indicator = Indicator(
    name="indicator",
    description="Green indicator",
    label="GCamp6f",
    viral_vector_injection=viral_vector_injection,
)

effector = Effector(
    name="effector",
    description="Excitatory opsin",
    label="hChR2",
    viral_vector_injection=viral_vector_injection,
)

fiber_insertion = FiberInsertion(
    name="fiber_insertion",
    depth_in_mm=3.5,
    insertion_position_ap_in_mm=2.0,
    insertion_position_ml_in_mm=1.5,
    insertion_position_dv_in_mm=3.0,
    position_reference="bregma",
    hemisphere="right",
    insertion_angle_pitch_in_deg=10.0,
)

lens_positioning = LensPositioning(
    name="lens_positioning",
    positioning_type="surface",
    depth_in_mm=0.0,
    target_position_ap_in_mm=1.5,
    target_position_ml_in_mm=2.0,
    target_position_dv_in_mm=0.0,
    working_distance_in_mm=2.0,
    position_reference="bregma",
    hemisphere="left",
    optical_axis_angle_pitch_in_deg=0.0,
)

# Create device models
optical_fiber_model = OpticalFiberModel(
    name="optical_fiber_model",
    manufacturer="Fiber Manufacturer",
    model_number="OF-123",
    description="Optical fiber model for optogenetics",
    numerical_aperture=0.2,
    core_diameter_in_um=400.0,
    active_length_in_mm=2.0,
    ferrule_name="cFCF - ∅2.5mm Ceramic Ferrule",
    ferrule_model="SM-SC-CF-10-FM",
    ferrule_diameter_in_mm=2.5,
)
nwbfile.add_device_model(optical_fiber_model)

optical_lens_model = OpticalLensModel(
    name="optical_lens_model",
    manufacturer="Lens Manufacturer",
    model_number="OL-123",
    description="Optical lens model for imaging",
    numerical_aperture=0.39,
    magnification=40.0,
)
nwbfile.add_device_model(optical_lens_model)

excitation_source_model = ExcitationSourceModel(
    name="excitation_source_model",
    manufacturer="Laser Manufacturer",
    model_number="ES-123",
    description="Excitation source model for green indicator",
    source_type="laser",
    excitation_mode="one-photon",
    wavelength_range_in_nm=[400.0, 800.0],
)
nwbfile.add_device_model(excitation_source_model)

photodetector_model = PhotodetectorModel(
    name="photodetector_model",
    manufacturer="Detector Manufacturer",
    model_number="PD-123",
    description="Photodetector model for green emission",
    detector_type="PMT",
    wavelength_range_in_nm=[400.0, 800.0],
    gain=100.0,
    gain_unit="A/W",
)
nwbfile.add_device_model(photodetector_model)

dichroic_mirror_model = DichroicMirrorModel(
    name="dichroic_mirror_model",
    manufacturer="Mirror Manufacturer",
    model_number="DM-123",
    description="Dichroic mirror model for green indicator",
    cut_on_wavelength_in_nm=470.0,
    cut_off_wavelength_in_nm=500.0,
    reflection_band_in_nm=[460.0, 480.0],
    transmission_band_in_nm=[490.0, 520.0],
    angle_of_incidence_in_degrees=45.0,
)
nwbfile.add_device_model(dichroic_mirror_model)

band_optical_filter_model = BandOpticalFilterModel(
    name="band_optical_filter_model",
    manufacturer="Filter Manufacturer",
    model_number="BOF-123",
    description="Band optical filter model for green indicator",
    filter_type="Bandpass",
    center_wavelength_in_nm=480.0,
    bandwidth_in_nm=30.0,  # 480±15nm
)
nwbfile.add_device_model(band_optical_filter_model)

edge_optical_filter_model = EdgeOpticalFilterModel(
    name="edge_optical_filter_model",
    manufacturer="Filter Manufacturer",
    model_number="EOF-123",
    description="Edge optical filter model for green indicator",
    filter_type="Longpass",
    cut_wavelength_in_nm=585.0,
    slope_in_percent_cut_wavelength=1.0,
    slope_starting_transmission_in_percent=10.0,
    slope_ending_transmission_in_percent=80.0,
)
nwbfile.add_device_model(edge_optical_filter_model)

# Create devices
optical_fiber = OpticalFiber(
    name="optical_fiber",
    description="Optical fiber for optogenetics",
    serial_number="OF-SN-123456",
    model=optical_fiber_model,
    fiber_insertion=fiber_insertion,
)

optical_lens = OpticalLens(
    name="optical_lens",
    description="Optical lens for imaging",
    serial_number="OL-SN-123456",
    model=optical_lens_model,
    lens_positioning=lens_positioning,
)

excitation_source = ExcitationSource(
    name="excitation_source",
    description="Excitation source for green indicator",
    serial_number="ES-SN-123456",
    model=excitation_source_model,
    power_in_W=0.7,
    intensity_in_W_per_m2=0.005,
    exposure_time_in_s=2.51e-13,
)

pulsed_excitation_source = PulsedExcitationSource(
    name="pulsed_excitation_source",
    description="Pulsed excitation source for red indicator",
    serial_number="PES-SN-123456",
    model=excitation_source_model,
    peak_power_in_W=0.7,
    peak_pulse_energy_in_J=0.7,
    intensity_in_W_per_m2=0.005,
    exposure_time_in_s=2.51e-13,
    pulse_rate_in_Hz=2.0e6,
)

photodetector = Photodetector(
    name="photodetector",
    description="Photodetector for green emission",
    serial_number="PD-SN-123456",
    model=photodetector_model,
)

dichroic_mirror = DichroicMirror(
    name="dichroic_mirror",
    description="Dichroic mirror for green indicator",
    serial_number="DM-SN-123456",
    model=dichroic_mirror_model,
)

band_optical_filter = BandOpticalFilter(
    name="band_optical_filter",
    description="Band optical filter for green indicator",
    serial_number="BOF-SN-123456",
    model=band_optical_filter_model,
)

edge_optical_filter = EdgeOpticalFilter(
    name="edge_optical_filter",
    description="Edge optical filter for green indicator",
    serial_number="EOF-SN-123456",
    model=edge_optical_filter_model,
)

# Add objects to the NWBFile
nwbfile.add_device(optical_fiber)
nwbfile.add_device(optical_lens)
nwbfile.add_device(excitation_source)
nwbfile.add_device(pulsed_excitation_source)
nwbfile.add_device(photodetector)
nwbfile.add_device(dichroic_mirror)
nwbfile.add_device(band_optical_filter)
nwbfile.add_device(edge_optical_filter)

```


## Entity relationship diagrams

#### Molecular Tools

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', 'primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%
classDiagram
    direction BT
    class ViralVector {
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        **construct_name** : text
        titer_in_vg_per_ml : numeric, optional
        manufacturer : text, optional
        description : text, optional
    }
    class ViralVectorInjection {
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        location : text, optional
        hemisphere : text, optional
        ap_in_mm : numeric, optional
        ml_in_mm : numeric, optional
        dv_in_mm : numeric, optional
        pitch_in_deg : numeric, optional
        yaw_in_deg : numeric, optional
        roll_in_deg : numeric, optional
        stereotactic_rotation_in_deg : numeric, optional
        stereotactic_tilt_in_deg : numeric, optional
        volume_in_uL : numeric, optional
        injection_date : text, optional
        **viral_vector** : ViralVector
        }
    class Indicator {
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        **label** : text
        description : text, optional
        manufacturer : text, optional
        injection_brain_region : text, optional
        injection_coordinates_in_mm : numeric, length 3, optional
        **viral_vector_injection** : ViralVectorInjection
    }
    class Effector {
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        **label** : text
        description : text, optional
        manufacturer : text, optional
        injection_brain_region : text, optional
        injection_coordinates_in_mm : numeric, length 3, optional
        **viral_vector_injection** : ViralVectorInjection
    }
    Indicator --> ViralVectorInjection : links
    Effector --> ViralVectorInjection : links
    ViralVectorInjection --> ViralVector : links
```

#### Device Models and Devices

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%
classDiagram
    direction TB
    
    class DeviceModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        manufacturer : text
        model_number : text, optional
    }
    
    class Device{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        serial_number : text, optional
        --------------------------------------
        links
        --------------------------------------
        model : DeviceModel, optional
    }
    
    class ExcitationSourceModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **source_type** : text
        **excitation_mode** : text
        wavelength_range_in_nm : numeric, optional
    }
    
    class ExcitationSource{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        power_in_W : numeric, optional
        intensity_in_W_per_m2 : numeric, optional
        exposure_time_in_s : numeric, optional
    }
    
    class PulsedExcitationSource{
        <<ExcitationSource>>
        --------------------------------------
        attributes
        --------------------------------------
        peak_power_in_W : numeric, optional
        peak_pulse_energy_in_J : numeric, optional
        pulse_rate_in_Hz : numeric, optional
    }
    
    class PhotodetectorModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **detector_type** : text
        wavelength_range_in_nm : numeric, optional
        gain : numeric, optional
        gain_unit : text, optional
    }
    
    class Photodetector{
        <<Device>>
    }
    
    Device o--> DeviceModel : links

    DeviceModel <|-- ExcitationSourceModel : extends
    Device <|-- ExcitationSource : extends
    ExcitationSource o--> ExcitationSourceModel : links
    ExcitationSource <|-- PulsedExcitationSource : extends
    PulsedExcitationSource o--> ExcitationSourceModel : links

    DeviceModel <|-- PhotodetectorModel : extends
    Device <|-- Photodetector : extends
    Photodetector o--> PhotodetectorModel : links
```

#### Optical Fiber and Optical Lens
```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%
classDiagram
    direction TB    
    
    class DeviceModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        manufacturer : text
        model_number : text, optional
    }
    
    class Device{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        serial_number : text, optional
        --------------------------------------
        links
        --------------------------------------
        model : DeviceModel, optional
    }
    
    class FiberInsertion{
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        insertion_position_ap_in_mm : numeric, optional
        insertion_position_ml_in_mm : numeric, optional
        insertion_position_dv_in_mm : numeric, optional
        depth_in_mm : numeric, optional
        position_reference : text, optional
        hemisphere : text, optional
        insertion_angle_yaw_in_deg : numeric, optional
        insertion_angle_pitch_in_deg : numeric, optional
        insertion_angle_roll_in_deg : numeric, optional
    }

     class OpticalFiberModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **numerical_aperture** : numeric
        core_diameter_in_um : numeric, optional
        active_length_in_mm : numeric, optional
        ferrule_name : text, optional
        ferrule_model : text, optional
        ferrule_diameter_in_mm : numeric, optional 
    }
    
    class OpticalFiber{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        **fiber_insertion** : FiberInsertion
    }
    
    class LensPositioning{
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        **positioning_type** : text
        target_position_ap_in_mm : numeric, optional
        target_position_ml_in_mm : numeric, optional
        target_position_dv_in_mm : numeric, optional
        depth_in_mm : numeric
        working_distance_in_mm : numeric, optional
        position_reference : text, optional
        hemisphere : text, optional
        optical_axis_angle_yaw_in_deg : numeric, optional
        optical_axis_angle_pitch_in_deg : numeric, optional
        optical_axis_angle_roll_in_deg : numeric, optional
    }

    class OpticalLensModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **numerical_aperture** : numeric
        magnification : numeric, optional
    }
    
    class OpticalLens{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        **lens_positioning** : LensPositioning
    }

    DeviceModel <|-- OpticalFiberModel : extends
    Device <|-- OpticalFiber : extends
    OpticalFiber *-- FiberInsertion : contains
    OpticalFiber o--> OpticalFiberModel : links

    DeviceModel <|-- OpticalLensModel : extends
    Device <|-- OpticalLens : extends
    OpticalLens *-- LensPositioning : contains
    OpticalLens o--> OpticalLensModel : links
```

#### Optical Filters and Dichroic Mirrors

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', "primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%
classDiagram
    direction TB 
    
    class DeviceModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        manufacturer : text, optional
        model_number : text, optional
    }
    
    class Device{
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        serial_number : text, optional
        --------------------------------------
        links
        --------------------------------------
        model : DeviceModel, optional
    }
    
    class OpticalFilterModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **filter_type** : text
    }
    
    class OpticalFilter{
        <<Device>>
    }
    
    class BandOpticalFilterModel{
        <<OpticalFilterModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **center_wavelength_in_nm** : numeric
        **bandwidth_in_nm** : numeric
    }
    
    class BandOpticalFilter{
        <<OpticalFilter>>
    }
    
    class EdgeOpticalFilterModel{
        <<OpticalFilterModel>>
        --------------------------------------
        attributes
        --------------------------------------
        **cut_wavelength_in_nm** : numeric
        slope_in_percent_cut_wavelength : numeric, optional
        slope_starting_transmission_in_percent : numeric, optional
        slope_ending_transmission_in_percent : numeric, optional
    }
    
    class EdgeOpticalFilter{
        <<OpticalFilter>>
    }
    
    class DichroicMirrorModel{
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        cut_on_wavelength_in_nm : numeric, optional
        cut_off_wavelength_in_nm : numeric, optional
        reflection_band_in_nm : numeric, optional
        transmission_band_in_nm : numeric, optional
        angle_of_incidence_in_degrees : numeric, optional
    }
    
    class DichroicMirror{
        <<Device>>
    }
    

    DeviceModel <|-- OpticalFilterModel : extends
    Device <|-- OpticalFilter : extends
    OpticalFilter o--> OpticalFilterModel : links
    
    OpticalFilterModel <|-- BandOpticalFilterModel : extends
    OpticalFilter <|-- BandOpticalFilter : extends
    BandOpticalFilter o--> BandOpticalFilterModel : links
    
    OpticalFilterModel <|-- EdgeOpticalFilterModel : extends
    OpticalFilter <|-- EdgeOpticalFilter : extends
    EdgeOpticalFilter o--> EdgeOpticalFilterModel : links

    DeviceModel <|-- DichroicMirrorModel : extends
    Device <|-- DichroicMirror : extends
    DichroicMirror o--> DichroicMirrorModel : links
```

## Contributing

To help ensure a smooth Pull Request (PR) process, please always begin by raising an issue on the main repository so we can openly discuss any problems/additions before taking action.

The main branch of ndx-ophys-devices is protected; you cannot push to it directly. You must upload your changes by pushing a new branch, then submit your changes to the main branch via a Pull Request. This allows us to conduct automated testing of your contribution, and gives us a space for developers to discuss the contribution and request changes. If you decide to tackle an issue, please make yourself an assignee on the issue to communicate this to the team. Don’t worry - this does not commit you to solving this issue. It just lets others know who they should talk to about it.

From your local copy directory, use the following commands.

If you have not already, you will need to clone the repo:
```bash
$ git clone https://github.com/catalystneuro/ndx-ophys-devices
```

First create a new branch to work on
```bash
$ git checkout -b <new_branch>
```

Make your changes. Add new devices related to optical experiment setup or add more attributes on the existing ones. To speed up the process, you can write mock function (see _mock.py) that would be used to test the new neurodata type

We will automatically run tests to ensure that your contributions didn’t break anything and that they follow our style guide. You can speed up the testing cycle by running these tests locally on your own computer by calling pytest from the top-level directory.
Push your feature branch to origin (i.e. GitHub)

```bash
$ git push origin <new_branch>
```

Once you have tested and finalized your changes, create a pull request (PR) targeting dev as the base branch:
Ensure the PR description clearly describes the problem and solution.
Include the relevant issue number if applicable. TIP: Writing e.g. “fix #613” will automatically close issue #613 when this PR is merged.
Before submitting, please ensure that the code follows the standard coding style of the respective repository.
If you would like help with your contribution, or would like to communicate contributions that are not ready to merge, submit a PR where the title begins with “[WIP].”

Update the CHANGELOG.md regularly to document changes to the extension.

NOTE: Contributed branches will be removed by the development team after the merge is complete and should, hence, not be used after the pull request is complete.


---
This extension was created using [ndx-template](https://github.com/nwb-extensions/ndx-template).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ndx-ophys-devices",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "NWB, NeurodataWithoutBorders, ndx-extension, nwb-extension",
    "author": null,
    "author_email": "Alessandra Trapani <alessandra.trapani@catalystneuro.com>, Paul Adkisson-Floro <paul.adkisson@catalystneuro.com>",
    "download_url": "https://files.pythonhosted.org/packages/3e/09/c45dba14c4aa4bfba22c9ffd51c752e4a7cf43dd5b873d09667bbcee5305/ndx_ophys_devices-0.3.0.tar.gz",
    "platform": null,
    "description": "# ndx-ophys-devices Extension for NWB\n\nThis is an NWB extension for storing metadata of devices used in optical experimental setup (microscopy, fiber photometry, optogenetic stimulation etc.)\n\nThis extension consists of neurodata types in the following categories:\n\n**Container Classes:**\n- **ViralVector** extends NWBContainer to hold metadata on viral vectors used for gene delivery.\n- **ViralVectorInjection** extends NWBContainer to hold metadata on viral vector injection procedures.\n- **Indicator** extends NWBContainer to hold metadata on the fluorescent indicator.\n- **Effector** extends NWBContainer to hold metadata on the effector/opsin.\n- **LensPositioning** extends NWBContainer to hold metadata on the positioning of a lens relative to the brain.\n- **FiberInsertion** extends NWBContainer to hold metadata on the insertion of a fiber into the brain.\n\n**Model Classes:**\n- **OpticalFiberModel** extends DeviceModel to hold metadata on the optical fiber model.\n- **ExcitationSourceModel** extends DeviceModel to hold metadata on the excitation source model.\n- **PhotodetectorModel** extends DeviceModel to hold metadata on the photodetector model.\n- **DichroicMirrorModel** extends DeviceModel to hold metadata on the dichroic mirror model.\n- **OpticalFilterModel** extends DeviceModel to hold metadata on a general optical filter model.\n- **BandOpticalFilterModel** extends OpticalFilterModel to hold metadata on any bandpass or bandstop optical filter models.\n- **EdgeOpticalFilterModel** extends OpticalFilterModel to hold metadata on any edge optical filter models.\n- **OpticalLensModel** extends DeviceModel to hold metadata on the optical lens model.\n\n**Device Classes:**\n- **OpticalFiber** extends Device to hold metadata on optical fibers.\n- **ExcitationSource** extends Device to hold metadata on excitation sources.\n- **PulsedExcitationSource** extends ExcitationSource to hold metadata on pulsed excitation sources.\n- **Photodetector** extends Device to hold metadata on photodetectors.\n- **DichroicMirror** extends Device to hold metadata on dichroic mirrors.\n- **OpticalFilter** extends Device to hold metadata on general optical filters.\n- **BandOpticalFilter** extends OpticalFilter to hold metadata on bandpass or bandstop optical filters.\n- **EdgeOpticalFilter** extends OpticalFilter to hold metadata on edge optical filters.\n- **OpticalLens** extends Device to hold metadata on optical lenses.\n\nNote that the container classes cannot be directly added to the NWB file, but instead require extending `LabMetaData` to\ncontain one or more of these container classes in a separate extension. \nFor example, see [ndx-optogenetics](https://github.com/rly/ndx-optogenetics). \n\n## Installation\nTo install the latest stable release through PyPI,\n```bash\npip install ndx-ophys-devices\n```\n\n## Usage\n\n```python\nimport datetime\nimport numpy as np\nfrom pynwb import NWBFile\nfrom ndx_ophys_devices import (\n    # Container classes\n    ViralVector,\n    ViralVectorInjection,\n    Indicator,\n    Effector,\n    LensPositioning,\n    FiberInsertion,\n    \n    # Model classes\n    OpticalFiberModel,\n    ExcitationSourceModel,\n    PhotodetectorModel,\n    DichroicMirrorModel,\n    OpticalFilterModel,\n    BandOpticalFilterModel,\n    EdgeOpticalFilterModel,\n    OpticalLensModel,\n    \n    # Device classes\n    OpticalFiber,\n    ExcitationSource,\n    PulsedExcitationSource,\n    Photodetector,\n    DichroicMirror,\n    OpticalFilter,\n    BandOpticalFilter,\n    EdgeOpticalFilter,\n    OpticalLens,\n)\n\nnwbfile = NWBFile(\n    session_description='session_description',\n    identifier='identifier',\n    session_start_time=datetime.datetime.now(datetime.timezone.utc)\n)\n\n# Create container objects\nviral_vector = ViralVector(\n    name=\"viral_vector\",\n    description=\"AAV viral vector for optogenetic stimulation\",\n    construct_name=\"AAV-EF1a-DIO-hChR2(H134R)-EYFP\",\n    manufacturer=\"Vector Manufacturer\",\n    titer_in_vg_per_ml=1.0e12,\n)\n\nviral_vector_injection = ViralVectorInjection(\n    name=\"viral_vector_injection\",\n    description=\"Viral vector injection for optogenetic stimulation\",\n    location=\"Hippocampus\",\n    hemisphere=\"right\",\n    reference=\"Bregma at the cortical surface\",\n    ap_in_mm=2.0,\n    ml_in_mm=1.5,\n    dv_in_mm=-3.0,\n    pitch_in_deg=0.0,\n    yaw_in_deg=0.0,\n    roll_in_deg=0.0,\n    stereotactic_rotation_in_deg=0.0,\n    stereotactic_tilt_in_deg=0.0,\n    volume_in_uL=0.45,\n    injection_date=\"1970-01-01T00:00:00+00:00\",\n    viral_vector=viral_vector,\n)\n\nindicator = Indicator(\n    name=\"indicator\",\n    description=\"Green indicator\",\n    label=\"GCamp6f\",\n    viral_vector_injection=viral_vector_injection,\n)\n\neffector = Effector(\n    name=\"effector\",\n    description=\"Excitatory opsin\",\n    label=\"hChR2\",\n    viral_vector_injection=viral_vector_injection,\n)\n\nfiber_insertion = FiberInsertion(\n    name=\"fiber_insertion\",\n    depth_in_mm=3.5,\n    insertion_position_ap_in_mm=2.0,\n    insertion_position_ml_in_mm=1.5,\n    insertion_position_dv_in_mm=3.0,\n    position_reference=\"bregma\",\n    hemisphere=\"right\",\n    insertion_angle_pitch_in_deg=10.0,\n)\n\nlens_positioning = LensPositioning(\n    name=\"lens_positioning\",\n    positioning_type=\"surface\",\n    depth_in_mm=0.0,\n    target_position_ap_in_mm=1.5,\n    target_position_ml_in_mm=2.0,\n    target_position_dv_in_mm=0.0,\n    working_distance_in_mm=2.0,\n    position_reference=\"bregma\",\n    hemisphere=\"left\",\n    optical_axis_angle_pitch_in_deg=0.0,\n)\n\n# Create device models\noptical_fiber_model = OpticalFiberModel(\n    name=\"optical_fiber_model\",\n    manufacturer=\"Fiber Manufacturer\",\n    model_number=\"OF-123\",\n    description=\"Optical fiber model for optogenetics\",\n    numerical_aperture=0.2,\n    core_diameter_in_um=400.0,\n    active_length_in_mm=2.0,\n    ferrule_name=\"cFCF - \u22052.5mm Ceramic Ferrule\",\n    ferrule_model=\"SM-SC-CF-10-FM\",\n    ferrule_diameter_in_mm=2.5,\n)\nnwbfile.add_device_model(optical_fiber_model)\n\noptical_lens_model = OpticalLensModel(\n    name=\"optical_lens_model\",\n    manufacturer=\"Lens Manufacturer\",\n    model_number=\"OL-123\",\n    description=\"Optical lens model for imaging\",\n    numerical_aperture=0.39,\n    magnification=40.0,\n)\nnwbfile.add_device_model(optical_lens_model)\n\nexcitation_source_model = ExcitationSourceModel(\n    name=\"excitation_source_model\",\n    manufacturer=\"Laser Manufacturer\",\n    model_number=\"ES-123\",\n    description=\"Excitation source model for green indicator\",\n    source_type=\"laser\",\n    excitation_mode=\"one-photon\",\n    wavelength_range_in_nm=[400.0, 800.0],\n)\nnwbfile.add_device_model(excitation_source_model)\n\nphotodetector_model = PhotodetectorModel(\n    name=\"photodetector_model\",\n    manufacturer=\"Detector Manufacturer\",\n    model_number=\"PD-123\",\n    description=\"Photodetector model for green emission\",\n    detector_type=\"PMT\",\n    wavelength_range_in_nm=[400.0, 800.0],\n    gain=100.0,\n    gain_unit=\"A/W\",\n)\nnwbfile.add_device_model(photodetector_model)\n\ndichroic_mirror_model = DichroicMirrorModel(\n    name=\"dichroic_mirror_model\",\n    manufacturer=\"Mirror Manufacturer\",\n    model_number=\"DM-123\",\n    description=\"Dichroic mirror model for green indicator\",\n    cut_on_wavelength_in_nm=470.0,\n    cut_off_wavelength_in_nm=500.0,\n    reflection_band_in_nm=[460.0, 480.0],\n    transmission_band_in_nm=[490.0, 520.0],\n    angle_of_incidence_in_degrees=45.0,\n)\nnwbfile.add_device_model(dichroic_mirror_model)\n\nband_optical_filter_model = BandOpticalFilterModel(\n    name=\"band_optical_filter_model\",\n    manufacturer=\"Filter Manufacturer\",\n    model_number=\"BOF-123\",\n    description=\"Band optical filter model for green indicator\",\n    filter_type=\"Bandpass\",\n    center_wavelength_in_nm=480.0,\n    bandwidth_in_nm=30.0,  # 480\u00b115nm\n)\nnwbfile.add_device_model(band_optical_filter_model)\n\nedge_optical_filter_model = EdgeOpticalFilterModel(\n    name=\"edge_optical_filter_model\",\n    manufacturer=\"Filter Manufacturer\",\n    model_number=\"EOF-123\",\n    description=\"Edge optical filter model for green indicator\",\n    filter_type=\"Longpass\",\n    cut_wavelength_in_nm=585.0,\n    slope_in_percent_cut_wavelength=1.0,\n    slope_starting_transmission_in_percent=10.0,\n    slope_ending_transmission_in_percent=80.0,\n)\nnwbfile.add_device_model(edge_optical_filter_model)\n\n# Create devices\noptical_fiber = OpticalFiber(\n    name=\"optical_fiber\",\n    description=\"Optical fiber for optogenetics\",\n    serial_number=\"OF-SN-123456\",\n    model=optical_fiber_model,\n    fiber_insertion=fiber_insertion,\n)\n\noptical_lens = OpticalLens(\n    name=\"optical_lens\",\n    description=\"Optical lens for imaging\",\n    serial_number=\"OL-SN-123456\",\n    model=optical_lens_model,\n    lens_positioning=lens_positioning,\n)\n\nexcitation_source = ExcitationSource(\n    name=\"excitation_source\",\n    description=\"Excitation source for green indicator\",\n    serial_number=\"ES-SN-123456\",\n    model=excitation_source_model,\n    power_in_W=0.7,\n    intensity_in_W_per_m2=0.005,\n    exposure_time_in_s=2.51e-13,\n)\n\npulsed_excitation_source = PulsedExcitationSource(\n    name=\"pulsed_excitation_source\",\n    description=\"Pulsed excitation source for red indicator\",\n    serial_number=\"PES-SN-123456\",\n    model=excitation_source_model,\n    peak_power_in_W=0.7,\n    peak_pulse_energy_in_J=0.7,\n    intensity_in_W_per_m2=0.005,\n    exposure_time_in_s=2.51e-13,\n    pulse_rate_in_Hz=2.0e6,\n)\n\nphotodetector = Photodetector(\n    name=\"photodetector\",\n    description=\"Photodetector for green emission\",\n    serial_number=\"PD-SN-123456\",\n    model=photodetector_model,\n)\n\ndichroic_mirror = DichroicMirror(\n    name=\"dichroic_mirror\",\n    description=\"Dichroic mirror for green indicator\",\n    serial_number=\"DM-SN-123456\",\n    model=dichroic_mirror_model,\n)\n\nband_optical_filter = BandOpticalFilter(\n    name=\"band_optical_filter\",\n    description=\"Band optical filter for green indicator\",\n    serial_number=\"BOF-SN-123456\",\n    model=band_optical_filter_model,\n)\n\nedge_optical_filter = EdgeOpticalFilter(\n    name=\"edge_optical_filter\",\n    description=\"Edge optical filter for green indicator\",\n    serial_number=\"EOF-SN-123456\",\n    model=edge_optical_filter_model,\n)\n\n# Add objects to the NWBFile\nnwbfile.add_device(optical_fiber)\nnwbfile.add_device(optical_lens)\nnwbfile.add_device(excitation_source)\nnwbfile.add_device(pulsed_excitation_source)\nnwbfile.add_device(photodetector)\nnwbfile.add_device(dichroic_mirror)\nnwbfile.add_device(band_optical_filter)\nnwbfile.add_device(edge_optical_filter)\n\n```\n\n\n## Entity relationship diagrams\n\n#### Molecular Tools\n\n```mermaid\n%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', 'primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%\nclassDiagram\n    direction BT\n    class ViralVector {\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **construct_name** : text\n        titer_in_vg_per_ml : numeric, optional\n        manufacturer : text, optional\n        description : text, optional\n    }\n    class ViralVectorInjection {\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        location : text, optional\n        hemisphere : text, optional\n        ap_in_mm : numeric, optional\n        ml_in_mm : numeric, optional\n        dv_in_mm : numeric, optional\n        pitch_in_deg : numeric, optional\n        yaw_in_deg : numeric, optional\n        roll_in_deg : numeric, optional\n        stereotactic_rotation_in_deg : numeric, optional\n        stereotactic_tilt_in_deg : numeric, optional\n        volume_in_uL : numeric, optional\n        injection_date : text, optional\n        **viral_vector** : ViralVector\n        }\n    class Indicator {\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **label** : text\n        description : text, optional\n        manufacturer : text, optional\n        injection_brain_region : text, optional\n        injection_coordinates_in_mm : numeric, length 3, optional\n        **viral_vector_injection** : ViralVectorInjection\n    }\n    class Effector {\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **label** : text\n        description : text, optional\n        manufacturer : text, optional\n        injection_brain_region : text, optional\n        injection_coordinates_in_mm : numeric, length 3, optional\n        **viral_vector_injection** : ViralVectorInjection\n    }\n    Indicator --> ViralVectorInjection : links\n    Effector --> ViralVectorInjection : links\n    ViralVectorInjection --> ViralVector : links\n```\n\n#### Device Models and Devices\n\n```mermaid\n%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', \"primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%\nclassDiagram\n    direction TB\n    \n    class DeviceModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        manufacturer : text\n        model_number : text, optional\n    }\n    \n    class Device{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        serial_number : text, optional\n        --------------------------------------\n        links\n        --------------------------------------\n        model : DeviceModel, optional\n    }\n    \n    class ExcitationSourceModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **source_type** : text\n        **excitation_mode** : text\n        wavelength_range_in_nm : numeric, optional\n    }\n    \n    class ExcitationSource{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        power_in_W : numeric, optional\n        intensity_in_W_per_m2 : numeric, optional\n        exposure_time_in_s : numeric, optional\n    }\n    \n    class PulsedExcitationSource{\n        <<ExcitationSource>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        peak_power_in_W : numeric, optional\n        peak_pulse_energy_in_J : numeric, optional\n        pulse_rate_in_Hz : numeric, optional\n    }\n    \n    class PhotodetectorModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **detector_type** : text\n        wavelength_range_in_nm : numeric, optional\n        gain : numeric, optional\n        gain_unit : text, optional\n    }\n    \n    class Photodetector{\n        <<Device>>\n    }\n    \n    Device o--> DeviceModel : links\n\n    DeviceModel <|-- ExcitationSourceModel : extends\n    Device <|-- ExcitationSource : extends\n    ExcitationSource o--> ExcitationSourceModel : links\n    ExcitationSource <|-- PulsedExcitationSource : extends\n    PulsedExcitationSource o--> ExcitationSourceModel : links\n\n    DeviceModel <|-- PhotodetectorModel : extends\n    Device <|-- Photodetector : extends\n    Photodetector o--> PhotodetectorModel : links\n```\n\n#### Optical Fiber and Optical Lens\n```mermaid\n%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', \"primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%\nclassDiagram\n    direction TB    \n    \n    class DeviceModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        manufacturer : text\n        model_number : text, optional\n    }\n    \n    class Device{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        serial_number : text, optional\n        --------------------------------------\n        links\n        --------------------------------------\n        model : DeviceModel, optional\n    }\n    \n    class FiberInsertion{\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        insertion_position_ap_in_mm : numeric, optional\n        insertion_position_ml_in_mm : numeric, optional\n        insertion_position_dv_in_mm : numeric, optional\n        depth_in_mm : numeric, optional\n        position_reference : text, optional\n        hemisphere : text, optional\n        insertion_angle_yaw_in_deg : numeric, optional\n        insertion_angle_pitch_in_deg : numeric, optional\n        insertion_angle_roll_in_deg : numeric, optional\n    }\n\n     class OpticalFiberModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **numerical_aperture** : numeric\n        core_diameter_in_um : numeric, optional\n        active_length_in_mm : numeric, optional\n        ferrule_name : text, optional\n        ferrule_model : text, optional\n        ferrule_diameter_in_mm : numeric, optional \n    }\n    \n    class OpticalFiber{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **fiber_insertion** : FiberInsertion\n    }\n    \n    class LensPositioning{\n        <<NWBContainer>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **positioning_type** : text\n        target_position_ap_in_mm : numeric, optional\n        target_position_ml_in_mm : numeric, optional\n        target_position_dv_in_mm : numeric, optional\n        depth_in_mm : numeric\n        working_distance_in_mm : numeric, optional\n        position_reference : text, optional\n        hemisphere : text, optional\n        optical_axis_angle_yaw_in_deg : numeric, optional\n        optical_axis_angle_pitch_in_deg : numeric, optional\n        optical_axis_angle_roll_in_deg : numeric, optional\n    }\n\n    class OpticalLensModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **numerical_aperture** : numeric\n        magnification : numeric, optional\n    }\n    \n    class OpticalLens{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **lens_positioning** : LensPositioning\n    }\n\n    DeviceModel <|-- OpticalFiberModel : extends\n    Device <|-- OpticalFiber : extends\n    OpticalFiber *-- FiberInsertion : contains\n    OpticalFiber o--> OpticalFiberModel : links\n\n    DeviceModel <|-- OpticalLensModel : extends\n    Device <|-- OpticalLens : extends\n    OpticalLens *-- LensPositioning : contains\n    OpticalLens o--> OpticalLensModel : links\n```\n\n#### Optical Filters and Dichroic Mirrors\n\n```mermaid\n%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', \"primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%\nclassDiagram\n    direction TB \n    \n    class DeviceModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        manufacturer : text, optional\n        model_number : text, optional\n    }\n    \n    class Device{\n        <<Device>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        serial_number : text, optional\n        --------------------------------------\n        links\n        --------------------------------------\n        model : DeviceModel, optional\n    }\n    \n    class OpticalFilterModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **filter_type** : text\n    }\n    \n    class OpticalFilter{\n        <<Device>>\n    }\n    \n    class BandOpticalFilterModel{\n        <<OpticalFilterModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **center_wavelength_in_nm** : numeric\n        **bandwidth_in_nm** : numeric\n    }\n    \n    class BandOpticalFilter{\n        <<OpticalFilter>>\n    }\n    \n    class EdgeOpticalFilterModel{\n        <<OpticalFilterModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        **cut_wavelength_in_nm** : numeric\n        slope_in_percent_cut_wavelength : numeric, optional\n        slope_starting_transmission_in_percent : numeric, optional\n        slope_ending_transmission_in_percent : numeric, optional\n    }\n    \n    class EdgeOpticalFilter{\n        <<OpticalFilter>>\n    }\n    \n    class DichroicMirrorModel{\n        <<DeviceModel>>\n        --------------------------------------\n        attributes\n        --------------------------------------\n        cut_on_wavelength_in_nm : numeric, optional\n        cut_off_wavelength_in_nm : numeric, optional\n        reflection_band_in_nm : numeric, optional\n        transmission_band_in_nm : numeric, optional\n        angle_of_incidence_in_degrees : numeric, optional\n    }\n    \n    class DichroicMirror{\n        <<Device>>\n    }\n    \n\n    DeviceModel <|-- OpticalFilterModel : extends\n    Device <|-- OpticalFilter : extends\n    OpticalFilter o--> OpticalFilterModel : links\n    \n    OpticalFilterModel <|-- BandOpticalFilterModel : extends\n    OpticalFilter <|-- BandOpticalFilter : extends\n    BandOpticalFilter o--> BandOpticalFilterModel : links\n    \n    OpticalFilterModel <|-- EdgeOpticalFilterModel : extends\n    OpticalFilter <|-- EdgeOpticalFilter : extends\n    EdgeOpticalFilter o--> EdgeOpticalFilterModel : links\n\n    DeviceModel <|-- DichroicMirrorModel : extends\n    Device <|-- DichroicMirror : extends\n    DichroicMirror o--> DichroicMirrorModel : links\n```\n\n## Contributing\n\nTo help ensure a smooth Pull Request (PR) process, please always begin by raising an issue on the main repository so we can openly discuss any problems/additions before taking action.\n\nThe main branch of ndx-ophys-devices is protected; you cannot push to it directly. You must upload your changes by pushing a new branch, then submit your changes to the main branch via a Pull Request. This allows us to conduct automated testing of your contribution, and gives us a space for developers to discuss the contribution and request changes. If you decide to tackle an issue, please make yourself an assignee on the issue to communicate this to the team. Don\u2019t worry - this does not commit you to solving this issue. It just lets others know who they should talk to about it.\n\nFrom your local copy directory, use the following commands.\n\nIf you have not already, you will need to clone the repo:\n```bash\n$ git clone https://github.com/catalystneuro/ndx-ophys-devices\n```\n\nFirst create a new branch to work on\n```bash\n$ git checkout -b <new_branch>\n```\n\nMake your changes. Add new devices related to optical experiment setup or add more attributes on the existing ones. To speed up the process, you can write mock function (see _mock.py) that would be used to test the new neurodata type\n\nWe will automatically run tests to ensure that your contributions didn\u2019t break anything and that they follow our style guide. You can speed up the testing cycle by running these tests locally on your own computer by calling pytest from the top-level directory.\nPush your feature branch to origin (i.e. GitHub)\n\n```bash\n$ git push origin <new_branch>\n```\n\nOnce you have tested and finalized your changes, create a pull request (PR) targeting dev as the base branch:\nEnsure the PR description clearly describes the problem and solution.\nInclude the relevant issue number if applicable. TIP: Writing e.g. \u201cfix #613\u201d will automatically close issue #613 when this PR is merged.\nBefore submitting, please ensure that the code follows the standard coding style of the respective repository.\nIf you would like help with your contribution, or would like to communicate contributions that are not ready to merge, submit a PR where the title begins with \u201c[WIP].\u201d\n\nUpdate the CHANGELOG.md regularly to document changes to the extension.\n\nNOTE: Contributed branches will be removed by the development team after the merge is complete and should, hence, not be used after the pull request is complete.\n\n\n---\nThis extension was created using [ndx-template](https://github.com/nwb-extensions/ndx-template).\n",
    "bugtrack_url": null,
    "license": "BSD-3",
    "summary": "This is an NWB extension for storing metadata of devices used in optical experimental setup (microscopy, fiber photometry, optogenetic stimulation etc.)",
    "version": "0.3.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/catalystneuro/ndx-ophys-devices/issues",
        "Changelog": "https://github.com/catalystneuro/ndx-ophys-devices/blob/main/CHANGELOG.md",
        "Discussions": "https://github.com/catalystneuro/ndx-ophys-devices/discussions",
        "Documentation": "https://ndx-ophys-devices.readthedocs.io/",
        "Homepage": "https://github.com/catalystneuro/ndx-ophys-devices"
    },
    "split_keywords": [
        "nwb",
        " neurodatawithoutborders",
        " ndx-extension",
        " nwb-extension"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ad4bac247a68436acb2a884fd1f17021dd91d1b33d1886963a0d9a038dcb8bcd",
                "md5": "624c51fee893b46927f5f16d76613ad4",
                "sha256": "483edc998259f22318224adb4fc953f252519318f02da905795280638131d2d7"
            },
            "downloads": -1,
            "filename": "ndx_ophys_devices-0.3.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "624c51fee893b46927f5f16d76613ad4",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 17976,
            "upload_time": "2025-09-17T16:38:11",
            "upload_time_iso_8601": "2025-09-17T16:38:11.766182Z",
            "url": "https://files.pythonhosted.org/packages/ad/4b/ac247a68436acb2a884fd1f17021dd91d1b33d1886963a0d9a038dcb8bcd/ndx_ophys_devices-0.3.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3e09c45dba14c4aa4bfba22c9ffd51c752e4a7cf43dd5b873d09667bbcee5305",
                "md5": "79925920e4030ce64544916c280729ec",
                "sha256": "772171d581c9ced1da18c420ef48158a3e96333bd0a9240faec1098b2ff9e3bc"
            },
            "downloads": -1,
            "filename": "ndx_ophys_devices-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "79925920e4030ce64544916c280729ec",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 27775,
            "upload_time": "2025-09-17T16:38:12",
            "upload_time_iso_8601": "2025-09-17T16:38:12.976451Z",
            "url": "https://files.pythonhosted.org/packages/3e/09/c45dba14c4aa4bfba22c9ffd51c752e4a7cf43dd5b873d09667bbcee5305/ndx_ophys_devices-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-17 16:38:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "catalystneuro",
    "github_project": "ndx-ophys-devices",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "ndx-ophys-devices"
}
        
Elapsed time: 1.92392s