Skip to content

fileLoader_abf

Classes¤

fileLoader_abf ¤

Bases: fileLoader_base

Source code in sanpy/fileloaders/fileLoader_abf.py
 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

Functions¤

All material is Copyright 2011-2023 Robert H. Cudmore