/usr/share/pyshared/fabio/mrcimage.py is in python-fabio 0.1.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #!/usr/bin/env python
# coding: utf8
"""
MRC image for FabIO
Authors: Jerome Kieffer
email: Jerome.Kieffer@terre-adelie.org
Specifications from:
http://ami.scripps.edu/software/mrctools/mrc_specification.php
"""
# Get ready for python3:
from __future__ import with_statement, print_function
__authors__ = ["Jérôme Kieffer"]
__contact__ = "Jerome.Kieffer@terre-adelie.org"
__license__ = "GPLv3+"
__copyright__ = "Jérôme Kieffer"
__version__ = "29 Oct 2013"
import numpy, logging, sys
from .fabioimage import fabioimage
logger = logging.getLogger("mrcimage")
if sys.version_info < (3.0):
bytes = str
class mrcimage(fabioimage):
"""
FabIO image class for Images from a mrc image stack
"""
KEYS = ("NX", "NY", "NZ", "MODE", "NXSTART", "NYSTART", "NZSTART",
"MX", "MY", "MZ", "CELL_A", "CELL_B", "CELL_C",
"CELL_ALPHA", "CELL_BETA", "CELL_GAMMA",
"MAPC", "MAPR", "MAPS", "DMIN", "DMAX", "DMEAN", "ISPG", "NSYMBT",
"EXTRA", "ORIGIN", "MAP", "MACHST", "RMS", "NLABL")
def __init__(self, *arg, **kwargs):
"""
Generic constructor
"""
fabioimage.__init__(self, *arg, **kwargs)
self.data = None
self.header = {}
self.dim1 = self.dim2 = 0
self.m = self.maxval = self.stddev = self.minval = None
self.header_keys = self.header.keys()
self.bytecode = None
def _readheader(self, infile):
"""
Read and decode the header of an image:
@param infile: Opened python file (can be stringIO or bipped file)
"""
# list of header key to keep the order (when writing)
self.header = {}
self.header_keys = []
# header is composed of 56-int32 plus 10x80char lines
int_block = numpy.fromstring(infile.read(56 * 4), dtype=numpy.int32)
for key, value in zip(self.KEYS, int_block):
self.header_keys.append(key)
self.header[key] = value
assert self.header["MAP"] == 542130509 # "MAP " in int32 !
for i in range(10):
label = "LABEL_%02i" % i
self.header_keys.append(label)
self.header[label] = infile.read(80).strip()
self.dim1 = self.header["NX"]
self.dim2 = self.header["NY"]
self.nframes = self.header["NZ"]
mode = self.header["MODE"]
if mode == 0:
self.bytecode = numpy.int8
elif mode == 1:
self.bytecode = numpy.int16
elif mode == 2:
self.bytecode = numpy.float32
elif mode == 3:
self.bytecode = numpy.complex64
elif mode == 4:
self.bytecode = numpy.complex64
elif mode == 6:
self.bytecode = numpy.uint16
self.imagesize = self.dim1 * self.dim2 * numpy.dtype(self.bytecode).itemsize
def read(self, fname, frame=None):
"""
try to read image
@param fname: name of the file
@param frame:
"""
self.resetvals()
self.sequencefilename = fname
self.currentframe = frame or 0
with self._open(fname) as infile:
self._readheader(infile)
self._readframe(infile, self.currentframe)
return self
def _calc_offset(self, frame):
"""
Calculate the frame position in the file
@param frame: frame number
"""
assert frame < self.nframes
return 1024 + frame * self.imagesize
def _makeframename(self):
self.filename = "%s$%04d" % (self.sequencefilename,
self.currentframe)
def _readframe(self, infile, img_num):
"""
Read a frame an populate data
@param infile: opened file
@param img_num: frame number (int)
"""
if (img_num > self.nframes or img_num < 0):
raise RuntimeError("Requested frame number is out of range")
imgstart = self.header['offset'] + img_num * (512 * 476 * 2 + 24)
infile.seek(self.calc_offset(img_num), 0)
self.data = numpy.fromstring(infile.read(self.imagesize),
self.bytecode)
self.data.shape = self.dim2, self.dim1
self.currentframe = int(img_num)
self._makeframename()
def write(self, fname, force_type=numpy.uint16):
raise NotImplementedError("Write is not implemented")
def getframe(self, num):
"""
Returns a frame as a new fabioimage object
@param num: frame number
"""
if num < 0 or num > self.nframes:
raise RuntimeError("Requested frame number is out of range")
# Do a deep copy of the header to make a new one
frame = mrcimage(header=self.header.copy())
frame.header_keys = self.header_keys[:]
for key in ("dim1", "dim2", "nframes", "bytecode", "imagesize", "sequencefilename"):
frame.__setattr__(key, self.__getattribute__(key))
with frame._open(self.sequencefilename, "rb") as infile:
frame._readframe(infile, num)
return frame
def next(self):
"""
Get the next image in a series as a fabio image
"""
if self.currentframe < (self.nframes - 1) and self.nframes > 1:
return self.getframe(self.currentframe + 1)
else:
newobj = mrcimage()
newobj.read(next_filename(
self.sequencefilename))
return newobj
def previous(self):
"""
Get the previous image in a series as a fabio image
"""
if self.currentframe > 0:
return self.getframe(self.currentframe - 1)
else:
newobj = mrcimage()
newobj.read(previous_filename(
self.sequencefilename))
return newobj
|