Exemple #1
0
    def parseISF(self, isf_data, header_only=None, convert=None):
        """
        Determine starting point of data.
        Header has something like 'CURVE #520000', where ascii '5' is the
        length of the length field '20000'.

        ::

            'CURVE #520000xxxx...'
              ^      ^^    ^
              |      ||    +---- data_loc:    location of first valid byte of data
              |      |+--------- len_loc:     location of first byte of data length field
              |      +---------- len_len_loc: location of length of length
              +----------------- tag_loc:     location of start tag
        """
        start_tag = 'CURVE #'
        tag_loc = int(isf_data.find(start_tag))
        len_len_loc = tag_loc + len(start_tag)
        len_loc = len_len_loc + 1
        len_len = int(isf_data[len_len_loc]) # e.g. 5
        data_loc = len_loc + len_len
        data_len = int(isf_data[len_loc:len_loc+len_len]) # e.g. 20000

        # Extract and parse header
        header = isf_data[:tag_loc]
        # Reformat the header into a dictionary
        header_dict = {}
        items = header.replace(':WFMPRE:','').replace(':','').split(';') # list of "key value" pairs
        for item in items:
            if(item):
                key, value = item.split(' ', 1) # maxsplit 1 to ignore subsequent spaces in value
                value = value.replace('"', '')
                header_dict[key] = value

        if(header_only):
            return header_dict

        # Extract data and convert from string to integer value
        data = isf_data[data_loc:]

        stats = Stats()
        stats.npts = int(header_dict['NR_PT'])
        stats.calib = float(header_dict['YMULT'])
        byte_order = header_dict['BYT_OR'] # 'MSB' or 'LSB'

        if(byte_order == 'MSB'):
            byte_order = '>'
        else:
            byte_order = '<'
        points = []
        for i in range(0, stats.npts*2, 2):
            value = data[i:i+2] # as string
            converted = struct.unpack('%sh' % byte_order, value)[0]
            points.append(converted)

        # Optionally convert points to engineering units
        if(convert):
            try:
                points = np.array(points) * stats.calib  # requires numpy
            except NameError:
                # If numpy not available, use list instead.
                p = []
                for point in points:
                    p.append(point * stats.calib)
                points = p
        stats.time_offset = float(header_dict['XZERO'])
        stats.calib_unit = header_dict['YUNIT']
        stats.delta = float(header_dict['XINCR'])
        stats.amp_offset = float(header_dict['YOFF'])
        stats.comments = header_dict['WFID']
        stats.channel = header_dict['WFID'][0:3]

        return stats, points