myokit 1.35.0__py3-none-any.whl → 1.35.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- myokit/__init__.py +11 -14
- myokit/__main__.py +0 -3
- myokit/_config.py +1 -3
- myokit/_datablock.py +914 -12
- myokit/_model_api.py +1 -3
- myokit/_myokit_version.py +1 -1
- myokit/_protocol.py +14 -28
- myokit/_sim/cable.c +1 -1
- myokit/_sim/cable.py +3 -2
- myokit/_sim/cmodel.h +1 -0
- myokit/_sim/cvodessim.c +79 -42
- myokit/_sim/cvodessim.py +20 -8
- myokit/_sim/fiber_tissue.c +1 -1
- myokit/_sim/fiber_tissue.py +3 -2
- myokit/_sim/openclsim.c +1 -1
- myokit/_sim/openclsim.py +8 -11
- myokit/_sim/pacing.h +121 -106
- myokit/_unit.py +1 -1
- myokit/formats/__init__.py +178 -0
- myokit/formats/axon/_abf.py +911 -841
- myokit/formats/axon/_atf.py +62 -59
- myokit/formats/axon/_importer.py +2 -2
- myokit/formats/heka/__init__.py +38 -0
- myokit/formats/heka/_importer.py +39 -0
- myokit/formats/heka/_patchmaster.py +2512 -0
- myokit/formats/wcp/_wcp.py +318 -133
- myokit/gui/datablock_viewer.py +144 -77
- myokit/gui/datalog_viewer.py +212 -231
- myokit/tests/ansic_event_based_pacing.py +3 -3
- myokit/tests/{ansic_fixed_form_pacing.py → ansic_time_series_pacing.py} +6 -6
- myokit/tests/data/formats/abf-v2.abf +0 -0
- myokit/tests/test_datablock.py +84 -0
- myokit/tests/test_datalog.py +2 -1
- myokit/tests/test_formats_axon.py +589 -136
- myokit/tests/test_formats_wcp.py +191 -22
- myokit/tests/test_pacing_system_c.py +51 -23
- myokit/tests/test_pacing_system_py.py +18 -0
- myokit/tests/test_simulation_1d.py +62 -22
- myokit/tests/test_simulation_cvodes.py +52 -3
- myokit/tests/test_simulation_fiber_tissue.py +35 -4
- myokit/tests/test_simulation_opencl.py +28 -4
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/LICENSE.txt +1 -1
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/METADATA +1 -1
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/RECORD +47 -44
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/WHEEL +0 -0
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/entry_points.txt +0 -0
- {myokit-1.35.0.dist-info → myokit-1.35.2.dist-info}/top_level.txt +0 -0
|
@@ -13,7 +13,179 @@ import numpy as np
|
|
|
13
13
|
import myokit
|
|
14
14
|
import myokit.formats.axon as axon
|
|
15
15
|
|
|
16
|
-
from myokit.tests import TemporaryDirectory, DIR_FORMATS
|
|
16
|
+
from myokit.tests import TemporaryDirectory, DIR_FORMATS, WarningCollector
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
V1_INFO = '''
|
|
20
|
+
Axon Binary File: abf-v1.abf
|
|
21
|
+
ABF Format version 1.65
|
|
22
|
+
Recorded on: 2014-11-14 12:52:29.389999
|
|
23
|
+
Acquisition mode: 5: Episodic stimulation mode
|
|
24
|
+
Protocol set for 1 trials, spaced 0.0s apart.
|
|
25
|
+
with 1 runs per trial, spaced 0.0s apart.
|
|
26
|
+
and 9 sweeps per run, spaced 0.5s apart.
|
|
27
|
+
Sampling rate: 10000.0 Hz
|
|
28
|
+
A/D Channel 0: "IN 0"
|
|
29
|
+
Unit: [pA]
|
|
30
|
+
D/A Channel 0: "OUT 0"
|
|
31
|
+
Unit: [mV]
|
|
32
|
+
'''.strip()
|
|
33
|
+
|
|
34
|
+
V1_PROTO_INFO = '''
|
|
35
|
+
Axon Protocol File: abf-protocol.pro
|
|
36
|
+
ABF Format version 1.65
|
|
37
|
+
Recorded on: 2005-06-17 14:33:02.160000
|
|
38
|
+
Acquisition mode: 5: Episodic stimulation mode
|
|
39
|
+
Protocol set for 1 trials, spaced 0.0s apart.
|
|
40
|
+
with 1 runs per trial, spaced 0.0s apart.
|
|
41
|
+
and 30 sweeps per run, spaced 5.0s apart.
|
|
42
|
+
Sampling rate: 20000.0 Hz
|
|
43
|
+
D/A Channel 0: "Cmd 0"
|
|
44
|
+
Unit: [mV]
|
|
45
|
+
'''.strip()
|
|
46
|
+
|
|
47
|
+
V1_PROTOCOL = '''
|
|
48
|
+
[[protocol]]
|
|
49
|
+
# Level Start Length Period Multiplier
|
|
50
|
+
-100.0 0.0 100.0 0.0 0
|
|
51
|
+
0.0 100.0 400.0 0.0 0
|
|
52
|
+
-80.0 500.0 100.0 0.0 0
|
|
53
|
+
0.0 600.0 400.0 0.0 0
|
|
54
|
+
-60.0 1000.0 100.0 0.0 0
|
|
55
|
+
0.0 1100.0 400.0 0.0 0
|
|
56
|
+
-40.0 1500.0 100.0 0.0 0
|
|
57
|
+
0.0 1600.0 400.0 0.0 0
|
|
58
|
+
-20.0 2000.0 100.0 0.0 0
|
|
59
|
+
0.0 2100.0 400.0 0.0 0
|
|
60
|
+
0.0 2500.0 100.0 0.0 0
|
|
61
|
+
0.0 2600.0 400.0 0.0 0
|
|
62
|
+
20.0 3000.0 100.0 0.0 0
|
|
63
|
+
0.0 3100.0 400.0 0.0 0
|
|
64
|
+
40.0 3500.0 100.0 0.0 0
|
|
65
|
+
0.0 3600.0 400.0 0.0 0
|
|
66
|
+
60.0 4000.0 100.0 0.0 0
|
|
67
|
+
0.0 4100.0 400.0 0.0 0
|
|
68
|
+
'''.strip()
|
|
69
|
+
|
|
70
|
+
V1_PROTOCOL_VS = '''
|
|
71
|
+
[[protocol]]
|
|
72
|
+
# Level Start Length Period Multiplier
|
|
73
|
+
-0.1 0.0 0.1 0.0 0
|
|
74
|
+
0.0 0.1 0.4 0.0 0
|
|
75
|
+
-0.08 0.5 0.1 0.0 0
|
|
76
|
+
0.0 0.6 0.4 0.0 0
|
|
77
|
+
-0.06 1.0 0.1 0.0 0
|
|
78
|
+
0.0 1.1 0.4 0.0 0
|
|
79
|
+
-0.04 1.5 0.1 0.0 0
|
|
80
|
+
0.0 1.6 0.4 0.0 0
|
|
81
|
+
-0.02 2.0 0.1 0.0 0
|
|
82
|
+
0.0 2.1 0.4 0.0 0
|
|
83
|
+
0.0 2.5 0.1 0.0 0
|
|
84
|
+
0.0 2.6 0.4 0.0 0
|
|
85
|
+
0.02 3.0 0.1 0.0 0
|
|
86
|
+
0.0 3.1 0.4 0.0 0
|
|
87
|
+
0.04 3.5 0.1 0.0 0
|
|
88
|
+
0.0 3.6 0.4 0.0 0
|
|
89
|
+
0.06 4.0 0.1 0.0 0
|
|
90
|
+
0.0 4.1 0.4 0.0 0
|
|
91
|
+
'''.strip()
|
|
92
|
+
|
|
93
|
+
V2_INFO = '''
|
|
94
|
+
Axon Binary File: abf-v2.abf
|
|
95
|
+
ABF Format version 2.0.0.0
|
|
96
|
+
Recorded on: 2016-01-07 10:51:55.345000
|
|
97
|
+
Acquisition mode: 5: Episodic stimulation mode
|
|
98
|
+
Protocol set for 1 trials, spaced 0.0s apart.
|
|
99
|
+
with 1 runs per trial, spaced 0.0s apart.
|
|
100
|
+
and 37 sweeps per run, spaced 5.0s apart.
|
|
101
|
+
Sampling rate: 20000.0 Hz
|
|
102
|
+
A/D Channel 0: "IN 0"
|
|
103
|
+
Unit: [pA]
|
|
104
|
+
Low-pass filter: 10000.0 Hz
|
|
105
|
+
Cm (telegraphed): 11.083984375 pF
|
|
106
|
+
D/A Channel 0: "Cmd 0"
|
|
107
|
+
Unit: [mV]
|
|
108
|
+
|
|
109
|
+
'''.strip()
|
|
110
|
+
|
|
111
|
+
V2_PROTOCOL = '''
|
|
112
|
+
[[protocol]]
|
|
113
|
+
# Level Start Length Period Multiplier
|
|
114
|
+
-100.0 0.0 25.0 0.0 0
|
|
115
|
+
-120.0 25.0 4975.0 0.0 0
|
|
116
|
+
-95.0 5000.0 25.0 0.0 0
|
|
117
|
+
-120.0 5025.0 4975.0 0.0 0
|
|
118
|
+
-90.0 10000.0 25.0 0.0 0
|
|
119
|
+
-120.0 10025.0 4975.0 0.0 0
|
|
120
|
+
-85.0 15000.0 25.0 0.0 0
|
|
121
|
+
-120.0 15025.0 4975.0 0.0 0
|
|
122
|
+
-80.0 20000.0 25.0 0.0 0
|
|
123
|
+
-120.0 20025.0 4975.0 0.0 0
|
|
124
|
+
-75.0 25000.0 25.0 0.0 0
|
|
125
|
+
-120.0 25025.0 4975.0 0.0 0
|
|
126
|
+
-70.0 30000.0 25.0 0.0 0
|
|
127
|
+
-120.0 30025.0 4975.0 0.0 0
|
|
128
|
+
-65.0 35000.0 25.0 0.0 0
|
|
129
|
+
-120.0 35025.0 4975.0 0.0 0
|
|
130
|
+
-60.0 40000.0 25.0 0.0 0
|
|
131
|
+
-120.0 40025.0 4975.0 0.0 0
|
|
132
|
+
-55.0 45000.0 25.0 0.0 0
|
|
133
|
+
-120.0 45025.0 4975.0 0.0 0
|
|
134
|
+
-50.0 50000.0 25.0 0.0 0
|
|
135
|
+
-120.0 50025.0 4975.0 0.0 0
|
|
136
|
+
-45.0 55000.0 25.0 0.0 0
|
|
137
|
+
-120.0 55025.0 4975.0 0.0 0
|
|
138
|
+
-40.0 60000.0 25.0 0.0 0
|
|
139
|
+
-120.0 60025.0 4975.0 0.0 0
|
|
140
|
+
-35.0 65000.0 25.0 0.0 0
|
|
141
|
+
-120.0 65025.0 4975.0 0.0 0
|
|
142
|
+
-30.0 70000.0 25.0 0.0 0
|
|
143
|
+
-120.0 70025.0 4975.0 0.0 0
|
|
144
|
+
-25.0 75000.0 25.0 0.0 0
|
|
145
|
+
-120.0 75025.0 4975.0 0.0 0
|
|
146
|
+
-20.0 80000.0 25.0 0.0 0
|
|
147
|
+
-120.0 80025.0 4975.0 0.0 0
|
|
148
|
+
-15.0 85000.0 25.0 0.0 0
|
|
149
|
+
-120.0 85025.0 4975.0 0.0 0
|
|
150
|
+
-10.0 90000.0 25.0 0.0 0
|
|
151
|
+
-120.0 90025.0 4975.0 0.0 0
|
|
152
|
+
-5.0 95000.0 25.0 0.0 0
|
|
153
|
+
-120.0 95025.0 4975.0 0.0 0
|
|
154
|
+
0.0 100000.0 25.0 0.0 0
|
|
155
|
+
-120.0 100025.0 4975.0 0.0 0
|
|
156
|
+
5.0 105000.0 25.0 0.0 0
|
|
157
|
+
-120.0 105025.0 4975.0 0.0 0
|
|
158
|
+
10.0 110000.0 25.0 0.0 0
|
|
159
|
+
-120.0 110025.0 4975.0 0.0 0
|
|
160
|
+
15.0 115000.0 25.0 0.0 0
|
|
161
|
+
-120.0 115025.0 4975.0 0.0 0
|
|
162
|
+
20.0 120000.0 25.0 0.0 0
|
|
163
|
+
-120.0 120025.0 4975.0 0.0 0
|
|
164
|
+
25.0 125000.0 25.0 0.0 0
|
|
165
|
+
-120.0 125025.0 4975.0 0.0 0
|
|
166
|
+
30.0 130000.0 25.0 0.0 0
|
|
167
|
+
-120.0 130025.0 4975.0 0.0 0
|
|
168
|
+
35.0 135000.0 25.0 0.0 0
|
|
169
|
+
-120.0 135025.0 4975.0 0.0 0
|
|
170
|
+
40.0 140000.0 25.0 0.0 0
|
|
171
|
+
-120.0 140025.0 4975.0 0.0 0
|
|
172
|
+
45.0 145000.0 25.0 0.0 0
|
|
173
|
+
-120.0 145025.0 4975.0 0.0 0
|
|
174
|
+
50.0 150000.0 25.0 0.0 0
|
|
175
|
+
-120.0 150025.0 4975.0 0.0 0
|
|
176
|
+
55.0 155000.0 25.0 0.0 0
|
|
177
|
+
-120.0 155025.0 4975.0 0.0 0
|
|
178
|
+
60.0 160000.0 25.0 0.0 0
|
|
179
|
+
-120.0 160025.0 4975.0 0.0 0
|
|
180
|
+
65.0 165000.0 25.0 0.0 0
|
|
181
|
+
-120.0 165025.0 4975.0 0.0 0
|
|
182
|
+
70.0 170000.0 25.0 0.0 0
|
|
183
|
+
-120.0 170025.0 4975.0 0.0 0
|
|
184
|
+
75.0 175000.0 25.0 0.0 0
|
|
185
|
+
-120.0 175025.0 4975.0 0.0 0
|
|
186
|
+
80.0 180000.0 25.0 0.0 0
|
|
187
|
+
-120.0 180025.0 4975.0 0.0 0
|
|
188
|
+
'''.strip()
|
|
17
189
|
|
|
18
190
|
|
|
19
191
|
class AbfTest(unittest.TestCase):
|
|
@@ -27,122 +199,203 @@ class AbfTest(unittest.TestCase):
|
|
|
27
199
|
# Load file
|
|
28
200
|
path = os.path.join(DIR_FORMATS, 'abf-v1.abf')
|
|
29
201
|
abf = axon.AbfFile(path)
|
|
30
|
-
self.assertEqual(abf.
|
|
202
|
+
self.assertEqual(abf.path(), path)
|
|
203
|
+
self.assertEqual(abf.filename(), 'abf-v1.abf')
|
|
204
|
+
self.assertIsInstance(abf, myokit.formats.SweepSource)
|
|
31
205
|
|
|
32
|
-
# Check
|
|
33
|
-
self.assertIn('version 1.65', abf.
|
|
34
|
-
self.
|
|
35
|
-
|
|
36
|
-
'Axon Binary File: abf-v1.abf\n'
|
|
37
|
-
'ABF Format version 1.65\n'
|
|
38
|
-
'Recorded on: 2014-11-14 12:52:29.389999\n'
|
|
39
|
-
'Acquisition mode: 5: Episodic stimulation mode\n'
|
|
40
|
-
'Protocol set for 1 trials, spaced 0.0s apart.\n'
|
|
41
|
-
' with 1 runs per trial, spaced 0.0s apart.\n'
|
|
42
|
-
' and 9 sweeps per run, spaced 0.5s apart.\n'
|
|
43
|
-
'Sampling rate: 10000.0 Hz\n'
|
|
44
|
-
'Channel 0: "IN 0 "\n'
|
|
45
|
-
' Unit: pA'
|
|
46
|
-
)
|
|
47
|
-
# Test getting full header runs without crashing
|
|
48
|
-
abf.info(True)
|
|
206
|
+
# Check getting info
|
|
207
|
+
self.assertIn('version 1.65', abf.meta_str())
|
|
208
|
+
self.maxDiff = None
|
|
209
|
+
self.assertEqual(abf.meta_str(), V1_INFO)
|
|
49
210
|
|
|
50
|
-
# Test
|
|
51
|
-
|
|
211
|
+
# Test getting full header runs without crashing
|
|
212
|
+
abf.meta_str(True)
|
|
52
213
|
|
|
53
|
-
#
|
|
54
|
-
self.assertEqual(abf.
|
|
55
|
-
x = abf.extract_channel(0)
|
|
56
|
-
self.assertEqual(len(x), 1 + len(abf)) # sweeps + time
|
|
57
|
-
self.assertEqual(len(x[0]), len(x[1]))
|
|
58
|
-
self.assertEqual(len(x[0]), len(x[2]))
|
|
59
|
-
self.assertEqual(len(x[0]), len(x[3]))
|
|
60
|
-
self.assertEqual(len(x[0]), len(x[4]))
|
|
61
|
-
self.assertEqual(len(x[0]), len(x[5]))
|
|
62
|
-
self.assertEqual(len(x[0]), len(x[6]))
|
|
63
|
-
self.assertEqual(len(x[0]), len(x[7]))
|
|
64
|
-
self.assertEqual(len(x[0]), len(x[8]))
|
|
65
|
-
self.assertEqual(len(x[0]), len(x[9]))
|
|
66
|
-
y = abf.extract_channel_as_myokit_log(0)
|
|
67
|
-
self.assertEqual(len(y), 1 + len(abf)) # sweeps + time
|
|
68
|
-
z = abf.myokit_log()
|
|
69
|
-
self.assertEqual(len(z), 6) # time + channel + 4 protocol channels
|
|
70
|
-
sweep = abf[0]
|
|
71
|
-
self.assertEqual(len(sweep), 1) # 1 channel in sweep
|
|
72
|
-
channel = sweep[0]
|
|
73
|
-
self.assertIsInstance(channel.number(), int)
|
|
74
|
-
self.assertIn('Channel', str(channel))
|
|
75
|
-
self.assertEqual(len(abf) * len(channel.times()), len(z.time()))
|
|
76
|
-
self.assertEqual(len(abf) * len(channel.values()), len(z.time()))
|
|
77
|
-
|
|
78
|
-
# Test reading of sweeps as one long array
|
|
79
|
-
x, y = abf.extract_channel(0, join=True)
|
|
80
|
-
z = abf.extract_channel(0)
|
|
81
|
-
self.assertEqual(len(x), len(y))
|
|
82
|
-
self.assertEqual(len(x), len(abf) * len(z[0]))
|
|
83
|
-
self.assertTrue(np.all(x[1:] > x[:-1]))
|
|
214
|
+
# Get version
|
|
215
|
+
self.assertEqual(abf.version(), '1.65')
|
|
84
216
|
|
|
85
|
-
#
|
|
86
|
-
self.assertEqual(abf
|
|
87
|
-
|
|
88
|
-
self.assertEqual(len(
|
|
89
|
-
|
|
90
|
-
|
|
217
|
+
# Sweep count
|
|
218
|
+
self.assertEqual(len(abf), 9)
|
|
219
|
+
self.assertEqual(abf.sweep_count(), 9)
|
|
220
|
+
self.assertEqual(len([s for s in abf]), 9)
|
|
221
|
+
|
|
222
|
+
# Test access to A/D and D/A channels via sequence interface
|
|
223
|
+
self.assertIsInstance(abf[0], axon.Sweep)
|
|
224
|
+
self.assertIsInstance(abf[8], axon.Sweep)
|
|
225
|
+
self.assertFalse(abf[0] is abf[1])
|
|
226
|
+
self.assertEqual(len(abf[0]), 2)
|
|
227
|
+
self.assertEqual(len(abf[8]), 2)
|
|
228
|
+
self.assertIsInstance(abf[0][0], axon.Channel)
|
|
229
|
+
self.assertIsInstance(abf[0][1], axon.Channel)
|
|
230
|
+
|
|
231
|
+
# Test abf.Channel methods
|
|
232
|
+
channel = abf[0][0]
|
|
233
|
+
self.assertEqual(channel.index(), 0)
|
|
234
|
+
self.assertEqual(channel.name(), 'IN 0')
|
|
235
|
+
self.assertIsInstance(channel.unit(), myokit.Unit)
|
|
236
|
+
self.assertEqual(channel.unit(), myokit.units.pA)
|
|
237
|
+
self.assertEqual(str(channel),
|
|
238
|
+
'Channel(0 "IN 0"); 5000 points sampled at 10000.0Hz,'
|
|
239
|
+
' starts at t=0.0.')
|
|
240
|
+
self.assertEqual(len(channel.times()), len(channel.values()))
|
|
241
|
+
self.assertFalse(np.all(channel.times() == channel.values()))
|
|
242
|
+
|
|
243
|
+
# Test SweepSource info
|
|
244
|
+
self.assertTrue(abf.equal_length_sweeps())
|
|
245
|
+
self.assertEqual(abf.time_unit(), myokit.units.s)
|
|
246
|
+
|
|
247
|
+
# Test A/D channel access via SweepSource interface
|
|
248
|
+
self.assertEqual(abf.channel_count(), 1)
|
|
249
|
+
self.assertEqual(abf.channel_names(), ['IN 0'])
|
|
250
|
+
self.assertEqual(abf.channel_names(0), 'IN 0')
|
|
251
|
+
self.assertEqual(abf.channel_units(), [myokit.units.pA])
|
|
252
|
+
self.assertEqual(abf.channel_units(0), myokit.units.pA)
|
|
253
|
+
|
|
254
|
+
times, values = abf.channel(0)
|
|
255
|
+
self.assertEqual(9, len(times), len(values))
|
|
256
|
+
self.assertEqual(len(times[0]), len(values[0]))
|
|
257
|
+
self.assertEqual(len(times[0]), len(times[1]), len(values[1]))
|
|
258
|
+
self.assertEqual(len(times[0]), len(times[2]), len(values[2]))
|
|
259
|
+
self.assertEqual(len(times[0]), len(times[3]), len(values[3]))
|
|
260
|
+
self.assertEqual(len(times[0]), len(times[4]), len(values[4]))
|
|
261
|
+
self.assertEqual(len(times[0]), len(times[5]), len(values[5]))
|
|
262
|
+
self.assertEqual(len(times[0]), len(times[6]), len(values[6]))
|
|
263
|
+
self.assertEqual(len(times[0]), len(times[7]), len(values[7]))
|
|
264
|
+
self.assertEqual(len(times[0]), len(times[8]), len(values[8]))
|
|
265
|
+
|
|
266
|
+
tj, vj = abf.channel(0, join_sweeps=True)
|
|
267
|
+
self.assertTrue(np.all(tj == np.concatenate(times)))
|
|
268
|
+
self.assertTrue(np.all(vj == np.concatenate(values)))
|
|
269
|
+
|
|
270
|
+
# Channel doesn't exist
|
|
271
|
+
self.assertRaises(IndexError, abf.channel, -1)
|
|
272
|
+
self.assertRaises(IndexError, abf.channel, 1)
|
|
273
|
+
self.assertRaises(KeyError, abf.channel, 'OUT 0')
|
|
274
|
+
|
|
275
|
+
# Test D/A output access via SweepSource interface
|
|
276
|
+
self.assertEqual(abf.da_count(), 1)
|
|
277
|
+
self.assertEqual(abf.da_names(), ['OUT 0'])
|
|
278
|
+
self.assertEqual(abf.da_names(0), 'OUT 0')
|
|
279
|
+
self.assertEqual(abf.da_units(), [myokit.units.mV])
|
|
280
|
+
self.assertEqual(abf.da_units(0), myokit.units.mV)
|
|
281
|
+
|
|
282
|
+
da_times, da_values = abf.da(0)
|
|
283
|
+
self.assertEqual(9, len(da_times), len(da_values))
|
|
284
|
+
self.assertEqual(len(da_times[0]), len(da_values[0]))
|
|
285
|
+
self.assertEqual(len(da_times[0]), len(da_times[1]), len(da_values[1]))
|
|
286
|
+
self.assertEqual(len(da_times[0]), len(da_times[8]), len(da_values[8]))
|
|
287
|
+
self.assertEqual(len(da_times[0]), len(times[0]))
|
|
288
|
+
self.assertTrue(np.all(times[0] == da_times[0]))
|
|
289
|
+
self.assertFalse(np.all(values[0] == da_values[0]))
|
|
290
|
+
self.assertTrue(np.all(da_values[3] == abf.da('OUT 0')[1][3]))
|
|
291
|
+
self.assertRaises(IndexError, abf.da, -1)
|
|
292
|
+
self.assertRaises(IndexError, abf.da, 1)
|
|
293
|
+
self.assertRaises(KeyError, abf.da, 'hiya')
|
|
294
|
+
|
|
295
|
+
tj, vj = abf.da(0, join_sweeps=True)
|
|
296
|
+
self.assertTrue(np.all(tj == np.concatenate(da_times)))
|
|
297
|
+
self.assertTrue(np.all(vj == np.concatenate(da_values)))
|
|
298
|
+
|
|
299
|
+
# Conversion to data log without joining
|
|
300
|
+
x = abf.log()
|
|
301
|
+
k = list(x.keys())
|
|
302
|
+
self.assertEqual(len(x), 1 + 2 * 9)
|
|
303
|
+
self.assertIn('time', x)
|
|
304
|
+
self.assertIn('0.0.channel', k)
|
|
305
|
+
self.assertIn('1.0.channel', k)
|
|
306
|
+
self.assertIn('2.0.channel', k)
|
|
307
|
+
self.assertIn('3.0.channel', k)
|
|
308
|
+
self.assertIn('4.0.channel', k)
|
|
309
|
+
self.assertIn('5.0.channel', k)
|
|
310
|
+
self.assertIn('6.0.channel', k)
|
|
311
|
+
self.assertIn('7.0.channel', k)
|
|
312
|
+
self.assertIn('8.0.channel', k)
|
|
313
|
+
self.assertIn('0.0.da', k)
|
|
314
|
+
self.assertIn('1.0.da', k)
|
|
315
|
+
self.assertIn('2.0.da', k)
|
|
316
|
+
self.assertIn('3.0.da', k)
|
|
317
|
+
self.assertIn('4.0.da', k)
|
|
318
|
+
self.assertIn('5.0.da', k)
|
|
319
|
+
self.assertIn('6.0.da', k)
|
|
320
|
+
self.assertIn('7.0.da', k)
|
|
321
|
+
self.assertIn('8.0.da', k)
|
|
322
|
+
self.assertEqual(len(x['time']), len(x['5.0.channel']))
|
|
323
|
+
self.assertEqual(len(x['7.0.da']), len(x['5.0.channel']))
|
|
324
|
+
|
|
325
|
+
x = abf.log(include_da=False)
|
|
326
|
+
k = list(x.keys())
|
|
327
|
+
self.assertEqual(len(x), 1 + 1 * 9)
|
|
328
|
+
self.assertIn('time', x)
|
|
329
|
+
self.assertIn('0.0.channel', k)
|
|
330
|
+
self.assertIn('1.0.channel', k)
|
|
331
|
+
self.assertIn('2.0.channel', k)
|
|
332
|
+
self.assertIn('3.0.channel', k)
|
|
333
|
+
self.assertIn('4.0.channel', k)
|
|
334
|
+
self.assertIn('5.0.channel', k)
|
|
335
|
+
self.assertIn('6.0.channel', k)
|
|
336
|
+
self.assertIn('7.0.channel', k)
|
|
337
|
+
self.assertIn('8.0.channel', k)
|
|
338
|
+
self.assertEqual(len(x['time']), len(x['5.0.channel']))
|
|
339
|
+
|
|
340
|
+
x = abf.log(use_names=True)
|
|
341
|
+
k = list(x.keys())
|
|
342
|
+
self.assertEqual(len(x), 1 + 2 * 9)
|
|
343
|
+
self.assertIn('time', k)
|
|
344
|
+
self.assertIn('0.IN 0', k)
|
|
345
|
+
self.assertIn('1.IN 0', k)
|
|
346
|
+
self.assertIn('2.IN 0', k)
|
|
347
|
+
self.assertIn('3.IN 0', k)
|
|
348
|
+
self.assertIn('4.IN 0', k)
|
|
349
|
+
self.assertIn('5.IN 0', k)
|
|
350
|
+
self.assertIn('6.IN 0', k)
|
|
351
|
+
self.assertIn('7.IN 0', k)
|
|
352
|
+
self.assertIn('8.IN 0', k)
|
|
353
|
+
self.assertIn('0.OUT 0', k)
|
|
354
|
+
self.assertIn('1.OUT 0', k)
|
|
355
|
+
self.assertIn('2.OUT 0', k)
|
|
356
|
+
self.assertIn('3.OUT 0', k)
|
|
357
|
+
self.assertIn('4.OUT 0', k)
|
|
358
|
+
self.assertIn('5.OUT 0', k)
|
|
359
|
+
self.assertIn('6.OUT 0', k)
|
|
360
|
+
self.assertIn('7.OUT 0', k)
|
|
361
|
+
self.assertIn('8.OUT 0', k)
|
|
362
|
+
|
|
363
|
+
# Conversion to data log with joining
|
|
364
|
+
y = abf.log(join_sweeps=True)
|
|
365
|
+
self.assertEqual(len(y), 3)
|
|
366
|
+
self.assertIn('time', y.keys())
|
|
367
|
+
self.assertIn('0.channel', y.keys())
|
|
368
|
+
self.assertIn('0.da', y.keys())
|
|
369
|
+
self.assertEqual(len(y['time']), 9 * len(x['time']))
|
|
370
|
+
self.assertEqual(len(y['time']), len(y['0.channel']))
|
|
371
|
+
self.assertEqual(len(y['time']), len(y['0.da']))
|
|
372
|
+
|
|
373
|
+
y = abf.log(join_sweeps=True, use_names=True)
|
|
374
|
+
self.assertEqual(len(y), 3)
|
|
375
|
+
self.assertIn('time', y.keys())
|
|
376
|
+
self.assertIn('IN 0', y.keys())
|
|
377
|
+
self.assertIn('OUT 0', y.keys())
|
|
378
|
+
self.assertEqual(len(y['time']), 9 * len(x['time']))
|
|
379
|
+
self.assertEqual(len(y['time']), len(y['IN 0']))
|
|
380
|
+
self.assertEqual(len(y['time']), len(y['OUT 0']))
|
|
381
|
+
|
|
382
|
+
y = abf.log(join_sweeps=True, use_names=True, include_da=False)
|
|
383
|
+
self.assertEqual(len(y), 2)
|
|
384
|
+
self.assertIn('time', y.keys())
|
|
385
|
+
self.assertIn('IN 0', y.keys())
|
|
386
|
+
self.assertEqual(len(y['time']), 9 * len(x['time']))
|
|
387
|
+
self.assertEqual(len(y['time']), len(y['IN 0']))
|
|
388
|
+
|
|
389
|
+
# Test conversion to Myokit protocol
|
|
390
|
+
p = abf.da_protocol(0)
|
|
91
391
|
self.assertEqual(len(p), 18)
|
|
392
|
+
self.assertEqual(p.code(), V1_PROTOCOL)
|
|
92
393
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# Load file
|
|
97
|
-
path = os.path.join(DIR_FORMATS, 'abf-v2.abf')
|
|
98
|
-
abf = axon.AbfFile(path)
|
|
99
|
-
|
|
100
|
-
# Check version info
|
|
101
|
-
self.assertIn('version 2.0', abf.info())
|
|
102
|
-
self.assertEqual(
|
|
103
|
-
abf.info(),
|
|
104
|
-
'Axon Binary File: abf-v2.abf\n'
|
|
105
|
-
'ABF Format version 2.0\n'
|
|
106
|
-
'Recorded on: 2014-10-01 14:03:55.980999\n'
|
|
107
|
-
'Acquisition mode: 5: Episodic stimulation mode\n'
|
|
108
|
-
'Protocol set for 1 trials, spaced 0.0s apart.\n'
|
|
109
|
-
' with 1 runs per trial, spaced 0.0s apart.\n'
|
|
110
|
-
' and 1 sweeps per run, spaced 5.0s apart.\n'
|
|
111
|
-
'Sampling rate: 10000.0 Hz\n'
|
|
112
|
-
'Channel 0: "IN 0"\n'
|
|
113
|
-
' Unit: pA\n'
|
|
114
|
-
' Low-pass filter: 10000.0 Hz\n'
|
|
115
|
-
' Cm (telegraphed): 6.34765625 pF')
|
|
116
|
-
# Test getting full header runs without crashing
|
|
117
|
-
abf.info(True)
|
|
118
|
-
|
|
119
|
-
# Test len returns number of sweeps
|
|
120
|
-
self.assertEqual(len(abf), 1)
|
|
121
|
-
|
|
122
|
-
# Test data access
|
|
123
|
-
self.assertEqual(abf.data_channels(), 1) # 1 data channel
|
|
124
|
-
x = abf.extract_channel(0)
|
|
125
|
-
self.assertEqual(len(x), 1 + len(abf)) # sweeps + time
|
|
126
|
-
self.assertEqual(len(x[0]), len(x[1]))
|
|
127
|
-
y = abf.extract_channel_as_myokit_log(0)
|
|
128
|
-
self.assertEqual(len(y), 1 + len(abf)) # sweeps + time
|
|
129
|
-
z = abf.myokit_log()
|
|
130
|
-
self.assertEqual(len(z), 6) # time + channel + 4 protocol channels
|
|
131
|
-
sweep = abf[0]
|
|
132
|
-
self.assertEqual(len(sweep), 1) # 1 channel in sweep
|
|
133
|
-
channel = sweep[0]
|
|
134
|
-
self.assertEqual(len(abf) * len(channel.times()), len(z.time()))
|
|
135
|
-
self.assertEqual(len(abf) * len(channel.values()), len(z.time()))
|
|
394
|
+
p = abf.da_protocol(0, vu=myokit.units.V, tu='s')
|
|
395
|
+
self.assertEqual(len(p), 18)
|
|
396
|
+
self.assertEqual(p.code(), V1_PROTOCOL_VS)
|
|
136
397
|
|
|
137
|
-
|
|
138
|
-
self.assertEqual(abf.protocol_channels(), 4) # 4 protocol channels
|
|
139
|
-
p = abf.myokit_protocol()
|
|
140
|
-
self.assertEqual(len(p), 2) # 2 steps in this protocol
|
|
141
|
-
self.assertEqual(abf.protocol_holding_level(0), -120)
|
|
142
|
-
p = abf.myokit_protocol(0)
|
|
143
|
-
self.assertEqual(len(p), 2)
|
|
144
|
-
|
|
145
|
-
def test_read_protocol_v1(self):
|
|
398
|
+
def test_read_protocol_file_v1(self):
|
|
146
399
|
# Test reading a v1 protocol file.
|
|
147
400
|
|
|
148
401
|
# Load file
|
|
@@ -150,37 +403,222 @@ class AbfTest(unittest.TestCase):
|
|
|
150
403
|
abf = axon.AbfFile(path)
|
|
151
404
|
|
|
152
405
|
# Check version info
|
|
153
|
-
self.assertIn('version 1.65', abf.
|
|
154
|
-
self.assertEqual(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
)
|
|
165
|
-
# Test getting full header runs without crashing
|
|
166
|
-
abf.info(True)
|
|
406
|
+
self.assertIn('version 1.65', abf.meta_str())
|
|
407
|
+
self.assertEqual(abf.meta_str(), V1_PROTO_INFO)
|
|
408
|
+
abf.meta_str(True) # Test getting full header runs without crashing
|
|
409
|
+
self.assertEqual(abf.channel_count(), 0)
|
|
410
|
+
self.assertEqual(abf.channel_names(), [])
|
|
411
|
+
self.assertEqual(abf.channel_units(), [])
|
|
412
|
+
self.assertEqual(abf.da_count(), 1)
|
|
413
|
+
self.assertEqual(abf.da_names(), ['Cmd 0'])
|
|
414
|
+
self.assertEqual(abf.da_names(0), 'Cmd 0')
|
|
415
|
+
self.assertEqual(abf.da_units(), [myokit.units.mV])
|
|
416
|
+
self.assertEqual(abf.da_units(0), myokit.units.mV)
|
|
417
|
+
#self.assertEqual(len(abf.log(join_sweeps=True)), 2)
|
|
167
418
|
|
|
168
419
|
# Load, force as protocol
|
|
169
420
|
path = os.path.join(DIR_FORMATS, 'abf-protocol.pro')
|
|
170
421
|
abf = axon.AbfFile(path, is_protocol_file=True)
|
|
422
|
+
self.assertEqual(abf.channel_count(), 0)
|
|
423
|
+
self.assertEqual(abf.channel_count(), 0)
|
|
424
|
+
self.assertEqual(abf.da_count(), 1)
|
|
171
425
|
|
|
172
426
|
# Check version info
|
|
173
|
-
self.assertIn('version 1.65', abf.
|
|
174
|
-
self.assertIn('Axon Protocol File', abf.
|
|
427
|
+
self.assertIn('version 1.65', abf.meta_str())
|
|
428
|
+
self.assertIn('Axon Protocol File', abf.meta_str())
|
|
175
429
|
|
|
176
430
|
# Test protocol extraction
|
|
177
|
-
p = abf.
|
|
431
|
+
p = abf.da_protocol()
|
|
178
432
|
self.assertEqual(len(p), 60)
|
|
179
433
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
434
|
+
def test_read_v2(self):
|
|
435
|
+
# Test reading a version 2 file.
|
|
436
|
+
|
|
437
|
+
# Load file
|
|
438
|
+
path = os.path.join(DIR_FORMATS, 'abf-v2.abf')
|
|
439
|
+
abf = axon.AbfFile(path)
|
|
440
|
+
self.assertEqual(abf.path(), path)
|
|
441
|
+
self.assertEqual(abf.filename(), 'abf-v2.abf')
|
|
442
|
+
|
|
443
|
+
# Check getting info
|
|
444
|
+
self.assertIn('version 2.0', abf.meta_str())
|
|
445
|
+
self.maxDiff = None
|
|
446
|
+
self.assertEqual(abf.meta_str(), V2_INFO)
|
|
447
|
+
|
|
448
|
+
# Test getting full header runs without crashing
|
|
449
|
+
abf.meta_str(True)
|
|
450
|
+
|
|
451
|
+
# Get version
|
|
452
|
+
self.assertEqual(abf.version(), '2.0.0.0')
|
|
453
|
+
|
|
454
|
+
# Sweep count
|
|
455
|
+
self.assertEqual(len(abf), 37)
|
|
456
|
+
self.assertEqual(abf.sweep_count(), 37)
|
|
457
|
+
|
|
458
|
+
# Test access to A/D channels via native API
|
|
459
|
+
self.assertIsInstance(abf[0], axon.Sweep)
|
|
460
|
+
self.assertIsInstance(abf[1], axon.Sweep)
|
|
461
|
+
self.assertIsInstance(abf[36], axon.Sweep)
|
|
462
|
+
self.assertFalse(abf[0] is abf[1])
|
|
463
|
+
self.assertEqual(len(abf[0]), 2)
|
|
464
|
+
self.assertEqual(len(abf[36]), 2)
|
|
465
|
+
self.assertIsInstance(abf[0][0], axon.Channel)
|
|
466
|
+
self.assertIsInstance(abf[0][1], axon.Channel)
|
|
467
|
+
self.assertFalse(abf[0][0] is abf[0][1])
|
|
468
|
+
|
|
469
|
+
# Test abf.Channel methods
|
|
470
|
+
channel = abf[0][0]
|
|
471
|
+
self.assertEqual(channel.index(), 0)
|
|
472
|
+
self.assertEqual(channel.name(), 'IN 0')
|
|
473
|
+
self.assertIsInstance(channel.unit(), myokit.Unit)
|
|
474
|
+
self.assertEqual(channel.unit(), myokit.units.pA)
|
|
475
|
+
self.assertEqual(str(channel),
|
|
476
|
+
'Channel(0 "IN 0"); 516 points sampled at 20000.0Hz,'
|
|
477
|
+
' starts at t=0.0.')
|
|
478
|
+
self.assertEqual(len(channel.times()), len(channel.values()))
|
|
479
|
+
self.assertFalse(np.all(channel.times() == channel.values()))
|
|
480
|
+
|
|
481
|
+
# Test SweepSource info
|
|
482
|
+
self.assertTrue(abf.equal_length_sweeps())
|
|
483
|
+
self.assertEqual(abf.time_unit(), myokit.units.s)
|
|
484
|
+
|
|
485
|
+
# Test A/D channel access via SweepSource interface
|
|
486
|
+
self.assertEqual(abf.channel_count(), 1)
|
|
487
|
+
self.assertEqual(abf.channel_names(), ['IN 0'])
|
|
488
|
+
self.assertEqual(abf.channel_names(0), 'IN 0')
|
|
489
|
+
self.assertEqual(abf.channel_units(), [myokit.units.pA])
|
|
490
|
+
self.assertEqual(abf.channel_units(0), myokit.units.pA)
|
|
491
|
+
|
|
492
|
+
times, values = abf.channel(0)
|
|
493
|
+
self.assertEqual(37, len(times), len(values))
|
|
494
|
+
self.assertEqual(len(times[0]), len(values[0]))
|
|
495
|
+
self.assertEqual(len(times[0]), len(times[1]), len(values[1]))
|
|
496
|
+
self.assertEqual(len(times[0]), len(times[2]), len(values[2]))
|
|
497
|
+
self.assertEqual(len(times[0]), len(times[17]), len(values[13]))
|
|
498
|
+
self.assertEqual(len(times[0]), len(times[36]), len(values[36]))
|
|
499
|
+
|
|
500
|
+
tj, vj = abf.channel(0, join_sweeps=True)
|
|
501
|
+
self.assertTrue(np.all(tj == np.concatenate(times)))
|
|
502
|
+
self.assertTrue(np.all(vj == np.concatenate(values)))
|
|
503
|
+
|
|
504
|
+
# Channel doesn't exist
|
|
505
|
+
self.assertRaises(IndexError, abf.channel, -1)
|
|
506
|
+
self.assertRaises(IndexError, abf.channel, 1)
|
|
507
|
+
self.assertRaises(KeyError, abf.channel, 'OUT 0')
|
|
508
|
+
|
|
509
|
+
# Test D/A output access via SweepSource interface
|
|
510
|
+
self.assertEqual(abf.da_count(), 1)
|
|
511
|
+
self.assertEqual(abf.da_names(), ['Cmd 0'])
|
|
512
|
+
self.assertEqual(abf.da_names(0), 'Cmd 0')
|
|
513
|
+
self.assertEqual(abf.da_units(), [myokit.units.mV])
|
|
514
|
+
self.assertEqual(abf.da_units(0), myokit.units.mV)
|
|
515
|
+
|
|
516
|
+
da_times, da_values = abf.da(0)
|
|
517
|
+
self.assertEqual(37, len(da_times), len(da_values))
|
|
518
|
+
self.assertEqual(len(da_times[0]), len(da_values[0]))
|
|
519
|
+
self.assertEqual(len(da_times[0]), len(da_times[1]), len(da_values[1]))
|
|
520
|
+
self.assertEqual(len(da_times[0]), len(da_times[4]), len(da_values[9]))
|
|
521
|
+
self.assertEqual(len(da_times[0]), len(times[0]))
|
|
522
|
+
self.assertTrue(np.all(times[0] == da_times[0]))
|
|
523
|
+
self.assertFalse(np.all(values[0] == da_values[0]))
|
|
524
|
+
|
|
525
|
+
tj, vj = abf.da(0, join_sweeps=True)
|
|
526
|
+
self.assertTrue(np.all(tj == np.concatenate(da_times)))
|
|
527
|
+
self.assertTrue(np.all(vj == np.concatenate(da_values)))
|
|
528
|
+
|
|
529
|
+
# Conversion to data log without joining
|
|
530
|
+
x = abf.log()
|
|
531
|
+
k = list(x.keys())
|
|
532
|
+
self.assertEqual(len(x), 1 + 2 * 37)
|
|
533
|
+
self.assertIn('time', x)
|
|
534
|
+
self.assertIn('0.0.channel', k)
|
|
535
|
+
self.assertIn('1.0.channel', k)
|
|
536
|
+
self.assertIn('2.0.channel', k)
|
|
537
|
+
self.assertIn('3.0.channel', k)
|
|
538
|
+
self.assertIn('36.0.channel', k)
|
|
539
|
+
self.assertIn('0.0.da', k)
|
|
540
|
+
self.assertIn('5.0.da', k)
|
|
541
|
+
self.assertIn('16.0.da', k)
|
|
542
|
+
self.assertIn('36.0.da', k)
|
|
543
|
+
self.assertEqual(len(x['time']), len(x['5.0.channel']))
|
|
544
|
+
self.assertEqual(len(x['7.0.da']), len(x['5.0.channel']))
|
|
545
|
+
|
|
546
|
+
x = abf.log(include_da=False)
|
|
547
|
+
k = list(x.keys())
|
|
548
|
+
self.assertEqual(len(x), 1 + 1 * 37)
|
|
549
|
+
self.assertIn('time', x)
|
|
550
|
+
self.assertIn('0.0.channel', k)
|
|
551
|
+
self.assertIn('1.0.channel', k)
|
|
552
|
+
self.assertIn('2.0.channel', k)
|
|
553
|
+
self.assertIn('3.0.channel', k)
|
|
554
|
+
self.assertIn('36.0.channel', k)
|
|
555
|
+
self.assertNotIn('0.0.da', k)
|
|
556
|
+
self.assertNotIn('7.0.da', k)
|
|
557
|
+
self.assertNotIn('36.0.da', k)
|
|
558
|
+
self.assertEqual(len(x['time']), len(x['6.0.channel']))
|
|
559
|
+
|
|
560
|
+
x = abf.log(use_names=True)
|
|
561
|
+
k = list(x.keys())
|
|
562
|
+
self.assertEqual(len(x), 1 + 2 * 37)
|
|
563
|
+
self.assertIn('time', x)
|
|
564
|
+
self.assertIn('0.IN 0', k)
|
|
565
|
+
self.assertIn('1.IN 0', k)
|
|
566
|
+
self.assertIn('2.IN 0', k)
|
|
567
|
+
self.assertIn('36.IN 0', k)
|
|
568
|
+
self.assertIn('0.Cmd 0', k)
|
|
569
|
+
self.assertIn('5.Cmd 0', k)
|
|
570
|
+
self.assertIn('16.Cmd 0', k)
|
|
571
|
+
self.assertIn('36.Cmd 0', k)
|
|
572
|
+
self.assertEqual(len(x['time']), len(x['5.IN 0']))
|
|
573
|
+
self.assertEqual(len(x['7.Cmd 0']), len(x['5.IN 0']))
|
|
574
|
+
|
|
575
|
+
# Conversion to data log with joining
|
|
576
|
+
y = abf.log(join_sweeps=True)
|
|
577
|
+
self.assertEqual(len(y), 3)
|
|
578
|
+
self.assertIn('time', y.keys())
|
|
579
|
+
self.assertIn('0.channel', y.keys())
|
|
580
|
+
self.assertIn('0.da', y.keys())
|
|
581
|
+
self.assertEqual(len(y['time']), 37 * len(x['time']))
|
|
582
|
+
self.assertEqual(len(y['time']), len(y['0.channel']))
|
|
583
|
+
self.assertEqual(len(y['time']), len(y['0.da']))
|
|
584
|
+
|
|
585
|
+
y = abf.log(join_sweeps=True, use_names=True)
|
|
586
|
+
self.assertEqual(len(y), 3)
|
|
587
|
+
self.assertIn('time', y.keys())
|
|
588
|
+
self.assertIn('IN 0', y.keys())
|
|
589
|
+
self.assertIn('Cmd 0', y.keys())
|
|
590
|
+
self.assertEqual(len(y['time']), 37 * len(x['time']))
|
|
591
|
+
self.assertEqual(len(y['time']), len(y['IN 0']))
|
|
592
|
+
self.assertEqual(len(y['time']), len(y['Cmd 0']))
|
|
593
|
+
|
|
594
|
+
y = abf.log(join_sweeps=True, use_names=True, include_da=False)
|
|
595
|
+
self.assertEqual(len(y), 2)
|
|
596
|
+
self.assertIn('time', y.keys())
|
|
597
|
+
self.assertIn('IN 0', y.keys())
|
|
598
|
+
self.assertEqual(len(y['time']), 37 * len(x['time']))
|
|
599
|
+
self.assertEqual(len(y['time']), len(y['IN 0']))
|
|
600
|
+
|
|
601
|
+
# Test conversion to Myokit protocol
|
|
602
|
+
p = abf.da_protocol(0)
|
|
603
|
+
self.assertEqual(len(p), 37 * 2)
|
|
604
|
+
self.assertEqual(p.code(), V2_PROTOCOL)
|
|
605
|
+
|
|
606
|
+
# Test conversion with initial holding as in the real experiment
|
|
607
|
+
p = abf.da_protocol(0, include_initial_holding=True)
|
|
608
|
+
e = p.events()
|
|
609
|
+
self.assertEqual(e[0].level(), -120) # Pre step
|
|
610
|
+
self.assertEqual(e[0].start(), 0)
|
|
611
|
+
self.assertEqual(e[0].duration(), 0.4)
|
|
612
|
+
self.assertEqual(e[1].level(), -100) # Real step
|
|
613
|
+
self.assertEqual(e[1].start(), 0.4)
|
|
614
|
+
self.assertEqual(e[1].duration(), 25)
|
|
615
|
+
self.assertEqual(e[2].level(), -120) # Shortened post-step
|
|
616
|
+
self.assertEqual(e[2].start(), 25.4)
|
|
617
|
+
self.assertEqual(e[2].duration(), 4974.6)
|
|
618
|
+
self.assertEqual(e[3].level(), -120) # Next pre step
|
|
619
|
+
self.assertEqual(e[3].start(), 5000)
|
|
620
|
+
self.assertEqual(e[3].duration(), 0.4)
|
|
621
|
+
self.assertEqual(len(e), 37 * 3)
|
|
184
622
|
|
|
185
623
|
def test_matplotlib_figure(self):
|
|
186
624
|
# Test figure drawing method (doesn't inspect output).
|
|
@@ -189,7 +627,8 @@ class AbfTest(unittest.TestCase):
|
|
|
189
627
|
matplotlib.use('template')
|
|
190
628
|
path = os.path.join(DIR_FORMATS, 'abf-v1.abf')
|
|
191
629
|
abf = axon.AbfFile(path)
|
|
192
|
-
abf.matplotlib_figure()
|
|
630
|
+
f = abf.matplotlib_figure()
|
|
631
|
+
self.assertIsInstance(f, matplotlib.figure.Figure)
|
|
193
632
|
|
|
194
633
|
|
|
195
634
|
class AtfTest(unittest.TestCase):
|
|
@@ -219,6 +658,15 @@ class AtfTest(unittest.TestCase):
|
|
|
219
658
|
for k, v in log.items():
|
|
220
659
|
self.assertTrue(np.all(v == log2[k]))
|
|
221
660
|
|
|
661
|
+
# Deprecated method
|
|
662
|
+
with WarningCollector() as w:
|
|
663
|
+
log3 = axon.AtfFile(path).myokit_log()
|
|
664
|
+
self.assertIn('deprecated', w.text())
|
|
665
|
+
self.assertEqual(len(log), len(log3))
|
|
666
|
+
self.assertEqual(set(log.keys()), set(log3.keys()))
|
|
667
|
+
for k, v in log.items():
|
|
668
|
+
self.assertTrue(np.all(v == log3[k]))
|
|
669
|
+
|
|
222
670
|
# Write selected fields
|
|
223
671
|
axon.save_atf(log, path, fields=['time', 'sint'])
|
|
224
672
|
log2 = axon.load_atf(path)
|
|
@@ -272,7 +720,7 @@ class AtfTest(unittest.TestCase):
|
|
|
272
720
|
f.write('1\t10\t20\n')
|
|
273
721
|
f.write('2\t30\t40\n')
|
|
274
722
|
self.assertRaisesRegex(
|
|
275
|
-
Exception, 'double
|
|
723
|
+
Exception, 'double quotes', axon.load_atf, path)
|
|
276
724
|
|
|
277
725
|
# Bad column headers
|
|
278
726
|
with open(path, 'w') as f:
|
|
@@ -363,8 +811,9 @@ class AtfTest(unittest.TestCase):
|
|
|
363
811
|
# Read atf file
|
|
364
812
|
atf = myokit.formats.axon.AtfFile(path)
|
|
365
813
|
|
|
366
|
-
# Test filename()
|
|
367
|
-
self.assertEqual(atf.
|
|
814
|
+
# Test filename() and path()
|
|
815
|
+
self.assertEqual(atf.path(), path)
|
|
816
|
+
self.assertEqual(atf.filename(), 'test.atf')
|
|
368
817
|
|
|
369
818
|
# Test iter and getitem
|
|
370
819
|
self.assertEqual(len(list(iter(atf))), 3)
|
|
@@ -394,7 +843,11 @@ class AtfTest(unittest.TestCase):
|
|
|
394
843
|
self.assertEqual(len(atf), 3)
|
|
395
844
|
|
|
396
845
|
# Test info
|
|
397
|
-
|
|
846
|
+
meta = atf.meta_str()
|
|
847
|
+
self.assertIn('myokit', meta)
|
|
848
|
+
with WarningCollector() as w:
|
|
849
|
+
self.assertEqual(meta, atf.info())
|
|
850
|
+
self.assertIn('deprecated', w.text())
|
|
398
851
|
|
|
399
852
|
# Test version
|
|
400
853
|
self.assertEqual(atf.version(), '1.0')
|