Source

python-axonbinaryfile / tests / abf1load.py

Full commit
import struct
tmp='tmp'
"""
Format  C Type          Python type          Standard size 
-----------------------------------------------------------
x       pad byte        no value                      
c       char            string of length 1   1           
b       signed char     integer              1          (3)
B       unsigned char   integer              1          (3)
?       _Bool           bool                 1          (1)
h       short           integer              2          (3)
H       unsigned short  integer              2          (3)
i       int             integer              4          (3)
I       unsigned int    integer              4          (3)
l       long            integer              4          (3)
L       unsigned long   integer              4          (3)
q       long long       integer              8          (2), (3)
Q       unsigned long   long  integer        8          (2), (3)
f       float           float                4          (4)
d       double          float                8          (4)
s       char[]          string                      
p       char[]          string                      
P       void *          integer                     (5), (3)
"""
# abf1.x has a fixed header size
# (<name>, <file offset>, <struct fmt code>, <unused>)
abf1header=[     #Group #1 - File ID and size info 40bytes
    ('c4FileSignature', 0, 'cccc', -1), 
    ('fFileVersionNumber',4,'<f',-1),
    ('nOperationMode',8,'<h',-1),
    ('lActualAcqLength',10,'<i',-1),
    ('nNumPointsIgnored',14,'<h',-1),
    ('lActualEpisodes',16,'<i',-1),
    ('lFileStartDate',20,'<l',-1), # YYYYMMDD
    ('lFileStartTime',24,'<i',-1),
    ('lStopwatchTime',28,'<l',-1),
    ('fHeaderVersionNumber', 32, '<f',-1),
    ('nFileType',36, '<h', -1),
    ('nMSBinFormat', 38, '<h',-1), 

    # group #2 file structure 78 bytes
    ('lDataSectionPtr',40,'<i',-1), #
    ('lSynchArrayPtr',92,'<i',-1),
    ('lSynchArraySize',96,'<i',-1), 
    ('nDataFormat',100,'<h',-1),            
    ('nADCNumChannels', 120, '<h', -1),
    ('fADCSampleInterval',122,'<f', -1), 
    ('fSynchTimeUnit',130,'<f',-1),
    ('lNumSamplesPerEpisode',138,'<i',-1),        
    ('lPreTriggerSamples',142,'<i',-1),        
    ('lEpisodesPerRun',146,'<i',-1),        
    ('fADCRange', 244, '<f', -1),
    ('lADCResolution', 252, '<i', -1),
    ('nFileStartMillisecs', 366, '<h', -1),
    ('nADCPtoLChannelMap', 378, '<h', tmp),
    ('nADCSamplingSeq', 410, '<h',  tmp),
    ('sADCChannelName',442, '<B', 'repmat(tmp,1,10)'),
    ('fADCProgrammableGain', 730, '<f', tmp),
    ('fInstrumentScaleFactor', 922, '<f', tmp),
    ('fInstrumentOffset', 986, '<f', tmp),
    ('fSignalGain', 1050, '<f', tmp),
    ('fSignalOffset', 1114, '<f', tmp),
    ('nTelegraphEnable',4512,'<h',tmp),
    ('fTelegraphAdditGain',4576,'<f',tmp) ]
    # fields={'name','offs','numType','value'},

abf2_header =[
    ('fFileSignature',0,'cccc',[-1 -1 -1 -1]),
    ('fFileVersionNumber',4,'<f',[-1 -1 -1 -1]),
    ('uFileInfoSize',8,'uint32',-1,),
    ('lActualEpisodes',12,'uint32',-1,),
    ('uFileStartDate',16','uint32',-1,),
    ('uFileStartTimeMS',20,'uint32',-1,),
    ('uStopwatchTime',24,'uint32',-1,),
    ('nFileType',28,'int16',-1,),
    ('nDataFormat',30,'int16',-1,),
    ('nSimultaneousScan',32,'int16',-1,),
    ('nCRCEnable',34,'int16',-1,),
    ('uFileCRC',36,'uint32',-1,),
    ('FileGUID',40,'uint32',-1,),
    ('uCreatorVersion',56,'uint32',-1,),
    ('uCreatorNameIndex',60,'uint32',-1,),
    ('uModifierVersion',64,'uint32',-1,),
    ('uModifierNameIndex',68,'uint32',-1,),
    ('uProtocolPathIndex',72,'uint32',-1,),
    ]
    
abf2_sections= ['ProtocolSection',
                'ADCSection',
                'DACSection',
                'EpochSection',
                'ADCPerDACSection',
                'EpochPerDACSection',
                'UserListSection',
                'StatsRegionSection',
                'MathSection',
                'StringsSection',
                'DataSection',
                'TagSection',
                'ScopeSection',
                'DeltaSection',
                'VoiceTagSection',
                'SynchArraySection',
                'AnnotationSection',
                'StatsSection']

# format {'name','numType','number'}
abf2_ProtocolInfo=[
    ('nOperationMode','int16',1,),
    ('fADCSequenceInterval','float',1,),
    ('bEnableFileCompression','bit1',1,),
    ('sUnused1','char',3,),
    ('uFileCompressionRatio','uint32',1,),
    ('fSynchTimeUnit','float',1,),
    ('fSecondsPerRun','float',1,),
    ('lNumSamplesPerEpisode','int32',1,),
    ('lPreTriggerSamples','int32',1,),
    ('lEpisodesPerRun','int32',1,),
    ('lRunsPerTrial','int32',1,),
    ('lNumberOfTrials','int32',1,),
    ('nAveragingMode','int16',1,),
    ('nUndoRunCount','int16',1,),
    ('nFirstEpisodeInRun','int16',1,),
    ('fTriggerThreshold','float',1,),
    ('nTriggerSource','int16',1,),
    ('nTriggerAction','int16',1,),
    ('nTriggerPolarity','int16',1,),
    ('fScopeOutputInterval','float',1,),
    ('fEpisodeStartToStart','float',1,),
    ('fRunStartToStart','float',1,),
    ('lAverageCount','int32',1,),
    ('fTrialStartToStart','float',1,),
    ('nAutoTriggerStrategy','int16',1,),
    ('fFirstRunDelayS','float',1,),
    ('nChannelStatsStrategy','int16',1,),
    ('lSamplesPerTrace','int32',1,),
    ('lStartDisplayNum','int32',1,),
    ('lFinishDisplayNum','int32',1,),
    ('nShowPNRawData','int16',1,),
    ('fStatisticsPeriod','float',1,),
    ('lStatisticsMeasurements','int32',1,),
    ('nStatisticsSaveStrategy','int16',1,),
    ('fADCRange','float',1,),
    ('fDACRange','float',1,),
    ('lADCResolution','int32',1,),
    ('lDACResolution','int32',1,),
    ('nExperimentType','int16',1,),
    ('nManualInfoStrategy','int16',1,),
    ('nCommentsEnable','int16',1,),
    ('lFileCommentIndex','int32',1,),
    ('nAutoAnalyseEnable','int16',1,),
    ('nSignalType','int16',1,),
    ('nDigitalEnable','int16',1,),
    ('nActiveDACChannel','int16',1,),
    ('nDigitalHolding','int16',1,),
    ('nDigitalInterEpisode','int16',1,),
    ('nDigitalDACChannel','int16',1,),
    ('nDigitalTrainActiveLogic','int16',1,),
    ('nStatsEnable','int16',1,),
    ('nStatisticsClearStrategy','int16',1,),
    ('nLevelHysteresis','int16',1,),
    ('lTimeHysteresis','int32',1,),
    ('nAllowExternalTags','int16',1,),
    ('nAverageAlgorithm','int16',1,),
    ('fAverageWeighting','float',1,),
    ('nUndoPromptStrategy','int16',1,),
    ('nTrialTriggerSource','int16',1,),
    ('nStatisticsDisplayStrategy','int16',1,),
    ('nExternalTagType','int16',1,),
    ('nScopeTriggerOut','int16',1,),
    ('nLTPType','int16',1,),
    ('nAlternateDACOutputState','int16',1,),
    ('nAlternateDigitalOutputState','int16',1,),
    ('fCellID','float',3,),
    ('nDigitizerADCs','int16',1,),
    ('nDigitizerDACs','int16',1,),
    ('nDigitizerTotalDigitalOuts','int16',1,),
    ('nDigitizerSynchDigitalOuts','int16',1,),
    ('nDigitizerType','int16',1,),
    ]

abf2_ADCInfo=[
 ('nADCNum','int16',1,),
 ('nTelegraphEnable','int16',1,),
 ('nTelegraphInstrument','int16',1,),
 ('fTelegraphAdditGain','float',1,),
 ('fTelegraphFilter','float',1,),
 ('fTelegraphMembraneCap','float',1,),
 ('nTelegraphMode','int16',1,),
 ('fTelegraphAccessResistance','float',1,),
 ('nADCPtoLChannelMap','int16',1,),
 ('nADCSamplingSeq','int16',1,),
 ('fADCProgrammableGain','float',1,),
 ('fADCDisplayAmplification','float',1,),
 ('fADCDisplayOffset','float',1,),
 ('fInstrumentScaleFactor','float',1,),
 ('fInstrumentOffset','float',1,),
 ('fSignalGain','float',1,),
 ('fSignalOffset','float',1,),
 ('fSignalLowpassFilter','float',1,),
 ('fSignalHighpassFilter','float',1,),
 ('nLowpassFilterType','char',1,),
 ('nHighpassFilterType','char',1,),
 ('fPostProcessLowpassFilter','float',1,),
 ('nPostProcessLowpassFilterType','char',1,),
 ('bEnabledDuringPN','bit1',1,),
 ('nStatsChannelPolarity','int16',1,),
 ('lADCChannelNameIndex','int32',1,),
 ('lADCUnitsIndex','int32',1,),
 ]


abf2_TagInfo= [
    ('lTagTime','int32',1,),
    ('sComment','char',56,),
    ('nTagType','int16',1,),
    ('nVoiceTagNumber_or_AnnotationIndex','int16',1,),
    ]

"""

class Abf1(object):
    def read(self, file_name):
        self.file_name = file_name
        
        self.fp = open(file_name, 'rb')
        

def abf1info(fn):
    # first just load in the header information
    fp = open(fn,'rb')
    hvalue = {}
    hvalue["c4FileSignature"]=fp.read(4)
    assert hvalue["c4FileSignature"] == "ABF "
    for elem in abf1header[1:]:
        sz = struct.calcsize(elem[2])
        # print sz # size of element
        fp.seek(elem[1],0)
        buf = fp.read(sz)
        if len(elem[2])== 2: # if it's a scalar
            hvalue[elem[0]] = struct.unpack(elem[2], buf)[0]
        else: # otherwise just leave it as a tuple
            hvalue[elem[0]] = struct.unpack(elem[2], buf)
            
    return hvalue


def check_abf_file_type(fp):
    '''
>>> fp=open("pclamp9v183-1.abf")
>>> check_abf_file_type(fp)
1
>>> fg = open("pclamp10v2abf-2.abf")
>>> check_abf_file_type(fg)
2
>>> fh = open(__file__)
# now try to open a non-ABF file, should raise an IOError
>>> check_abf_file_type(fh)
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "abf1load.py", line 67, in check_abf_file_type
    """
IOError: not an axon abf file
'''

    fp.seek(0,0)
    sig = fp.read(4)
    if sig=='ABF ':
        return 1
    if sig=='ABF2':
        return 2
    else:
        raise IOError, "not an axon abf file"



   # headPar={
   #   'fFileSignature',0,'*char',[-1 -1 -1 -1],
   #   'fFileVersionNumber',4,'bit8=>int',[-1 -1 -1 -1],
   #   'uFileInfoSize',8,'uint32',-1,
   #   'lActualEpisodes',12,'uint32',-1,
   #   'uFileStartDate',16','uint32',-1,
   #   'uFileStartTimeMS',20,'uint32',-1,
   #   'uStopwatchTime',24,'uint32',-1,
   #   'nFileType',28,'int16',-1,
   #   'nDataFormat',30,'int16',-1,
   #   'nSimultaneousScan',32,'int16',-1,
   #   'nCRCEnable',34,'int16',-1,
   #   'uFileCRC',36,'uint32',-1,
   #   'FileGUID',40,'uint32',-1,
   #   'uCreatorVersion',56,'uint32',-1,
   #   'uCreatorNameIndex',60,'uint32',-1,
   #   'uModifierVersion',64,'uint32',-1,
   #   'uModifierNameIndex',68,'uint32',-1,
   #   'uProtocolPathIndex',72,'uint32',-1,
   #   },