Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ophys devices from ndx-ophys-devices #22

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

alessandratrapani
Copy link
Collaborator

@alessandratrapani alessandratrapani commented Aug 26, 2024

In this PR I added neurodatatypes from ndx-ophys-devices:

Entity relationship diagram for ndx-ophys-devices objects in ndx-microscopy

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', 'primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%

classDiagram
    direction TB

    class DeviceModel {
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        model : text, optional
    }

    class ExcitationLightPath {
        <<LabMetaData>>
        --------------------------------------
        attributes
        --------------------------------------
        excitation_wavelength_in_nm : numeric
        description : text
        --------------------------------------
        links
        --------------------------------------
        excitation_source : ExcitationSource, optional
        excitation_filter : OpticalFilter, optional
    }

    class EmissionLightPath {
        <<LabMetaData>>
        --------------------------------------
        attributes
        --------------------------------------
        emission_wavelength_in_nm : numeric
        description : text
        --------------------------------------
        groups
        --------------------------------------
        indicator : Indicator
        --------------------------------------
        links
        --------------------------------------
        photodetector : Photodetector, optional
        emission_filter : OpticalFilter, optional
    }

    class ExcitationSource {
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        illumination_type : text
        excitation_wavelength_in_nm : float
        power_in_W : float, optional
        intensity_in_W_per_m2 : float, optional
        exposure_time_in_s : float, optional
    }

    class PulsedExcitationSource {
        <<ExcitationSource>>
        --------------------------------------
        attributes
        --------------------------------------
        peak_power_in_W : float, optional
        peak_pulse_energy_in_J : float, optional
        pulse_rate_in_Hz : float, optional
    }

    class OpticalFilter {
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        filter_type : text
    }

    class BandOpticalFilter {
        <<OpticalFilter>>
        --------------------------------------
        attributes
        --------------------------------------
        center_wavelength_in_nm : float
        bandwidth_in_nm : float
    }

    class EdgeOpticalFilter {
        <<OpticalFilter>>
        --------------------------------------
        attributes
        --------------------------------------
        cut_wavelength_in_nm : float
        slope_in_percent_cut_wavelength : float, optional
        slope_starting_transmission_in_percent : float, optional
        slope_ending_transmission_in_percent : float, optional
    }

    class Photodetector {
        <<DeviceModel>>
        --------------------------------------
        attributes
        --------------------------------------
        detector_type : text
        detected_wavelength_in_nm : float
        gain : float, optional
        gain_unit : text, optional
    }

    class Indicator {
        <<NWBContainer>>
        --------------------------------------
        attributes
        --------------------------------------
        label : text
        description : text, optional
        manufacturer : text, optional
        injection_brain_region : text, optional
        injection_coordinates_in_mm : float[3], optional
    }

    DeviceModel <|-- ExcitationSource : extends
    DeviceModel <|-- OpticalFilter : extends
    DeviceModel <|-- Photodetector : extends
    ExcitationSource <|-- PulsedExcitationSource : extends
    OpticalFilter <|-- BandOpticalFilter : extends
    OpticalFilter <|-- EdgeOpticalFilter : extends

    ExcitationLightPath ..> ExcitationSource : links
    ExcitationLightPath ..> OpticalFilter : links
    EmissionLightPath ..> Photodetector : links
    EmissionLightPath ..> OpticalFilter : links
    EmissionLightPath *-- Indicator : contains
Loading

Entity relationship diagram for ndx-microscopy

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', 'primaryBorderColor': '#144E73', 'lineColor': '#D96F32'}}}%%

classDiagram
    direction BT

    class MicroscopySeries {
        <<TimeSeries>>
        --------------------------------------
        links
        --------------------------------------
        microscope : Microscope
        excitation_light_path : ExcitationLightPath
        emission_light_path : EmissionLightPath
    }

    class PlanarMicroscopySeries {
        <<MicroscopySeries>>
        --------------------------------------
        datasets
        --------------------------------------
        data : numeric, frame x height x width
        --------------------------------------
        links
        --------------------------------------
        imaging_space : PlanarImagingSpace
    }

    class VariableDepthMicroscopySeries {
        <<PlanarMicroscopySeries>>
        --------------------------------------
        datasets
        --------------------------------------
        depth_per_frame_in_um : numeric, length of frames
    }

    class VolumetricMicroscopySeries {
        <<MicroscopySeries>>
        --------------------------------------
        datasets
        --------------------------------------
        data : numeric, frame x height x width x depth
        --------------------------------------
        links
        --------------------------------------
        imaging_space : VolumetricImagingSpace
    }

    class MultiChannelMicroscopyVolume {
        <<NWBDataInterface>>
        --------------------------------------
        attributes
        --------------------------------------
        description : text, optional
        unit : text
        conversion : float32, optional, default=1.0
        offset : float32, optional, default=0.0
        --------------------------------------
        datasets
        --------------------------------------
        data : numeric, height x width x depth x emission_light_paths
        excitation_light_paths : ExcitationLightPath[]
        emission_light_paths : EmissionLightPath[]
        --------------------------------------
        links
        --------------------------------------
        imaging_space : VolumetricImagingSpace
        microscope : Microscope
    }
    
    class ImagingSpace {
        <<LabMetaData>>
        --------------------------------------
        datasets
        --------------------------------------
        description : text
        origin_coordinates : float64[3], optional
        --> unit : text, default="micrometers"
        --------------------------------------
        attributes
        --------------------------------------
        location : text, optional
    }

    class PlanarImagingSpace {
        <<ImagingSpace>>
        --------------------------------------
        datasets
        --------------------------------------
        grid_spacing_in_um : float64[2], optional
        --------------------------------------
        attributes
        --------------------------------------
        reference_frame : text, optional
    }

    class VolumetricImagingSpace {
        <<ImagingSpace>>
        --------------------------------------
        datasets
        --------------------------------------
        grid_spacing_in_um : float64[3], optional
        --------------------------------------
        attributes
        --------------------------------------
        reference_frame : text, optional
    }

    class ExcitationLightPath {
        <<LabMetaData>>
        --------------------------------------
        attributes
        --------------------------------------
        excitation_wavelength_in_nm : numeric
        description : text
        --------------------------------------
        links
        --------------------------------------
        excitation_source : ExcitationSource, optional
        excitation_filter : OpticalFilter, optional
    }

    class EmissionLightPath {
        <<LabMetaData>>
        --------------------------------------
        attributes
        --------------------------------------
        emission_wavelength_in_nm : numeric
        description : text
        --------------------------------------
        groups
        --------------------------------------
        indicator : Indicator
        --------------------------------------
        links
        --------------------------------------
        photodetector : Photodetector, optional
        emission_filter : OpticalFilter, optional
    }

    class Microscope {
        <<Device>>
        --------------------------------------
        attributes
        --------------------------------------
        model : text, optional
    }

    PlanarMicroscopySeries *-- MicroscopySeries : extends
    PlanarMicroscopySeries -- PlanarImagingSpace : links
    VariableDepthMicroscopySeries *-- PlanarMicroscopySeries : extends
    VolumetricMicroscopySeries *-- MicroscopySeries : extends
    VolumetricMicroscopySeries -- VolumetricImagingSpace : links
    MultiChannelMicroscopyVolume -- VolumetricImagingSpace : links
    PlanarImagingSpace *-- ImagingSpace : extends
    VolumetricImagingSpace *-- ImagingSpace : extends
    MicroscopySeries ..> Microscope : links
    MicroscopySeries ..> ExcitationLightPath : links
    MicroscopySeries ..> EmissionLightPath : links
Loading

@alessandratrapani alessandratrapani changed the base branch from main to use_updated_ndx_template December 18, 2024 11:10
@alessandratrapani alessandratrapani deleted the branch main December 18, 2024 11:39
@alessandratrapani alessandratrapani changed the base branch from use_updated_ndx_template to main December 18, 2024 11:56
@alessandratrapani
Copy link
Collaborator Author

alessandratrapani commented Jan 16, 2025

@pauladkisson Sorry for the messy PR. I'll try to explain what I did here:

  1. Added neurodata types from ndx-ophys-devices
  2. Update tests
  3. Update the entity relationship diagram in the README

Basically, I am asking you to review the following files that contain those 3 changes:

  • README.md
  • requirements-dev.txt
  • requirements-min.txt
  • spec/ndx-microscopy.extensions.yaml
  • spec/ndx-microscopy.namespace.yaml
  • src/pynwb/ndx_microscopy/init.py
  • src/pynwb/ndx_microscopy/testing/init.py
  • src/pynwb/ndx_microscopy/testing/_mock.py
  • src/pynwb/tests/test_constructors.py
  • src/pynwb/tests/test_roundtrip.py

All the other files have already been reviewed in #26, where we updated the base template for the extension and fixed the import of ndx-ophys-device (#23).

In a follow-up PR, I will make the ExcitationLightPath, the EmissionLightPath, and the ImagingSpace inherit from a general NWBContainer instead of LabMetadata.

In other PR I will update the documentation

Copy link
Member

@pauladkisson pauladkisson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good! I made a few suggestions but nothing major.

I think it would help me a lot to have a quick meeting on this to make sure I understand what's going on (esp. with the newer types). I marked some questions ZoomQ for that purpose.

- neurodata_type_def: MicroscopyLightSource
neurodata_type_inc: Device
doc: Light source used to illuminate an imaging space.
- neurodata_type_def: ExcitationLightPath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zoomQ: ExcitationLightPath is new to me, could you explain what its purpose is?

- name: description
doc: Description or other notes about the channel.
dtype: text
- neurodata_type_def: EmissionLightPath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZoomQ: EmissionLightPath is new to me, could you explain what its purpose is?

- name: emission_filter
target_type: OpticalFilter
doc: Link to OpticalFilter object which contains metadata about the optical filter in this emission light path. It can be either a BandOpticalFilter (e.g., 'Bandpass', 'Bandstop', 'Longpass', 'Shortpass') or a EdgeOpticalFilter (Longpass or Shortpass).
quantity: '?'

- neurodata_type_def: ImagingSpace
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This basically replaces ImagingPlane right?

- name: emission_filter
target_type: OpticalFilter
doc: Link to OpticalFilter object which contains metadata about the optical filter in this emission light path. It can be either a BandOpticalFilter (e.g., 'Bandpass', 'Bandstop', 'Longpass', 'Shortpass') or a EdgeOpticalFilter (Longpass or Shortpass).
quantity: '?'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a dichroic mirror in the light path of these microscopes? If so we should probably include it right?



def test_constructor_microscope():
ndx_microscopy.testing.mock_Microscope()
mock_Microscope()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests really should have some assertions to check that the information is propagating properly.

For example, for the microscope,

def test_constructor_microscope():
    microscope = mock_Microscope()
    assert microscope.description == "A mock instance of a Microscope type to be used for rapid testing."

imaging_space=imaging_space,
optical_channel=optical_channel,
emission_light_path=emission_light_path,
)
nwbfile.add_acquisition(nwbdata=planar_microscopy_series)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you add a PlanarMicroscopySeries to acquisition, but forget to add one of its devices?

I ask bc I've made this mistake and sometimes it fails ungracefully (ex. write works but read fails).

requirements-min.txt Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants