Skip to content
This repository has been archived by the owner on Mar 15, 2023. It is now read-only.

Refactor write segmentation I #601

Merged
merged 6 commits into from
Jul 21, 2022

Conversation

h-mayorquin
Copy link
Collaborator

This is part of a join effort with @weiglszonja to refactor write_segmentation in the roiextractors module. This first PR does a couple of things:

  1. It refactors the previously added function called add_imaging_plane and adds some unit tests.
  2. The add_imaging_plane function is then used to refactor the write_segmentation function with some code reduction.
  3. There are some other minor refactoring in documentation (add_device function) and style here and there.

@h-mayorquin h-mayorquin added testing refactoring writing for the long term labels Jul 20, 2022
@h-mayorquin h-mayorquin requested a review from weiglszonja July 20, 2022 16:21
@h-mayorquin h-mayorquin self-assigned this Jul 20, 2022
@@ -38,6 +39,20 @@ def get_default_ophys_metadata():
metadata = get_default_nwbfile_metadata()

default_device = dict(name="Microscope")
default_optical_channel = dict(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is just to flatten the metadata construction.

@@ -124,7 +123,12 @@ def get_nwb_imaging_metadata(imgextractor: ImagingExtractor):

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Flattening ends here.

imaging_plane = _create_imaging_plane_from_metadata(
nwbfile=nwbfile, imaging_plane_metadata=imaging_plane_metadata
)
nwbfile.add_imaging_plane(imaging_plane)

return nwbfile

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The diff is doing a terrible job at displaying this but from line 141 to here the code displays the substitution of the old private method _add_imaging_plane for a new add_imaging_plane which adds the imaging plane to an nwb file and a second private function _create_imaging_plane_from_metadata which creates an image plane from the metadata when its name does not exist in the nwbfile yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like this approach :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I think that makes sense for this module. Having an auxiliary private function that creates the pynwb objects from the metadata and then a public tested function that adds this to the nwb file checking for edge cases and controlling parameters/options/etc.

second_imaging_plane_description = "second_imaging_plane_description"
self.imaging_plane_metadata["name"] = second_imaging_plane_name
self.imaging_plane_metadata["description"] = second_imaging_plane_description
add_imaging_plane(nwbfile=self.nwbfile, metadata=self.metadata)
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a question here, there is an imaging_plane_index in add_imaging_plane which is 0 by default. When you add the second imaging plane here, are you using the same imaging_plane_index? (Maybe I don't get what an imaging_plane_index is for)

Copy link
Collaborator Author

@h-mayorquin h-mayorquin Jul 21, 2022

Choose a reason for hiding this comment

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

Yes, I think this is confusing (at least it confused me) and I think it stems from a design decision that was made about our metadata format. In order to mimic the nwb schema the metadata for imagine plane is stored at the top level of ophys as a list. The reason for this, as far as I understand, is that the imaging_plane in the nwb-schema is a group of objects. Each of the imaging plane in this group are then stored as links in all the objects that require them (e.g. TwoPhotonSeries). I think that the decision was make to make our own schema in nwb-conversion tools mimic as much as possible the true schema. Therefore, the metadata for imaging_plane is a list at the top level of our metadata.

The crucial fact is that the metadata for the imaging_plane in our metadata dict is a list and therefore an specification of which element/index of the list do we want to add becomes necessary. That's the role of imagine_plane_index. If you see the previous code that this is removing it was assumed that the element was always the first element of the list which I think works right now because we never had a conversion with more than one plane. I changed this to make this assumption explicit and make it a parameter that can be changed if it is required.

Maybe there is a better name? as we don't have examples of conversion data with more than two imaging planes I don't know what's the best way to handle this.

Copy link
Collaborator Author

@h-mayorquin h-mayorquin Jul 21, 2022

Choose a reason for hiding this comment

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

Now, the case when the segmentation extractor is an MultiSegmentationExtractor object would seem to be this case that I mention is lacking as it was meant to handle segmentation objects each with a different imaging plane (see catalystneuro/roiextractors#178).

But strangely, the decision was make to instead pass a list of metadata dictionaries (as you can see at the beginning of the code in the function) and therefore the metadata for image_list is still a list with only one element and the code that assumes that the first element of the list is the corresponding metadata of the image list still works.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, thanks for clarifying it.

@h-mayorquin
Copy link
Collaborator Author

h-mayorquin commented Jul 21, 2022

@codecov
Copy link

codecov bot commented Jul 21, 2022

Codecov Report

Merging #601 (29b2bcf) into main (9a9fb75) will increase coverage by 0.04%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #601      +/-   ##
==========================================
+ Coverage   88.34%   88.38%   +0.04%     
==========================================
  Files          59       59              
  Lines        3218     3221       +3     
==========================================
+ Hits         2843     2847       +4     
+ Misses        375      374       -1     
Flag Coverage Δ
unittests 88.38% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...b_conversion_tools/tools/roiextractors/__init__.py 100.00% <ø> (ø)
...version_tools/tools/roiextractors/roiextractors.py 80.63% <100.00%> (+0.63%) ⬆️

@h-mayorquin h-mayorquin merged commit 3ce21b6 into main Jul 21, 2022
@h-mayorquin h-mayorquin deleted the refactor_write_segmentation_using_add_image_plane branch July 21, 2022 11:58
@CodyCBakerPhD
Copy link
Member

@h-mayorquin @weiglszonja FYI this stuff did not make it over to https://github.com/catalystneuro/neuroconv prior to commit I used to split so this chain of PRs will have to be ported over

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
refactoring writing for the long term testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants