File: test_read.py

package info (click to toggle)
pynwb 2.8.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 44,312 kB
  • sloc: python: 17,501; makefile: 597; sh: 11
file content (138 lines) | stat: -rw-r--r-- 7,737 bytes parent folder | download
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
import numpy as np
from pathlib import Path
import warnings

from pynwb import NWBHDF5IO, validate, TimeSeries
from pynwb.image import ImageSeries
from pynwb.testing import TestCase


class TestReadOldVersions(TestCase):

    expected_warnings = {
        ''
        '2.1.0_imageseries_non_external_format.nwb': [(
            "ImageSeries 'test_imageseries': Format must be 'external' when external_file is specified."
        )],
        '2.1.0_imageseries_nonmatch_starting_frame.nwb': [(
            "ImageSeries 'test_imageseries': The number of frame indices in 'starting_frame' should have the same "
            "length as 'external_file'."
        )],
    }

    expected_errors = {
        '1.0.2_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected "
                                        "an array of shape '[None]', got non-array data 'one experimenter'")],
        '1.0.3_str_experimenter.nwb': [("root/general/experimenter (general/experimenter): incorrect shape - expected "
                                        "an array of shape '[None]', got non-array data 'one experimenter'")],
        '1.0.2_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape "
                               "- expected an array of shape '[None]', got non-array data 'one publication'")],
        '1.0.3_str_pub.nwb': [("root/general/related_publications (general/related_publications): incorrect shape "
                               "- expected an array of shape '[None]', got non-array data 'one publication'")],
        '1.5.1_timeseries_no_data.nwb': [("TimeSeries/data/data (acquisition/test_timeseries/data): argument missing")],
        '1.5.1_timeseries_no_unit.nwb': [("TimeSeries/data/unit (acquisition/test_timeseries/data): argument missing")],
        '1.5.1_imageseries_no_data.nwb': [("ImageSeries/data/data (acquisition/test_imageseries/data): "
                                           "argument missing")],
        '1.5.1_imageseries_no_unit.nwb': [("ImageSeries/data/unit (acquisition/test_imageseries/data): "
                                           "argument missing")],
    }

    def get_io(self, path):
        """Get an NWBHDF5IO object for the given path."""
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore",
                message=r"Ignoring cached namespace .*",
                category=UserWarning,
            )
            return NWBHDF5IO(str(path), 'r')

    def test_read(self):
        """Test reading and validating all NWB files in the same folder as this file.

        This folder contains NWB files generated by previous versions of NWB using the script
        src/pynwb/testing/make_test_files.py
        """
        dir_path = Path(__file__).parent
        nwb_files = dir_path.glob('*.nwb')
        for f in nwb_files:
            with self.subTest(file=f.name):
                with warnings.catch_warnings(record=True) as warnings_on_read:
                    warnings.simplefilter("always")
                    with self.get_io(f) as io:
                        errors = validate(io)
                        io.read()
                        for w in warnings_on_read:
                            if f.name in self.expected_warnings:
                                if str(w.message) not in self.expected_warnings[f.name]:
                                    pass
                                    # will replace above with below after the test file is updated
                                    # raise Exception("Unexpected warning: %s: %s" % (f.name, str(w.message)))
                            else:
                                pass
                                # will replace above with below after the test file is updated
                                # raise Exception("Unexpected warning: %s: %s" % (f.name, str(w.message)))
                        if errors:
                            for e in errors:
                                if f.name in self.expected_errors:
                                    if str(e) not in self.expected_errors[f.name]:
                                        warnings.warn('%s: %s' % (f.name, e))
                                else:
                                    raise Exception("Unexpected validation error: %s: %s" % (f.name, e))
                            # TODO uncomment below when validation errors have been fixed
                            # raise Exception('%d validation error(s). See warnings.' % len(errors))

    def test_read_timeseries_no_data(self):
        """Test that a TimeSeries written without data is read with data set to the default value."""
        f = Path(__file__).parent / '1.5.1_timeseries_no_data.nwb'
        with self.get_io(f) as io:
            read_nwbfile = io.read()
            np.testing.assert_array_equal(read_nwbfile.acquisition['test_timeseries'].data, TimeSeries.DEFAULT_DATA)

    def test_read_timeseries_no_unit(self):
        """Test that an ImageSeries written without unit is read with unit set to the default value."""
        f = Path(__file__).parent / '1.5.1_timeseries_no_unit.nwb'
        with self.get_io(f) as io:
            read_nwbfile = io.read()
            self.assertEqual(read_nwbfile.acquisition['test_timeseries'].unit, TimeSeries.DEFAULT_UNIT)

    def test_read_imageseries_no_data(self):
        """Test that an ImageSeries written without data is read with data set to the default value."""
        f = Path(__file__).parent / '1.5.1_imageseries_no_data.nwb'
        with self.get_io(f) as io:
            read_nwbfile = io.read()
            np.testing.assert_array_equal(read_nwbfile.acquisition['test_imageseries'].data, ImageSeries.DEFAULT_DATA)

    def test_read_imageseries_no_unit(self):
        """Test that an ImageSeries written without unit is read with unit set to the default value."""
        f = Path(__file__).parent / '1.5.1_imageseries_no_unit.nwb'
        with self.get_io(f) as io:
            read_nwbfile = io.read()
            self.assertEqual(read_nwbfile.acquisition['test_imageseries'].unit, ImageSeries.DEFAULT_UNIT)

    def test_read_imageseries_non_external_format(self):
        """Test that reading an ImageSeries with an inconsistent format does not change the value."""
        fbase = "2.1.0_imageseries_non_external_format.nwb"
        f = Path(__file__).parent / fbase
        expected_warning = self.expected_warnings[fbase][0]
        with self.assertWarnsWith(UserWarning, expected_warning):
            with self.get_io(f) as io:
                read_nwbfile = io.read()
                self.assertEqual(read_nwbfile.acquisition['test_imageseries'].format, "tiff")

    def test_read_imageseries_nonmatch_starting_frame(self):
        """Test that reading an ImageSeries with an inconsistent starting_frame does not change the value."""
        fbase = "2.1.0_imageseries_nonmatch_starting_frame.nwb"
        f = Path(__file__).parent / fbase
        expected_warning = self.expected_warnings[fbase][0]
        with self.assertWarnsWith(UserWarning, expected_warning):
            with self.get_io(f) as io:
                read_nwbfile = io.read()
                np.testing.assert_array_equal(read_nwbfile.acquisition['test_imageseries'].starting_frame, [1, 2, 3])

    def test_read_subject_no_age__reference(self):
        """Test that reading a Subject without an age__reference set with NWB schema 2.5.0 sets the value to None"""
        f = Path(__file__).parent / '2.2.0_subject_no_age__reference.nwb'
        with self.get_io(f) as io:
            read_nwbfile = io.read()
            self.assertIsNone(read_nwbfile.subject.age__reference)