# -*- coding: utf-8 -*-
r"""
IOimagefile module is made for reading data contained in binary image file
fully or partially.
More tools can be found in LaueTools package at sourceforge.net and gitlab.esrf.fr
March 2020
"""
__author__ = "Jean-Sebastien Micha, CRG-IF BM32 @ ESRF"
# built-in modules
import sys
import os
import copy
import struct
# third party modules
try:
import fabio
FABIO_EXISTS = True
except ImportError:
print("Missing fabio module. Please install it if you need open some tiff images "
"from the sCMOS camera")
FABIO_EXISTS = False
try:
from libtiff import TIFF, libtiff_ctypes
libtiff_ctypes.suppress_warnings()
LIBTIFF_EXISTS = True
except ImportError:
print("Missing library libtiff, Please install: pylibtiff if you need open some tiff images")
LIBTIFF_EXISTS = False
try:
from PIL import Image
PIL_EXISTS = True
except ImportError:
print("Missing python module called PIL. Please install it if you need open some tiff "
"images from vhr camera")
PIL_EXISTS = False
import numpy as np
# lauetools modules
if sys.version_info.major == 3:
from . import dict_LaueTools as DictLT
from . import imageprocessing as ImProc
else:
import dict_LaueTools as DictLT
import imageprocessing as ImProc
listfile = os.listdir(os.curdir)
[docs]def stringint(k, n):
r""" returns string of integer k with n zeros padding
(by placing zeros before to have n characters)
:param k: integer to convert
:param n: nb of digits for zero padding
:return: string of length n containing integer k
Example: 1 -> '0001'
15 -> '0015'
"""
# strint = str(k)
# res = '0' * (n - len(strint)) + strint
encodingdigits = "{" + ":0{}".format(int(n)) + "}"
res = encodingdigits % k
return res
# --- ---------------- read images functions
[docs]def setfilename(imagefilename, imageindex, nbdigits=4, CCDLabel=None):
r"""
reconstruct filename string from imagefilename and update filename index with imageindex
:param imagefilename: filename string (full path or not)
:param imageindex: index in filename
:type imageindex: string
:return filename: input filename with index replaced by input imageindex
:rtype: string
"""
# print "imagefilename",imagefilename
if imagefilename.endswith("mccd"):
lenext = 5 #length of extension including '.'
imagefilename = imagefilename[: -(lenext + nbdigits)] + "{:04d}.mccd".format(imageindex)
elif CCDLabel in ("sCMOS", "sCMOS_fliplr"):
#default file extension for sCMOS camera
ext = "tif"
lenext = 4 #length of extension including '.'
if imagefilename.endswith("tiff"):
ext = "tiff"
lenext = 5
# zero padded index for filename
if nbdigits is not None:
if imagefilename.endswith(ext):
imagefilename = imagefilename[: -(lenext + nbdigits)] + "{:04d}.{}".format(
imageindex, ext)
elif imagefilename.endswith(ext+".gz"):
imagefilename = imagefilename[: -(lenext+3 + nbdigits)] + "{:04d}.{}.gz".format(imageindex, ext)
# no zero padded index for filename
else:
if imagefilename.endswith(ext):
prefix, _ = imagefilename.split(".")
prefix0 = prefix.split("_")[0]
if imageindex > 9999:
imagefilename = prefix0 + "_{}.{}".format(imageindex, ext)
else:
imagefilename = prefix0 + "_{:04d}.{}".format(imageindex, ext)
elif CCDLabel in ("EIGER_4Mstack",):
# only stackimageindex is changed not imagefilename
pass
# print "imagefilename archetype", imagefilename
elif imagefilename.endswith("mar.tiff"):
imagefilename = imagefilename[: -(9 + nbdigits)] + "{:04d}_mar.tiff".format(imageindex)
elif imagefilename.endswith("mar.tif"):
# requires two underscores with number in between
# map1_105_mar.tif
sname = imagefilename.split("_")
if len(sname) >= 4: # pathfilename contain more than 1 underscore
sname2 = sname[-2] + "_" + sname[-1]
prefix = imagefilename.rstrip(sname2)
else:
prefix = imagefilename.split("_")[0]
imagefilename = prefix + "_{}_mar.tif".format(imageindex)
# special case for image id15 frelon corrected form distorsion
elif imagefilename.endswith((".tif", ".edf")):
if CCDLabel in ("ImageStar_raw", ):
prefixwihtindex = imagefilename[:-4]
prefixwithindex_list = list(prefixwihtindex)
indexnodigit = 0
while len(prefixwithindex_list) > 0:
lastelem = prefixwithindex_list.pop(-1)
print("lastelem", lastelem)
if not lastelem.isdigit():
break
indexnodigit += 1
prefix = prefixwihtindex[:-(indexnodigit)]
print("prefix", prefix)
imagefilename = prefix + "{}.tif".format(imageindex)
else:
suffix = imagefilename[-4:]
prefix = imagefilename[: -(4 + nbdigits)]
imagefilename = prefix + "{:04d}{}".format(imageindex, suffix)
elif imagefilename.endswith("mccd"):
imagefilename = imagefilename[: -(5 + nbdigits)] + "{:04d}.mccd".format(imageindex)
elif imagefilename.endswith("edf"):
imagefilename = imagefilename[: -(4 + nbdigits)] + "{:04d}.edf".format(imageindex)
elif imagefilename.endswith("unstacked"):
imagefilename = imagefilename[: -(10 + nbdigits)] + "{:04d}.unstacked".format(imageindex)
# print "set filename to:", imagefilename
return imagefilename
[docs]def getIndex_fromfilename(imagefilename, nbdigits=4, CCDLabel=None, stackimageindex=-1):
r"""
get integer index from imagefilename string
:param imagefilename: filename string (full path or not)
:return: file index
"""
if CCDLabel in ("sCMOS", "sCMOS_fliplr"):
#default file extension for sCMOS camera
ext = "tif"
lenext = 4 #length of extension including '.'
if imagefilename.endswith("tiff"):
ext = "tiff"
lenext = 5
print(imagefilename)
if nbdigits is not None:
if imagefilename.endswith(ext):
imageindex = int(imagefilename[-(lenext + nbdigits) : -(lenext)])
elif imagefilename.endswith(ext+".gz"):
imageindex = int(imagefilename[-(lenext+3 + nbdigits) : -(lenext+3)])
else:
if imagefilename.endswith(ext):
prefix, _ = imagefilename.split(".")
imageindex = int(prefix.split("_")[1])
# for stacked images we return the position of image data in the stack as imagefileindex
elif CCDLabel in ("EIGER_4Mstack",):
imageindex = stackimageindex
elif imagefilename.endswith("mar.tiff"):
imageindex = int(imagefilename[-(9 + nbdigits) : -9])
elif imagefilename.endswith("tiff"):
imageindex = int(imagefilename[-(5 + nbdigits) : -5])
elif imagefilename.endswith("mar.tif"):
imageindex = int(imagefilename.split("_")[-2])
elif imagefilename.endswith(".tif"):
# TODO: treat the case of HN56.tif without underscore (see setfilename)
imageindex = int(imagefilename.split("_")[-1][:-4])
elif imagefilename.endswith("mccd"):
imageindex = int(imagefilename[-(5 + nbdigits) : -5])
elif imagefilename.endswith("edf"):
imageindex = int(imagefilename[-(4 + nbdigits) : -4])
elif imagefilename.endswith("unstacked"):
imageindex = int(imagefilename[-(10 + nbdigits) : -10])
return imageindex
[docs]def getfilename(dirname, imfileprefix, imfilesuffix=None, numim=None,
nbdigits_filename=4):
"""
to get the global file name (name+path) for given components of the name
put %4d instead of stringint
"""
fileim = imfileprefix + stringint(numim, nbdigits_filename) + imfilesuffix
filename = os.path.join(dirname, fileim)
return filename
[docs]def getwildcardstring(CCDlabel):
r""" return smart wildcard to open binary CCD image file with priority of CCD type of CCDlabel
:param CCDlabel: string label defining the CCD type
:type CCDlabel: str
:return: string from concatenated strings to be used in wxpython open file dialog box
:rtype: str
.. see also::
- :func:`getIndex_fromfilename`
- LaueToolsGUI.AskUserfilename
- wx.FileDialog
.. example::
>>> from readmccd import getwildcardstring
>>> getwildcardstring('MARCCD165')
'MARCCD, ROPER(*.mccd)|*mccd|mar tif(*.tif)|*_mar.tiff|tiff(*.tiff)|*tiff|Princeton(*.spe)|*spe|Frelon(*.edf)|*edf|tif(*.tif)|*tif|All files(*)|*'
"""
ALL_EXTENSIONS = ["mccd", "_mar.tiff", "tiff", "spe", "edf", "tif", "h5", ""]
INFO_EXTENSIONS = ["MARCCD, ROPER(*.mccd)", "mar tif(*.tif)", "tiff(*.tiff)",
"Princeton(*.spe)", "Frelon(*.edf)", "tif(*.tif)", "hdf5(*.h5)",
"All files(*)"]
extensions = copy.copy(ALL_EXTENSIONS)
infos = copy.copy(INFO_EXTENSIONS)
chosen_extension = DictLT.dict_CCD[CCDlabel][7]
if chosen_extension in ALL_EXTENSIONS:
index = ALL_EXTENSIONS.index(chosen_extension)
ce = extensions.pop(index)
extensions.insert(0, ce)
inf = infos.pop(index)
infos.insert(0, inf)
wcd = ""
for inf, ext in zip(infos, extensions):
wcd += "{}|*{}|".format(inf, ext)
wildcard_extensions = wcd[:-1]
return wildcard_extensions
[docs]def getpixelValue(filename, x, y, ccdtypegeometry="edf"):
r"""return pixel value at x,y
.. warning::
Very old function. To be checked. Use better readpixelvalue in plotdip.py
:param filename: path to image file
:type filename: str
:param x: x pixel value
:type x: int
:param y: y pixel value
:type y: int
:param ccdtypegeometry: CCD label, defaults to "edf"
:type ccdtypegeometry: str, optional
:return: pixel intensity
:rtype: int
"""
if ccdtypegeometry == "edf":
# frelon camera as mounted on BM32 Oct2012
y = 2047 - y
if ccdtypegeometry in ("mccd",):
pass
f = open(filename, "rb")
f.seek(1024 + 2 * (2048 * y + x))
val = struct.unpack("H", f.read(2))
f.close()
return val[0]
[docs]def readoneimage_full(filename, frametype="mccd", dirname=None):
r"""
too SLOW!
reads 1 entire image (marCCD format)
:return: PILimage, image object of PIL module (16 bits integer) and
arrayofdata: 2D array of intensity
#TODO: manage framedim like readoneimage() just below"""
if frametype == "mccd":
shapeCCD = (2048, 2048)
elif frametype == "martiff":
# opposite of fit2d displays in loading data
shapeCCD = (2591, 2751)
elif frametype == "spe":
# opposite of fit2d displays in loading data
shapeCCD = (2048, 2048)
if dirname is None:
dirname = os.curdir
pilimage = Image.open(os.path.join(dirname, filename))
ravdata = np.array(pilimage.getdata())
return pilimage, np.reshape(ravdata, shapeCCD)
[docs]def readCCDimage(filename, CCDLabel="MARCCD165", dirname=None, stackimageindex=-1, verbose=0):
r"""Read raw data binary image file.
Read raw data binary image file and return pixel intensity 2D array such as
to fit the data (2theta, chi) scattering angles representation convention.
:param filename: path to image file (fullpath if ` dirname` =None)
:type filename: str
:param CCDLabel: label, defaults to "MARCCD165"
:type CCDLabel: str, optional
:param dirname: folder path, defaults to None
:type dirname: str, optional
:param stackimageindex: index of images bunch, defaults to -1
:type stackimageindex: int, optional
:param verbose: 0 or 1, defaults to 0
:type verbose: int, optional
:raises ValueError: if data format and CCD parameters from label are not compatible
:return:
- dataimage, 2D array image data pixel intensity properly oriented
- framedim, iterable of 2 integers shape of dataimage
- fliprot : string, key for CCD frame transform to orient image
:rtype: tuple of 3 elements
"""
(framedim, _, _, fliprot, offsetheader, formatdata, _, _) = DictLT.dict_CCD[CCDLabel]
USE_RAW_METHOD = False
print("CCDLabel in readCCDimage", CCDLabel)
# if extension != extension:
# print "warning : file extension does not match CCD type set in Set CCD File Parameters"
if FABIO_EXISTS:
if CCDLabel in ('MARCCD165', "EDF", "EIGER_4M", "EIGER_1M",
"sCMOS", "sCMOS_fliplr", "sCMOS_fliplr_16M", "sCMOS_16M",
"Rayonix MX170-HS", 'psl_weiwei'):
print('----> Using fabio ... to open %s\n'%filename)
# warning import Image # for well read of header only
if dirname is not None:
img = fabio.open(os.path.join(dirname, filename))
else:
img = fabio.open(filename)
dataimage = img.data
framedim = dataimage.shape
# pythonic way to change immutable tuple...
initframedim = list(DictLT.dict_CCD[CCDLabel][0])
initframedim[0] = framedim[0]
initframedim[1] = framedim[1]
initframedim = tuple(initframedim)
else:
USE_RAW_METHOD = True
elif CCDLabel in ("EIGER_4Mstack", ):
import tables as Tab
if dirname is not None:
pathtofile = os.path.join(dirname, filename)
else:
pathtofile = filename
# TODO check to correct version transition
if Tab.__version__ >= "3.4.2":
hdf5file = Tab.open_file(pathtofile)
else:
hdf5file = Tab.openFile(pathtofile)
print("opening hdf5 stacked data table")
alldata = hdf5file.root.entry.data.data
print("alldata.shape", alldata.shape)
dataimage = alldata[stackimageindex]
framedim = dataimage.shape
elif LIBTIFF_EXISTS:
print("----> Using libtiff...")
if CCDLabel in ("sCMOS", "MARCCD165", "TIFF Format", "FRELONID15_corrected", "VHR_PSI",
"VHR_DLS", "MARCCD225", "Andrea", "pnCCD_Tuba"):
# print "tiff format", CCDLabel
# print "dirname, filename", dirname, filename
if dirname is not None:
tifimage = TIFF.open(os.path.join(dirname, filename), mode="r")
else:
tifimage = TIFF.open(filename, mode="r")
dataimage = tifimage.read_image()
framedim = (int(tifimage.GetField("ImageLength")),
int(tifimage.GetField("ImageWidth")))
if tifimage.IsByteSwapped():
dataimage = dataimage.byteswap()
else:
USE_RAW_METHOD = True
elif PIL_EXISTS:
print("using PIL's module Image")
if CCDLabel in ("sCMOS", "MARCCD165"):
print('PIL is too slow. Better install libtiff or fabio. Meanwhile ...')
USE_RAW_METHOD = True
elif CCDLabel in ("VHR_PSI", "VHR_DLS", "MARCCD225", "Andrea", "pnCCD_Tuba"):
# data are compressed!
if dirname is not None:
fullpath = os.path.join(dirname, filename)
else:
fullpath = filename
im = Image.open(fullpath, "r")
dataimage = np.array(im.getdata()).reshape(framedim)
# RAW method knowing or deducing offsetheader and dataformat
if USE_RAW_METHOD:
print("----> not using libtiff, nor fabio, nor PIL!!! ")
if CCDLabel in ("MARCCD165",):
print("for MARCCD not using libtiff, raw method ...")
# offsetheader may change ...
#filesize = os.path.getsize(os.path.join(dirname, filename))
offsetheader = 4096 #filesize - 2048*2048 * 2
# offset header varying
elif CCDLabel.startswith("ImageStar_raw"):
filesize = os.path.getsize(os.path.join(dirname, filename))
bytes_per_pixels = 2
if CCDLabel.endswith("32bits"):
bytes_per_pixels = 4
nbpixels = 1500
if CCDLabel in ("ImageStar_1528x1528",):
nbpixels = 1528
offsetheader = filesize - nbpixels * nbpixels * bytes_per_pixels
elif CCDLabel in ("sCMOS",):
print("for sCMOS not using libtiff, raw method ...")
# offsetheader may change ...
filesize = os.path.getsize(os.path.join(dirname, filename))
offsetheader = filesize - 2016*2018 * 2
dataimage = readoneimage(filename,
framedim=framedim,
dirname=dirname,
offset=offsetheader,
formatdata=formatdata)
if CCDLabel in ("FRELONID15_corrected",):
dataimage = dataimage.byteswap()
if CCDLabel in ("EIGER_4Munstacked",):
print("framedim", framedim)
print("offsetheader", offsetheader)
print("formatdata", formatdata)
dataimage = np.ma.masked_where(dataimage > 4000000, dataimage)
print("dataimage", dataimage)
if verbose:
print("CCDLabel: ", CCDLabel)
print("nb of pixels", np.shape(dataimage))
# need to reshape data from 1D to 2D
try:
if len(dataimage.shape) == 1:
print("nb elements", len(dataimage))
print("framedim", framedim)
print("framedim nb of elements", framedim[0] * framedim[1])
dataimage = np.reshape(dataimage, framedim)
except ValueError:
raise ValueError(
"Selected CCD type :{} may be wrong (or nb of pixels, dimensions...)".format(
CCDLabel))
# some array transformations if needed depending on the CCD mounting
if fliprot == "spe":
dataimage = np.rot90(dataimage, k=1)
elif fliprot == "VHR_Feb13":
# self.dataimage_ROI = np.rot90(self.dataimage_ROI, k=3)
# TODO: do we need this left and right flip ?
dataimage = np.fliplr(dataimage)
elif fliprot == "sCMOS_fliplr":
dataimage = np.fliplr(dataimage)
elif fliprot == "vhr": # july 2012 close to diamond monochromator crystal
dataimage = np.rot90(dataimage, k=3)
dataimage = np.fliplr(dataimage)
elif fliprot == "vhrdiamond": # july 2012 close to diamond monochromator crystal
dataimage = np.rot90(dataimage, k=3)
dataimage = np.fliplr(dataimage)
elif fliprot == "frelon2":
dataimage = np.flipud(dataimage)
# print "framedim",framedim, fliprot
return dataimage, framedim, fliprot
[docs]def readoneimage(filename, framedim=(2048, 2048), dirname=None, offset=4096, formatdata="uint16"):
r""" returns a 1d array of integers from a binary image file (full data)
:param filename: image file name (full path if dirname=0)
:type filename: str
:param framedim: detector dimensions, defaults to (2048, 2048)
:type framedim: tuple of 2 integers, optional
:param dirname: folder path, defaults to None
:type dirname: str, optional
:param offset: file header in byte (octet), defaults to 4096
:type offset: int, optional
:param formatdata: numpy format of raw binary image pixel value, defaults to "uint16"
:type formatdata: str, optional
:return: dataimage : image data pixel intensity
:rtype: 1D array
"""
nb_elem = framedim[0] * framedim[1]
if dirname is None:
dirname = os.curdir
f = open(os.path.join(dirname, filename), "rb")
f.seek(offset)
# d=scipy.io.fread(f,2048*2048,np.oldnumeric.Int16)
# d = scipy.io.fread(f,nb_elem,np.oldnumeric.UInt16)
d = np.fromfile(f, dtype=formatdata, count=nb_elem)
f.close()
return d
[docs]def readoneimage_band(filename,
framedim=(2048, 2048),
dirname=None,
offset=4096,
line_startindex=0,
line_finalindex=2047,
formatdata="uint16"):
r"""
returns a 1d array of integers from a binary image file. Data located in band according shape of data (framedim)
:param filename: string
path to image file (fullpath if `dirname`=None)
:param offset: integer
nb of file header bytes
:param framedim: iterable of 2 integers
shape of expected 2D data
:param formatdata: string
key for numpy dtype to decode binary file
:return: dataimage, 1D array, image data pixel intensity
"""
if dirname is None:
dirname = os.curdir
if formatdata in ("uint16",):
nbBytesPerElement = 2
if formatdata in ("uint32",):
nbBytesPerElement = 4
nbElems = (line_finalindex - line_startindex + 1) * framedim[1]
f = open(os.path.join(dirname, filename), "rb")
f.seek(offset + line_startindex * framedim[1] * nbBytesPerElement)
# d=scipy.io.fread(f,2048*2048,np.oldnumeric.Int16)
# d = scipy.io.fread(f,nb_elem,np.oldnumeric.UInt16)
# print "line_finalindex-line_startindex",line_finalindex-line_startindex
# print "line_startindex*framedim[1]*nbBytesPerElement",line_startindex*framedim[1]*nbBytesPerElement
# print "line_startindex*framedim[1]",line_startindex*framedim[1]
# print "nbElems",nbElems
band = np.fromfile(f, dtype=formatdata, count=nbElems)
f.close()
return band
[docs]def readoneimage_crop_fast(filename, dirname=None, CCDLabel="MARCCD165",
firstElemIndex=0, lastElemIndex=2047):
r""" Returns a 2d array of integers from a binary image file. Data are taken only from a rectangle
with respect to firstElemIndex and lastElemIndex.
:param filename: string, path to image file (fullpath if ` dirname`=None)
:param offset: integer, nb of file header bytes
:param framedim: iterable of 2 integers, shape of expected 2D data
:param formatdata: string, key for numpy dtype to decode binary file
:return: dataimage : 1D array image data pixel intensity
"""
(framedim, _, _, fliprot, offsetheader, formatdata, _, _) = DictLT.dict_CCD[CCDLabel]
print("framedim read from DictLT.dict_CCD in readoneimage_crop_fast()", framedim)
print("formatdata", formatdata)
print("offsetheader", offsetheader)
if dirname is None:
dirname = os.curdir
# if formatdata in ("uint16",):
# nbBytesPerElement = 2
# if formatdata in ("uint32",):
# nbBytesPerElement = 4
dataimage2D = np.zeros(framedim)
# colFirstElemIndex = firstElemIndex % framedim[1]
lineFirstElemIndex = firstElemIndex // framedim[1]
# colLastElemIndex = lastElemIndex % framedim[1]
lineLastElemIndex = lastElemIndex // framedim[1]
band1D = readoneimage_band(filename, framedim=framedim, dirname=dirname, offset=offsetheader,
line_startindex=lineFirstElemIndex,
line_finalindex=lineLastElemIndex,
formatdata=formatdata)
# print "band1D.shape",band1D.shape
# print "(lineLastElemIndex-lineFirstElemIndex,framedim[1])",(lineLastElemIndex-lineFirstElemIndex,framedim[1])
# print "((lineLastElemIndex-lineFirstElemIndex)*framedim[1])",((lineLastElemIndex-lineFirstElemIndex)*framedim[1])
band2D = band1D.reshape((lineLastElemIndex - lineFirstElemIndex + 1, framedim[1]))
dataimage2D[lineFirstElemIndex : lineLastElemIndex + 1, :] = band2D
return dataimage2D, framedim, fliprot
[docs]def readrectangle_in_image(filename, pixx, pixy, halfboxx, halfboxy, dirname=None,
CCDLabel="MARCCD165",
verbose=True):
r"""
returns a 2d array of integers from a binary image file. Data are taken only from a rectangle
centered on pixx, pixy
:return: dataimage : 2D array, image data pixel intensity
"""
(framedim, _, _, fliprot, offsetheader, formatdata, _, _) = DictLT.dict_CCD[CCDLabel]
if verbose:
print("framedim read from DictLT.dict_CCD in readrectangle_in_image()", framedim)
print("formatdata", formatdata)
print("offsetheader", offsetheader)
# recompute headersize
if dirname is not None:
fullpathfilename = os.path.join(dirname, filename)
else:
dirname = os.curdir
fullpathfilename = filename
if formatdata in ("uint16",):
nbBytesPerElement = 2
if formatdata in ("uint32",):
nbBytesPerElement = 4
if verbose:
print("fullpathfilename", fullpathfilename)
try:
filesize = os.path.getsize(fullpathfilename)
except OSError:
print("missing file {}\n".format(fullpathfilename))
return None
# uint16
offsetheader = filesize - (framedim[0] * framedim[1]) * nbBytesPerElement
if verbose:
print("calculated offset of header from file size...", offsetheader)
x = int(pixx)
y = int(pixy)
if fliprot in ("sCMOS_fliplr",):
x = framedim[1] - x
boxx = int(halfboxx)
boxy = int(halfboxy)
xpixmin = x - boxx
xpixmax = x + boxx
ypixmin = y - boxy
ypixmax = y + boxy
# ymin= (y-boxy)*framedim[1]
# ymax= (y+boxy)*framedim[1]
lineFirstElemIndex = ypixmin
lineLastElemIndex = ypixmax
if verbose:
print("lineFirstElemIndex", lineFirstElemIndex)
print("lineLastElemIndex", lineLastElemIndex)
band = readoneimage_band(fullpathfilename,
framedim=framedim,
dirname=None,
offset=offsetheader,
line_startindex=lineFirstElemIndex,
line_finalindex=lineLastElemIndex,
formatdata=formatdata)
nblines = lineLastElemIndex - lineFirstElemIndex + 1
band2D = np.reshape(band, (nblines, framedim[1]))
# dataimage2D = np.zeros(framedim)
if verbose:
print("band2D.shape", band2D.shape)
rectangle2D = band2D[:, xpixmin : xpixmax + 1]
if verbose:
print("rectangle2D.shape", rectangle2D.shape)
return rectangle2D
[docs]def readoneimage_crop(filename, center, halfboxsize, CCDLabel="PRINCETON", dirname=None):
r"""
return a cropped array of data read in an image file
:param filename: string, path to image file (fullpath if ` dirname`=None)
:param center: iterable of 2 integers, (x,y) pixel coordinates
:param halfboxsize: integer or iterable of 2 integers, ROI half size in both directions
:return: dataimage : 1D array, image data pixel intensity
.. todo:: useless?
"""
if dirname is None:
dirname = os.curdir
else:
filename = os.path.join(dirname, filename)
if isinstance(halfboxsize, int):
boxsizex, boxsizey = halfboxsize, halfboxsize
elif len(halfboxsize) == 2:
boxsizex, boxsizey = halfboxsize
xpic, ypic = center
dataimage, framedim, _ = readCCDimage(filename, CCDLabel=CCDLabel, dirname=None)
x1 = np.maximum(0, xpic - boxsizex)
x2 = np.minimum(framedim[1], xpic + boxsizex + 1) # framedim[0]
y1 = np.maximum(0, ypic - boxsizey)
y2 = np.minimum(framedim[0], ypic + boxsizey + 1) # framedim[1]
return None, dataimage[y1:y2, x1:x2]
[docs]def readoneimage_manycrops(filename, centers, boxsize, stackimageindex=-1, CCDLabel="MARCCD165",
addImax=False,
use_data_corrected=None):
r"""
reads 1 image and extract many regions
centered on center_pixel with xyboxsize dimensions in pixel unit
:param filename: string,fullpath to image file
:param centers: list or array of [int,int] centers (x,y) pixel coordinates
:param use_data_corrected: enter data instead of reading data from file
must be a tuple of 3 elements:
fulldata, framedim, fliprot
where fulldata is a numpy.ndarray
as output by :func:`readCCDimage`
:param boxsize: iterable 2 elements or integer
boxsizes [in x, in y] direction or integer to set a square ROI
:return: Data, list of 2D array pixel intensity or Data and Imax
"""
# use alternate data (for instance for data from filename without background)
if use_data_corrected is not None:
if isinstance(use_data_corrected, tuple):
if len(use_data_corrected) == 3:
fulldata, framedim, _ = use_data_corrected
# use data by reading file
else:
fulldata, framedim, _ = readCCDimage(filename, stackimageindex=stackimageindex,
CCDLabel=CCDLabel,
dirname=None)
if isinstance(boxsize, int):
boxsizex, boxsizey = boxsize, boxsize
elif len(boxsize) == 2:
boxsizex, boxsizey = boxsize
# xpic, ypic = np.array(centers).T
# x1 = np.array(np.maximum(0, xpic - boxsizex), dtype=np.int)
# x2 = np.array(np.minimum(framedim[0], xpic + boxsizex), dtype=np.int)
# y1 = np.array(np.maximum(0, ypic - boxsizey), dtype=np.int)
# y2 = np.array(np.minimum(framedim[1], ypic + boxsizey), dtype=np.int)
Data = []
Imax = []
print("framedim in readoneimage_manycrops", framedim)
framedim = framedim[1], framedim[0]
for center in centers:
i1, i2, j1, j2 = ImProc.getindices2cropArray(center, (boxsizex, boxsizey), framedim)
# print "i1, i2, j1, j2-----", i1, i2, j1, j2
cropdata = fulldata[i1:i2, j1:j2]
# # print "cropdata.shape", cropdata.shape
# print "i2-i1",i2-i1
# print "boxsizey*2+1",boxsizey*2+1
# print "j2-j1",j2-j1
# print "boxsizex*2+1",boxsizex*2+1
# for spot near border, replace by zeros array
if i2 - i1 != boxsizey * 2 or j2 - j1 != boxsizex * 2:
cropdata = np.zeros((boxsizey * 2 + 1, boxsizex * 2 + 1))
Data.append(cropdata)
if addImax:
Imax.append(np.amax(cropdata))
# print "max in cropped data", np.amax(cropdata)
if addImax:
return Data, Imax
else:
return Data
[docs]def writeimage(outputname, _header, data, dataformat=np.uint16):
r"""
from data 1d array of integers
with header coming from a f.open('imagefile'); f.read(headersize);f.close()
.. warning:: header contain dimensions for subsequent data. Check before the compatibility of
data with header infos(nb of byte per pixel and array dimensions
"""
newfile = open(outputname, "wb")
newfile.write(_header)
data = np.array(data, dtype=dataformat)
data.tofile(newfile)
newfile.close()
print("image written in ", outputname)
[docs]def write_rawbinary(outputname, data, dataformat=np.uint16):
r"""
write a binary file without header of a 2D array
used ?
"""
newfile = open(outputname, "wb")
data = np.array(data, dtype=dataformat)
data.tofile(newfile)
newfile.close()
print("image written in ", outputname)
[docs]def SumImages(prefixname, suffixname, ind_start, ind_end, dirname=None,
plot=0,
output_filename=None,
CCDLabel=None,
nbdigits=0):
r"""
sum images and write image with 32 bits per pixel format (4 bytes)
used?
"""
# prefixname = 'HN08_'
# suffixname = '.tif'
# CCDLabel = 'ImageStar_raw'
# dirname = '/home/micha/LaueProjects/Vita'
output_filename = "mean_{}_{:04d}_{}{}".format(prefixname, ind_start, ind_end, suffixname)
filename = "{}{:04d}{}".format(prefixname, ind_start, suffixname)
data, shape, _ = readCCDimage(filename, CCDLabel=CCDLabel, dirname=dirname)
if CCDLabel == "ImageStar_raw":
# Add addition of 32 bits image => replace 2 by 4 nb of bytes per pixel
filesize = os.path.getsize(os.path.join(dirname, filename))
offsetheader = filesize - 1500 * 1500 * 2
if CCDLabel == "EIGER_1M":
filesize = os.path.getsize(os.path.join(dirname, filename))
offsetheader = filesize - 1065 * 1030 * 4
else:
# Add addition of 32 bits image => replace 2 by 4 nb of bytes per pixel
filesize = os.path.getsize(os.path.join(dirname, filename))
offsetheader = filesize - 2048 * 2048 * 2
# print "shape = ", np.shape(datastart)
datasum = np.zeros(shape, dtype=np.uint32)
# nb_images = ind_end - ind_start + 1
indexscanlist = list(range(ind_start, ind_end + 1, 1))
for k in indexscanlist:
# print k
filename = "{}{:04d}{}".format(prefixname, k, suffixname)
# print filename1
data, shape, _ = readCCDimage(filename, CCDLabel=CCDLabel, dirname=dirname)
# print max(data1), np.argmax(data1)
datasum = data + datasum
if output_filename:
outputfilename = output_filename
header = readheader(os.path.join(dirname, filename), offset=offsetheader)
writeimage(os.path.join(dirname, outputfilename), header, datasum, dataformat=np.uint32)
print("Added images with prefix {} from {} to {} written in {}".format(
prefixname, ind_start, ind_end, outputfilename))
if plot:
print("later")
return datasum
[docs]def Add_Images2(prefixname,
ind_start,
ind_end,
plot=0,
writefilename=None,
CCDLabel="MARCCD165",
average=True):
"""
in dev
"""
suffixname = "." + DictLT.dict_CCD[CCDLabel][-1]
filename = prefixname + stringint(ind_start, 4) + suffixname
datastart, _, _ = readCCDimage(filename, CCDLabel)
# print "shape = ", np.shape(datastart)
datastart = np.array(datastart, dtype=float)
indexscanlist = list(range(ind_start + 1, ind_end + 1, 1))
for k in indexscanlist:
# print k
filename1 = prefixname + stringint(k, 4) + suffixname
# print filename1
data1, _, _ = readCCDimage(filename1, CCDLabel)
# print max(data1), np.argmax(data1)
datastart = np.array(data1, dtype=float) + datastart
# datastart= datastart/((len(indexscanlist)+1)*1.)
# print "final"
# print max(datastart), np.argmax(datastart)
if average:
datastart = datastart / (float(len(indexscanlist)) + 1.0)
# print max(datastart), np.argmax(datastart)
datastart = np.array(datastart, dtype=np.uint16)
# print max(datastart), np.argmax(datastart)
if writefilename:
outputfilename = writefilename
header = readheader(filename1, CCDLabel=CCDLabel)
writeimage(outputfilename, header, datastart)
print("written in ", outputfilename)
if plot:
print("later")
return datastart
[docs]def Add_Images(prefixname, ind_start, ind_end, plot=0, writefilename=None):
r"""
Add continuous sequence of images
.. note::
Add_Images2 exists
:param prefixname: string, prefix common part of name of files
:param ind_start: int, starting image index
:param ind_end: int, final image index
:param writefilename: string, new image filename where to write datastart (with last image file header read)
:return: datastart, array accumulation of 2D data from each image
"""
suffixname = ".mccd"
datastart = readoneimage(prefixname + stringint(ind_start, 4) + suffixname)
# print "shape = ", np.shape(datastart)
datastart = np.array(datastart, dtype=float)
indexscanlist = list(range(ind_start + 1, ind_end + 1, 1))
for k in indexscanlist:
# print k
filename1 = prefixname + stringint(k, 4) + suffixname
# print filename1
data1 = readoneimage(filename1)
# print max(data1), np.argmax(data1)
datastart = np.array(data1, dtype=float) + datastart
# datastart= datastart/((len(indexscanlist)+1)*1.)
# print "final"
# print max(datastart), np.argmax(datastart)
datastart = datastart / (float(len(indexscanlist)) + 1.0)
# print max(datastart), np.argmax(datastart)
datastart = np.array(datastart, dtype=np.uint16)
# print max(datastart), np.argmax(datastart)
if writefilename:
outputfilename = writefilename
header = readheader(filename1)
writeimage(outputfilename, header, datastart)
print("written in ", outputfilename)
if plot:
print("later")
return datastart
[docs]def get_imagesize(framedim, nbbits_per_pixel, headersize_bytes):
r"""
return size of image in byte (= 1 octet = 8 bits)
"""
return (framedim[0] * framedim[1] * nbbits_per_pixel + headersize_bytes * 8) // 8