Source code for XRStools.xrs_rois

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]def get_geo_informations(shape): return geo_informations[shape]
[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