-
Notifications
You must be signed in to change notification settings - Fork 1
/
localFunctions.py
242 lines (210 loc) · 9.82 KB
/
localFunctions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
'''
Local functions for convert2nwbCaImg
'''
import numpy as np
from pynwb.core import VectorData
from pynwb.ophys import TwoPhotonSeries
from pynwb.icephys import CurrentClampSeries
def appendLinescans(linescans):
'''
appendedLinescans = appendLinescans(linescans)
Function takes linescans of unequal widths and appends them to have the
the same width and outputs the appended linescans as a 3D matrix with
the first dimension corresponding to the linescan number.
'''
# Find the largest width
nScans = len(linescans)
length = len(linescans[0])
maxWidth = len(linescans[0][0])
for iScan in range(nScans):
maxWidth = max([maxWidth, len(linescans[iScan][0])])
for iScan in range(nScans):
array2add = np.empty([len(linescans[iScan]),maxWidth - len(linescans[iScan][0])])
array2add[:] = np.nan
linescans[iScan] = np.append(linescans[iScan], array2add, axis=1)
return linescans
def setTwoPhotonSeries(nwb, input):
'''
nwb = setTwoPhotonSeries(nwb, input)
Function creates, names, and adds a two-photon series data to a given NWB
file.
Input: nwb - the NWB file object.
input - a dictionary with the following fields:
indicator - a string variable with the calcium indicator name
(e.g., 'Fluo5f' or 'Alexa594').
imagingPlane - the imaging plane object corresponding to the
indicator.
imagingRate - a scalar with the rate at which individual full
linescans are obtained.
lineRate - a scalar wit the frequency of individual lines within
a single linescan.
data - an n-dimensional matrix containing two-photon series
linescan data. The first dimension corresponds to time
(that is, individual linescans). The second dimension
corresponds to individual lines along the vertical
denditic segment. The third dimension corresponds to the
dendritic width. NaNs are appended at the end of linescans
to make them equal in width.
dendriteID - a string variable with the dendritic ID (i.e.,
'bottom', 'middle', and 'top').
Output: nwb - the NWB file object containing the newly added two-photon
series data.
'''
# Name the two-photon series to the NWB file
if input['indicator'] in 'Fluo5f':
opticalChannel = 'Green'
elif input['indicator'] in 'Alexa594':
opticalChannel = 'Red'
if input['dendriteID'] in 'bottom':
dendriteID = '1'
elif input['dendriteID'] in 'middle':
dendriteID = '2'
elif input['dendriteID'] in 'top':
dendriteID = '3'
# Create image series
image_series = TwoPhotonSeries(
name = 'TwoPhotonSeries' + opticalChannel + dendriteID,
description = input['indicator'] + ' linescans of the ' + input['dendriteID'] + ' dendrite',
imaging_plane = input['imagingPlane'],
starting_time = 0.0,
rate = input['imagingRate'],
scan_line_rate = input['lineRate'],
data = input['data'],
unit = 'a.u.',
comments = 'This two-photon series contains ' + input['indicator'] + ' linescans of the ' +\
input['dendriteID'] + ' (ROI) with the first dimension corresponding to time ' +\
'(or to individual linescans). Each linescan is 1-sec in duration with ' +\
'20-sec intervals between two linescans. The second dimension corresponds ' +\
'to individual lines spanning the length of the dendrite in the ROI. ' +\
'The third dimension corresponds to the width of the dendrite. ' +\
'Some linescans may contain appended NaN values to make ' +\
'widths of different linescans be equal within the same ROI. ' +\
'data_continuity = step')
nwb.add_acquisition(image_series)
return nwb
def setDeltaFSeries(nwb, input):
'''
nwb = setDeltaFSeries(nwb, input)
Function creates, names, and adds a two-photon series delta fluorescence
data to a given NWB file.
Input: nwb - the NWB file object.
input - a dictionary with the following fields:
indicator - a string variable with the calcium indicator name
(e.g., 'Fluo5f' or 'Alexa594').
imagingPlane - the imaging plane object corresponding to the
indicator.
imagingRate - a scalar with the rate at which individual full
linescans are obtained.
lineRate - a scalar wit the frequency of individual lines within
a single linescan.
data - a 2D matrix containing two-photon series delta F data.
The first dimension corresponds to time (that is, individual
linescans). The second dimension corresponds to individual
lines along the vertical dendritic segment. The data is
averaged across the dendritic width.
dendriteID - a string variable with the dendritic ID (i.e.,
'bottom', 'middle', and 'top').
Output: nwb - the NWB file object containing the newly added two-photon
delta F series data.
'''
# Name and add the two-photon delta F series to the NWB file
if input['dendriteID'] in 'bottom':
dendriteID = '1'
elif input['dendriteID'] in 'middle':
dendriteID = '2'
elif input['dendriteID'] in 'top':
dendriteID = '3'
# Create image series
image_series = TwoPhotonSeries(
name = 'TwoPhotonDeltaFSeries' + dendriteID,
description = 'Delta F data for the ' + input['dendriteID'] +\
' calculated based on ' + input['indicator'] + '.',
imaging_plane = input['imagingPlane'],
starting_time = 0.0,
rate = input['imagingRate'],
scan_line_rate = input['lineRate'],
data = input['data'],
unit = 'normalised',
comments = 'This two-photon series contains delta F data calculated based on ' +\
input['indicator'] + ' for the ' + input['dendriteID'] + ' (ROI) ' +\
'with the first dimension corresponding to time ' +\
'(or to individual linescans). Each linescan is 1-sec in duration with ' +\
'20-sec intervals between two linescans. The second dimension corresponds ' +\
'to individual lines spanning the length of the dendrite in the ROI. ' +\
'The data is averaged across the dendritic width. ' +\
'data_continuity = step')
nwb.add_acquisition(image_series)
return nwb
def setCClampSeries(nwb, input):
'''
nwb = setCClampSeries(nwb, input)
Function creates, names, and adds a current clamp series data to a given
NWB file.
Input: nwb - the NWB file object.
input - a dictionary with the following fields:
ephysTime - a time vector for a single recording sweep.
nSweeps - The total number of sweeps for every ROI.
imagingRate - a scalar with the rate at which individual full
linescans are obtained.
data - a 2D matrix containing somatic current clamp recordings
corresponding to the initial part of the calcium
imaging period at dendritic ROI. The first dimension
corresponds to individual recording sweeps. The second
dimension corresponds to individual sweep data samples.
electrode - an electrode object.
dendriteID - a string variable with the dendritic ID (i.e.,
'bottom', 'middle', and 'top').
Output: nwb - the NWB file object containing the newly added current
clamp series data.
'''
if input['dendriteID'] in 'bottom':
nSweeps = input['nSweeps'][0]
sweeps = list(range(0, nSweeps))
dendriteID = '1'
elif input['dendriteID'] in 'middle':
nSweeps = input['nSweeps'][1]
sweeps = list(range(input['nSweeps'][0],input['nSweeps'][0]+nSweeps))
dendriteID = '2'
else:
nSweeps = input['nSweeps'][2]
sweeps = list(range(input['nSweeps'][0]+input['nSweeps'][1],input['nSweeps'][0]+input['nSweeps'][1]+nSweeps))
dendriteID = '3'
timestamps = input['ephysTime']/1000; # sec
current_clamp_series = CurrentClampSeries(
name = 'CurrentClampSeries' + dendriteID,
description = 'Somatic current clamp recording corresponding to ' +\
'the initial part of the calcium imaging period ' +\
'at ' + input['dendriteID'] + ' dendrite.',
data = input['data'][sweeps],
gain = 1.,
unit = 'millivolt',
electrode = input['electrode'],
stimulus_description = 'N/A',
timestamps = timestamps,
comments = 'Somatic current clamp recording corresponding to ' +\
'the initial part of the calcium imaging period ' +\
'at ' + input['dendriteID'] + ' dendrite.' +\
'The first dimension corresponds to individual ' +\
'recording sweeps. The second dimension corresponds to ' +\
'individual sweep data samples. The associated timestamps ' +\
'variable provides timestamps for the second dimension. ' +\
'This variable has to be combined with starting_time and ' +\
'rate variables to get absolute timestamps ' +\
'for each data point. ' +\
'data_continuity = step. ' +\
'rate = ' + str(input['imagingRate']))
nwb.add_acquisition(current_clamp_series)
return nwb
def reshapeData(data):
'''
reshapedArray = reshapeData(data)
Function converts an ndarray of the shape (n, )
into an ndarray of the shape (n, m, p).
'''
dim1size = len(data)
dim2size = len(data[0])
dim3size = len(data[0][0])
reshapedArray = np.empty((dim1size,dim2size,dim3size))
for element in range(dim1size):
reshapedArray[element] = data[element]
return reshapedArray