from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import six
from six.moves import range
#!/usr/bin/python
# Filename: xrs_rois.py
#/*##########################################################################
#
# The XRStools software package for XRS spectroscopy
#
# Copyright (c) 2013-2014 European Synchrotron Radiation Facility
#
# This file is part of the XRStools XRS spectroscopy package developed at
# the ESRF by the DEC and 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__ = "Christoph J. Sahle - ESRF"
__contact__ = "christoph.sahle@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import numpy as np
import copy
import h5py
import os
import matplotlib.pyplot as plt
from collections import Iterable
# commented the *import because otherwise sphinx documents all the symbol of other packages
# from xrs_utilities import *
# from math_functions import *
from . import xrs_utilities
from . import math_functions
###########################################
from matplotlib.widgets import Cursor, Button
from scipy.ndimage import measurements
from scipy import signal
[docs]def h5_assign_force(h5group, name, item):
if name in h5group:
del h5group[name]
h5group[name] = item
[docs]class container:
"""
Random container class to hold values
"""
def __init__(self):
pass
sl={}
sl[0 ] = slice(0 ,256)
sl[256] = slice(256,512)
sl[512] = slice(512,768)
sl[3*256] = slice(3*256 ,3*256 + 256)
sl[4*256] = slice(4*256 ,4*256 + 256)
V147 = [1,4,7,10,2,5,8,11,3,6,9,12]
V1296 = [12,9,6,3,11,8,5,2,10,7,4,1]
V1074 = [10,7,4,1,11,8,5,2,12,9,6,3 ]
V369 = [3,6,9,12,2,5,8,11,1,4,7,10 ]
V1234 = [1,2,3,4]
[docs]def order_generator_ascending(a,b,c,d):
return [ a,b,c,d,
a+1,b+1,c+1,d+1,
a+2,b+2,c+2,d+2]
[docs]def order_generator_descending(a,b,c,d):
return [ a,b,c,d,
a-1,b-1,c-1,d-1,
a-2,b-2,c-2,d-2]
OG_inc = order_generator_ascending
OG_dec = order_generator_descending
geo_informations = {(256,768,None): { "DET_PIXEL_NUM":256, "geo":[256,768], "nofrois":36,
"subnames": ["RD" ,"LU","B"],
"subgeos" : [(sl[0] ,sl[0]),
(sl[0],sl[256]),
(sl[0],sl[512])] ,
"analyser_nIDs": {"LU":{"3x4":OG_inc(10,7,4,1),"Vertical": OG_inc(1,4,7,10)},
"RD":{"3x4":OG_inc(1,4,7,10),"Vertical": OG_inc(1,4,7,10)},
"B": {"3x4":OG_inc(1,4,7,10),"Vertical": OG_inc(1,4,7,10)}
}
},
(512,768,None) : { "DET_PIXEL_NUM":256, "geo":[512,768],"nofrois":72,
"subnames":["VD" , "VU","VB","HR" ,"HL","HB", ] ,
"subgeos" :[(sl[0],sl[0] ),
(sl[0],sl[256] ),
(sl[0],sl[512] ),
(sl[256],sl[0] ),
(sl[256],sl[256] ),
(sl[256],sl[512] )],
"analyser_nIDs": {"VD":{"3x4": OG_dec(12,9,6,3) ,"Vertical": OG_dec(12,9,6,3) },
"VU":{"3x4": OG_dec(3,6,9,12) ,"Vertical": OG_dec(12,9,6,3) },
"VB":{"3x4": OG_dec(3,6,9,12) ,"Vertical": OG_dec(12,9,6,3) },
"HR":{"3x4": OG_inc(1,4,7,10) ,"Vertical": OG_inc(1,4,7,10) },
"HL":{"3x4": OG_inc(10,7,4,1) ,"Vertical": OG_inc(1,4,7,10) },
"HB":{"3x4": OG_inc(10,7,4,1) ,"Vertical": OG_inc(1,4,7,10) },
}
},
(256,256,None):{"DET_PIXEL_NUM":256, "geo":[256,256],"nofrois":1,"subnames":["DETECTOR"],"subgeos" : [(sl[0] ,sl[0])],
"analyser_nIDs": {"DETECTOR":{"3x4":V147,"Vertical": V147}}
},
(256,256,"1X1-4"):{"DET_PIXEL_NUM":256, "geo":[256,256],"nofrois":4,"subnames":["DETECTOR"],"subgeos" : [(sl[0] ,sl[0])],
"analyser_nIDs": {"DETECTOR":{ "Vertical": V1234} }
}
}
geo_informations[(256,768,"1X3-12")]=geo_informations[(256,768,None)]
geo_informations[(512,768,"2X3-12")]=geo_informations[(512,768,None)]
geo_informations[(256,256,"1X1-12")]=geo_informations[(256,256,None)]
for NBCU in [255,256]:
geo_informations[(NBCU,5*259,"1X5-1")] = { "DET_PIXEL_NUM":NBCU, "geo":[NBCU,5*259],"nofrois":5,
"subnames":["A" ,"B","C","D" , "E" ] ,
"subgeos" :[(slice(0,NBCU),slice(259*0,259*1) ),
(slice(0,NBCU),slice(259*1,259*2) ),
(slice(0,NBCU),slice(259*2,259*3) ),
(slice(0,NBCU),slice(259*3,259*4) ),
(slice(0,NBCU),slice(259*4,259*5) ),
],
"analyser_nIDs": {"A":{"Vertical":[1]},
"B":{"Vertical":[1]},
"C":{"Vertical":[1]},
"D":{"Vertical":[1]},
"E":{"Vertical":[1]},
}
}
geo_informations[(NBCU,5*259+1,"1X5-1")] = geo_informations[(NBCU,5*259,"1X5-1")]
[docs]class roi_object:
"""
Container class to hold all relevant information about given ROIs.
"""
def __init__( self ):
self.roi_matrix = np.array([]) # single matrix of zeros, ones, twos, ... ,
# n's (where n is the number of ROIs defined)
self.red_rois = {} # dictionary, one entry for each ROI, each ROI
# has an origin and a rectangular box of ones
# and zeros defining the ROI
self.indices = [] # list of list of tuples (one list of tuples
# for each ROI)
self.number_of_rois = 0 # number of ROIs defined
self.kind = [] # keyword (e.g. 'zoom', 'line', 'auto', etc.),
# certain features (esp. in imaging) are only
# available for certain kinds of ROIs
self.x_indices = [] # list of numpy arrays of x-indices (for each ROI)
self.y_indices = [] # list of numpy arrays of y-indices (for each ROI)
self.masks = [] # 3D numpy array with slices of zeros and ones (same
# size as detector image) for each roi
self.input_image = [] # 2D imput image that was used to define the ROIs
def __add__( self, roi_obj ):
""" **__add__**
Allows appending two ROI objects by using the + operator.
"""
assert ( type(roi_obj) == type(self) )
# create a new instance
new_obj = roi_object()
# copy the ROIs
new_obj.red_rois = copy.deepcopy( self.red_rois )
# append the other ROIs
self_len = len( new_obj.red_rois )
for ii,key in enumerate( sorted( roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ) ):
new_key = 'ROI%02d'%( ii+self_len )
if not new_key in list( new_obj.red_rois.keys() ):
new_obj.red_rois[new_key] = roi_obj.red_rois[key]
new_obj.red_rois[new_key][1][ new_obj.red_rois[new_key][1]>0 ] += self_len
else:
'something fishy happened, skipping %s.'%(key)
return self
# add the input images
new_obj.input_image = self.input_image + roi_obj.input_image
# convert summed ROIs to other ROI formats
new_obj.roi_matrix = convert_redmatrix_to_matrix( new_obj.red_rois,
np.zeros_like( new_obj.input_image ), offsetX=0,
offsetY=0 )
new_obj.masks = convert_roi_matrix_to_masks( new_obj.roi_matrix)
new_obj.indices = convert_matrix_rois_to_inds( new_obj.roi_matrix)
new_obj.number_of_rois = int( np.amax( new_obj.roi_matrix ) )
new_obj.x_indices = convert_inds_to_xinds( new_obj.indices )
new_obj.y_indices = convert_inds_to_yinds( new_obj.indices )
return new_obj
[docs] def load_rois_fromMasksDict( self, masksDict, newshape=None, kind="zoom" ):
""" **load_rois_fromMasksDict**
"""
self.kind=kind
self.red_rois = masksDict
if newshape is not None:
self.roi_matrix = np.zeros(newshape)
self.roi_matrix = convert_redmatrix_to_matrix( masksDict, self.roi_matrix,
offsetX=0, offsetY=0)
self.masks = convert_roi_matrix_to_masks(self.roi_matrix)
self.indices = convert_matrix_rois_to_inds(self.roi_matrix)
self.number_of_rois = int(np.amax(self.roi_matrix))
self.x_indices = convert_inds_to_xinds(self.indices)
self.y_indices = convert_inds_to_yinds(self.indices)
[docs] def writeH5( self, fname ):
""" **writeH5**
Creates an HDF5 file and writes the ROIs into it.
Args:
* fname (str) : Full path and filename for the HDF5 file to be created.
"""
if self.indices:
# check if file already exists
if os.path.isfile(fname):
os.remove(fname)
f = h5py.File(fname, "w")
f.require_group("rois_definition")
f["rois_definition"]["image"] = self.input_image
f["rois_definition"].require_group("rois_dict")
write_rois_toh5(f["rois_definition"]["rois_dict"],self.red_rois)
f.close()
else:
print('There are no ROIs to save.')
[docs] def loadH5(self,fname):
""" **loadH5**
Loads ROIs from an HDF5 file written by the self.writeH5() method.
Args:
* fname (str) : Full path and filename for the HDF5 file to be read.
"""
groupname=""
if ":" in fname:
fname, groupname = xrs_utilities.split_hdf5_address(fname)
groupname = groupname +"/"
f = h5py.File(fname, "r")
self.input_image = f[groupname + "rois_definition"]["image"][:]
self.red_rois = {}
if groupname == "" :
shape = load_rois_fromh5(f,self.red_rois)
else:
shape = load_rois_fromh5(f[groupname],self.red_rois)
if 1:
self.load_rois_fromMasksDict(self.red_rois , newshape = shape, kind="zoom")
else:
self.roi_matrix = convert_redmatrix_to_matrix( self.red_rois,
np.zeros_like(self.input_image), offsetX=0, offsetY=0)
self.indices = convert_matrix_rois_to_inds(self.roi_matrix)
self.number_of_rois = int(np.amax(self.roi_matrix))
self.x_indices = convert_inds_to_xinds(self.indices)
self.y_indices = convert_inds_to_yinds(self.indices)
self.masks = convert_roi_matrix_to_masks(self.roi_matrix)
[docs] def load_shadok_h5( self, fname, group_name1, group_name2='ROI_AS_SELECTED' ):
""" **load_shadok_h5**
Load ROIs from a HDF5-file created by the Shadok/XRS_Swissknife.
"""
f = h5py.File(fname, "r")
self.input_image = f[group_name1][group_name2]["rois_definition"]["image"][:]
self.red_rois = {}
load_rois_fromh5(f[group_name1][group_name2],self.red_rois)
self.roi_matrix = convert_redmatrix_to_matrix( self.red_rois,
np.zeros_like(self.input_image), offsetX=0, offsetY=0)
self.indices = convert_matrix_rois_to_inds(self.roi_matrix)
self.number_of_rois = int(np.amax(self.roi_matrix))
self.x_indices = convert_inds_to_xinds(self.indices)
self.y_indices = convert_inds_to_yinds(self.indices)
self.masks = convert_roi_matrix_to_masks(self.roi_matrix)
[docs] def append( self, roi_object ):
""" **append**
Append other ROI definitions.
Args:
* roi_object (roi_obj) : Instance of the roi_object class.
"""
assert ( type(roi_object) == type(self) )
orig_length = len( self.red_rois )
for ii,key in enumerate(sorted(roi_object.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )):
new_key = 'ROI%02d'%(ii+orig_length)
self.red_rois[new_key] = roi_object.red_rois[key]
self.red_rois[new_key][1][ self.red_rois[new_key][1]>0 ] += orig_length
# convert summed ROIs to other ROI formats
self.roi_matrix = convert_redmatrix_to_matrix( self.red_rois,
np.zeros_like( self.input_image ), offsetX=0,
offsetY=0 )
self.masks = convert_roi_matrix_to_masks( self.roi_matrix)
self.indices = convert_matrix_rois_to_inds( self.roi_matrix)
self.number_of_rois = int( np.amax( self.roi_matrix ) )
self.x_indices = convert_inds_to_xinds( self.indices )
self.y_indices = convert_inds_to_yinds( self.indices )
[docs] def get_number_of_rois( self ):
""" **get_number_of_rois**
Returns the number of currently defined ROIs.
"""
return self.number_of_rois
[docs] def get_indices(self):
return self.indices
[docs] def get_x_indices(self):
return self.x_indices
[docs] def get_y_indices(self):
return self.y_indices
[docs] def get_bounding_boxes(self):
return self.bounding_boxes
[docs] def get_masks(self):
return self.masks
[docs] def get_copy(self):
"""
**get_copy**
Returns a deep copy of self.
"""
return copy.deepcopy(self)
[docs] def strip( self ):
""" **strip**
Strips extra zeros from border of the ROIs.
"""
for key in self.red_rois:
num = int("".join([c for c in key if c.isdigit()]))
origin = self.red_rois[key][0]
data = self.red_rois[key][1]
inds1, inds2 = np.where(data>0)
new_data = np.zeros((inds1.max()-inds1.min()+1, inds2.max()-inds2.min()+1))
new_data = data[inds1, inds2].reshape(new_data)
new_origin = (origin[0]+inds1.min(), origin[1]+inds2.min())
self.red_rois[key][0] = new_origin
self.red_rois[key][1] = new_data
[docs] def delete_empty_rois( self ):
""" **delete_empty_rois**
Deletes ROI entries that are completely empty.
"""
for key in self.red_rois:
if not np.any(self.red_rois[key][1]) > 0:
self.pop(key)
[docs] def shift( self, shiftVal, direction='horiz', roi_inds=None ):
""" **shift**
Displaces the defined ROIs by the provided value.
Args
* shiftVal (int) : Value by which the ROIs should be shifted.
* direction (str) : Description of which direction to shift
by (can be 'horiz' or 'vert'), default
is 'horiz'.
* roi_inds (int) or (sequence) : Index or Sequence (iterable)
for which ROIs should be shifted.
If None, all ROIs defined are
shifted (default.)
"""
if not roi_inds:
inds = list(range(len(self.red_rois)))
else:
inds = roi_inds
if not isinstance( inds, Iterable ):
inds = list([inds])
for ind in inds:
key = 'ROI%02d'%ind
if direction == 'horiz':
self.red_rois[key][0][1] += shiftVal
elif direction == 'vert':
self.red_rois[key][0][0] += shiftVal
# convert summed ROIs to other ROI formats
self.roi_matrix = convert_redmatrix_to_matrix( self.red_rois,
np.zeros_like( self.input_image ), offsetX=0,
offsetY=0 )
self.masks = convert_roi_matrix_to_masks( self.roi_matrix)
self.indices = convert_matrix_rois_to_inds( self.roi_matrix)
self.number_of_rois = int( np.amax( self.roi_matrix ) )
self.x_indices = convert_inds_to_xinds( self.indices )
self.y_indices = convert_inds_to_yinds( self.indices )
[docs] def pop( self, roi_key=None ):
""" **pop**
Discards a ROI.
Args
* roi_key (str) : Dict key for ROI to delete. If None, the ROI with
highest index (defined last) will be discarded (defalt).
"""
# delete last ROI if no key is specified
if not roi_key:
roi_key = sorted(list( self.red_rois.keys()) , key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )[-1]
# make sure the ROI exists
assert(roi_key in list(self.red_rois.keys()) )
# delete the ROI from the maskDict
self.red_rois.pop( roi_key )
# convert summed ROIs to other ROI formats
self.roi_matrix = convert_redmatrix_to_matrix( self.red_rois,
np.zeros_like( self.input_image ), offsetX=0,
offsetY=0 )
self.masks = convert_roi_matrix_to_masks( self.roi_matrix)
self.indices = convert_matrix_rois_to_inds( self.roi_matrix)
self.number_of_rois = int( np.amax( self.roi_matrix ) )
self.x_indices = convert_inds_to_xinds( self.indices )
self.y_indices = convert_inds_to_yinds( self.indices )
[docs] def show(self, cmap='Blues', interpolation='nearest', logscaling=True):
""" **show**
Creates a figure showing the existing ROIs.
Args:
* colormap (str): Image colormape (matplotlib.colors.Colormap).
* interpolation (str): see matplotlib.pyplot.imshow()
* logscaling (bool): Use logarithmic scaling for image, default is True.
"""
# make sure ROIs are defined, image exists
assert len(self.red_rois)>0, "Please select some rois first."
assert np.any(self.input_image), "No 2D image found."
if logscaling:
inds = self.input_image == 0.0
image = copy.deepcopy(self.input_image)
image[inds] = 1.0
image = np.log( image )
else:
image = self.input_image
# prepare figure
plt.ioff() # unset interactive mode
fig, ax = plt.subplots()
ax.imshow( image, interpolation=interpolation, cmap=cmap )
#plt.subplots_adjust(bottom=0.2)
# ticks and labels
ax.set_xlabel( 'x [pixels]' )
ax.set_ylabel( 'y [pixels]' )
ax.set_xlim( [0, image.shape[1]] )
ax.set_ylim( [image.shape[0], 0] )
ax.tick_params( left=False,
labelleft=True,
right=False,
labelright=False,
bottom=False,
top=False,
labelbottom=True )
# draw ROIs and labels
for ii, key in enumerate( sorted(self.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ) ):
# plot the ROI as frame
corner = self.red_rois[key][0]
inset = self.red_rois[key][1]
shape = self.red_rois[key][1].shape
contour_line_x = [corner[1], corner[1]+shape[1], corner[1]+shape[1], corner[1], corner[1] ]
contour_line_y = [corner[0], corner[0], corner[0]+shape[0], corner[0]+shape[0], corner[0] ]
ax.plot( contour_line_x, contour_line_y, '-k', lw=0.8 )
# find center of the ROI and write the label
xcenter = corner[1] + int( inset.shape[1]/2)
ycenter = corner[0] + int( inset.shape[0]/2)
string = '%02d' % (ii+1)
plt.text( xcenter, ycenter, string )
plt.show()
[docs]def convert_redmatrix_to_matrix( masksDict, mask, offsetX=0, offsetY=0 ):
for key, (pos,M) in six.iteritems(masksDict):
num=int("".join([c for c in key if c.isdigit()]))
S = M.shape
inset = (slice(offsetY+pos[0] , offsetY+pos[0]+S[0] ), slice( offsetX+pos[1] , offsetX+pos[1]+S[1] ) )
mask[ inset ][M>0] = num+1
return mask
[docs]def convert_redmatrix_to_matrix_my( masksDict, mask, offsetX=0, offsetY=0):
for key in masksDict:
num = int("".join([c for c in key if c.isdigit()]))
origin = masksDict[key][0]
data = masksDict[key][1]
for xx in range(len(data[:,0])):
for yy in range(len(data[0,:])):
if data[xx,yy] >= 1.0:
mask[origin[0]+xx,origin[1]+yy] = num+1
return mask
[docs]def convert_inds_to_matrix(ind_rois,image_shape):
"""
Converts a ROI defined by a list of lists of tuples into a ROI
that is defined by an array containing zeros, ones, twos, ..., n's,
where n is the number of ROIs.
ind_rois = list of lists with pairs of pixel indices
image_shape = touple defining the shape of the matrix for which the ROIs are valid
"""
roi_matrix = np.zeros(image_shape)
counter = 1
for pixel in ind_rois:
for xyind in pixel:
roi_matrix[int(xyind[0]),int(xyind[1])] = counter
counter += 1
return roi_matrix
[docs]def convert_matrix_to_redmatrix(matrix_rois, labelformat= 'ROI%02d'):
"""
Converts a ROI defined by an array containing zeros, ones, twos, ..., n's,
where n is the number of ROIs, into a dictionary with keys 'ROI00',
'ROI01', ..., 'ROInn'. Each entry of the dictionary is a list containing a
tuple with the origin and the reduced ROI.
matrix_roi = numpy array
"""
redmatrix = {}
for ind in range(int(np.amax(matrix_rois))):
try:
indices = np.where(matrix_rois == ind+1)
origin = (np.amin(indices[0]), np.amin(indices[1]))
bound_box = matrix_rois[np.amin(indices[0]):np.amax(indices[0])+1,np.amin(indices[1]):np.amax(indices[1])+1]
thekey =labelformat % ind
redmatrix[thekey] = [origin,bound_box]
except: # handle empty ROIs
indices = np.where(matrix_rois == ind+1)
origin = (0, 0)
bound_box = matrix_rois[0:0,0:0]
thekey =labelformat % ind
redmatrix[thekey] = [origin,bound_box]
return redmatrix
[docs]def convert_inds_to_xinds(roi_inds):
"""
Converts ROIs defined in lists of lists of x-y-coordinate tuples into
a list of x-coordinates only.
"""
xind_rois = []
for roi in roi_inds:
xinds = []
for pair in roi:
xinds.append(pair[0])
xind_rois.append(xinds)
return xind_rois
[docs]def convert_inds_to_yinds(roi_inds):
"""
Converts ROIs defined in lists of lists of x-y-coordinate tuples into
a list of y-coordinates only.
"""
yind_rois = []
for roi in roi_inds:
yinds = []
for pair in roi:
yinds.append(pair[1])
yind_rois.append(yinds)
return yind_rois
[docs]def convert_roi_matrix_to_masks(roi_matrix):
"""
Converts a 2D ROI matrix with zeros, ones, twos, ..., n's (where n is the number of ROIs) to
a 3D matrix with one slice of zeros and ones per ROI.
"""
# get the shape
roi_masks = np.zeros((int(np.amax(roi_matrix)),roi_matrix.shape[0],roi_matrix.shape[1]))
for ii in range(int(np.amax(roi_matrix))):
inds = np.where(roi_matrix[:,:] == ii+1)
for jj in range(len(inds[0])):
roi_masks[ii,inds[0][jj],inds[1][jj]] = ii+1
return roi_masks
[docs]def convert_matrix_rois_to_inds(roi_matrix):
"""
Converts a 2D ROI matrix with zeros, ones, twos, ..., n's (where n is the number of ROIs) to
a list of lists each of which has tuples with coordinates for each pixel in each roi.
"""
rois = []
number_of_rois = int(np.amax(roi_matrix))
for ii in range(int(number_of_rois)):
inds = np.where(roi_matrix[:,:] == ii+1)
oneroi = []
for i in range(len(inds[0])):
oneroi.append( (inds[0][i],inds[1][i]) )
rois.append(oneroi)
return rois
[docs]def break_down_det_image(image,pixel_num):
"""
Desomposes a Detector image into subimages. Returns a 3D matrix.
"""
# check that there are integer multiples of pixel_num in the big image
if not image.shape[0] % pixel_num == 0 or not image.shape[1] % pixel_num == 0:
print( 'There must be an integer number of \'pixel_num\' in the large image.')
return
detnum_row = image.shape[0]//pixel_num
detnum_col = image.shape[1]//pixel_num
num_of_dets = detnum_row * detnum_col
det_images = np.zeros((num_of_dets,pixel_num,pixel_num))
x_ranges = []
for ii in range(detnum_col):
x_ranges.append((ii*pixel_num, (ii+1)*pixel_num))
y_ranges = []
for ii in range(detnum_row):
y_ranges.append((ii*pixel_num, (ii+1)*pixel_num))
counter = 0
offsets = []
for i in x_ranges:
for j in y_ranges:
det_images[counter,:,:]=image[j[0]:j[1],i[0]:i[1]]
offsets.append((j[0],i[0]))
counter += 1
return det_images, offsets
[docs]def shift_roi_indices(indices,shift):
"""
Applies a given shift (xshift,yshift) to given indices. \
indices = list of (x,y)-tuples
shift = (xshift,yshift) tuple
"""
for ind in indices:
ind[0] += shift[0]
ind[1] += shift[1]
return indices
[docs]def merge_roi_objects_by_matrix(list_of_roi_objects,large_image_shape,offsets,pixel_num):
"""
Merges several roi_objects into one big one using the roi_matrices.
"""
# prepare a big roi matrix
roi_matrix = np.zeros(large_image_shape)
counter = 0
for roi_obj in list_of_roi_objects:
max_number = int(np.amax(roi_matrix))
single_matrix = roi_obj.roi_obj.roi_matrix
inds = single_matrix != 0
single_matrix[inds] += max_number
roi_matrix[offsets[counter][0]:offsets[counter][0]+pixel_num,offsets[counter][1]:offsets[counter][1]+pixel_num] = single_matrix
#roi_obj.roi_obj.roi_matrix + max_number
counter += 1
# make a new object to return
merged_obj = roi_object()
merged_obj.roi_matrix = roi_matrix
merged_obj.indices = convert_matrix_rois_to_inds(roi_matrix)
merged_obj.red_rois = convert_matrix_to_redmatrix(roi_matrix)
merged_obj.number_of_rois = int(np.amax(roi_matrix))
merged_obj.kind = list_of_roi_objects[0].roi_obj.kind
merged_obj.x_indices = convert_inds_to_xinds(merged_obj.indices)
merged_obj.y_indices = convert_inds_to_yinds(merged_obj.indices)
merged_obj.masks = convert_roi_matrix_to_masks(roi_matrix)
return merged_obj
[docs]def swap_indices_old_rois(old_indices):
"""
Swappes x- and y-indices from indices ROIs.
"""
new_indices = []
for roi in old_indices:
one_new_roi = []
for point in roi:
one_new_roi.append((point[1],point[0]))
new_indices.append(one_new_roi)
return new_indices
[docs]def load_rois_fromh5_address(address):
filename, groupname = xrs_utilities.split_hdf5_address(address)
h5file = h5py.File(filename, "r")
h5group = h5file[groupname]
masks={}
newshape, imagesum = load_rois_fromh5(h5group,masks, retrieveImage=True)
myroi = roi_object()
myroi.load_rois_fromMasksDict(masks, newshape=newshape)
return myroi
[docs]def load_rois_fromh5(h5group_tot,md, retrieveImage=False, metadata = None):
h5group = h5group_tot["rois_definition/rois_dict"]
for key in h5group.keys():
md[key]=[]
md[key].append(h5group[key]["origin"][:])
md[key].append(h5group[key]["mask"][:])
if metadata is not None:
newmeta = {}
print("metadata", h5group[key], key)
if "metadata" in h5group[key]:
for kk in h5group[key]["metadata"]:
newmeta[kk] = h5group[key]["metadata"][kk].value
metadata[key]=newmeta
h5data = h5group_tot["rois_definition/image"]
shape = h5data.shape
if retrieveImage:
return shape, np.array(h5data[:])
else:
return shape
[docs]def write_rois_toh5(h5group,md, filterMask=None, metadata=None):
for key in md.keys():
if key in h5group:
del h5group[key]
h5group.require_group(key)
README="""origin : the Y and X coordinates of the bottom left corner of the mask (putting the origin at the bottom left)
mask : the mask , 1 for considered pixel, zero for discarded ones.
"""
h5_assign_force(h5group[key], "README" , README )
h5group[key]["origin"]=md[key][0]
if filterMask is None:
h5group[key]["mask"]=md[key][1]
else:
ori = md[key][0]
sh = md[key][1].shape
Mfilter = filterMask[ori[0]:ori[0]+sh[0], ori[1]:ori[1]+sh[1] ]
h5group[key]["mask"]=md[key][1]*Mfilter
if metadata is not None:
if key in metadata:
metagroup = h5group[key].require_group("metadata")
for kk,mdata in metadata[key].items():
metagroup[kk] = mdata
[docs]def write_rois_toh5_for_resynth(h5group,md, filterMask=None, metadata=None):
for original_key in md.keys():
# key = str(int(original_key[len("ROI"):]))
key = original_key
h5group.require_group(key)
h5group[key]["origin"]=md[original_key][0]
if filterMask is None:
h5group[key]["mask"]=md[original_key][1]
else:
ori = md[original_key][0]
sh = md[original_key][1].shape
Mfilter = filterMask[ori[0]:ori[0]+sh[0], ori[1]:ori[1]+sh[1] ]
h5group[key]["mask"]=md[key][1]*Mfilter