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 | class fileLoader_abf(fileLoader_base):
loadFileType = ".abf"
# @property
# def loadFileType(self):
# return 'abf'
def loadFile(self):
self._loadAbf()
def _loadAbf(
self, byteStream=None, loadData: bool = True, stimulusFileFolder: str = None
):
"""Load pyAbf from path."""
try:
# logger.info(f'loadData:{loadData}')
if byteStream is not None:
logger.info("Loading byte stream")
self._abf = pyabf.ABF(byteStream)
self._isBytesIO = True
else:
# logger.info(f'Loading file: {self.filepath}')
self._abf = pyabf.ABF(
self.filepath,
loadData=loadData,
stimulusFileFolder=stimulusFileFolder,
)
except NotImplementedError as e:
logger.error(f" did not load abf file: {self.filepath}")
logger.error(f" NotImplementedError exception was: {e}")
self._loadError = True
self._abf = None
except Exception as e:
# some abf files throw: 'unpack requires a buffer of 234 bytes'
# 'ABF' object has no attribute 'sweepEpochs'
logger.error(f" did not load abf file: {self.filepath}")
logger.error(f" unknown Exception was: {e}")
self._loadError = True
self._abf = None
self._epochTableList = None
if not self._loadError and loadData:
try:
_tmp = self._abf.sweepEpochs.p1s
except AttributeError as e:
logger.warning(
f" did not find epochTable loadData:{loadData}: {e} in file {self.filepath}"
)
else:
_numSweeps = len(self._abf.sweepList)
self._epochTableList = [None] * _numSweeps
for _sweepIdx in range(_numSweeps):
self._abf.setSweep(_sweepIdx)
self._epochTableList[_sweepIdx] = sanpy.fileloaders.epochTable(
self._abf
)
self._abf.setSweep(0)
self._sweepList = self._abf.sweepList
self._sweepLengthSec = (
self._abf.sweepLengthSec
) # assuming all sweeps have the same duration
# on load, sweep is 0
if loadData:
_numRows = self._abf.sweepX.shape[0]
numSweeps = len(self._sweepList)
self._sweepX = np.zeros((_numRows, 1))
self._sweepY = np.zeros((_numRows, numSweeps))
self._sweepC = np.zeros((_numRows, numSweeps))
_channel = 0
for sweep in self._sweepList:
self._abf.setSweep(sweepNumber=sweep, channel=_channel)
if sweep == 0:
self._sweepX[
:, sweep
] = self._abf.sweepX # <class 'numpy.ndarray'>, (60000,)
self._sweepY[:, sweep] = self._abf.sweepY
try:
self._sweepC[:, sweep] = self._abf.sweepC
except ValueError as e:
# pyabf will raise this error if it is an atf file
logger.warning(
f" exception fetching sweepC for sweep {sweep} with {self.numSweeps}: {e}"
)
#
# if we were recorded with a stimulus file abf
# needed to assign stimulusWaveformFromFile
try:
tmpSweepC = self._abf.sweepC
self._sweepC[:, sweep] = self._abf.sweepC
except ValueError as e:
logger.warning(f"ba has no sweep {sweep} sweepC ???")
# not needed
self._abf.setSweep(0)
# get v from pyAbf
self._dataPointsPerMs = self._abf.dataPointsPerMs
# turned back on when implementing Santana rabbit Ca kymographs
abfDateTime = self._abf.abfDateTime # 2019-01-14 15:20:48.196000
acqDate = abfDateTime.strftime("%Y-%m-%d")
acqTime = abfDateTime.strftime("%H:%M:%S")
logger.info(f'acqDate:"{acqDate}')
logger.info(f'acqTime:"{acqTime}')
# self._acqDate = abfDateTime.strftime("%Y-%m-%d")
# self._acqTime = abfDateTime.strftime("%H:%M:%S")
self.setAcqDate(acqDate)
self.setAcqTime(acqTime)
self._numChannels = len(self._abf.adcUnits)
if self._numChannels > 1:
logger.warning(
f" SanPy does not work with multi-channel recordings numChannels is {self._numChannels} {self._path}"
)
# logger.warning(' Will default to channel 0')
# self.sweepUnitsY = self.adcUnits[channel]
channel = 0
# dacUnits = self._abf.dacUnits[channel]
adcUnits = self._abf.adcUnits[channel]
# print(' adcUnits:', adcUnits) # 'mV'
self._sweepLabelY = adcUnits
self._sweepLabelX = "sec"
# self._sweepLabelX = self._abf.sweepLabelX
# self._sweepLabelY = self._abf.sweepLabelY
if self._sweepLabelY in ["pA", "nA"]:
self._recordingMode = recordingModes.vclamp # 'V-Clamp'
# self._sweepY_label = self._abf.sweepUnitsY
elif self._sweepLabelY in ["mV"]:
self._recordingMode = recordingModes.iclamp #'I-Clamp'
# self._sweepY_label = self._abf.sweepUnitsY
else:
logger.warning(f'did not understand adcUnit "{adcUnits}"')
#
self.myFileType = "abf"
# base sanpy does not keep the abf around
# logger.warning('[[[TURNED BACK ON]]] I turned off assigning self._abf=None for stoch-res stim file load')
self._abf = None
|