Source code for PyMca5.PyMcaIO.MRCMap

#/*##########################################################################
#
# The PyMca X-Ray Fluorescence Toolkit
#
# Copyright (c) 2004-2015 European Synchrotron Radiation Facility
#
# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
# the ESRF by the Software group.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
__author__ = "V.A. Sole - ESRF Data Analysis"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import os
import sys
import re
import struct
import numpy
import copy
from PyMca5 import DataObject

if sys.version < '2.6':
    def bytes(x):
        return str(x)

DEBUG = 0
SOURCE_TYPE = "EdfFileStack"

[docs]class MRCMap(DataObject.DataObject): ''' Class to read MRC files It reads the spectra into a DataObject instance. This class info member contains all the parsed information. This class data member contains the map itself as a 3D array. ''' def __init__(self, filename): ''' Parameters: ----------- filename : str Name of the input file. It is expected to work with files generated at BESSY with raw2mrc ''' DataObject.DataObject.__init__(self) try: fid = open(filename, 'rb') header = fid.read(1024) fid.close() except: fid.close() raise if not _isMRCHeader(header): raise IOError("File does not seem to be an MRC file") self.sourceName = filename # check endianness flag = struct.unpack("4B", header[212:216])[0] if flag in [17, 18]: # high endian (Motorola) endianness = ">" else: # little endian (Intel) endianness = "<" fmt = endianness + "10i" tenIntegers = struct.unpack(fmt, header[0:40]) nColumns, nRows, nImages, mode = tenIntegers[0:4] fmt = endianness + "6f" sixFloats = struct.unpack(fmt, header[40:64]) fmt = endianness + "3i" threeIntegers = struct.unpack(fmt, header[64:76]) fmt = endianness + "3f" threeFloats = struct.unpack(fmt, header[76:88]) # number of bytes in extended header fmt = endianness + "i" offset = struct.unpack(fmt, header[92:96])[0] fmt = endianness + "ii" imodStamp, imodFlags = struct.unpack(fmt, header[152:160]) if mode == 0: # bytes dataFormat = endianness + "%dB" % (nRows * nColumns) elif mode == 1: # signed short integers (16 bit) dataFormat = endianness + "%dh" % (nRows * nColumns) elif mode == 2: # float dataFormat = endianness + "%df" % (nRows * nColumns) elif mode == 3: # two shorts, complex data dataFormat = endianness + "%dh" % (2 * nRows * nColumns) elif mode == 4: # two floats, complex data dataFormat = endianness + "%df" % (2 * nRows * nColumns) elif mode == 6: # unsigned 16 bit integers (non-standard) dataFormat = endianness + "%dH" % (nRows * nColumns) elif mode == 16: # unsigned char * 3(rgb data, non-standard) dataFormat = endianness + "%dB" % (3 * nRows * nColumns) else: raise IOError("Data format not undestood") if imodFlags == 1: # bytes stored as signed dataFormat = dataFormat.lower() data = numpy.zeros((nImages, nRows * nColumns), numpy.float) fid = open(filename, 'rb') fileOffset = 1024 + offset fid.seek(fileOffset) dataSize= struct.calcsize(dataFormat) try: for i in range(nImages): tmpData = fid.read(dataSize) data[i] = struct.unpack(dataFormat, tmpData) fid.close() except: fid.close() raise data.shape = nImages, nRows, nColumns self.data = data self.info = {} self.info["SourceType"] = SOURCE_TYPE self.info["SourceName"] = self.sourceName shape = self.data.shape for i in range(len(shape)): key = 'Dim_%d' % (i + 1,) self.info[key] = shape[i] self.info["NumberOfFiles"] = 1 self.info["McaIndex"] = 0 self.info["McaCalib"] = [0.0, 1.0, 0.0] self.info["Channel0"] = 0.0
def _isMRCHeader(header): try: if sys.version < '3.0': test = "MAP " else: test = bytes("MAP ", "utf-8") if struct.unpack("4s", header[208:212])[0] == test: return True except: pass return False
[docs]def isMRCFile(filename): try: fid = open(filename, 'rb') header = fid.read(1024) fid.close() except: fid.close() return False nColumns, nRows, nImages = struct.unpack("iii", header[0:12]) imodStamp, imodFlags = struct.unpack("ii", header[152:160]) #print(imodStamp, imodFlags) # system byte order #print("system ",sys.byteorder) return _isMRCHeader(header)
if __name__ == "__main__": filename = None if len(sys.argv) > 1: filename = sys.argv[1] print("is MRC File?", isMRCFile(filename)) instance = MRCMap(filename) print(instance.info) print(instance.data)