Coder Social home page Coder Social logo

ndx-icephys-meta's People

Contributors

bendichter avatar oruebel avatar rly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ndx-icephys-meta's Issues

to_hierarchical_dataframe() DataFrames are too wide and long

Not sure if in your control but I mention this anyway.
to_hierarchical_dataframe() and to_denormalized_dataframe() generate very wide and long DataFrames. To save some space and facilitate visualization, the stimulus, response and electrode columns from intracellular_recordings should contain fewer details.

image

Define more descriptive names for the tables

We should use descriptive names for the tables that: 1) better communicate the intended use of the tables and 2) avoid overlap with terms used in the community that are ambiguous. Suggested names are:

  1. intracellular_stimuli (new, see #31)
  2. intracellular_responses (new, see #31)
  3. intracellular_recordings (remain as is)
  4. sweeps ---rename to---> simultaneous_recordings
  5. sweep_sequence ---rename to---> sequential_recordings
  6. runs ---rename to ---> repetitions
  7. conditions ---rename to---> experimental_conditions

Also rename the columns

to_hierarchical_dataframe() fails on tables that contain indexed columns

Tested on 279bb2e

MWE:

ir_index = nwbfile.add_intracellular_recording(electrode=electrode,
                                               stimulus=stimulus,
                                               response=response)

# (B) Add a list of sweeps to the sweeps table
sim_rec_table = nwbfile.get_icephys_simultaneous_recordings()
sim_rec_table.add_column('new_metadata',description = 'metadata as array', index= True)
sweep_index = nwbfile.add_icephys_simultaneous_recording(recordings=[ir_index,], new_metadata = [1,2,3])

nwbfile.icephys_simultaneous_recordings.to_hierarchical_dataframe()

because of

...
~/miniconda3/envs/nwb/lib/python3.7/site-packages/ndx_icephys_meta/icephys.py in to_hierarchical_dataframe(self, flat_column_index)
    192 
    193         # Construct the pandas dataframe with the hierarchical multi-index
--> 194         multi_index = pd.MultiIndex.from_tuples(index, names=index_names)
    195         out_df = pd.DataFrame(data=data, index=multi_index, columns=columns)
    196         return out_df

...

TypeError: unhashable type: 'list'

to_hierarchical_dataframe not working as intended

In here, syllable_start_time is part of the syllable table, and should have the same level as syllable_start_time, but instead has the same level as the phonemes table. This is a general problem that occurs for the last column of the second-to-last columns in a table hierarchy.

image (11)

Add Stimulus and Reponse tables

As part of the hackathon it was identified that we should add tables for intracellular_stimulus and intracellular_response, which in turn are referenced from the intracellular_recordings table. This is to avoid mixing metadata specific to stimulus and response in the same table.

DynamicTableGrouping type not necessary

We recently decided to make the Sweeps, SweepSequences, Runs, and Conditions types be of type DynamicTable instead of type DynamicTableGrouping in order to allow better naming of the column of DynamicTableRegion objects in each one.

Now the DynamicTableGrouping table has little use. I think anyone who wants to make a custom type for a custom hierarchy would also want to be able to customize the column name. We can provide guidance in a tutorial of how to do this without needing a DynamicTableGrouping type.

Therefore I propose removing the DynamicTableGrouping type.

Suggestion: Add super simple example to README

The notebooks are great and well documented; however, I have found it useful to have a barebones almost minimum working demonstration of the new data types. I suggest such an example is added to the bottom of the README. Something like the following:

from datetime import datetime
from dateutil.tz import tzlocal
import numpy as np
from pynwb.icephys import VoltageClampStimulusSeries, VoltageClampSeries
from pynwb import NWBHDF5IO
from ndx_icephys_meta.icephys import ICEphysFile

nwbfile = ICEphysFile(session_description='my first recording',
                      identifier='EXAMPLE_ID',
                      session_start_time=datetime.now(tzlocal()))

# Add a device
device = nwbfile.create_device(name='Heka ITC-1600')

# Add an intracellular electrode
electrode = nwbfile.create_ic_electrode(name="elec0",
                                        description='a mock intracellular electrode',
                                        device=device)

# Create an ic-ephys stimulus
stimulus = VoltageClampStimulusSeries(
            name="stimulus",
            data=[1, 2, 3, 4, 5],
            starting_time=123.6,
            rate=10e3,
            electrode=electrode,
            gain=0.02,
            sweep_number=15)

# Create an ic-response
response = VoltageClampSeries(
            name='response',
            data=[0.1, 0.2, 0.3, 0.4, 0.5],
            conversion=1e-12,
            resolution=np.nan,
            starting_time=123.6,
            rate=20e3,
            electrode=electrode,
            gain=0.02,
            capacitance_slow=100e-12,
            resistance_comp_correction=70.0,
            sweep_number=15)

# Add an intracellular recording to the file
nwbfile.add_intracellular_recording(electrode=electrode,
                                    stimulus=stimulus,
                                    response=response)

# Add a list of sweeps to the sweeps table
nwbfile.add_ic_sweep(recordings=[0])

# Add a list of sweep table indices as a sweep sequence
nwbfile.add_ic_sweep_sequence(sweeps=[0])

# Add a list of sweep sequence table indices as a run
nwbfile.add_ic_run(sweep_sequences=[0])

# Add a list of run table indices as a condition
nwbfile.add_ic_condition(runs=[0])

# Write our test file
testpath = "test_icephys_file.h5"
with NWBHDF5IO(testpath, 'w') as io:
    io.write(nwbfile)

# Read the data back in
with NWBHDF5IO(testpath, 'r') as io:
    infile = io.read()
    print(infile)

I think the above should run. The downside of including code in the README is that it is not testable and it is quite long, but I think it is helpful for an at-a-glance overview of the extension and its usage nevertheless

API: add_intracellular_recording

nwbfile.add_intracellular_recording(electrode=electrode,
                                    stimulus=stim,
                                    response=resp,
                                    id=sweep_number
                                    )
  • All arguments should be optional, of course skipping all does not make sense.

  • If both stimulus and response are PatchClampSeries they should also both
    reference the same electrode and sweep (if not raise an exception).

  • It should also raise an error if you mix stimulus and response in a intracellular recording in an erroneous way.

The valid combinations are:

if stimulus == timeseries and response == timeseries:
   pass
elif response == VoltageClampSeries:
   if stimulus != VoltageClampStimulusSeries:
     raise(...)
elif response == CurrentClampSeries:
   if stimulus != CurrentClampStimulusSeries:
     raise(...)
elif response == IZeroClampSeries:
  if stimulus is not None:
    raise(...)
else:
   raise(...)

AttributeError: type object 'HierarchicalDynamicTableMixin' has no attribute '_get_fields'

Using the latest hdmf-dev, this package will run into this error:

...
  File "c:\users\luiz\documents\github\nwb-jupyter-widgets\nwbwidgets\view.py", line 9, in <module>
    from ndx_icephys_meta.icephys import SweepSequences
  File "C:\Users\Luiz\Anaconda3\envs\env_allen\lib\site-packages\ndx_icephys_meta\__init__.py", line 32, in <module>
    from .icephys import ICEphysFile,  IntracellularRecordings, Sweeps, SweepSequences, Runs, Conditions # noqa E402, F401
  File "C:\Users\Luiz\Anaconda3\envs\env_allen\lib\site-packages\ndx_icephys_meta\icephys.py", line 307, in <module>
    class Sweeps(DynamicTable, HierarchicalDynamicTableMixin):
  File "c:\users\luiz\documents\github\hdmf\src\hdmf\utils.py", line 734, in __init__
    func(name, bases, classdict)
  File "c:\users\luiz\documents\github\hdmf\src\hdmf\container.py", line 122, in __gather_fields
    base_fields = bases[-1]._get_fields()  # tuple of field names from base class
AttributeError: type object 'HierarchicalDynamicTableMixin' has no attribute '_get_fields'

It looks like ndx-icephys-meta is performing an invalid operation with HierarchicalDynamicTableMixin. The problem only happens with the latest changes in hdmf, I guess this _get_fields was substituted by get_fields_conf

return id when custom id not given as argument

It would be nice if add_intracellular_recording, add_ic_sweep, add_ic_sweep_sequence, add_ic_run, when called without an id (or always), returned the automatically generated id that can be used to populate the ic_sweeps, ic_sweep_sequences, ic_runs, ic_conditions, respectively.

to_denormalized_dataframe() creates weird MultiIndex column ('i', 'd')

Tested on branch add/spec_resp_elec_tables: 607e1ae

Unexpected column i,d appears as a column of the DataFrame generated with to_denormalized_dataframe()

image

How to reproduce: run the example code including line

sweep_index = nwbfile.add_icephys_simultaneous_recording(recordings=[ir_index, ])

then compare

nwbfile.get_icephys_meta_parent_table().to_hierarchical_dataframe().columns
nwbfile.get_icephys_meta_parent_table().to_denormalized_dataframe().columns

Latest tests fail

Using PyNWB 1.4.0 and HDMF 2.2.0, tests fail:

============================================================== short test summary info ============================================================== FAILED src/pynwb/ndx_icephys_meta/test/test_aligned_dynamic_table_container.py::TestAlignedDynamicTableContainer::test_to_dataframe - AttributeErro...

FAILED src/pynwb/ndx_icephys_meta/test/test_hierarchical_dynamic_table_mixin.py::TestHierarchicalDynamicTableMixin::test_to_denormalized_dataframe
FAILED src/pynwb/ndx_icephys_meta/test/test_hierarchical_dynamic_table_mixin.py::TestHierarchicalDynamicTableMixin::test_to_denormalized_dataframe_flat_column_index
FAILED src/pynwb/ndx_icephys_meta/test/test_hierarchical_dynamic_table_mixin.py::TestHierarchicalDynamicTableMixin::test_to_hierarchical_dataframe
FAILED src/pynwb/ndx_icephys_meta/test/test_hierarchical_dynamic_table_mixin.py::TestHierarchicalDynamicTableMixin::test_to_hierarchical_dataframe_flat_column_index
FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row - ValueError: Shape of passed values is (3,...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row_no_response - ValueError: Shape of passed v...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row_no_stimulus - ValueError: Shape of passed v...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_round_trip_container_no_data - AssertionError: Data...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::ICEphysFileTests::test_add_icephys_meta_full_roundtrip - ValueError: Shape of passed values...

Looks related to conversion to Pandas data frames.

Rename table types to end in Table

@bendichter and I would prefer the convention of having subtypes of DynamicTable end in "Table", similar to how we name descendants of TimeSeries with "Series". See discussion here: NeurodataWithoutBorders/nwb-schema#337 (comment)

To conform with this convention, I suggest changing: IntracellularRecordings, SweepSequences, Runs, and Conditions to IntracellularRecordingsTable, SweepSequencesTable, RunsTable, and ConditionsTable. The 'name' can remain as is, without the 'Table' suffix.

convenience function to get the highest level of the hierarchy

Some experiments might not have a ic_conditions or a ic_runs table. So if one needs to retrieve the whole hierarchy at once (for example with ic_conditions.to_denormalized_dataframe()) they should be able to do it without querying to see if these tables exist in the first place.

performance issue when indexing table

It seems the auto-dereferencing dynamic tables code is struggling with these nested tables. Test data is here. On my computer, after setting up the file read

from pynwb import NWBHDF5IO

fpath = '001_140327B01_EXP_ndx.nwb'
io = NWBHDF5IO(fpath,'r')
nwbfile = io.read()

this line:

nwbfile.ic_conditions[0]

took 57 seconds to create a 1x1 pandas DataFrame. Is this how the API is intended to be used? I think this is due to the fact that indexing the downstream tables now reads all of that data into memory while creating a pandas DataFrame.

intracellular_recordings: Should store plain TimeSeries

(The current SweepTable implementation suffers from the same issue, see NeurodataWithoutBorders/pynwb#1116).

In ICEphys it is customary to have AD/DA channels which are not associated to an electrode. In MIES and NWBv1/2 we store this channel data as plain timeseries.

And the intracellular_recordings table should therefore also allow to hold plain TimeSeries without an attached electrode.

adding response with no corresponding stimulus

If there is a response, but no stimulus, like in the case of IZeroClamp, how are you supposed to add an entry to the intracellular recordings table? Are rows allows to be added that are missing a stimulus? I tried this and was not able to get it to work. All of the tests that add rows to that table provide both stimulus and response. If this is an intended use-case it should be tested.

id in ic_sweeps not referencing the id in intracellular_recordings

Adding an intracellular recording with a given id and then a sweep with the same id works. But generating the ic_sweeps table raises a IndexError: list index out of range error.

Note though that, if a sweep with index 0 is added, generating the table works just fine.

MWE:

nwbfile.add_intracellular_recording(electrode=electrode,
                                    stimulus=stimulus,
                                    response=response,
                                    id=10)
nwbfile.add_ic_sweep(recordings=[10], id=12) # replace 10 with 0 to fix
nwbfile.ic_sweeps.to_dataframe()

error when add_intracellular_recording called only with electrode and stimulus

In section 3.1 in the icephys tutorial adding an intracellular recording with just a stimulus or a response doesn't seem to work as intended:

A recording may optionally also consist of just an electrode and stimulus or electrode and response, but at least one of stimulus or response are required.

MWE:

rowindex = nwbfile.add_intracellular_recording(electrode=electrode,
                                               stimulus=stimulus,
                                               id=10)

error

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-9493f38a37ac> in <module>
      1 rowindex = nwbfile.add_intracellular_recording(electrode=electrode,
      2                                                stimulus=stimulus,
----> 3                                                id=10)

~/miniconda3/envs/nwb_latest/lib/python3.7/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
    451 
    452             if is_method:
--> 453                 return func(args[0], **parsed['args'])
    454             else:
    455                 return func(**parsed['args'])

~/miniconda3/envs/nwb_latest/lib/python3.7/site-packages/ndx_icephys_meta/icephys.py in add_intracellular_recording(self, **kwargs)
    679         if stimulus.name not in self.stimulus:
    680             self.add_stimulus(stimulus, use_sweep_table=False)
--> 681         if response.name not in self.acquisition:
    682             self.add_acquisition(response, use_sweep_table=False)
    683         if electrode.name not in self.ic_electrodes:

AttributeError: 'NoneType' object has no attribute 'name'

Generalize Runs/Conditions tables

It would be nicer to be able to define the meaning of tables which index Sweeps/SweepSequence tables on the go and don't have them hard coded.

Use case:

  • In MIES we have two different sweep sequences (repeated acquisition (RA) cycles and stimset cycle IDs). None of them fits into Runs.
  • In addition we also store quality control results (true/false/not done) per sweep and per RA cycle. It would therefore be nice to have one table for storing all quality control results.

Profile read/write performance of the extension

ICEphysFileTests.test_add_icephys_meta_full_roundtrip has code to add profiling for writing and reading a file that can be enabled by removing the corresponding line comments. The read performance seems reasonable, but it appears that for write HDMF currently may do a large number of recursions, that slow down performance. It would be good investigate why this occurs. It is unclear whether this is specific to the extension (maybe something with the ObjectMappers) or whether this is a general issue in HDMF.

         42486451 function calls (40629931 primitive calls) in 21.592 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 630747/1    1.722    0.000   21.592   21.592 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:459(func_call)
        1    0.000    0.000   21.592   21.592 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:267(write)
        1    0.000    0.000   19.730   19.730 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:362(call_docval_func)
        1    0.000    0.000   19.730   19.730 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/io.py:38(write)
  29995/1    0.124    0.000   19.611   19.611 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:136(build)
  29995/1    0.277    0.000   19.611   19.611 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:725(build)
  29995/1    0.231    0.000   19.595   19.595 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:546(build)
   6570/1    0.018    0.000   19.592   19.592 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:767(__add_groups)
 41833/22    0.219    0.000   19.584    0.890 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:807(__add_containers)
  6570/38    0.099    0.000   19.559    0.515 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:742(__add_datasets)
30052/130    0.178    0.000   19.492    0.150 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:696(__add_attributes)
   630747    5.395    0.000   12.060    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:124(__parse_args)
1562007/1348213    1.171    0.000    2.599    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:29(__type_okay)
  6962989    1.339    0.000    2.591    0.000 {built-in method builtins.isinstance}
   630747    0.930    0.000  a  2.570    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/collections/__init__.py:550(__init__)
    34868    0.072    0.000    2.194    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/io/table.py:24(get_attr_value)
    29995    0.042    0.000    2.105    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:237(get_builder_name)
    53837    0.157    0.000    1.865    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:480(get_attr_value)
        3    0.000    0.000    1.848    0.616 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:172(__convert_namespace)
       73    0.001    0.000    1.829    0.025 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:199(__copy_spec)
   628/73    0.005    0.000    1.794    0.025 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:76(build_spec)
   146/62    0.001    0.000    1.765    0.028 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1210(build_const_args)
   363/64    0.001    0.000    1.762    0.028 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:95(build_const_args)
692990/37781    0.738    0.000    1.729    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:132(deepcopy)
      378    0.001    0.000    1.665    0.004 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:516(build_const_args)
      597    0.001    0.000    1.653    0.003 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:136(build_const_args)
      628    0.008    0.000    1.653    0.003 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:71(build_const_args)
93441/921    0.189    0.000    1.639    0.002 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:268(_reconstruct)
59183/767    0.126    0.000    1.630    0.002 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:236(_deepcopy_dict)
   630747    0.656    0.000    1.574    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/collections/__init__.py:619(update)
    29995    0.065    0.000    1.516    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:772(get_builder_name)
   720095    0.829    0.000    1.401    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:565(getargs)
  1976816    0.457    0.000    1.252    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/abc.py:137(__instancecheck__)
    17844    0.059    0.000    1.202    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/core.py:58(get_attr_value)
      232    0.001    0.000    0.970    0.004 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:740(build_const_args)
    34289    0.074    0.000    0.912    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:225(set_attribute)
  1976816    0.793    0.000    0.795    0.000 {built-in method _abc._abc_instancecheck}
  6561276    0.657    0.000    0.689    0.000 {method 'get' of 'dict' objects}
5734789/5725142    0.590    0.000    0.596    0.000 {built-in method builtins.len}
112429/111821    0.062    0.000    0.548    0.000 {built-in method builtins.any}
   310844    0.120    0.000    0.495    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:66(<genexpr>)
   123426    0.185    0.000    0.479    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:125(set_attribute)
40383/30689    0.123    0.000    0.449    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:173(convert_dtype)
    59990    0.102    0.000    0.345    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:673(get_map)
   387176    0.245    0.000    0.326    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:576(<listcomp>)
      122    0.000    0.000    0.318    0.003 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:521(<listcomp>)
   186284    0.038    0.000    0.306    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:273(<genexpr>)
      205    0.000    0.000    0.295    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:267(build_const_args)
86459/79268    0.091    0.000    0.278    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:210(_deepcopy_list)
40393/40383    0.120    0.000    0.250    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:223(__check_edgecases)
    60104    0.059    0.000    0.243    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:472(get_attribute)
   630747    0.238    0.000    0.238    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:158(<listcomp>)
  1978960    0.232    0.000    0.232    0.000 {built-in method builtins.next}
   630747    0.231    0.000    0.231    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:157(<listcomp>)
   630747    0.231    0.000    0.231    0.000 {built-in method _collections._count_elements}
    47214    0.084    0.000    0.216    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:503(__convert_value)
   343010    0.112    0.000    0.199    0.000 {built-in method builtins.getattr}
    29995    0.066    0.000    0.159    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:566(__type_key)
    29995    0.075    0.000    0.156    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:1007(get_builder_name)
    22533    0.030    0.000    0.137    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:285(set_dataset)
   336453    0.099    0.000    0.132    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:237(dtype)
   238784    0.094    0.000    0.132    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:252(_keep_alive)
  1262452    0.132    0.000    0.132    0.000 {method 'keys' of 'dict' objects}
        1    0.000    0.000    0.119    0.119 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:536(write_builder)
     21/5    0.001    0.000    0.107    0.021 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:687(write_group)
  1262569    0.104    0.000    0.104    0.000 {built-in method builtins.id}
   630747    0.099    0.000    0.099    0.000 {built-in method builtins.iter}
    89985    0.077    0.000    0.095    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:656(get_container_cls_dt)
    58398    0.024    0.000    0.093    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:910(__check_ref_resolver)
    27229    0.068    0.000    0.091    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:248(__set_builder)
   690455    0.085    0.000    0.085    0.000 {method 'items' of 'dict' objects}
       39    0.001    0.000    0.079    0.002 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:757(write_dataset)
    56283    0.044    0.000    0.076    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:55(getter)
    93441    0.076    0.000    0.076    0.000 {method '__reduce_ex__' of 'object' objects}
    53837    0.026    0.000    0.072    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:466(__get_override_attr)
    52572    0.050    0.000    0.069    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:465(data_type_inc)
   106235    0.051    0.000    0.067    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:119(name)
   303947    0.059    0.000    0.059    0.000 {method 'pop' of 'dict' objects}
    29995    0.027    0.000    0.058    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:651(get_container_ns_dt)
    57395    0.049    0.000    0.057    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:423(attributes)
       56    0.002    0.000    0.057    0.001 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:71(create_dataset)
    72234    0.031    0.000    0.055    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:200(parent)
    38676    0.036    0.000    0.049    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:470(data_type_def)
       21    0.001    0.000    0.048    0.002 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:1038(__list_fill__)
    29995    0.026    0.000    0.048    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:624(<dictcomp>)
     6530    0.017    0.000    0.046    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/io/table.py:18(attr_columns)
       61    0.001    0.000    0.039    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:648(set_attributes)
      220    0.001    0.000    0.038    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:133(__init__)
      748    0.035    0.000    0.037    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:114(_e)
       59    0.001    0.000    0.037    0.001 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:342(__setitem__)
      154    0.003    0.000    0.036    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/attrs.py:87(__setitem__)
   413388    0.036    0.000    0.036    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:190(_deepcopy_atomic)
      143    0.000    0.000    0.035    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:145(__init__)
      259    0.001    0.000    0.033    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:219(__get_new_specs)
        3    0.000    0.000    0.032    0.011 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:666(__get_ref_builder)
      154    0.018    0.000    0.032    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/attrs.py:102(create)
    60684    0.022    0.000    0.032    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:145(__hash__)
    27802    0.031    0.000    0.031    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:56(<listcomp>)
     4684    0.006    0.000    0.028    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:308(set_group)
      146    0.002    0.000    0.027    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:814(__init__)
   292747    0.027    0.000    0.027    0.000 {method 'append' of 'list' objects}
      232    0.002    0.000    0.025    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:621(__init__)
       17    0.000    0.000    0.024    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:329(__init__)
    58164    0.024    0.000    0.024    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:142(fields)
       17    0.000    0.000    0.024    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:410(__map_spec)
      378    0.003    0.000    0.022    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:300(__init__)
   150956    0.022    0.000    0.022    0.000 {function GroupBuilder.__getitem__ at 0x11c294e60}
    39678    0.016    0.000    0.020    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:242(value)
      273    0.001    0.000    0.019    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:450(map_spec)
     4665    0.005    0.000    0.019    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/table.py:347(__len__)
    57163    0.019    0.000    0.019    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:152(modified)
    60033    0.018    0.000    0.018    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:342(spec)
    29995    0.018    0.000    0.018    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:146(object_id)
    30028    0.012    0.000    0.017    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:176(__conthash__)
    10656    0.010    0.000    0.016    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:410(__bool__)
    40783    0.013    0.000    0.016    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:843(<genexpr>)
    32238    0.013    0.000    0.016    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:62(_unicode)
        1    0.000    0.000    0.015    0.015 /Users/oruebel/Devel/nwb/icephys_extensions/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/io/icephys.py:19(__init__)
        1    0.000    0.000    0.015    0.015 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/file.py:11(__init__)
    19897    0.011    0.000    0.014    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copyreg.py:87(__newobj__)
    46930    0.014    0.000    0.014    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:120(name)
6536/6535    0.003    0.000    0.013    0.000 {built-in method builtins.all}
       56    0.011    0.000    0.013    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:57(make_new_dset)
   113201    0.013    0.000    0.013    0.000 {built-in method builtins.issubclass}
      421    0.001    0.000    0.013    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:948(is_inherited_spec)
        3    0.001    0.000    0.013    0.004 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:175(export)
6551/6539    0.002    0.000    0.013    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:735(__add_links)
    11505    0.004    0.000    0.011    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/io/table.py:20(<genexpr>)
    53162    0.011    0.000    0.011    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:77(inc_key)
    22553    0.011    0.000    0.011    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:485(dtype)
     2795    0.003    0.000    0.010    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:643(__is_reftype)
    27405    0.010    0.000    0.010    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:56(name)
       20    0.000    0.000    0.010    0.001 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:174(require_dataset)
       73    0.000    0.000    0.010    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:128(add_spec)
       17    0.000    0.000    0.010    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5_utils.py:273(__write)
    18069    0.007    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:262(shape)
      205    0.001    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:206(__init__)
        8    0.000    0.000    0.009    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/io/table.py:11(__init__)
     6807    0.008    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1083(groups)
     6807    0.008    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1088(datasets)
        2    0.000    0.000    0.009    0.005 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/base.py:26(__init__)
    27274    0.009    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:73(parent)
    30008    0.009    0.000    0.009    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:72(type_key)
       14    0.000    0.000    0.008    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5_utils.py:279(write_spec)
    39136    0.008    0.000    0.008    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:82(def_key)
    29995    0.008    0.000    0.008    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:433(id_key)
        1    0.001    0.001    0.008    0.008 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:553(__add_refs)
    22944    0.008    0.000    0.008    0.000 {built-in method builtins.hasattr}
       25    0.007    0.000    0.008    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:52(create_group)
      366    0.000    0.000    0.008    0.000 <__array_function__ internals>:2(product)
       24    0.003    0.000    0.008    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:584(__setitem__)
    16341    0.006    0.000    0.008    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:257(dims)
  732/366    0.000    0.000    0.007    0.000 {built-in method numpy.core._multiarray_umath.implement_array_function}
    19311    0.007    0.000    0.007    0.000 {method 'update' of 'dict' objects}
     9640    0.006    0.000    0.007    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:413(__len__)
      366    0.000    0.000    0.007    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/fromnumeric.py:3524(product)
     1555    0.004    0.000    0.007    0.000 /Users/oruebel/Devel/nwb/icephys_extensions/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/icephys.py:281(categories)
     6642    0.006    0.000    0.007    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1093(links)
      366    0.000    0.000    0.007    0.000 <__array_function__ internals>:2(prod)
        1    0.000    0.000    0.007    0.007 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/icephys.py:16(__init__)
       15    0.000    0.000    0.007    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:921(__scalar_fill__)
      254    0.001    0.000    0.006    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:983(is_overridden_spec)
      366    0.001    0.000    0.006    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/fromnumeric.py:2792(prod)
    23444    0.006    0.000    0.006    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:268(dataset_spec_cls)
     2793    0.002    0.000    0.006    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:529(__init__)
      366    0.001    0.000    0.006    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/fromnumeric.py:73(_wrapreduction)
   157/73    0.001    0.000    0.006    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/catalog.py:79(auto_register)
       17    0.000    0.000    0.005    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:393(get_attr_names)
       63    0.004    0.000    0.005    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:395(__init__)
      104    0.000    0.000    0.005    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:305(get_spec)
    30114    0.005    0.000    0.005    0.000 {method 'values' of 'dict' objects}
  188/114    0.001    0.000    0.005    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:369(__get_fields)
       19    0.000    0.000    0.004    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:265(add_dataset)
    10683    0.004    0.000    0.004    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:388(data)
      430    0.001    0.000    0.004    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copy.py:66(copy)
      366    0.004    0.000    0.004    0.000 {method 'reduce' of 'numpy.ufunc' objects}
      364    0.004    0.000    0.004    0.000 {built-in method h5py.h5t.py_create}
       39    0.000    0.000    0.004    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:436(__init__)
    19897    0.003    0.000    0.003    0.000 {built-in method __new__ of type object at 0x10ceeb568}
        2    0.000    0.000    0.003    0.002 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:825(_filler)
       71    0.000    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:95(__init__)
     1860    0.002    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/common/table.py:694(table)
      363    0.002    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:107(_translate_kwargs)
      597    0.001    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:99(__init__)
        8    0.000    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:683(_filler)
       32    0.000    0.000    0.003    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:148(__init__)
 1274/114    0.000    0.000    0.003    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/abc.py:141(__subclasscheck__)
 1274/114    0.002    0.000    0.003    0.000 {built-in method _abc._abc_subclasscheck}
      221    0.001    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1138(set_dataset)
     6551    0.002    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:273(group_spec_cls)
      104    0.000    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:146(get_spec)
      154    0.000    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/uuid.py:757(uuid4)
       17    0.000    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5_utils.py:266(stringify)
       17    0.000    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/json/__init__.py:183(dumps)
       98    0.000    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:368(is_inherited_spec)
      364    0.000    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/_asarray.py:16(asarray)
       17    0.000    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/json/encoder.py:182(encode)
       17    0.002    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/json/encoder.py:204(iterencode)
      372    0.002    0.000    0.002    0.000 {built-in method numpy.array}
       34    0.000    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:352(convert_dt_name)
      592    0.001    0.000    0.002    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:88(__is_int)
       24    0.000    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:27(select)
       69    0.001    0.000    0.002    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:283(shape)
      273    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:435(map_const_arg)
       75    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:380(is_overridden_spec)
      149    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:267(attrs)
      400    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:579(popargs)
      273    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:415(map_attr)
        1    0.000    0.000    0.001    0.001 /Users/oruebel/Devel/nwb/icephys_extensions/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/io/icephys.py:36(__init__)
        1    0.000    0.000    0.001    0.001 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:886(_filler)
       68    0.000    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/re.py:185(sub)
        3    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5_utils.py:282(write_namespace)
       20    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:253(__getitem__)
      994    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:306(get_docval)
       11    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:1079(__get_ref)
       84    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:124(get_lcpl)
       84    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1106(set_group)
      186    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:48(guess_dtype)
       48    0.000    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:272(broadcast)
      100    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:302(dtype)
      205    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:488(set_attribute)
      137    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1041(__add_data_type_inc)
      154    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/uuid.py:121(__init__)
       24    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:250(__getitem__)
       34    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:120(__resolve_dtype)
      154    0.001    0.000    0.001    0.000 {built-in method posix.urandom}
     2084    0.001    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:103(__is_bool)
       56    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/filters.py:109(fill_dcpl)
       68    0.000    0.000    0.001    0.000 {method 'sub' of 're.Pattern' objects}
      395    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:590(<listcomp>)
       24    0.001    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:410(__contains__)
       68    0.000    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/re.py:271(_compile)
       24    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:154(get_neurodata_type)
       83    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:16(__init__)
       86    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/catalog.py:29(register_spec)
      290    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:894(is_inherited_dataset)
        4    0.000    0.000    0.001    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:238(require_group)
       14    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:762(__init__)
     1556    0.001    0.000    0.001    0.000 {method 'keys' of 'collections.OrderedDict' objects}
       16    0.000    0.000    0.001    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:585(build_const_args)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:759(compile)
       54    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/_dtype.py:319(_name_get)
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:195(__get_name)
       12    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:510(__init__)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:730(write_link)
      363    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:113(<listcomp>)
      278    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:416(parent)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:244(__init__)
       63    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/filters.py:249(get_filters)
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:137(add_source)
       73    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/posixpath.py:121(splitext)
      190    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:1009(_handle_fromlist)
     1248    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:89(<genexpr>)
     1555    0.000    0.000    0.000    0.000 {method 'values' of 'collections.OrderedDict' objects}
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:435(_handle_simple)
      752    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:147(__init__)
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:225(add_spec)
      366    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/fromnumeric.py:74(<dictcomp>)
      104    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/catalog.py:49(get_spec)
      155    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/attrs.py:51(__init__)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:167(build_namespace)
      133    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:903(is_overridden_dataset)
       54    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/numerictypes.py:365(issubdtype)
      693    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:241(id)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:919(parse)
      779    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:449(inc_key)
      524    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:129(parent)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/files.py:217(attrs)
      6/2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:417(_parse_sub)
    49/43    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:1108(__is_ref)
       20    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:338(fmt_docval_args)
      475    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:712(dtype)
      611    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:124(parent)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:598(_code)
       33    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:165(prebuilt)
      6/2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:475(_parse)
       98    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:392(is_inherited_attribute)
      154    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/uuid.py:318(hex)
       73    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/genericpath.py:117(_splitext)
      788    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:457(def_key)
      345    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:475(quantity)
      308    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:717(shape)
       75    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:402(is_overridden_attribute)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:104(__init__)
       68    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/re.py:307(_subx)
       14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:720(__get_path)
       54    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:510(get_attribute)
       18    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:633(get_data_shape)
       36    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/re.py:313(filter)
       41    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:36(__init__)
       33    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1156(get_dataset)
      7/2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:71(_compile)
       41    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1020(is_inherited_type)
       40    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1075(get_data_type)
       16    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:92(__is_float)
      108    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/numerictypes.py:293(issubclass_)
      732    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/numpy/core/fromnumeric.py:2787(_prod_dispatcher)
       58    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:912(is_inherited_group)
       20    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:628(__check_dset_spec)
      278    0.000    0.000    0.000    0.000 {method 'rpartition' of 'str' objects}
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:412(_expand_ellipsis)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/dateutil/tz/tz.py:212(utcoffset)
       36    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:1036(expand_template)
      154    0.000    0.000    0.000    0.000 {built-in method from_bytes}
       64    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:91(neurodata_type_def)
       25    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1124(get_group)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:216(file)
      670    0.000    0.000    0.000    0.000 {method 'setdefault' of 'dict' objects}
       17    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:443(unmap)
       64    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:87(neurodata_type_inc)
    36/18    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:648(__get_shape_helper)
       96    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:183(__to_list)
      104    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:274(__init__)
       16    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:535(__init__)
    25/19    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:356(is_empty)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/dateutil/tz/tz.py:256(_isdst)
       79    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:215(datasets)
       12    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:324(set_link)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:168(nselect)
       50    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:412(is_many)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/_collections_abc.py:657(get)
       14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1170(set_link)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/re.py:297(_compile_repl)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/attrs.py:56(__getitem__)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/dateutil/tz/tz.py:252(_naive_is_dst)
       61    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:120(attributes)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:951(parse_template)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/files.py:307(__init__)
      257    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:114(doc)
       12    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:247(ref)
       50    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:210(groups)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:536(_compile_info)
        2    0.000    0.000    0.000    0.000 {method 'isoformat' of 'datetime.datetime' objects}
      146    0.000    0.000    0.000    0.000 {method 'rfind' of 'str' objects}
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:481(_translate_slice)
       34    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:188(source)
       14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:627(__resolve_dtype__)
      212    0.000    0.000    0.000    0.000 {method 'pop' of 'list' objects}
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/files.py:226(filename)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:276(_optimize_charset)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:41(__init__)
       28    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:921(is_overridden_group)
       63    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:50(written)
      154    0.000    0.000    0.000    0.000 {method 'count' of 'list' objects}
       15    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:164(__init__)
       75    0.000    0.000    0.000    0.000 {method 'setdefault' of 'collections.OrderedDict' objects}
       99    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:707(dims)
    20/14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:637(__resolve_dtype_helper__)
       63    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:45(written)
       14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:346(get_types)
       45    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:233(__next)
       32    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:254(get)
       52    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/utils.py:100(<genexpr>)
       22    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:220(links)
       17    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/json/encoder.py:104(__init__)
       80    0.000    0.000    0.000    0.000 {built-in method posix.fspath}
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:344(default_name)
       17    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:930(is_inherited_link)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/dateutil/tz/tz.py:1796(_datetime_to_timestamp)
       37    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:573(__exhaust_dcis)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/compat.py:119(filename_decode)
       33    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:194(container_source)
      129    0.000    0.000    0.000    0.000 {method 'copy' of 'dict' objects}
       73    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:428(linkable)
       41    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:78(parent)
       39    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:464(data)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/base.py:195(data)
       81    0.000    0.000    0.000    0.000 {built-in method h5py.h5.get_config}
       24    0.000    0.000    0.000    0.000 {built-in method builtins.sum}
       16    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:558(assertValidDtype)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:595(<genexpr>)
       25    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:164(__getitem__)
     11/6    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:174(getwidth)
        6    0.000    0.000    0.000    0.000 {built-in method time.localtime}
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:96(closegroup)
       74    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/spec.py:150(dataset_spec_cls)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/os.py:815(fsdecode)
        8    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:659(<listcomp>)
       33    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/container.py:187(container_source)
       11    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:1117(__queue_ref)
       24    0.000    0.000    0.000    0.000 {method 'indices' of 'slice' objects}
       72    0.000    0.000    0.000    0.000 {method 'group' of 're.Match' objects}
       47    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/dataset.py:596(<genexpr>)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:295(get_namespace)
      4/2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:461(_get_literal_prefix)
       34    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:61(source)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:249(match)
        6    0.000    0.000    0.000    0.000 {method 'replace' of 'datetime.datetime' objects}
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/dateutil/tz/tz.py:234(is_ambiguous)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/base.py:49(timestamps_attr)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/enum.py:836(__and__)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:646(<listcomp>)
       84    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:108(_lcpl)
      144    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:163(shape)
       48    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:267(<genexpr>)
       64    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1201(link_spec_cls)
    12/10    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:365(<genexpr>)
       33    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:179(__bldrhash__)
      105    0.000    0.000    0.000    0.000 {method 'extend' of 'list' objects}
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:224(__init__)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:581(<listcomp>)
       48    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:309(<genexpr>)
       48    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/filters.py:124(rq_tuple)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5_utils.py:262(__init__)
       79    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/base.py:102(_lapl)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:960(addgroup)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:249(_compile_charset)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:939(is_overridden_link)
        8    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/hdf5/h5tools.py:672(_make_attr_ref_filler)
       15    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:286(tell)
       19    0.000    0.000    0.000    0.000 {method 'find' of 'bytearray' objects}
       34    0.000    0.000    0.000    0.000 {method 'lower' of 'str' objects}
        9    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:160(__len__)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/catalog.py:10(__init__)
       34    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:48(<genexpr>)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:171(<listcomp>)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/objectmapper.py:74(_ascii)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/enum.py:284(__call__)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:84(opengroup)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/filters.py:86(_normalize_external)
       11    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:534(builder)
        9    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:172(append)
       12    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:81(groups)
       14    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:553(dtype)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/write.py:169(include_namespace)
       16    0.000    0.000    0.000    0.000 {built-in method builtins.min}
       11    0.000    0.000    0.000    0.000 {method 'popleft' of 'collections.deque' objects}
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/copyreg.py:96(_slotnames)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:415(<genexpr>)
       24    0.000    0.000    0.000    0.000 {method 'reverse' of 'list' objects}
        2    0.000    0.000    0.000    0.000 {built-in method _sre.compile}
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:408(_uniq)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/enum.py:526(__new__)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:492(_get_charset_prefix)
        6    0.000    0.000    0.000    0.000 {method 'total_seconds' of 'datetime.timedelta' objects}
        6    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:95(version)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/base.py:206(timestamps)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/file.py:174(experimenter_obj_attr)
        5    0.000    0.000    0.000    0.000 {method 'decode' of 'bytes' objects}
        8    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:65(_combine_flags)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:603(__init__)
       24    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/selections.py:301(<listcomp>)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:115(doc)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:262(namespaces)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:183(is_region)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/file.py:121(scratch_containers)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/file.py:112(scratch_datas)
       23    0.000    0.000    0.000    0.000 {method 'items' of 'collections.OrderedDict' objects}
       10    0.000    0.000    0.000    0.000 {built-in method builtins.ord}
       11    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/_collections_abc.py:252(__subclasshook__)
        7    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:111(__init__)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:903(fix_flags)
        6    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:453(_get_iscased)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:595(isstring)
        2    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:76(__init__)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/compat.py:103(filename_encode)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:80(full_name)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:110(name)
        5    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:731(dtype_spec_cls)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/builders.py:521(builder)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:92(namespace_catalog)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/pynwb/src/pynwb/io/file.py:192(publication_obj_attr)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/_collections_abc.py:72(_check_methods)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_compile.py:423(_simple)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:90(author)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/icephys_extensions/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/icephys.py:969(ic_filtering)
        2    0.000    0.000    0.000    0.000 {method 'copy' of 'list' objects}
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/os.py:803(fsencode)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/_collections_abc.py:392(__subclasshook__)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/site-packages/h5py/_hl/group.py:598(path)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:72(types_key)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:85(contact)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/namespace.py:119(schema)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:178(reftype)
        4    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:441(type_key)
        3    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/spec/spec.py:1192(dataset_spec_cls)
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/build/manager.py:310(namespace_catalog)
        1    0.000    0.000    0.000    0.000 {method 'get' of 'mappingproxy' objects}
        1    0.000    0.000    0.000    0.000 /Users/oruebel/anaconda3/envs/py4nwb/lib/python3.7/sre_parse.py:168(__setitem__)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 /Users/oruebel/Devel/nwb/hdmf/src/hdmf/backends/io.py:19(manager)

CurrentClampStimulusSeries and VoltageClampSeries combined in add_intracellular_recording

In the notebook provided as example at https://github.com/oruebel/ndx-icephys-meta/blob/master/src/pynwb/examples/icephys_meta_to_pandas.ipynb, CurrentClampStimulusSeries and VoltageClampSeries are added as stimulus and response in the intracellular_recordings table (Section 3. Construct our Intracellular Electrophysiolgy Metadata tables, paragraph Add intracelluar recordings).

Not only this is not ideal for a tutorial, because it's creating confusion, but add_intracellular_recording should actually raise an exception if incompatible classes are stored together. (I think they are incompatible...)

Extract complex VectorData to its own type: TimeSeriesRef

The IntracellularStimuliTable and IntracellularResponsesTable types both have a dataset:

- name: stimulus
  neurodata_type_inc: VectorData
  dtype:
  - name: idx_start
    dtype: int32
    doc: Start index into the TimeSeries 'data' and 'timestamp' datasets of the
      referenced TimeSeries. The first dimension of those arrays is always time.
  - name: count
    dtype: int32
    doc: Number of data samples available in this time series, during this epoch
  - name: timeseries
    dtype:
      target_type: TimeSeries
      reftype: object
    doc: The TimeSeries that this index applies to
  doc: Column storing the reference to the recorded stimulus for the recording
    (rows)

Aside from the name and docstring, this is the same as the definition for the 'timeseries' column of the TimeIntervals table. Since this exact structure would now be used three times in the schema, I think this should be its own type named something like TimeSeriesRef or TimeSeriesColumn and included in the table, e.g.:

- name: stimulus
  neurodata_type_inc: TimeSeriesRef
  doc: Column storing the reference to the recorded stimulus for the recording
    (rows)

Add ic prefix to ICEphysFile functions and properties

In the ICEphysFile type the properties and functions specific to the icephys metadata structure should include the ic prefix to prevent name collisions later on and to make the context clear. E.g., ICEphysFile.conditions should be renamed to ICEphysFile.ic_conditions, ICEphysFile.add_condition to ICEphysFile.add_ic_condition etc. This will require changes to the fields, functions and init function of ICEphysFile as well as update of ObjectMapper and tests. Per discussion with @rly

Tests fail

With the dev branch of PyNWB and HDMF, I get the following test errors:

============================================================== short test summary info ============================================================== FAILED src/pynwb/ndx_icephys_meta/test/test_aligned_dynamic_table_container.py::TestAlignedDynamicTableContainer::test_round_trip_container - Excep...

FAILED src/pynwb/ndx_icephys_meta/test/test_aligned_dynamic_table_container.py::TestAlignedDynamicTableContainer::test_to_dataframe - AttributeErro...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row - Exception: Container 'intracellular_recor...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row_no_response - Exception: Container 'intrace...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_add_row_no_stimulus - Exception: Container 'intrace...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_basic_write - Exception: Container 'intracellular_r...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_round_trip_container_no_data - Exception: Container...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::IntracellularRecordingsTableTests::test_write_with_stimulus_template - Exception: Container...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::SimultaneousRecordingsTableTests::test_basic_write - Exception: Container 'intracellular_re...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::SequentialRecordingsTableTests::test_basic_write - Exception: Container 'intracellular_reco...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::RepetitionsTableTests::test_basic_write - Exception: Container 'intracellular_recordings' (...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::ExperimentalConditionsTableTests::test_basic_write - Exception: Container 'intracellular_re...

FAILED src/pynwb/ndx_icephys_meta/test/test_icephys.py::ICEphysFileTests::test_add_icephys_meta_full_roundtrip - Exception: Container 'intracellula...

===================================================== 13 failed, 58 passed, 1 skipped in 28.71s =====================================================

There are several different errors:
ValueError: Must supply 'columns' if specifying 'colnames'
AttributeError: 'Int64Index' object has no attribute 'data'
AttributeError: 'IntracellularRecordingsTable' object has no attribute 'electrodes'

compression of new tables

These tables can potentially be large and repetitive.
Will there be a way to apply H5DataIO on them for compression?

Enrico reports some significant differences in size between a) a NWB file in which each acquisition and stimulation datasets have been wrapped for compression with H5DataIO and b) a NWB file simply archived with gzip.

Prevent binding of stimuli, responses and electrodes metadata dictionaries to external variables

If a dictionary is passed to one of the stimulus_, response_, electrode_metadata arguments, the dictionary is changed with some internal tuples after the call to add_intracellular_recording:

Example from icephys_meta_simple_example.ipynb:

nwbfile.intracellular_recordings.add_column(
    name='voltage_threshold', 
    data=[0.1, 0.12, 0.13], 
    description='Just and example filter on the electrode',
    category='electrodes') # Just added a PR with this line

em = {}
em['voltage_threshold'] = 2
em
# outputs: {'voltage_threshold': 2}

nwbfile.add_intracellular_recording(electrode=electrode,
    stimulus=stimulus, response=response, recording_tag='B', electrode_metadata = em)

em
# outputs:
# {'voltage_threshold': 2,
#  'electrode': elec0 pynwb.icephys.IntracellularElectrode at 0x4538476176
#  Fields:
#    description: a mock intracellular electrode
#    device: Heka ITC-1600 pynwb.device.Device at 0x4538475536}

The issue probably comes from these lines: x = popargs('x_metadata', kwargs).
I am not sure if this is intended but it's surely unexpected.

'table' attribute should be on 'recordings' dataset not 'recordings_index' dataset?

attributes=[
NWBAttributeSpec(
name='table',
dtype=NWBRefSpec(target_type='IntracellularRecordings',
reftype='object'),
doc='Reference to the IntracellularRecordings table that '
'this table region applies to. This specializes the '
'attribute inherited from DynamicTableRegion to fix '
'the type of table that can be referenced here.'

In the Sweeps type, the 'recordings' dataset is of type DynamicTableRegion which contains the 'table' attribute that should be overridden with a target table.

Same for the SweepSequences, Runs, and Conditions types.

Category tables require metadata even if stimulus/object is missing

The stimuli table (IntracellularStimuliTable) (and co.) requires stimulus_metadata to be passed even if the stimulus argument itself is None.
I understand why this is happening, but it doesn't seem like an expected behavior.

Example from README identical until line (A):

ir_table = nwbfile.get_intracellular_recordings()
ir_table.add_column('new_column', 'Stimulus special column', category='stimuli')
meta = {}
meta['new_column'] = 2
ir_index = nwbfile.add_intracellular_recording(electrode=electrode,
                                               stimulus=stimulus,
                                               response=response,
                                               stimulus_metadata = meta)

# All going fine until here
ir_index = nwbfile.add_intracellular_recording(electrode=electrode,
                                               response=response)

Error:

ValueError: row data keys don't match available columns
you supplied 0 extra keys: set()
and were missing 1 keys: {'new_column'}

Add stimulus_type metadata table

The metadata structure for describing stimulus types should be further refined. One proposal for this has been to add a separatestimulus_types stable which in turn should be referenced from the the sweep_sequences (aka, sequential_recording) table. Having the stimulus_types as a separate table would have the added advantage that the table can be reused across experiments.

add_intracellular_recording raises ValueError: row data keys don't match available columns

After the last updates, I am not able to add_intracellular_recordings anymore:
For example in https://github.com/oruebel/ndx-icephys-meta/blob/master/src/pynwb/examples/icephys_meta_simple_example.ipynb

nwbfile.add_intracellular_recording(electrode=electrode, stimulus, response, 10)

raises a ValueError. Full error is pasted at the end.

ValueError: row data keys don't match available columns
you supplied 1 extra keys: {'enforce_unique_id'}
and were missing 0 keys: set()

Is any of these packages at the wrong version?

h5py                      2.10.0                   pypi_0    pypi
hdmf                      1.3.3                    pypi_0    pypi
ndx-icephys-meta          0.1.0                     dev_0    <develop>
numpy                     1.17.3                   pypi_0    pypi
nwb-docutils              0.3.1                    pypi_0    pypi
pandas                    0.25.2                   pypi_0    pypi
pynwb                     1.1.2                    pypi_0    pypi
python                    3.7.4                h265db76_1  
ruamel-yaml               0.16.5                   pypi_0    pypi
ruamel-yaml-clib          0.2.0                    pypi_0    pypi 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-6537f1a1d799> in <module>
      2                                     stimulus=stimulus,
      3                                     response=response,
----> 4                                     id=10)

~/miniconda3/envs/ndx/lib/python3.7/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
    436                         raise_from(ExceptionType(msg), None)
    437 
--> 438                 return func(self, **parsed['args'])
    439         else:
    440             def func_call(*args, **kwargs):

/nfs4/bbp.epfl.ch/user/username/private/git/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/icephys.py in add_intracellular_recording(self, **kwargs)
    482         self._check_intracellular_recordings()
    483         # Add the recoding to the intracellular_recordings table
--> 484         call_docval_func(self.intracellular_recordings.add_recording, kwargs)
    485 
    486     def _check_ic_sweeps(self):

~/miniconda3/envs/ndx/lib/python3.7/site-packages/hdmf/utils.py in call_docval_func(func, kwargs)
    325 def call_docval_func(func, kwargs):
    326     fargs, fkwargs = fmt_docval_args(func, kwargs)
--> 327     return func(*fargs, **fkwargs)
    328 
    329 

~/miniconda3/envs/ndx/lib/python3.7/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
    436                         raise_from(ExceptionType(msg), None)
    437 
--> 438                 return func(self, **parsed['args'])
    439         else:
    440             def func_call(*args, **kwargs):

/nfs4/bbp.epfl.ch/user/username/private/git/ndx-icephys-meta/src/pynwb/ndx_icephys_meta/icephys.py in add_recording(self, **kwargs)
    114                       'response': (response_start_index, response_index_count, response)}
    115         row_kwargs.update(kwargs)
--> 116         return super(IntracellularRecordings, self).add_row(enforce_unique_id=True, **row_kwargs)
    117 
    118 

~/miniconda3/envs/ndx/lib/python3.7/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
    436                         raise_from(ExceptionType(msg), None)
    437 
--> 438                 return func(self, **parsed['args'])
    439         else:
    440             def func_call(*args, **kwargs):

~/miniconda3/envs/ndx/lib/python3.7/site-packages/hdmf/common/table.py in add_row(self, **kwargs)
    325                     'row data keys don\'t match available columns',
    326                     'you supplied {} extra keys: {}'.format(len(extra_columns), extra_columns),
--> 327                     'and were missing {} keys: {}'.format(len(missing_columns), missing_columns)
    328                 ])
    329             )

ValueError: row data keys don't match available columns
you supplied 1 extra keys: {'enforce_unique_id'}
and were missing 0 keys: set()

sql-like "unique index" for the id column

intracellular_recordings, ic_sweeps, ic_sweep_sequences, ic_runs tables allow insertions of rows with the same id.
I think id should be unique.

MWE:

nwbfile.add_ic_sweep(recordings=[0], id=12)
nwbfile.add_ic_sweep(recordings=[0], id=12)
nwbfile.ic_sweeps.to_dataframe()

Make all tables AlignedDynamicTables

The Conditions, Repeat, SequentialRecording, SimultaneousRecording tables should also be AlignedDynamicTables to make it easier to extend them later on add metadata specific to sub-categories to the table.

Validation error in example file

After resolving the validation error in #21 , another validation error appears: the 'colnames' attribute of /general/intracellular_ephys/intracellular_recordings/ is empty which raises an IndexError.

I raised this issue in hdmf-dev/hdmf#317

Example notebooks should use either current clamp or voltage clamp

The example notebooks add a CurrentClampStimulusSeries and a VoltageClampSeries as stimulus and response to the NWBFile. These types are semantically incompatible. The CurrentClampStimulusSeries should be paired with a CurrentClampSeries and a VoltageClampStimulusSeries should be paired with a VoltageClampSeries.

I don't know if there are any exceptions to this rule (besides when a response is recorded without a stimulus and perhaps vice versa). If there are no exceptions, then perhaps the API should raise an error (or at least a warning) if incompatible types are passed into the new sweep table. At the very least, the example notebooks should use the typical use case.

@t-b and @lvsltz please let me know if I am wrong here.

Remove nested type definition specifications

The type definition of IntracellularRecordingsTable includes the type definitions for IntracellularElectrodesTable, IntracellularStimuliTable, and IntracellularResponsesTable. I understand that these three types are meant to be used only within the IntracellularRecordingsTable, but these types can still technically be used elsewhere, and if these types are defined outside of IntracellularRecordingsTable, it would be easier to parse the schema and avoid edge cases that arise from having nested type definitions.

I suggest moving the specifications for these types to the root level of the extension and using neurodata_type_inc to include them in the IntracellularElectrodesTable type.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.