Exemple #1
0
    def _validDM(self):
        '''
        Test whether a file is a valid DM3 or DM4 file, and
        verify that it's written in Little Endian format
        '''
        output = True  #output will stay == 1 if the file is a true DM4 file

        self.dmType = self.fromfile(
            self.fid, dtype=np.dtype('>u4'),
            count=1)[0]  #file type: == 3 for DM3 or == 4 for DM4

        if self.v:
            print('validDM: DM file type numer = {}'.format(self.dmType))

        if self.dmType == 3:
            self.specialType = np.dtype('>u4')  #uint32
        elif self.dmType == 4:
            self.specialType = np.dtype('>u8')  #uint64
        else:
            raise IOError('File is not a valid DM3 or DM4')
            output = False

        self.fileSize = self.fromfile(
            self.fid, dtype=self.specialType,
            count=1)[0]  #file size: real size - 24 bytes
        self.endianType = self.fromfile(
            self.fid, dtype=np.dtype('>u4'), count=1
        )[0]  #endian type: 1 == little endian (Intel), 2 == big endian (old powerPC Mac)

        if self.endianType != 1:
            #print('File is not written Little Endian (PC) format and can not be read by this program.')
            raise IOError(
                'File is not written Little Endian (PC) format and can not be read by this program.'
            )
            output = False

        #Test file size for corruption. Note that DM3/DM4 file size is always off by 20/24 bytes from what is written in the header
        osSize = fileStats(self.filename).st_size
        if self.dmType == 3:
            if self.fileSize != osSize - 20:
                pass
                #raise IOError('File size on disk ({}) does not match expected file size in header ({}). Invalid file.'.format(osSize, self.fileSize))
                #output = False
                #print('Warning: file size on disk ({}) does not match expected file size in header ({}).'.format(osSize, self.fileSize))
        elif self.dmType == 4:
            if self.fileSize != osSize - 24:
                pass
                #raise IOError('File size on disk ({}) does not match expected file size in header ({}). Invalid file.'.format(osSize, self.fileSize))
                #output = False
                #print('Warning: file size on disk ({}) does not match expected file size in header ({}).'.format(osSize, self.fileSize))

        return output
Exemple #2
0
    def __init__(self, filename, verbose=False, on_memory=False):

        self.filename = filename

        # necessary declarations, if something fails
        self.fid = None

        self._on_memory = on_memory

        # check for string
        if not isinstance(filename, str):
            raise TypeError('Filename is supposed to be a string')

        #Add a top level variable to indicate verbosee output for debugging
        self.v = verbose

        # try opening the file
        try:
            if not self._on_memory:
                self.fid = open(filename, 'rb')
            if self._on_memory:
                self._buffer_offset = 0
                # Pre-load the file as a memory map that supports operations
                # similar to a file.
                with open(filename, 'rb') as _fid:
                    if os.name == 'nt':
                        self.fid = mmap.mmap(_fid.fileno(),
                                             0,
                                             access=mmap.ACCESS_READ)
                    else:
                        self.fid = mmap.mmap(
                            _fid.fileno(), 0,
                            prot=mmap.PROT_READ)  #, flags=mmap.MAP_PRIVATE)
                    self._buffer_size = fileStats(filename).st_size

        except IOError:
            print('Error reading file: "{}"'.format(filename))
            raise
        except:
            raise

        if not self._validDM():
            #print('Not a valid DM3 or DM4 file: "{}"'.format(filename))
            raise IOError('Can not read file: {}'.format(filename))

        #Lists that will contain information about binary data arrays
        self.xSize = []
        self.ySize = []
        self.zSize = []
        self.zSize2 = []  #only used for 4D datasets in DM4 files
        self.dataType = []
        self.dataSize = []
        self.dataOffset = []
        self.dataShape = [
        ]  #1,2,3, or 4. The total number of dimensions in a data set

        #The number of objects found in the DM3 file
        self.numObjects = 0

        #Indicator that a thumbnail exists (tested for later)
        self.thumbnail = False

        self.curGroupLevel = 0  #track how deep we currently are in a group
        self.maxDepth = 64  #maximum number of group levels allowed
        self.curGroupAtLevelX = np.zeros(
            (self.maxDepth, ), dtype=np.int8)  #track group at current level
        self.curGroupNameAtLevelX = ''  #set the name of the root group

        self.curTagAtLevelX = np.zeros(
            (self.maxDepth, ),
            dtype=np.int8)  #track tag number at the current level
        self.curTagName = ''  #string of the current tag

        #lists that will contain scale information (pixel size)
        self.scale = []
        self.scaleUnit = []
        self.origin = []

        #Temporary variables to keep in case a tag entry shows useful information in an array
        self.scale_temp = 0
        self.origin_temp = 0

        self.allTags = {}

        self._encodedTypeSizes = {
            0: 0,
            8: 1,
            9: 1,
            10: 1,
            2: 2,
            4: 2,
            3: 4,
            5: 4,
            6: 4,
            7: 8,
            12: 8
        }

        self._DM2NPDataTypes = {
            1: np.int16,
            2: np.float32,
            3: np.complex64,
            6: np.uint8,
            7: np.int32,
            9: np.int8,
            10: np.uint16,
            11: np.uint32,
            12: np.float64,
            13: np.complex128
        }

        self._TagType2NPDataTypes = {
            2: np.int16,
            3: np.int32,
            4: np.uint16,
            5: np.uint32,
            6: np.float32,
            7: np.float64,
            8: np.uint8,
            9: np.int8,
            10: np.int8,
            11: np.uint64,
            12: np.uint64
        }

        self._EncodedTypeDTypes = {
            2: np.int16,
            3: np.int32,
            4: np.uint16,
            5: np.uint32,
            6: np.float32,
            7: np.float64,
            8: np.uint8,
            9: np.uint8,
            10: np.uint8,
            12: np.uint64
        }
        self.parseHeader()
Exemple #3
0
    def __init__(self, filename, verbose=False, on_memory=False):
        '''
        Opens the file and reads its header.

        Accepts:
            filename:   (str) the file path.
            verbose:    (bool) if True, debug information is printed.
            on_memory:  (bool) if True, file data is pre-loaded in memory and all data
                               parsing is performed against memory. Use this mode if the file
                               is in a network based or paralle file system.
        '''

        self.filename = filename

        # necessary declarations, if something fails
        self.fid = None
        self.fidOut = None

        self._on_memory = on_memory

        # check for string
        if not isinstance(filename, str):
            raise TypeError('Filename is supposed to be a string ;D')

        #Add a top level variable to indicate verbose output for debugging
        self.v = verbose

        # try opening the file
        try:
            if not self._on_memory:
                self.fid = open(filename, 'rb')
            if self._on_memory:
                self._buffer_offset = 0
                # Pre-load the file as a memory map that supports operations
                # similar to a file.
                with open(filename, 'rb') as _fid:
                    if os.name == 'nt':
                        self.fid = mmap.mmap(_fid.fileno(),
                                             0,
                                             access=mmap.ACCESS_READ)
                    else:
                        self.fid = mmap.mmap(
                            _fid.fileno(), 0,
                            prot=mmap.PROT_READ)  #, flags=mmap.MAP_PRIVATE)
                    self._buffer_size = fileStats(filename).st_size

        except IOError:
            print('Error reading file: "{}"'.format(filename))
            raise
        except:
            raise

        if not self._validDM():
            #print('Not a valid DM3 or DM4 file: "{}"'.format(filename))
            raise IOError('Can not read file: {}'.format(filename))

        #Lists that will contain information about binary data arrays
        self.xSize = []
        self.ySize = []
        self.zSize = []
        self.zSize2 = []  #only used for 4D datasets in DM4 files
        self.dataType = []
        self.dataSize = []
        self.dataOffset = []
        self.dataShape = [
        ]  #1,2,3, or 4. The total number of dimensions in a data set

        #The number of objects found in the DM3 file
        self.numObjects = 0

        #Indicator that a thumbnail exists (tested for later)
        self.thumbnail = False

        self.curGroupLevel = 0  #track how deep we currently are in a group
        self.maxDepth = 64  #maximum number of group levels allowed
        self.curGroupAtLevelX = np.zeros(
            (self.maxDepth, ), dtype=np.int8)  #track group at current level
        self.curGroupNameAtLevelX = ''  #set the name of the root group

        self.curTagAtLevelX = np.zeros(
            (self.maxDepth, ),
            dtype=np.int8)  #track tag number at the current level
        self.curTagName = ''  #string of the current tag

        #lists that will contain scale information (pixel size)
        self.scale = []
        self.scaleUnit = []
        self.origin = []
        self.dataType = []

        #Temporary variables to keep in case a tag entry shows useful information in an array
        self.scale_temp = 0
        self.origin_temp = 0

        self.outputDic = {}
        self.allTags = {}