Skip to content

Commit

Permalink
Add comments to io/file.py (#1925)
Browse files Browse the repository at this point in the history
* Add comments to io/file.py

* Update changelog
  • Loading branch information
rly authored Jun 28, 2024
1 parent 3c5fa48 commit c99c0c5
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Documentation and tutorial enhancements
- Simplified the introduction to NWB tutorial. @rly [#1914](https://github.com/NeurodataWithoutBorders/pynwb/pull/1914)
- Simplified the ecephys and ophys tutorials. [#1915](https://github.com/NeurodataWithoutBorders/pynwb/pull/1915)
- Add comments to `src/pynwb/io/file.py` to improve developer documentation. @rly [#1925](https://github.com/NeurodataWithoutBorders/pynwb/pull/1925)

### Bug fixes
- Fixed use of `channel_conversion` in `TimeSeries` `get_data_in_units`. @rohanshah [1923](https://github.com/NeurodataWithoutBorders/pynwb/pull/1923)
Expand Down
104 changes: 100 additions & 4 deletions src/pynwb/io/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ def __init__(self, spec):

@ObjectMapper.object_attr('scratch_datas')
def scratch_datas(self, container, manager):
"""Set the value for the 'scratch_datas' spec on NWBFile to a list of ScratchData objects.
Used when writing (building) the NWBFile container to a file.
The 'scratch' group can contain both groups and datasets. This mapping function
is used when writing the value for the 'scratch_datas' spec (ScratchData type
-- see __init__ above). The value is set to a list of all ScratchData
objects in the 'scratch' field of the NWBFile container.
"""
scratch = container.scratch
ret = list()
for s in scratch.values():
Expand All @@ -136,6 +145,15 @@ def scratch_datas(self, container, manager):

@ObjectMapper.object_attr('scratch_containers')
def scratch_containers(self, container, manager):
"""Set the value for the 'scratch_containers' spec on NWBFile to a list of non-ScratchData objects.
Used when writing (building) the NWBFile container to a file.
The 'scratch' group can contain both groups and datasets. This mapping function
is used when writing the value for the 'scratch_containers' spec (NWBContainers
and DynamicTable type -- see __init__ above). The value is set to a list of all non-ScratchData
objects in the 'scratch' field of the NWBFile container.
"""
scratch = container.scratch
ret = list()
for s in scratch.values():
Expand All @@ -145,6 +163,14 @@ def scratch_containers(self, container, manager):

@ObjectMapper.constructor_arg('scratch')
def scratch(self, builder, manager):
"""Set the constructor arg for 'scratch' to a tuple of objects.
Used when constructing the NWBFile container from a written file.
The 'scratch' group can contain both groups and datasets. This mapping function
is used to construct the contained groups and datasets and put them into a single
field 'scratch' on the NWBFile container for user convenience.
"""
scratch = builder.get('scratch')
ret = list()
if scratch is not None:
Expand All @@ -156,28 +182,54 @@ def scratch(self, builder, manager):

@ObjectMapper.constructor_arg('session_start_time')
def dateconversion(self, builder, manager):
"""Set the constructor arg for 'session_start_time' to a datetime object.
Used when constructing the NWBFile container from a written file.
Dates are read into builders as strings and are parsed into datetime objects
for user convenience and consistency with how they are written.
"""
datestr = builder.get('session_start_time').data
date = dateutil_parse(datestr)
return date

@ObjectMapper.constructor_arg('timestamps_reference_time')
def dateconversion_trt(self, builder, manager):
"""Set the constructor arg for 'timestamps_reference_time' to a datetime object.
Used when constructing the NWBFile container from a written file.
Dates are read into builders as strings and are parsed into datetime objects
for user convenience and consistency with how they are written.
"""
datestr = builder.get('timestamps_reference_time').data
date = dateutil_parse(datestr)
return date

@ObjectMapper.constructor_arg('file_create_date')
def dateconversion_list(self, builder, manager):
"""Set the constructor arg for 'file_create_date' to a datetime object.
Used when constructing the NWBFile container from a written file.
Dates are read into builders as strings and are parsed into datetime objects
for user convenience and consistency with how they are written.
"""
datestr = builder.get('file_create_date').data
dates = list(map(dateutil_parse, datestr))
return dates

@ObjectMapper.constructor_arg('file_name')
def name(self, builder, manager):
return builder.name

@ObjectMapper.constructor_arg('experimenter')
def experimenter_carg(self, builder, manager):
"""Set the constructor arg for 'experimenter' to a tuple if the builder value is a string.
Used when constructing the NWBFile container from a written file.
In early versions of the NWB 2 schema, 'experimenter' was specified as a string.
Then it was changed to be a 1-D array of strings. This mapping function is necessary
to allow reading of both data where 'experimenter' was specified as a string and data
where 'experimenter' was specified as an array.
"""
ret = None
exp_bldr = builder['general'].get('experimenter')
if exp_bldr is not None:
Expand All @@ -189,13 +241,30 @@ def experimenter_carg(self, builder, manager):

@ObjectMapper.object_attr('experimenter')
def experimenter_obj_attr(self, container, manager):
"""Change the value for the field 'experimenter' on NWBFile to a tuple if it is a string.
Used when writing (building) the NWBFile container to a file.
In early versions of the NWB 2 schema, 'experimenter' was specified as a string.
Then it was changed to be a 1-D array of strings. This mapping function is necessary
for writing a valid 'experimenter' array if it is a string in the NWBFile container.
"""
ret = None
if isinstance(container.experimenter, str):
ret = (container.experimenter,)
return ret

@ObjectMapper.constructor_arg('related_publications')
def publications_carg(self, builder, manager):
"""Set the constructor arg for 'related_publications' to a tuple if the builder value is a string.
Used when constructing the NWBFile container from a written file.
In early versions of the NWB 2 schema, 'related_publications' was specified as a string.
Then it was changed to be a 1-D array of strings. This mapping function is necessary
to allow reading of both data where 'related_publications' was specified as a string and data
where 'related_publications' was specified as an array.
"""
ret = None
pubs_bldr = builder['general'].get('related_publications')
if pubs_bldr is not None:
Expand All @@ -207,6 +276,14 @@ def publications_carg(self, builder, manager):

@ObjectMapper.object_attr('related_publications')
def publication_obj_attr(self, container, manager):
"""Change the value for the field 'related_publications' on NWBFile to a tuple if it is a string.
Used when writing (building) the NWBFile container to a file.
In early versions of the NWB 2 schema, 'related_publications' was specified as a string.
Then it was changed to be a 1-D array of strings. This mapping function is necessary
for writing a valid 'related_publications' array if it is a string in the NWBFile container.
"""
ret = None
if isinstance(container.related_publications, str):
ret = (container.related_publications,)
Expand All @@ -218,6 +295,13 @@ class SubjectMap(ObjectMapper):

@ObjectMapper.constructor_arg('date_of_birth')
def dateconversion(self, builder, manager):
"""Set the constructor arg for 'date_of_birth' to a datetime object.
Used when constructing the Subject container from a written file.
Dates are read into builders as strings and are parsed into datetime objects
for user convenience and consistency with how they are written.
"""
dob_builder = builder.get('date_of_birth')
if dob_builder is None:
return
Expand All @@ -228,6 +312,18 @@ def dateconversion(self, builder, manager):

@ObjectMapper.constructor_arg("age__reference")
def age_reference_none(self, builder, manager):
"""Set the constructor arg for 'age__reference' to "unspecified" for NWB files < 2.6, else "birth".
Used when constructing the Subject container from a written file.
NWB schema 2.6.0 introduced a new optional attribute 'reference' on the 'age' dataset with a default
value of "birth". When data written with NWB versions < 2.6 are read, 'age__reference' is set to
"unspecified" in the Subject constructor. "unspecified" is a special non-None placeholder value
that is handled specially in Subject.__init__ to distinguish it from no value being provided by the
user. When data written with NWB versions >= 2.6 are read, 'age__reference' is set to the default
value, "birth", in the Subject constructor (this is not strictly necessary because Subject.__init__
has default value "birth" for 'age__reference').
"""
age_builder = builder.get("age")
age_reference = None
if age_builder is not None:
Expand Down

0 comments on commit c99c0c5

Please sign in to comment.