Package qubx :: Module data_abf
[hide private]
[frames] | no frames]

Source Code for Module qubx.data_abf

  1  """ 
  2  Reads Axon binary data using ABFFIO.dll, if available. 
  3   
  4  Copyright 2008-2013 Research Foundation State University of New York  
  5  This file is part of QUB Express.                                           
  6   
  7  QUB Express is free software; you can redistribute it and/or modify           
  8  it under the terms of the GNU General Public License as published by  
  9  the Free Software Foundation, either version 3 of the License, or     
 10  (at your option) any later version.                                   
 11   
 12  QUB Express is distributed in the hope that it will be useful,                
 13  but WITHOUT ANY WARRANTY; without even the implied warranty of        
 14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
 15  GNU General Public License for more details.                          
 16   
 17  You should have received a copy of the GNU General Public License,    
 18  named LICENSE.txt, in the QUB Express program directory.  If not, see         
 19  <http://www.gnu.org/licenses/>.                                       
 20   
 21  """ 
 22   
 23  from qubx.data_types import * 
 24  from ctypes import * 
 25   
 26  c_uint_p = POINTER(c_uint) 
 27  c_short_p = POINTER(c_short) 
 28   
 29  try: 
 30      abffio = windll.LoadLibrary("ABFFIO.dll") 
 31      from ctypes.wintypes import * 
 32   
 33      ABF_ADCCOUNT = 16 
 34      ABF_DACCOUNT = 4 
 35      ABF_EPOCHCOUNT = 10 
 36      ABF_ADCUNITLEN = 8 
 37      ABF_ADCNAMELEN_USER = 8 
 38      ABF_ADCNAMELEN = 10 
 39      ABF_DACUNITLEN = 8 
 40      ABF_DACNAMELEN = 10 
 41      ABF_USERLISTLEN = 256 
 42      ABF_USERLISTCOUNT = 4 
 43      ABF_OLDFILECOMMENTLEN = 56 
 44      ABF_FILECOMMENTLEN = 128 
 45      ABF_PATHLEN = 256 
 46      ABF_CREATORINFOLEN = 16 
 47      ABF_ARITHMETICOPLEN = 2 
 48      ABF_ARITHMETICUNITSLEN = 8 
 49      ABF_TAGCOMMENTLEN = 56 
 50      ABF_BLOCKSIZE = 512 
 51      PCLAMP6_MAXSWEEPLENGTH = 16384 
 52      PCLAMP7_MAXSWEEPLEN_PERCHAN = 1032258 
 53      ABF_MAX_SWEEPS_PER_AVERAGE = 65500 
 54      ABF_MAX_TRIAL_SAMPLES = 0x7FFFFFFF 
 55       
 56      # ... 
 57       
 58      ABF_DATAFILE = 0 
 59       
 60      ABF_STATS_REGIONS = 8 
 61      ABF_BASELINE_REGIONS = 1 
 62      ABF_STATS_NUM_MEASUREMENTS = 18 
 63   
64 - class GUID(Structure):
65 _fields_ = [('Data1', c_uint), 66 ('Data2', c_ushort), 67 ('Data3', c_ushort), 68 ('Data4', c_ubyte * 8)]
69
70 - class ABFFileHeader(Structure):
71 _pack_ = 1 72 _fields_ = [('fFileVersionNumber', c_float), 73 ('nOperationMode', c_short), 74 ('lActualAcqLength', c_long), 75 ('nNumPointsIgnored', c_short), 76 ('lActualEpisodes', c_long), 77 ('uFileStartDate', c_uint), 78 ('uFileStartTimeMS', c_uint), 79 ('lStopwatchTime', c_long), 80 ('fHeaderVersionNumber', c_float), 81 ('nFileType', c_short), 82 83 ('lDataSectionPtr', c_long), 84 ('lTagSectionPtr', c_long), 85 ('lNumTagEntries', c_long), 86 ('lScopeConfigPtr', c_long), 87 ('lNumScopes', c_long), 88 ('lDeltaArrayPtr', c_long), 89 ('lNumDeltas', c_long), 90 ('lVoiceTagPtr', c_long), 91 ('lVoiceTagEntries', c_long), 92 ('lSynchArayPtr', c_long), 93 ('lSynchArraySize', c_long), 94 ('nDataFormat', c_short), 95 ('nSimultaneousScan', c_short), 96 ('lStatisticsConfigPtr', c_long), 97 ('lAnnotationSectionPtr', c_long), 98 ('lNumAnnotations', c_long), 99 ('lDACFilePtr', c_long * ABF_DACCOUNT), 100 ('lDACFileNumEpisodes', c_long * ABF_DACCOUNT), 101 102 ('nADCNumChannels', c_short), 103 ('fADCSequenceInterval', c_float), 104 ('uFileCompressionRatio', c_uint), 105 ('bEnableFileCompression', c_byte), ## ? c++ bool 106 ('fSynchTimeUnit', c_float), 107 ('fSecondsPerRun', c_float), 108 ('lNumSamplesPerEpisode', c_long), 109 ('lPreTriggerSamples', c_long), 110 ('lEpisodesPerRun', c_long), 111 ('lRunsPerTrial', c_long), 112 ('lNumberOfTrials', c_long), 113 ('nAveragingMode', c_short), 114 ('nUndoRunCount', c_short), 115 ('nFirstEpisodeInRun', c_short), 116 ('fTriggerThreshold', c_float), 117 ('nTriggerSource', c_short), 118 ('nTriggerAction', c_short), 119 ('nTriggerPolarity', c_short), 120 ('fScopeOutputInterval', c_float), 121 ('fEpisodeStartToStart', c_float), 122 ('fRunStartToStart', c_float), 123 ('fTrialStartToStart', c_float), 124 ('lAverageCount', c_long), 125 ('nAutoTriggerStrategy', c_short), 126 ('fFirstRunDelayS', c_float), 127 128 ('nDataDisplayMode', c_short), 129 ('nChannelStatsStrategy', c_short), 130 ('lSamplesPerTrace', c_long), 131 ('lStartDisplayNum', c_long), 132 ('lFinishDisplayNum', c_long), 133 ('nShowPNRawData', c_short), 134 ('fStatisticsPeriod', c_float), 135 ('lStatisticsMeasurements', c_long), 136 ('nStatisticsSaveStrategy', c_short), 137 138 ('fADCRange', c_float), 139 ('fDACRange', c_float), 140 ('lADCResolution', c_long), 141 ('lDACResolution', c_long), 142 ('nDigitizerADCs', c_short), 143 ('nDigitizerDACs', c_short), 144 ('nDigitizerTotalDigitalOuts', c_short), 145 ('nDigitizerSynchDigitalOuts', c_short), 146 ('nDigitizerType', c_short), 147 148 ('nExperimentType', c_short), 149 ('nManualInfoStrategy', c_short), 150 ('fCellID1', c_float), 151 ('fCellID2', c_float), 152 ('fCellID3', c_float), 153 ('sProtocolPath', c_char * ABF_PATHLEN), 154 ('sCreatorInfo', c_char * ABF_CREATORINFOLEN), 155 ('sModifierInfo', c_char * ABF_CREATORINFOLEN), 156 ('nCommentsEnable', c_short), 157 ('sFileComment', c_char * ABF_FILECOMMENTLEN), 158 ('nTelegraphEnable', c_short * ABF_ADCCOUNT), 159 ('nTelegraphInstrument', c_short * ABF_ADCCOUNT), 160 ('fTelegraphAdditGain', c_float * ABF_ADCCOUNT), 161 ('fTelegraphFilter', c_float * ABF_ADCCOUNT), 162 ('fTelegraphMembraneCap', c_float * ABF_ADCCOUNT), 163 ('fTelegraphAccessResistance', c_float * ABF_ADCCOUNT), 164 ('nTelegraphMode', c_short * ABF_ADCCOUNT), 165 ('nTelegraphDACScaleFactorEnable', c_short * ABF_DACCOUNT), 166 167 ('nAutoAnalyseEnable', c_short), 168 169 ('FileGUID', GUID), 170 ('fIntstrumentHoldingLevel', c_float * ABF_DACCOUNT), 171 ('ulFileCRC', c_ulong), 172 ('nCRCEnable', c_short), 173 174 ('nSignalType', c_short), 175 ('nADCPtoLChannelMap', c_short * ABF_ADCCOUNT), 176 ('nADCSamplingSeq', c_short * ABF_ADCCOUNT), 177 ('fADCProgrammableGain', c_float * ABF_ADCCOUNT), 178 ('fADCDisplayAmplification', c_float * ABF_ADCCOUNT), 179 ('fADCDisplayOffset', c_float * ABF_ADCCOUNT), 180 ('fInstrumentScaleFactor', c_float * ABF_ADCCOUNT), 181 ('fInstrumentOffset', c_float * ABF_ADCCOUNT), 182 ('fSignalGain', c_float * ABF_ADCCOUNT), 183 ('fSignalOffset', c_float * ABF_ADCCOUNT), 184 ('fSignalLowpassFilter', c_float * ABF_ADCCOUNT), 185 ('fSignalHighpassFilter', c_float * ABF_ADCCOUNT), 186 ('nLowpassFilterType', c_char * ABF_ADCCOUNT), 187 ('nHighpassFilterType', c_char * ABF_ADCCOUNT), 188 189 ('sADCChannelName', (c_char * ABF_ADCNAMELEN) * ABF_ADCCOUNT), 190 ('sADCUnits', (c_char * ABF_ADCUNITLEN) * ABF_ADCCOUNT), 191 ('fDACScaleFactor', c_float * ABF_DACCOUNT), 192 ('fDACHoldingLevel', c_float * ABF_DACCOUNT), 193 ('fDACCalibrationFactor', c_float * ABF_DACCOUNT), 194 ('fDACCalibrationOffset', c_float * ABF_DACCOUNT), 195 ('sDACChannelName', (c_char * ABF_DACNAMELEN) * ABF_DACCOUNT), 196 ('sDACChannelUnits', (c_char * ABF_DACUNITLEN) * ABF_DACCOUNT), 197 198 ('nDigitalEnable', c_short), 199 ('nActiveDACChannel', c_short), 200 ('nDigitalDACChannel', c_short), 201 ('nDigitalHolding', c_short), 202 ('nDigitalInterEpisode', c_short), 203 ('nDigitalTrainActiveLogic', c_short), 204 ('nDigitalValue', c_short * ABF_EPOCHCOUNT), 205 ('nDigitalTrainValue', c_short * ABF_EPOCHCOUNT), 206 ('bEpochCompression', c_byte * ABF_EPOCHCOUNT), ## 207 ('nWaveformEnable', c_short * ABF_DACCOUNT), 208 ('nWaveformSource', c_short * ABF_DACCOUNT), 209 ('nInterEpisodeLevel', c_short * ABF_DACCOUNT), 210 ('nEpochType', (c_short * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 211 ('fEpochInitLevel', (c_float * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 212 ('fEpochLevelInc', (c_float * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 213 ('lEpochInitDuration', (c_long * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 214 ('lEpochDurationInc', (c_long * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 215 216 ('fDACFileScale', c_float * ABF_DACCOUNT), 217 ('fDACFileOffset', c_float * ABF_DACCOUNT), 218 ('lDACFileEpisodeNum', c_long * ABF_DACCOUNT), 219 ('nDACFileADCNum', c_short * ABF_DACCOUNT), 220 ('sDACFilePath', (c_char * ABF_PATHLEN) * ABF_DACCOUNT), 221 222 ('nConditEnable', c_short * ABF_DACCOUNT), 223 ('lConditNumPulses', c_long * ABF_DACCOUNT), 224 ('fBaselineDuration', c_float * ABF_DACCOUNT), 225 ('fBaselineLevel', c_float * ABF_DACCOUNT), 226 ('fStepDuration', c_float * ABF_DACCOUNT), 227 ('fStepLevel', c_float * ABF_DACCOUNT), 228 ('fPostTrainPeriod', c_float * ABF_DACCOUNT), 229 ('fPostTrainLevel', c_float * ABF_DACCOUNT), 230 ('nMembTestEnable', c_short * ABF_DACCOUNT), 231 ('fMembTestPreSettlingTimeMS', c_float * ABF_DACCOUNT), 232 ('fMembTestPostSettlingTimeMS', c_float * ABF_DACCOUNT), 233 234 ('nULEnable', c_short * ABF_USERLISTCOUNT), 235 ('nULParamToVary', c_short * ABF_USERLISTCOUNT), 236 ('nULRepeat', c_short * ABF_USERLISTCOUNT), 237 ('sULParamValueList', (c_char * ABF_USERLISTLEN) * ABF_USERLISTCOUNT), 238 239 ('nStatsEnable', c_short), 240 ('nStatsActiveChannels', c_ushort), 241 ('nStatsSearchRegionFlags', c_ushort), 242 ('nStatsSmoothing', c_short), 243 ('nStatsSmoothingEnable', c_short), 244 ('nStatsBaseline', c_short), 245 ('nStatsBaselineDAC', c_short), 246 ('lStatsBaselineStart', c_long), 247 ('lStatsBaselineEnd', c_long), 248 ('lStatsMeasurements', c_long * ABF_STATS_REGIONS), 249 ('lStatsStart', c_long * ABF_STATS_REGIONS), 250 ('lStatsEnd', c_long * ABF_STATS_REGIONS), 251 ('nRiseBottomPercentile', c_short * ABF_STATS_REGIONS), 252 ('nRiseTopPercentile', c_short * ABF_STATS_REGIONS), 253 ('nDecayBottomPercentile', c_short * ABF_STATS_REGIONS), 254 ('nDecayTopPercentile', c_short * ABF_STATS_REGIONS), 255 ('nStatsChannelPolarity', c_short * ABF_STATS_REGIONS), 256 ('nStatsSearchMode', c_short * ABF_STATS_REGIONS), 257 ('nStatsSearchDAC', c_short * ABF_STATS_REGIONS), 258 259 ('nArithmeticEnable', c_short), 260 ('nArithmeticExpression', c_short), 261 ('fArithmeticUpperLimit', c_float), 262 ('fArithmeticLowerLimit', c_float), 263 ('nArithmeticADCNumA', c_short), 264 ('nArithmeticADCNumB', c_short), 265 ('fArithmeticK1', c_float), 266 ('fArithmeticK2', c_float), 267 ('fArithmeticK3', c_float), 268 ('fArithmeticK4', c_float), 269 ('fArithmeticK5', c_float), 270 ('fArithmeticK6', c_float), 271 ('sArithmeticOperator', c_char * ABF_ARITHMETICOPLEN), 272 ('sArithmeticUnits', c_char * ABF_ARITHMETICUNITSLEN), 273 274 ('nPNPosition', c_short), 275 ('nPNNumPulses', c_short), 276 ('nPNPolarity', c_short), 277 ('fPNSettlingTime', c_float), 278 ('fPNInterpulse', c_float), 279 ('nLeakSubtractType', c_short * ABF_DACCOUNT), 280 ('fPNHoldingLevel', c_float * ABF_DACCOUNT), 281 ('nLeakSubtractADCIndex', c_short * ABF_DACCOUNT), 282 283 ('nLevelHysteresis', c_short), 284 ('lTimeHysteresis', c_long), 285 ('nAllowExternalTags', c_short), 286 ('nAverageAlgorithm', c_short), 287 ('fAverageWeighting', c_float), 288 ('nUndoPromptStrategy', c_short), 289 ('nTrialTriggerSource', c_short), 290 ('nStatisticsDisplayStrategy', c_short), 291 ('nExternalTagType', c_short), 292 ('lHeaderSize', c_long), 293 ('nStatisticsClearStrategy', c_short), 294 295 ('lEpochPulsePeriod', (c_long * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 296 ('lEpochPulseWidth', (c_long * ABF_EPOCHCOUNT) * ABF_DACCOUNT), 297 298 ('nCreatorMajorVersion', c_short), 299 ('nCreatorMinorVersion', c_short), 300 ('nCreatorBugfixVersion', c_short), 301 ('nCreatorBuildVersion', c_short), 302 ('nModifierMajorVersion', c_short), 303 ('nModifierMinorVersion', c_short), 304 ('nModifierBugfixVersion', c_short), 305 ('nModifierBuildVersion', c_short), 306 307 ('nLTPType', c_short), 308 ('nLTPUsageOfDAC', c_short * ABF_DACCOUNT), 309 ('nLTPPresynapticPulses', c_short * ABF_DACCOUNT), 310 311 ('nScopeTriggerOut', c_short), 312 313 ('nAlternateDACOutputState', c_short), 314 ('nAlternateDigitalOutputState', c_short), 315 ('nAlternateDigitalValue', c_short * ABF_EPOCHCOUNT), 316 ('nAlternateDigitalTrainValue', c_short * ABF_EPOCHCOUNT), 317 318 ('fPostProcessLowpassFilter', c_float * ABF_ADCCOUNT), 319 ('nPostProcessLowpassFilterType', c_ubyte * ABF_ADCCOUNT), 320 321 ('fLegacyADCSequenceInterval', c_float), 322 ('fLegacyADCSecondSequenceInterval', c_float), 323 ('lLegacyClockChange', c_long), 324 ('lLegacyNumSamplesPerEpisode', c_long), 325 ('padding_in_case_more_bogus', c_long*10)]
326 P_ABFFileHeader = POINTER(ABFFileHeader) 327 328 abffio.ABF_IsABFFile.argtypes = (c_char_p, c_int_p, c_int_p) 329 abffio.ABF_IsABFFile.restype = BOOL 330 331 abffio.ABF_ReadOpen.argtypes = (c_char_p, c_int_p, c_uint, P_ABFFileHeader, c_uint_p, c_uint_p, c_int_p) 332 abffio.ABF_ReadOpen.restype = BOOL 333 334 abffio.ABF_Close.argtypes = (c_int, c_int_p) 335 abffio.ABF_Close.restype = BOOL 336 337 abffio.ABF_GetNumSamples.argtypes = (c_int, P_ABFFileHeader, c_uint, c_uint_p, c_int_p) 338 abffio.ABF_GetNumSamples.restype = BOOL 339 340 abffio.ABF_ReadChannel.argtypes = (c_int, P_ABFFileHeader, c_int, c_uint, c_float_p, c_uint_p, c_int_p) 341 abffio.ABF_ReadChannel.restype = BOOL 342 343 abffio.ABF_GetWaveform.argtypes = (c_int, P_ABFFileHeader, c_uint, c_uint, c_float_p, c_int_p) 344 abffio.ABF_GetWaveform.restype = BOOL 345 346 abffio.ABF_BuildErrorText.argtypes = (c_int, c_char_p, c_char_p, c_uint) 347 abffio.ABF_BuildErrorText.restype = BOOL 348 349 except: 350 abffio = None 351 352
353 -class QubData_ABF_Signal(QubData_Analog):
354 - def __init__(self, data):
355 """ 356 @param data: L{QubData_ABF} 357 """ 358 QubData_Analog.__init__(self) 359 self.data = data
360 - def read(self, first, last, latency=0, skip=1):
361 ifirst, ilast = [self.data.segmentation.index_at(x) for x in (first, last)] 362 if ifirst != ilast: 363 raise Exception("ABF: can't read() from multiple segments at once") 364 segfirst = self.data.segmentation.segments[ifirst][0] 365 seglast = self.data.segmentation.segments[ifirst][1] 366 return read_with_latency(self.read_in_seg, first, last, latency, skip, ifirst, segfirst, seglast)
367 368
369 -class QubData_ABF_Analog(QubData_ABF_Signal):
370 - def __init__(self, data, channel, abfchannel, lNumSamplesPerEpisode):
371 """ 372 @param data: L{QubData_QDF} 373 @param channel: integer 0-based signal index 374 @param abfchannel: == nADCSamplingSeq[channel] 375 """ 376 QubData_ABF_Signal.__init__(self, data) 377 self.channel = channel 378 self.abfchannel = abfchannel 379 self.lNumSamplesPerEpisode = lNumSamplesPerEpisode
380 - def read_in_seg(self, iseg, first, last, skip):
381 samples = numpy.zeros(dtype='float32', shape=(max(self.data.segmentation.segments[iseg][2], self.lNumSamplesPerEpisode),)) 382 uNumSamples = c_uint() 383 print iseg, first, last, skip, samples.shape 384 abffio.ABF_ReadChannel(self.data.file, self.data.phdr, self.abfchannel, iseg+1, 385 samples.ctypes.data_as(c_float_p), byref(uNumSamples), self.data.pnError) 386 samples = numpy.array(samples[first:last+1], dtype='float32', copy=True) 387 scale = self.data.signals.get(self.channel, 'Scale') 388 if scale != 1.0: 389 samples *= scale 390 offset = self.data.signals.get(self.channel, 'Offset') 391 if offset != 0.0: 392 samples += offset 393 return samples
394
395 -class QubData_ABF_Waveform(QubData_ABF_Signal):
396 - def __init__(self, data, channel, lNumSamplesPerEpisode):
397 """ 398 @param data: L{QubData_QDF} 399 @param channel: integer 0-based signal index 400 """ 401 QubData_ABF_Signal.__init__(self, data) 402 self.channel = channel 403 self.lNumSamplesPerEpisode = lNumSamplesPerEpisode
404 - def read_in_seg(self, iseg, first, last, skip):
405 samples = numpy.zeros(dtype='float32', shape=(max(self.data.segmentation.segments[iseg][2], self.lNumSamplesPerEpisode),)) 406 abffio.ABF_GetWaveform(self.data.file, self.data.phdr, self.channel, iseg+1, 407 samples.ctypes.data_as(c_float_p), self.data.pnError) 408 samples = numpy.array(samples[first:last+1], dtype='float32', copy=True) 409 scale = self.data.signals.get(self.channel, 'Scale') 410 if scale != 1.0: 411 samples *= scale 412 offset = self.data.signals.get(self.channel, 'Offset') 413 if offset != 0.0: 414 samples += offset 415 return samples
416 417
418 -class QubData_ABF(QubData):
419 """One open Axon binary file. 420 421 @ivar file: c_int: file handle 422 @ivar nDataFormat: c_int 423 @ivar nError: c_int 424 @ivar hdr: L{ABFFileHeader} 425 """
426 - def __init__(self, path, progressf):
427 QubData.__init__(self) 428 self.path = path 429 self.file = c_int() 430 self.hdr = ABFFileHeader() 431 self.phdr = pointer(self.hdr) 432 self.nDataFormat = c_int() 433 self.nError = c_int() 434 self.pnError = pointer(self.nError) 435 self.uMaxSamples = c_uint() 436 self.dwMaxEpi = c_uint() 437 438 if not abffio.ABF_IsABFFile(path, byref(self.nDataFormat), self.pnError): 439 raise Exception('%s is not an ABF file: '+self.last_error()) 440 if not abffio.ABF_ReadOpen(path, byref(self.file), ABF_DATAFILE, self.phdr, 441 byref(self.uMaxSamples), byref(self.dwMaxEpi), self.pnError): 442 raise Exception('ABF_ReadOpen: '+self.last_error()) 443 self.sampling = self.hdr.fADCSequenceInterval * 1e-6; 444 445 for c in xrange(self.hdr.nADCNumChannels): 446 c_abf = self.hdr.nADCSamplingSeq[c] 447 self.signals.append({'Name' : self.hdr.sADCChannelName[c_abf].value.strip(), 448 'Units' : self.hdr.sADCUnits[c_abf].value.strip()}) 449 self.set_analog(c, QubData_ABF_Analog(self, c, c_abf, self.hdr.lNumSamplesPerEpisode)) 450 451 seglen = c_uint() 452 abffio.ABF_GetNumSamples(self.file, self.phdr, 1, byref(seglen), self.pnError) 453 testbuf = (c_float * seglen.value)() 454 455 for c in xrange(ABF_DACCOUNT): 456 if abffio.ABF_GetWaveform(self.file, self.phdr, c, 1, testbuf, self.pnError): 457 self.signals.append({'Name': self.hdr.sDACChannelName[c].value.strip(), 458 'Units' : self.hdr.sDACChannelUnits[c].value.strip()}) 459 self.set_analog(self.signals.size-1, QubData_ABF_Waveform(self, c, self.hdr.lNumSamplesPerEpisode)) 460 461 last = -1 462 for i in xrange(1, self.dwMaxEpi.value + 1): 463 abffio.ABF_GetNumSamples(self.file, self.phdr, i, byref(seglen), self.pnError) 464 first = last + 1 465 last = first + seglen.value - 1 466 self.segmentation.add_seg(first, last, self.sampling*1e3*first) 467 468 base, ext = os.path.splitext(path) 469 sess = qubx.tree.Open(base+'.qsf', True) 470 sess.close() # release file, keep in mem 471 472 # override QuB's integer scaling values 473 for chan in qubx.tree.children(sess.find('DataChannels'), 'Channel'): 474 chan['Scaling'].data = 1.0 475 chan['Offset'].data = 0.0 476 477 self.read_session(sess, progressf)
478
479 - def __del__(self):
480 abffio.ABF_Close(self.file, self.pnError)
481
482 - def dump_header(self, path):
483 buf = cast(self.phdr, POINTER(c_ubyte)) 484 fi = open(path, 'w') 485 for i in xrange(sizeof(ABFFileHeader)): 486 fi.write(chr(buf[i]))
487
488 - def last_error(self, maxlen=256):
489 buf = create_string_buffer(maxlen) 490 abffio.ABF_BuildErrorText(self.nError, self.path, buf, maxlen-1) 491 return buf.value.strip()
492 493 494 fallback_reader = None 495
496 -def QubData_ABF_Open(path, progressf):
497 try: 498 return QubData_ABF(path, progressf) 499 except: 500 if fallback_reader: 501 return fallback_reader(path, progressf) 502 else: 503 raise
504 505 if abffio: 506 fallback_reader = SetReader('.dat', 'DAT files', QubData_ABF_Open) 507 SetReader('.abf', 'Axon binary files', QubData_ABF_Open) 508