-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathplot_external_resources.py
More file actions
177 lines (141 loc) · 7.92 KB
/
Copy pathplot_external_resources.py
File metadata and controls
177 lines (141 loc) · 7.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""
.. _external_resources:
Linking to External Resources (HERD)
====================================
The :py:class:`~pynwb.resources.HERD` (HDMF External Resources Data Structure) class lets you map
terms used in your data to entities defined in external, web-accessible resources such as
ontologies. For example, you may store a species name ``"Mus musculus"`` on a
:py:class:`~pynwb.file.Subject` and want to link it to the corresponding NCBI Taxonomy term so that
the value is standardized and easy to query.
From a user's perspective, a HERD can be treated as a single table that associates a ``key`` (a term
used on an ``object``, i.e. a dataset or attribute in the file) with an ``entity`` (a term in an
external resource, identified by an ``entity_id`` and an ``entity_uri``). Internally, HERD stores
this in six interlinked tables (``keys``, ``files``, ``entities``, ``entity_keys``, ``objects``, and
``object_keys``) and provides convenience methods so you rarely need to interact with those tables
directly.
This tutorial shows how to create a HERD, annotate objects in an NWB file, store the HERD in the
file, and inspect the annotations after reading the file back. For the full HERD API (including
``add_ref_termset`` for validating terms against a :py:class:`~hdmf.term_set.TermSet`, ``get_key``,
and compound-data references), see the
`HDMF HERD tutorial <https://hdmf.readthedocs.io/en/stable/tutorials/plot_external_resources.html>`_.
"""
# sphinx_gallery_thumbnail_path = 'figures/gallery_thumbnails_external_resources.png'
from datetime import datetime
from uuid import uuid4
from dateutil.tz import tzlocal
from pynwb import NWBHDF5IO, NWBFile
from pynwb.file import Subject
from pynwb.resources import HERD
###############################################################################
# Create an NWB file
# ------------------
# Start with an :py:class:`~pynwb.file.NWBFile` that has a :py:class:`~pynwb.file.Subject`. The
# subject's species is the value we will annotate with an external resource.
nwbfile = NWBFile(
session_description="a demonstration of external resources",
identifier=str(uuid4()),
session_start_time=datetime(2018, 4, 25, 2, 30, 3, tzinfo=tzlocal()),
subject=Subject(subject_id="001", species="Mus musculus"),
)
###############################################################################
# Create a HERD and attach it to the file
# ---------------------------------------
# Create a :py:class:`~pynwb.resources.HERD` and assign it to the ``external_resources`` field of the
# :py:class:`~pynwb.file.NWBFile`.
nwbfile.external_resources = HERD()
###############################################################################
# Add references with ``add_ref``
# -------------------------------
# Use :py:meth:`~hdmf.common.resources.HERD.add_ref` to add a row that links a key on an object to an
# external entity. Here we link the subject's species to the NCBI Taxonomy entry for *Mus musculus*.
# The subject must be part of a file before a reference is added to it.
#
# An entity is identified by an ``entity_id`` and an ``entity_uri``. The ``entity_id`` is a compact
# URI (CURIE) of the form ``prefix:identifier`` whose prefix is registered with
# `bioregistry.io <https://bioregistry.io/>`_, such as ``NCBITaxon`` for the NCBI Taxonomy. The
# ``entity_uri`` is the persistent URL the CURIE resolves to, which you can look up at
# ``https://bioregistry.io/<entity_id>``.
nwbfile.external_resources.add_ref(
container=nwbfile.subject,
key=nwbfile.subject.species,
entity_id="NCBITaxon:10090",
entity_uri="http://purl.obolibrary.org/obo/NCBITaxon_10090",
)
###############################################################################
# References can also point to an attribute of an object, such as a column of a table. Here we record
# the brain region of a set of electrodes in the electrodes table and link the region to the
# corresponding structure in the
# `Allen Mouse Brain Atlas <https://atlas.brain-map.org/>`_. When the target is a column, pass the
# table as the ``container`` and the column name as the ``attribute``; HERD resolves the reference to
# the column object itself.
device = nwbfile.create_device(name="probe")
electrode_group = nwbfile.create_electrode_group(
name="shank0",
description="a shank of the recording probe",
location="VISp",
device=device,
)
for _ in range(4):
nwbfile.add_electrode(location="VISp", group=electrode_group)
nwbfile.external_resources.add_ref(
container=nwbfile.electrodes,
attribute="location",
key="VISp",
entity_id="MBA:385",
entity_uri="https://purl.brain-bican.org/ontology/mbao/MBA_385",
)
###############################################################################
# Inspect the HERD
# ----------------
# :py:meth:`~hdmf.common.resources.HERD.to_dataframe` flattens the interlinked tables into a single
# :py:class:`~pandas.DataFrame`, with one row per (object, key, entity) association.
nwbfile.external_resources.to_dataframe()
###############################################################################
# You can also view the individual tables. Each is a
# :py:class:`~hdmf.common.table.DynamicTable` and has its own ``to_dataframe`` method.
nwbfile.external_resources.keys.to_dataframe()
###############################################################################
nwbfile.external_resources.entities.to_dataframe()
###############################################################################
# :py:meth:`~hdmf.common.resources.HERD.get_object_type` returns all annotations for objects of a
# given type, for example every annotated :py:class:`~pynwb.file.Subject`.
nwbfile.external_resources.get_object_type(object_type="Subject")
###############################################################################
# Write and read the NWB file
# ---------------------------
# Writing the file stores the HERD inside it. Reading the file back makes the HERD available again
# through the ``external_resources`` field.
filename = "external_resources_tutorial.nwb"
with NWBHDF5IO(filename, mode="w") as io:
io.write(nwbfile)
read_io = NWBHDF5IO(filename, mode="r")
read_nwbfile = read_io.read()
read_herd = read_nwbfile.external_resources
###############################################################################
# Access the loaded data
# -----------------------
# The loaded HERD provides the same accessors as before. In a Jupyter notebook, displaying the HERD
# renders the flattened references as a table, and
# :py:meth:`~hdmf.common.resources.HERD.to_dataframe` returns that same table as a
# :py:class:`~pandas.DataFrame`. The individual tables give a more focused view.
read_herd.to_dataframe()
###############################################################################
# View the individual tables, for example:
read_herd.keys.to_dataframe()
###############################################################################
# :py:meth:`~hdmf.common.resources.HERD.get_object_entities` returns the entities annotated on a
# single object as a :py:class:`~pandas.DataFrame`. Here we view the species annotation stored for
# the subject:
read_herd.get_object_entities(container=read_nwbfile.subject)
###############################################################################
# Close the file once you are done reading from it.
read_io.close()
###############################################################################
# Alternative: store a HERD outside an NWB file
# ---------------------------------------------
# A HERD can also be saved independently of an NWB file as a zip archive of the underlying tables
# using :py:meth:`~hdmf.common.resources.HERD.to_zip`, and read back with
# :py:meth:`~hdmf.common.resources.HERD.from_zip`. This is useful when external resources span
# multiple files; see :ref:`external_resources_streaming` for an example that annotates many NWB
# files with a single HERD. For the full HERD API, see the
# `HDMF HERD tutorial <https://hdmf.readthedocs.io/en/stable/tutorials/plot_external_resources.html>`_.