from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
import shelve
from matplotlib.path import Path
from . import xrs_utilities, xrs_rois, xrs_scans, roiSelectionWidget, math_functions
from matplotlib.widgets import Cursor, Button
from scipy.ndimage import measurements
from scipy import signal, stats
import copy
import matplotlib
# def findroisColumns(scans,scannumbers,roi_obj, whichroi,logscaling=False):
# """
# Constructs a waterfall plot from the columns in a scan, i.e. energy vs. pixel number along the ROI
# scannumbers = scannumber or list of scannumbers from which to construct the plot
# whichroi = integer (starting from 0) from which ROI to use for constructing the plot
# """
# if not isinstance(scannumbers,list):
# scannums = []
# scannums.append(scannumbers)
# else:
# scannums = scannumbers
# if not roi_obj.indices:
# 'Please define some zoom ROIs first.'
# return
# if not roi_obj.kind == 'zoom':
# 'Currently this feature only works for ROIs of type \'zoom\'.'
# return
# xinds = np.unique(roi_obj.x_indices[whichroi])
# yinds = np.unique(roi_obj.y_indices[whichroi])
# scanname = 'Scan%03d' % scannums[0]
# edfmats = np.zeros_like(scans[scanname].edfmats)
# energy = scans[scanname].energy
# waterfall = np.zeros((len(yinds),len(energy)))
# for scannum in scannums:
# scanname = 'Scan%03d' % scannum
# scanedf = scans[scanname].edfmats
# scanmonitor = scans[scanname].monitor
# for ii in range(len(energy)):
# edfmats[ii,:,:] += scanedf[ii,:,:]/scanmonitor[ii]
# for ii in range(len(energy)):
# for jj in range(len(yinds)):
# waterfall[jj,ii] = np.sum(edfmats[ii,xinds,yinds[jj]])
# plt.figure()
# for ii in range(len(yinds)):
# plt.plot(waterfall[ii,:])
# fig = plt.figure()
# ax = fig.add_subplot(111)
# if logscaling:
# ax.imshow(np.log(np.transpose(waterfall)), interpolation='nearest')
# else:
# ax.imshow(np.transpose(waterfall), interpolation='nearest')
# ax.set_aspect('auto')
# plt.xlabel('ROI pixel')
# plt.ylabel('energy point')
# plt.show()
# def get_auto_rois_eachdet(scans,DET_PIXEL_NUM ,scannumbers,kernel_size=5,threshold=100.0,logscaling=True,colormap='jet',interpolation='bilinear'):
# """
# Define ROIs automatically using median filtering and a variable threshold for each detector
# separately.
# scannumbers = either single scannumber or list of scannumbers
# kernel_size = used kernel size for the median filter (must be an odd integer)
# logscaling = set to 'True' if images is to be shown on log-scale (default is True)
# colormap = string to define the colormap which is to be used for display (anything
# supported by matplotlib, 'Blues' by default)
# interpolation = interpolation scheme to be used for displaying the image (anything
# supported by matplotlib, 'nearest' by default)
# """
# # check that kernel_size is odd
# if not kernel_size % 2 == 1:
# print( 'The \'kernal_size\' must be an odd number.' )
# return
# # create a big image
# image = xrs_scans.create_sum_image(scans,scannumbers)
# # break down the image into 256x256 pixel images
# det_images, offsets = xrs_rois.break_down_det_image(image,DET_PIXEL_NUM)
# # create one roi_object per sub-image
# temp_objs = []
# for ii in range(det_images.shape[0]):
# temp = roi_finder()
# temp.get_auto_rois(det_images[ii,:,:],kernel_size=kernel_size,threshold=threshold,logscaling=logscaling,colormap=colormap,interpolation=interpolation)
# temp_objs.append(temp)
# # merge all roi_objects into one
# merged_obj = xrs_rois.merge_roi_objects_by_matrix(temp_objs,image.shape,offsets,DET_PIXEL_NUM)
# roi_obj = merged_obj
# return roi_obj
# def get_polygon_rois_eachdet(scans,DET_PIXEL_NUM, scannumbers,logscaling=True,colormap='Blues',interpolation='nearest'):
# """
# Define a polygon shaped ROI from an image constructed from
# the sum of all edf-files in 'scannumbers'
# image_shape = tuple with shape of the current image (i.e. (256,256))
# scannumbers = either single scannumber or list of scannumbers
# logscaling = set to 'True' if images is to be shown on log-scale (default is True)
# colormap = string to define the colormap which is to be used for display (anything
# supported by matplotlib, 'Blues' by default)
# interpolation = interpolation scheme to be used for displaying the image (anything
# supported by matplotlib, 'nearest' by default)
# """
# # create a big image
# image = xrs_scans.create_sum_image(scans,scannumbers)
# # break down the image into 256x256 pixel images
# det_images, offsets = xrs_rois.break_down_det_image(image,DET_PIXEL_NUM)
# # create one roi_object per sub-image
# temp_objs = []
# for modind in range(det_images.shape[0]):
# temp = roi_finder()
# temp.get_polygon_rois( det_images[modind,:,:],modind,logscaling=logscaling,colormap=colormap,interpolation=interpolation)
# temp_objs.append(temp)
# # merge all roi_objects into one
# merged_obj = xrs_rois.merge_roi_objects_by_matrix(temp_objs,image.shape,offsets,DET_PIXEL_NUM)
# roi_obj = merged_obj
# return roi_obj
# def get_zoom_rois(scans,scannumbers,logscaling=True,colormap='Blues',interpolation='nearest'):
# # create a big image
# image = xrs_scans.create_sum_image(scans,scannumbers)
# # create one roi_object per sub-image
# roi_obj = roi_finder()
# roi_obj.get_zoom_rois(image,logscaling=logscaling,colormap=colormap,interpolation=interpolation)
# return roi_obj.roi_obj
[docs]class roi_finder:
def __init__(self):
self.roi_obj = xrs_rois.roi_object() # empty roi object
[docs] def appendROIobject(self,roi_object):
self.roi_obj.append(roi_object)
[docs] def deleterois(self):
"""
Clear the existing ROIs by creating a fresh roi_object.
"""
self.roi_obj = xrs_rois.roi_object()
[docs] def get_linear_rois( self, input_image, logscaling=True, height=5, colormap='Blues', interpolation='nearest' ):
"""
Define ROIs by clicking two points on a 2D image.
number_of_rois = integer defining how many ROIs should be determined
input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
height = integer defining the height (in pixels) of the ROIs
"""
# make sure the matplotlib interactive mode is off
plt.ioff()
# clear all existing rois
self.deleterois()
# check that the input is a 2d matrix
if not len(input_image.shape) == 2:
print( 'Please provide a 2D numpy array as input!' )
return
# save input image for later use
self.roi_obj.input_image = copy.deepcopy(input_image)
# calculate the logarithm if 'logscaling' == True
if logscaling:
# set all zeros to ones:
input_image[input_image[:,:] == 0.0] = 1.0
input_image = np.log(np.abs(input_image))
# prepare a figure
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# Initialize suptitle, which will be updated
titlestring = 'Start by clicking the \'Next\'-button.'
titleInst=plt.suptitle(titlestring)
# generate an image to be displayed
figure_obj = plt.imshow(input_image,interpolation=interpolation)
# set the colormap for the image
figure_obj.set_cmap(colormap)
rois = []
class Index:
ind = 0
def next(self, event):
titlestring = 'Click two points for ROI Nr. %02d, \'Finish\' to end.' %(self.ind+1)
titleInst.set_text(titlestring) # Update title
# Try needed, as FINISH button closes the figure and ginput() generates _tkinter.TclError
try:
one_roi = define_lin_roi(height,input_image.shape)
for index in one_roi:
input_image[index[0],index[1]] += 1.0e6
figure_obj.set_data(input_image)
plt.hold(True)
plt.draw()
rois.append(one_roi)
self.ind += 1
# Begin defining the next ROI right after current
self.next(self)
except KeyboardInterrupt: # to prevent "dead" figures
plt.close()
pass
except:
pass
def prev(self, event):
self.ind -= 1
try:
titlestring = 'Click the \'Next\' button again to continue.'
titleInst.set_text(titlestring) # Update title
# print titlestring
for index in rois[-1]:
input_image[index[0],index[1]] -= 1.0e6
figure_obj.set_data(input_image)
plt.hold(True)
rois.pop()
except:
pass
def close(self, event):
plt.hold(False)
plt.ion()
plt.close('all')
def dmy(self, event):
pass # adding a dummy function for the dummy button
callback = Index()
axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
bdmy = Button(axdmy,'') # which is why I am including a dummy button here
bdmy.on_clicked(callback.dmy) # this way, the real buttons work
bnext = Button(axnext, 'Next')
bnext.on_clicked(callback.next)
bprev = Button(axprev, 'Back')
bprev.on_clicked(callback.prev)
bclose = Button(axclose, 'Finish')
bclose.on_clicked(callback.close)
plt.show()
# assign the defined rois to the roi_object class
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(rois,input_image.shape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = rois
self.roi_obj.kind = 'linear'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
#plt.draw()
[docs] def get_zoom_rois( self, input_image, logscaling=True, colormap='Blues', interpolation='nearest'):
"""
Define ROIs by clicking two points on a 2D image.
number_of_rois = integer defining how many ROIs should be determined
input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
height = integer defining the height (in pixels) of the ROIs
"""
# make sure the matplotlib interactive mode is off
plt.ioff()
# clear all existing rois
self.deleterois()
# check that the input is a 2d matrix
if not len(input_image.shape) == 2:
print( 'please provide a 2D numpy array as input!' )
return
# save input image for later use
self.roi_obj.input_image = copy.deepcopy(input_image)
# calculate the logarithm if 'logscaling' == True
if logscaling:
# set all zeros to ones:
input_image[input_image[:,:] == 0.0] = 1.0
input_image = np.log(np.abs(input_image))
# prepare a figure
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# Initialize suptitle, which will be updated
titlestring = 'Start by clicking the \'Next\' button.'
titleInst=plt.suptitle(titlestring)
# generate an image to be displayed
figure_obj = plt.imshow(input_image,interpolation=interpolation)
# activate the zoom function already
thismanager = plt.get_current_fig_manager()
thismanager.toolbar.zoom()
# set the colormap for the image
figure_obj.set_cmap(colormap)
#plt.colorbar()
# initialize a matrix for the rois (will be filled with areas of ones, twos, etc
rois = []
# print info to start:
print( 'Start by clicking the \'Next\' button.' )
class Index:
ind = 0
initstage = True
next_clicked = False
def next( self, event ):
# for some reason, the first time this is used, it doesn't work, so here is one dummy round
if self.initstage:
#self.ind += 1
self.initstage = False
plt.sca(ax)
one_roi = define_zoom_roi(input_image,verbose=True)
#for index in one_roi:
# input_image[index[0],index[1]] *= 1.0
# reset the matrix to be displayed
figure_obj.set_data(input_image)
# reset the zoom
plt.xlim(0.0,input_image.shape[1])
plt.ylim(input_image.shape[0],0.0)
plt.draw()
titlestring = 'Zoom in to define ROI Nr. %02d, hit \'Next\' to continue.' % (self.ind + 1)
titleInst.set_text(titlestring) # Update title
else:
self.ind += 1
plt.sca(ax)
one_roi = define_zoom_roi(input_image)
for index in one_roi:
input_image[index[0],index[1]] += 1.0e10
# reset the matrix to be displayed
figure_obj.set_data(input_image)
# reset the zoom
plt.xlim(0.0,input_image.shape[1])
plt.ylim(input_image.shape[0],0.0)
plt.draw()
rois.append(one_roi)
titlestring = 'Zoom in to define ROI Nr. %02d, hit \'Next\' to continue, \'Finish\' to end.' % (self.ind + 1)
titleInst.set_text(titlestring) # Update title
def prev(self, event):
self.ind -= 1
titlestring = 'Undoing ROI Nr. %02d. Zoom again, click the \'Next\' button to continue.' % (self.ind + 1)
titleInst.set_text(titlestring) # Update title
#thedata[roimatrix == self.ind+1] -= 1.0e6
#roi_matrix[roimatrix == self.ind+1] = 0.0
for index in rois[-1]:
input_image[index[0],index[1]] -= 1.0e10
figure_obj.set_data(input_image)
plt.hold(True)
rois.pop()
def close(self, event):
plt.sca(ax)
one_roi = define_zoom_roi(input_image)
for index in one_roi:
input_image[index[0],index[1]] += 1.0e10
# reset the matrix to be displayed
figure_obj.set_data(input_image)
# reset the zoom
plt.xlim(0.0,input_image.shape[1])
plt.ylim(input_image.shape[0],0.0)
plt.draw()
rois.append(one_roi)
titlestring = 'Last ROI is Nr. %02d.' % (self.ind + 1)
titleInst.set_text(titlestring) # Update title
plt.close()
def dmy(self, event):
pass # adding a dummy function for the dummy button
callback = Index()
axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
bdmy = Button(axdmy,'') # which is why I am including a dummy button here
bdmy.on_clicked(callback.dmy) # this way, the real buttons work
bnext = Button(axnext, 'Next')
bnext.on_clicked(callback.next)
bprev = Button(axprev, 'Back')
bprev.on_clicked(callback.prev)
bclose = Button(axclose, 'Finish')
bclose.on_clicked(callback.close)
plt.show()
# assign the defined rois to the roi_object class
self.roi_obj.roi_matrix = (xrs_rois.convert_inds_to_matrix(rois,input_image.shape))
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = rois
self.roi_obj.kind = 'zoom'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def get_auto_rois(self,input_image,kernel_size=5,threshold=100.0,logscaling=True,colormap='Blues',interpolation='bilinear'):
"""
Define ROIs by choosing a threshold using a slider bar under the figure. In this function, the entire
detector is shown.
input_image = 2D numpy array with the image to be displayed
kernal_size = integer defining the median filter window (has to be odd)
theshold = initial number defining the upper end value for the slider bar (amax(input_image)/threshold defines this number), can be within GUI
logscaling = boolean, if True (default) the logarithm of input_image is displayed
colormap = matplotlib color scheme used in the display
interpolation = matplotlib interpolation scheme used for the display
"""
# make sure the matplotlib interactive mode is off
plt.ioff()
# clear all existing rois
self.deleterois()
# clear existing figure
# plt.clf()
# save input image for later use
self.roi_obj.input_image = copy.deepcopy(input_image)
# calculate the logarithm if 'logscaling' == True
if logscaling:
# set all zeros to ones:
input_image[input_image[:,:] == 0.0] = 1.0
input_image = np.log(np.abs(input_image))
ax = plt.subplot(111)
plt.subplots_adjust(left=0.05, bottom=0.2)
# print out some instructions
plt.suptitle('Use the slider bar to select ROIs, close the plotting window when satisfied.')
# initial threshold value
thres0 = 0.0
# create a figure object
figure_obj = plt.imshow(input_image,interpolation=interpolation)
figure_obj.set_cmap(colormap)
# prepare the slider bar
thresxcolor = 'lightgoldenrodyellow'
thresxamp = plt.axes([0.2, 0.10, 0.55, 0.03], axisbg=thresxcolor)
maxthreshold=np.floor(np.amax(input_image)) # maximum of slider
sthres = plt.Slider(thresxamp, 'Threshold', 0.0, maxthreshold, valinit=thres0)
textBox=plt.figtext(0.50, 0.065, 'Multiplier: 1.0',verticalalignment='center')
# define what happens when the slider is touched
def update(val):
# parse a threshold from the slider
thres = sthres.val*thresMultiplier.factor
# median filter the image
newmatrix = signal.medfilt2d(input_image, kernel_size=kernel_size)
# set pixels below the threshold to zero
belowthres_indices = newmatrix < thres
newmatrix[belowthres_indices] = 0
# identify connected regions (this is already the roi_matrix)
self.roi_obj.roi_matrix,numfoundrois = measurements.label(newmatrix)
print( str(numfoundrois) + ' ROIs found!' )
figure_obj.set_data(newmatrix)
plt.draw()
# Buttons for changing multiplier for the value of slider
class thresMultiplierClass:
factor = 1.0;
def __new__(cls):
return self.factor
def increase(self,event):
self.factor *=2.0
textBox.set_text('Multiplier: ' + str(self.factor))
return self.factor
def decrease(self,event):
self.factor /=2.0
textBox.set_text('Multiplier: ' + str(self.factor))
return self.factor
# call the update function when the slider is touched
sthres.on_changed(update)
thresMultiplier = thresMultiplierClass()
axincrease = plt.axes([0.8, 0.05, 0.05, 0.03])
axdecrease = plt.axes([0.7, 0.05, 0.05, 0.03])
bnincrease = Button(axincrease, 'x 2')
bndecrease = Button(axdecrease, '/ 2')
bnincrease.on_clicked(thresMultiplier.increase) # First change threshold
bnincrease.on_clicked(update) # Then update image
bndecrease.on_clicked(thresMultiplier.decrease)
bndecrease.on_clicked(update)
# ADDITION ENDS
plt.show()
# assign the defined rois to the roi_object class
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'auto'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def get_auto_rois_eachdet(self, input_image, kernel_size=5, threshold=100.0, logscaling=True, colormap='Blues', interpolation='bilinear'):
"""
Define ROIs automatically using median filtering and a variable threshold for each detector
separately.
scannumbers = either single scannumber or list of scannumbers
kernel_size = used kernel size for the median filter (must be an odd integer)
logscaling = set to 'True' if images is to be shown on log-scale (default is True)
colormap = string to define the colormap which is to be used for display (anything supported by matplotlib, 'Blues' by default)
interpolation = interpolation scheme to be used for displaying the image (anything supported by matplotlib, 'nearest' by default)
"""
# check that kernel_size is odd
if not kernel_size % 2 == 1:
print( 'The \'kernal_size\' must be an odd number.' )
return
self.roi_obj.input_image = copy.deepcopy(input_image)
# big many pixels in one detector image
DET_PIXEL_NUM = input_image.shape[0]/2
# break down the image into 256x256 pixel images
det_images, offsets = xrs_rois.break_down_det_image(input_image,DET_PIXEL_NUM)
# create one roi_object per sub-image
temp_objs = []
for ii in range(det_images.shape[0]):
temp = roi_finder()
temp.get_auto_rois(det_images[ii,:,:], kernel_size=kernel_size, threshold=threshold, \
logscaling=logscaling, colormap=colormap, interpolation=interpolation)
temp_objs.append(temp)
# merge all roi_objects into one
merged_obj = xrs_rois.merge_roi_objects_by_matrix(temp_objs,input_image.shape,offsets,DET_PIXEL_NUM)
# assign the defined rois to the roi_object class
self.roi_obj.roi_matrix = merged_obj.roi_matrix
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'auto'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def get_polygon_rois(self,input_image,modind=-1,logscaling=True,colormap='Blues',interpolation='nearest'):
"""
Define ROIs by clicking arbitrary number of points on a 2D image:
LEFT CLICK to define the corner points of polygon,
MIDDLE CLICK to finish current ROI and move to the next ROI,
RIGHT CLICK to cancel the previous point of polygon
input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
modind = integer to identify module, if -1 (default), no module info will be in title (the case of one big image)
logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
"""
# make sure the matplotlib interactive mode is off
plt.ioff()
# clear all existing rois
self.deleterois()
# check that the input is a 2d matrix
if not len(input_image.shape) == 2:
print( 'Please provide a 2D numpy array as input!' )
return
# save input image for later use
self.roi_obj.input_image = copy.deepcopy(input_image)
# calculate the logarithm if 'logscaling' == True
if logscaling:
# set all zeros to ones:
input_image[input_image[:,:] == 0.0] = 1.0
input_image = np.log(np.abs(input_image))
# prepare a figure
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
moduleNames='VD:','HR:','VU:','HL:','VB:','HB:','' # for plot title
# Initialize suptitle, which will be updated
titlestring = ''
titleInst=plt.suptitle(titlestring)
cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# generate an image to be displayed
figure_obj = plt.imshow(input_image,interpolation=interpolation)
# set the colormap for the image
figure_obj.set_cmap(colormap)
rois = []
class Index:
ind = 1
def next(self, event):
titlestring = '%s next ROI is Nr. %02d:\n Left button to new points, middle to finish ROI. Hit \'Finish\' to end with this image.' % (moduleNames[modind], self.ind)
titleInst.set_text(titlestring) # Update title
# Try needed, as FINISH button closes the figure and ginput() generates _tkinter.TclError
try:
one_roi = define_polygon_roi(input_image.shape)
for index in one_roi:
input_image[int(index[0]),int(index[1])] += 1.0e6
figure_obj.set_data(input_image)
plt.hold(True)
plt.draw()
rois.append(one_roi)
self.ind += 1
# Begin defining the next ROI right after current
self.next(self)
except KeyboardInterrupt: # to prevent "dead" figures
plt.close()
pass
except:
pass
def prev(self, event):
self.ind -= 1
for index in rois[-1]:
input_image[index[0],index[1]] -= 1.0e6
figure_obj.set_data(input_image)
plt.hold(True)
plt.draw()
rois.pop()
self.next(self)
def close(self, event):
plt.close()
def dmy(self, event):
pass # adding a dummy function for the dummy button
callback = Index()
axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
bdmy = Button(axdmy,'') # which is why I am including a dummy button here
bdmy.on_clicked(callback.dmy) # this way, the real buttons work
bnext = Button(axnext, 'Next')
bnext.on_clicked(callback.next)
bprev = Button(axprev, 'Back')
bprev.on_clicked(callback.prev)
bclose = Button(axclose, 'Finish')
bclose.on_clicked(callback.close)
# START: initiate NEXT button press
callback.next(self)
# assign the defined rois to the roi_object class
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(rois,input_image.shape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = rois
self.roi_obj.kind = 'polygon'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def show_rois( self, interpolation='nearest', cmap='Blues' ):
""" **show_rois**
Creates a figure with the defined ROIs as numbered boxes on it.
Args:
* interpolation (str) : Interpolation scheme used in the plot.
* colormap (str) : Colormap used in the plot.
"""
self.roi_obj.show( cmap=cmap,interpolation=interpolation )
[docs] def import_simo_style_rois( self, roiList, detImageShape=(512,768) ):
""" **import_simo_style_rois**
Converts Simo-style ROIs to the conventions used here.
Arguments:
* roiList (list): List of tuples that have [(xmin, xmax, ymin, ymax), (xmin, xmax, ymin, ymax), ...].
* detImageShape (tuple): Shape of the detector image (for convertion to roiMatrix)
"""
indices = []
for roi in roiList:
inds = []
for ii in range(roi[0],roi[1]):
for jj in range(roi[2],roi[3]):
inds.append((ii,jj))
indices.append(inds)
# assign the defined rois to the roi_object class
if detImageShape:
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(indices,detImageShape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = indices
self.roi_obj.kind = 'simoStyle'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def refine_pw_rois(self, roi_obj, pw_data, n_components=2, method='nnma', cov_thresh=-1):
"""**refine_pw_rois**
Use decomposition of pixelwise data for each ROI to find which of the pixels holds
data from the sample and which one only has background.
Args:
* roi_obj (roi_object): ROI object to be refined.
* pw_data (list): List containing one 2D numpy array per ROI holding pixel-wise signals.
* n_components (int): Number of components in the decomposition.
* method (string): Keyword describing which decomposition to be used ('pca', 'ica', 'nnma').
"""
# check if available method is used
avail_methods = ['pca','ica','nnma']
if not method in avail_methods:
print('Please use one of the following methods: ' + str(avail_methods) + '!')
return
# check if scikit learn is available
try:
from sklearn.decomposition import FastICA, PCA, ProjectedGradientNMF
except ImportError:
raise ImportError('Please install the scikit-learn package to use this feature.')
return
counter = 0
new_rois = {}
for data, key in zip(pw_data, sorted(roi_obj.red_rois , key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )): # go through each matrix (one per ROI)
# decompose data, choose method
if method == 'nnma': # non negative matrix factorisation
nnm = ProjectedGradientNMF(n_components=n_components)
N = nnm.fit_transform(data)
elif method == 'pca': # principal component analysis
pca = PCA(n_components=n_components)
N = pca.fit_transform(data)
elif method == 'ica': # independent component analysis
ica = FastICA(n_components=n_components)
N = ica.fit_transform(data)
else:
print('No method: \'' + method + '\' available. Will stop here.' )
# let user decide which component belongs to the data:
user_choise = 0
plt.cla()
title_txt = 'Click component that resembles the sample spectrum for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
legendstr = []
for ii in range(n_components):
plt.plot(N[:,ii])
legendstr.append('Component No. %01d' %ii)
plt.legend(legendstr)
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
user_input = np.array(plt.ginput(1,timeout=-1)[0])
# which curve was chosen
nearest_points = [(np.abs(N[:,ii]-user_input[1])).argmin() for ii in range(n_components)]
user_choice = (np.abs(nearest_points-user_input[0])).argmin()
# find covariance for all pixels with user choice
covariance = np.array([])
for ii in range(len(data[0,:])):
covariance = np.append(covariance, np.cov(data[:,ii],N[:,user_choice])[0,0])
# plot covariance, let user choose the the cutoff in y direction
plt.cla()
title_txt = 'Click to define a y-threshold for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(covariance,'-o')
plt.xlabel('pixels in ROI')
plt.ylabel('covariance [arb. units]')
if cov_thresh < 0:
user_cutoff = np.array(plt.ginput(1,timeout=-1)[0])
elif cov_thresh>0 and isinstance(cov_thresh,int):
if len(covariance) < cov_thresh:
print('ROI has fewer pixels than cov_thresh, will break here.')
return
else:
user_cutoff = np.array([0.0, np.sort(covariance)[-cov_thresh]])
else:
print('Please provide cov_thresh as positive integer!')
# find the ROI indices above the cutoff, reassign ROI indices
inds = covariance >= user_cutoff[1]
#print('inds is ', inds)
ravel_roi = roi_obj.red_rois[key][1].ravel()
ravel_roi[~inds] = 0.0
roi_obj.red_rois[key][1] = np.reshape(ravel_roi, (roi_obj.red_rois[key][1].shape))
# end loop
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def refine_rois_MF(self, hydra_obj, scan_numbers, n_components=2, method='nnma', cov_thresh=-1):
"""**refine_rois_MF**
Use decomposition of pixelwise data for each ROI to find which of the pixels holds
data from the sample and which one only has background.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
* n_components (int): Number of components in the decomposition.
* method (string): Keyword describing which decomposition to be used ('pca', 'ica', 'nnma').
"""
# check if available method is used
if not method in ['pca','ica','nnma']:
print('Please use one of the following methods: ' + str(avail_methods) + '!')
return
# check if scikit learn is available
try:
from sklearn.decomposition import FastICA, PCA, ProjectedGradientNMF
except ImportError:
from sklearn.decomposition import FastICA, PCA
from sklearn.decomposition import NMF as ProjectedGradientNMF
except:
raise ImportError('Please install the scikit-learn package to use this feature.')
return
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# get EDF-files and pw_data
hydra_obj.load_scan(scannums, direct=False)
pw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
counter = 0
new_rois = {}
for data, key in zip(pw_data, sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )): # go through each matrix (one per ROI)
# decompose data, choose method
if method == 'nnma': # non negative matrix factorisation
nnm = ProjectedGradientNMF(n_components=n_components)
N = nnm.fit_transform(data)
elif method == 'pca': # principal component analysis
pca = PCA(n_components=n_components)
N = pca.fit_transform(data)
elif method == 'ica': # independent component analysis
ica = FastICA(n_components=n_components)
N = ica.fit_transform(data)
else:
print('No method: \'' + method + '\' available. Will stop here.' )
# let user decide which component belongs to the data:
user_choise = 0
plt.cla()
title_txt = 'Click component that resembles the sample spectrum for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
legendstr = []
for ii in range(n_components):
plt.plot(N[:,ii])
legendstr.append('Component No. %01d' %ii)
plt.legend(legendstr)
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
user_input = np.array(plt.ginput(1,timeout=-1)[0])
# which curve was chosen
nearest_points = [(np.abs(N[:,ii]-user_input[1])).argmin() for ii in range(n_components)]
user_choice = (np.abs(nearest_points-user_input[0])).argmin()
# find covariance for all pixels with user choice
covariance = np.array([])
for ii in range(len(data[0,:])):
covariance = np.append(covariance, np.cov(data[:,ii],N[:,user_choice])[0,0])
# plot covariance, let user choose the the cutoff in y direction
plt.cla()
title_txt = 'Click to define a y-threshold for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(covariance,'-o')
plt.xlabel('pixels in ROI')
plt.ylabel('covariance [arb. units]')
if cov_thresh < 0:
user_cutoff = np.array(plt.ginput(1,timeout=-1)[0])
elif cov_thresh>0 and isinstance(cov_thresh,int):
if len(covariance) < cov_thresh:
print('ROI has fewer pixels than cov_thresh, will break here.')
return
else:
user_cutoff = np.array([0.0, np.sort(covariance)[-cov_thresh]])
else:
print('Please provide cov_thresh as positive integer!')
# find the ROI indices above the cutoff, reassign ROI indices
inds = covariance >= user_cutoff[1]
#print('inds is ', inds)
ravel_roi = self.roi_obj.red_rois[key][1].ravel()
ravel_roi[~inds] = 0.0
self.roi_obj.red_rois[key][1] = np.reshape(ravel_roi, (self.roi_obj.red_rois[key][1].shape))
# end loop
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact the new red_rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
[docs] def find_pw_rois(self,roi_obj,pw_data,save_dataset=False):
"""
**find_pw_rois**
Allows for manual refinement of ROIs by plotting the spectra pixel-wise.
Loops through the spectra pixel-by-pixel and ROI by ROI, click above the
black line to keep the pixel plotted, click below the black line to discard
the pixel.
Args:
* roi_obj (roi_object): ROI object from the XRStools.xrs_rois module with roughly defined ROIs.
* pw_data (np.array): List containing one 2D numpy array per ROI holding pixel-wise signals.
"""
counter = 0
new_indices = []
pixelCounter = 0
for data in pw_data: # go through each ROI
refined_indices = []
for ii in range(len(data[0,:])):
user_choice = 1
plt.cla()
title_txt = 'Click above to keep/below black line to discard pixel for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(data[:,ii],'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros(len(data[:,ii])) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Pixel No. %02d'%ii])
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
refined_indices.append(roi_obj.indices[counter][ii])
elif user_input[1] < offset:
user_choice = 0
else:
print('Something fishy happened!')
# save spectra and decisions for NN learning
if save_dataset:
s = shelve.open(save_dataset)
try:
thekey = 'PixelNo' + str(pixelCounter)
s[thekey] = { 'spectrum': data[:,ii], 'decision': user_choice }
finally:
s.close()
pixelCounter += 1
# reorganize pixels inside ROI
new_indices.append(refined_indices)
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = new_indices
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def refine_rois_PW_old(self, hydra_obj, scan_numbers, save_dataset=False):
""" **refine_rois_PW**
Allows for manual refinement of ROIs by plotting the spectra pixel-wise.
Loops through the spectra pixel-by-pixel and ROI by ROI, click above the
black line to keep the pixel plotted, click below the black line to discard
the pixel.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
"""
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# get EDF-files and pw_data
hydra_obj.load_scan(scannums, direct=False)
pw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
counter = 0
new_indices = []
pixelCounter = 0
for data in pw_data: # go through each ROI
refined_indices = []
for ii in range(len(data[0,:])):
user_choice = 1
plt.cla()
title_txt = 'Click above to keep/below black line to discard pixel for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(data[:,ii],'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros(len(data[:,ii])) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Pixel No. %02d'%ii])
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
refined_indices.append(self.roi_obj.indices[counter][ii])
elif user_input[1] < offset:
user_choice = 0
else:
print('Something fishy happened!')
# save spectra and decisions for NN learning
if save_dataset:
s = shelve.open(save_dataset)
try:
thekey = 'PixelNo' + str(pixelCounter)
s[thekey] = { 'spectrum': data[:,ii], 'decision': user_choice }
finally:
s.close()
pixelCounter += 1
# reorganize pixels inside ROI
new_indices.append(refined_indices)
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = new_indices
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def refine_rois_PW(self, hydra_obj, scan_numbers,save_dataset=None):
""" **refine_rois_PW**
Allows for manual refinement of ROIs by plotting the spectra column-wise.
Loops through the spectra column-by-column and ROI by ROI, click above the
black line to keep the column plotted, click below the black line to discard
the column of pixels.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
"""
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# get EDF-files and pw_data
hydra_obj.load_scan(scannums, direct=False)
cw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
plt.ioff()
counter = 0
for data, key in zip(cw_data, sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )):
for ii in range(data.shape[1]):
if save_dataset:
the_shelve = shelve.open(save_dataset)
the_key = str('%s_PixelNo%d'%(key,ii) )
plt.cla()
title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(data[:,ii],'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros_like(data[:,ii]) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Pixel No. %02d / %02d' %(ii+1,data.shape[1])])
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
if save_dataset:
the_shelve[the_key] = { 'spectrum': data[:,ii], 'decision': 1 }
pass
elif user_input[1] < offset:
index = np.unravel_index([ii],self.roi_obj.red_rois[key][1].shape )
self.roi_obj.red_rois[key][1][index[0],index[1]] = 0
if save_dataset:
the_shelve[the_key] = { 'spectrum': data[:,ii], 'decision': 0 }
else:
print('Something fishy happened!')
if save_dataset:
the_shelve.close()
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
[docs] def find_cw_rois(self,roi_obj,pw_data):
"""
**find_cw_rois**
Allows for manual refinement of ROIs by plotting the spectra column-wise.
Loops through the spectra column-by-column and ROI by ROI, click above the
black line to keep the column plotted, click below the black line to discard
the column of pixels.
Args:
* roi_obj (roi_object): ROI object from the XRStools.xrs_rois module with roughly defined ROIs.
* pw_data (np.array): List containing one 2D numpy array per ROI holding pixel-wise signals.
"""
counter = 0
new_indices = []
for data,ind in zip(pw_data,range(len(pw_data))): # go through each ROI
refined_indices = []
# find the range/number of columns
y_indices = roi_obj.y_indices[ind]
y_min = np.amin(y_indices)
y_max = np.amax(y_indices)
for ii,col in zip(range(y_min,y_max+1),range(len(range(y_min,y_max+1)))):
theindices = []
cw_data = np.zeros_like(data[:,0])
for yind,xind in zip(roi_obj.y_indices[ind],roi_obj.x_indices[ind]):
if yind == ii:
cw_data += data[:,col]
theindices.append((xind,yind))
plt.cla()
title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(cw_data,'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros_like(cw_data) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Column No. %02d'%col])
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
for index in theindices:
refined_indices.append(index)
elif user_input[1] < offset:
pass
else:
print('Something fishy happened!')
# reorganize pixels inside ROI
new_indices.append(refined_indices)
counter += 1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
self.roi_obj.indices = new_indices
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
[docs] def refine_rois_CW_old(self, hydra_obj, scan_numbers):
""" **refine_rois_CW**
Allows for manual refinement of ROIs by plotting the spectra column-wise.
Loops through the spectra column-by-column and ROI by ROI, click above the
black line to keep the column plotted, click below the black line to discard
the column of pixels.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
"""
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# get EDF-files and pw_data
hydra_obj.load_scan(scannums, direct=False)
cw_data = hydra_obj.get_pw_matrices( scannums, method='column' )
plt.ioff()
plt.cla()
counter = 0
for data, key in zip(cw_data, sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )):
print('Processing: ', key)
for ii in range(data.shape[1]):
print('>>>>>>>>> ', ii)
plt.cla()
title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(data[:,ii],'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros_like(data[:,ii]) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Column No. %02d / %02d' %(ii+1,data.shape[1])])
plt.draw()
plt.pause(0.01)
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
print('Taking pixel ', ii)
pass
elif user_input[1] < offset:
self.roi_obj.red_rois[key][1][:,ii] = 0
else:
print('Something fishy happened!')
counter += 1
# go through all ROIs and delete empty ones
for key in self.roi_obj.red_rois.keys():
if self.roi_obj.red_rois[key][1].shape == (0,0):
del self.roi_obj.red_rois[key]
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
[docs] def refine_rois_CW(self, hydra_obj, scan_numbers, interpolation='nearest', cmap='Blues'):
""" **refine_rois_CW**
Allows for manual refinement of ROIs by plotting the spectra column-wise.
Loops through the spectra column-by-column and ROI by ROI, click above the
black line to keep the column plotted, click below the black line to discard
the column of pixels.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class
that hold scans to be usedfor the refinement
of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
* interpolation (str): Interpolation keyword for matplotlib.imshow.
* cmap (str): Color-map for plotting.
"""
plt.ioff()
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# make sure there are rois defined
if not self.roi_obj.red_rois:
print("Please define ROIs first.")
return
# get EDF-files and cw_data
scans = []
for ii in scannums:
scan = xrs_scans.Scan()
scan.load( hydra_obj.path, hydra_obj.SPECfname, hydra_obj.EDFprefix, hydra_obj.EDFname, \
hydra_obj.EDFpostfix, ii, \
direct=True, roi_obj=self.roi_obj, scaling=None, scan_type='generic', \
en_column=None, moni_column=hydra_obj.moni_column, method='pixel', comp_factor=None,\
rot_angles=None, clean_edf_stack=False, cenom_dict=None, storeInsets=False )
scans.append( scan )
data_dict_norm = {}
# sum normalized raw data, if more than one scan
if len( scans ) > 1:
# undo individual normalization
for scan in scans:
for key2 in scan.raw_signals:
scan.raw_signals[key2] *= scan.monitor[:,None,None]
# sum all monitor signals
monitor_sum = np.zeros_like( scans[0].monitor )
for scan in scans:
monitor_sum += scan.monitor
# sum all signals
for key2 in scans[0].raw_signals:
data_dict_norm[key2] = np.zeros_like( scans[0].raw_signals[key2] )
for scan in scans:
data_dict_norm[key2] += scan.raw_signals[key2]
# normalize summed signals
for key2 in data_dict_norm:
data_dict_norm[key2] /= monitor_sum[:,None,None]
elif len( scans ) == 1:
for key in scans[0].raw_signals:
data_dict_norm[key] = scans[0].raw_signals[key]
#if 1:
# return data_dict_norm
cw_data = {}
for key in data_dict_norm:
cw_data[key] = np.sum( data_dict_norm[key], axis=1 )
# fetch all red_roi keys
roi_keys = [key for key in sorted(self.roi_obj.red_rois , key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )]
# deep copy all ROIs, set all to zero
red_rois_copy = {}
for key in sorted( self.roi_obj.red_rois , key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ):
red_rois_copy[key] = copy.deepcopy( self.roi_obj.red_rois[key] )
red_rois_copy[key][1] = np.zeros_like( self.roi_obj.red_rois[key][1] )
# prepare the figure
fig, (ax1, ax2) = plt.subplots( 2, 1 )
plt.subplots_adjust(bottom=0.2)
title_txt = 'Active ROI is No. %d of %d'%(1, len(cw_data)) + '.'
plt.suptitle(title_txt)
# plot the very first column spectrum
ax1.plot(cw_data[roi_keys[0]][:,0], lw=2)
ax1.set_xlabel( 'points along scan' )
ax1.set_ylabel( 'intensity [arb. units]' )
ax1.legend(['Column No. %02d / %02d' %(1, cw_data[roi_keys[0]].shape[1])],
frameon=False, loc=1, fontsize='x-small')
# plot the very first mask image
ax2.plot([0, 0], [-0.5, data_dict_norm['ROI00'].shape[1]+0.5, ], 'k-')
ax2.imshow( np.sum(data_dict_norm['ROI00'], axis=0), interpolation=interpolation, cmap=cmap )
ax2.imshow( red_rois_copy[roi_keys[0]][1], interpolation=interpolation, cmap='Greys', alpha=0.5 )
# plotter
def plot_all( roi_ind, column_ind, red_mask, col_max ):
fig.canvas.flush_events()
the_key = roi_keys[roi_ind]
# plot the spectra
ax1.cla()
data = cw_data[roi_keys[roi_ind]]
title_txt = 'Active ROI is No. %d of %d.'%(roi_ind+1, len(cw_data))
plt.suptitle(title_txt)
ax1.plot(data[:,column_ind], lw=2)
#offset = np.mean(ax1.get_ylim())
#ax1.plot(np.zeros_like(data[:,column_ind]) + offset ,'k-')
ax1.set_xlabel( 'points along scan' )
ax1.set_ylabel( 'intensity [arb. units]' )
ax1.legend(['Column No. %02d / %02d' %(column_ind+1,data.shape[1])],
frameon=False, loc=1, fontsize='x-small')
# plot the mask
ax2.cla()
ax2.plot([column_ind-0.5, column_ind+0.5, column_ind+0.5, column_ind-0.5, column_ind-0.5],
[-0.5, -0.5, data_dict_norm[roi_keys[roi_ind]].shape[1]+0.5, data_dict_norm[roi_keys[roi_ind]].shape[1]+0.5, -0.5], 'k-')
ax2.imshow( np.sum(data_dict_norm[roi_keys[roi_ind]], axis=0), interpolation=interpolation, cmap=cmap )
ax2.imshow( red_mask, interpolation=interpolation, alpha=0.5 , cmap='Greys')
#plt.tight_layout()
plt.draw()
plt.pause(0.01)
class Index(object):
def __init__(self, red_rois):
self.red_rois = red_rois
self.roi_ind = 0
self.column_ind = 0
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = np.zeros_like(red_rois_copy[self.roi_key][1])
self.num_ROI_max = len(red_rois)
self.num_ROI_min = 0
self.num_col_max = red_rois_copy[self.roi_key][1].shape[1]
self.num_col_min = 0
def update_shape(self):
self.num_ROI_max = len(self.red_rois)
self.num_ROI_min = 0
self.num_col_max = red_rois_copy[self.roi_key][1].shape[1]
self.num_col_min = 0
def next_roi(self, event):
if self.roi_ind < self.num_ROI_max-1:
red_rois_copy[self.roi_key][1] = self.red_mask
self.roi_ind += 1
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = np.zeros_like(red_rois_copy[self.roi_key][1])
self.column_ind = 0
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind < self.num_col_max and self.column_ind >= self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
else:
pass
def prev_roi(self, event):
if self.roi_ind > self.num_ROI_min:
self.roi_ind -= 1
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = self.red_rois[self.roi_key][1]
self.column_ind = 0
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind < self.num_col_max and self.column_ind >= self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
else:
pass
def next_column( self, event ):
if self.column_ind < self.num_col_max-1:
self.column_ind += 1
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind < self.num_col_max and self.column_ind >= self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
else:
self.column_ind += 0
def prev_column( self, event ):
if self.column_ind > self.num_col_min:
self.column_ind -= 1
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind < self.num_col_max and self.column_ind >= self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
else:
self.column_ind -= 0
def finish( self, event ):
for key in sorted(red_rois_copy, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ):
red_rois_copy[key][1] = self.red_rois[key][1]
plt.close()
def take( self, event ):
if self.column_ind > self.num_col_min and self.column_ind < self.num_col_max:
self.red_mask[:,self.column_ind] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind < self.num_col_max and self.column_ind > self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
elif self.column_ind <= self.num_col_min:
self.red_mask[:,0] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
plot_all( self.roi_ind, 0, self.red_mask, self.num_col_max )
elif self.column_ind >= self.num_col_max:
self.red_mask[:,-1] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
plot_all( self.roi_ind, -1, self.red_mask, self.num_col_max )
else:
pass
def discard( self, event ):
if self.column_ind >= self.num_col_min and self.column_ind <= self.num_col_max:
self.red_mask[:,self.column_ind] = 0
self.red_rois[self.roi_key][1] = self.red_mask
if self.roi_ind <= self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.column_ind <= self.num_col_max and self.column_ind >= self.num_col_min:
plot_all( self.roi_ind, self.column_ind, self.red_mask, self.num_col_max )
else:
pass
callback = Index(self.roi_obj.red_rois)
# buttons for next/prev roi
axprev_roi = plt.axes([0.7, 0.05, 0.1, 0.075])
axnext_roi = plt.axes([0.82, 0.05, 0.1, 0.075])
bnext_roi = Button(axnext_roi, 'next ROI')
bnext_roi.on_clicked(callback.next_roi)
bprev_roi = Button(axprev_roi, 'prev ROI')
bprev_roi.on_clicked(callback.prev_roi)
# buttons for xext/prev column
axprev_column = plt.axes([0.1, 0.05, 0.1, 0.075])
axnext_column = plt.axes([0.22, 0.05, 0.1, 0.075])
bnext_column = Button(axnext_column, 'next Col.')
bnext_column.on_clicked(callback.next_column)
bprev_prev = Button(axprev_column, 'prev Col.')
bprev_prev.on_clicked(callback.prev_column)
# take column button
axtake = plt.axes([0.34, 0.05, 0.1, 0.075])
btake = Button(axtake, 'take')
btake.on_clicked(callback.take)
# discard column button
axdisc = plt.axes([0.46, 0.05, 0.1, 0.075])
bdisc = Button(axdisc, 'discard')
bdisc.on_clicked(callback.discard)
# finish button
axfin = plt.axes([0.58, 0.05, 0.1, 0.075])
bfin = Button(axfin, 'finish')
bfin.on_clicked(callback.finish)
# show figure
plt.show()
#print(len(red_rois_copy))
# reassign ROI object
self.roi_obj.red_rois = red_rois_copy
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
#return red_rois_copy
[docs] def refine_rois_RW_old(self, hydra_obj, scan_numbers):
""" **refine_rois_RW**
Allows for manual refinement of ROIs by plotting the spectra row-wise.
Loops through the spectra column-by-column and ROI by ROI, click above the
black line to keep the column plotted, click below the black line to discard
the column of pixels.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
"""
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# get EDF-files and pw_data
hydra_obj.load_scan(scannums, direct=False)
cw_data = hydra_obj.get_pw_matrices( scannums, method='row' )
print("SHAPE OF CW DATA: ",cw_data[0].shape)
plt.ioff()
counter = 0
for data, key in zip(cw_data, sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )):
print('Processing: ', key)
for ii in range(data.shape[1]):
plt.cla()
title_txt = 'Click above to keep/below black line to discard row for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
plt.plot(data[:,ii],'b-')
axes = plt.gca()
offset = np.mean(axes.get_ylim())
plt.plot(np.zeros_like(data[:,ii]) + offset,'k-')
plt.xlabel('points along scan')
plt.ylabel('intensity [arb. units]')
plt.legend(['Row No. %02d / %02d' %(ii+1,data.shape[1])])
plt.draw()
plt.pause(0.01)
# let user click a point on figure
user_input = np.array(plt.ginput(1,timeout=-1)[0])
if user_input[1] >= offset:
print('Taking pixel ', ii)
pass
elif user_input[1] < offset:
self.roi_obj.red_rois[key][1][ii,:] = 0
else:
print('Something fishy happened!')
counter += 1
# go through all ROIs and delete empty ones
for key in self.roi_obj.red_rois.keys():
if self.roi_obj.red_rois[key][1].shape == (0,0):
del self.roi_obj.red_rois[key]
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
[docs] def get_zoom_rois_new( self, input_image, logscaling=True, cmap='Blues', interpolation='nearest'):
"""
Define ROIs by matplotlib's zoom/pan functions.
Args:
* input_image (np.array): 2D numpy array with the image to be displayed.
* logscaling (boolean): Display image using logarithmic scale.
* colormap (str): matplotlib color map string.
* interpolation (str): matplotlib interpolation for the display.
"""
# unset interactive mode
plt.ioff()
# clear all existing rois
self.deleterois()
# check that the input is a 2d matrix
if not len(input_image.shape) == 2:
print( 'please provide a 2D numpy array as input!' )
return
# save input image for later use
self.roi_obj.input_image = copy.deepcopy(input_image)
# calculate the logarithm if 'logscaling' == True
if logscaling:
# set all zeros to ones:
input_image[input_image[:,:] == 0.0] = 1.0
input_image = np.log(np.abs(input_image))
# first ROI
roi_key = 'ROI00'
# prepare a figure
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
ax.imshow( input_image, interpolation=interpolation, cmap=cmap)
# no ticks, no labels
ax.tick_params( left=False,
labelleft=False,
right=False,
labelright=False,
bottom=False,
top=False,
labelbottom=False )
ax.set_xlim( 0.0, input_image.shape[1] )
ax.set_ylim( input_image.shape[0], 0.0 )
title_txt = 'Active ROI Nr. is %d. of %d'%(1, 0)
ax.set_title(title_txt)
# activate the zoom function already
thismanager = plt.get_current_fig_manager()
thismanager.toolbar.zoom()
# plotter
def plot_all( roi_key, contour_lines ):
fig.canvas.flush_events()
ax.cla()
title_txt = 'Active ROI Nr. is %d. of %d'%( int(roi_key[-2:])+1, len(contour_lines))
ax.imshow( input_image, interpolation=interpolation, cmap=cmap)
# no ticks, no labels on axes
ax.tick_params( left=False,
labelleft=False,
right=False,
labelright=False,
bottom=False,
top=False,
labelbottom=False )
ax.imshow( input_image, interpolation=interpolation, cmap=cmap)
if contour_lines:
for key in contour_lines:
ax.plot( contour_lines[key][0], contour_lines[key][1], '-k' )
ax.set_xlim( 0.0, input_image.shape[1] )
ax.set_ylim( input_image.shape[0], 0.0 )
ax.set_title(title_txt)
plt.draw()
plt.pause(0.01)
class Index(object):
def __init__(self, red_rois):
self.red_rois = red_rois
self.roi_key = 'ROI00'
self.roi_ind = 0
self.num_ROI_min = 0
self.contour_lines = {}
def take_and_next( self, event ):
# grep axis limits
cur_xlim = ax.get_xlim()
cur_ylim = ax.get_ylim()
# limits = np.array([np.ceil(cur_xlim[0]),\
# np.floor(cur_xlim[1]+0.5), \
# np.floor(cur_ylim[1]+0.5),
# np.ceil(cur_ylim[0])])
limits = np.array([np.ceil(cur_xlim[0]), np.floor(cur_xlim[1]), \
np.floor(cur_ylim[1]), np.ceil(cur_ylim[0])])
# make sure they are inside the image
inds = limits < 0
limits[inds] = 0
if limits[1] > input_image.shape[1]:
limits[1] = input_image.shape[1]
if limits[2] > input_image.shape[0]:
limits[2] = input_image.shape[0]
print('Chosen limits are (x_min, x_max, y_min, y_max): ',limits)
self.red_rois[self.roi_key] = [ np.array([int(limits[2]), int(limits[0])]), \
np.zeros((int(limits[3]-limits[2]), int(limits[1]-limits[0])))+self.roi_ind+1 ]
self.contour_lines[self.roi_key] = [[limits[0]-0.5, limits[1]+0.5, limits[1]+0.5, \
limits[0]-0.5, limits[0]-0.5], \
[limits[2]-0.5, limits[2]-0.5, limits[3]+0.5, \
limits[3]+0.5, limits[2]-0.5]]
plot_all( self.roi_key, self.contour_lines )
# go to next roi
self.roi_ind += 1
self.roi_key = 'ROI%02d'%self.roi_ind
plot_all( self.roi_key, self.contour_lines )
def middle_mouse_press( self, event ):
if event.button == 2:
self.take_and_next( event )
def take_and_exit( self, event ):
# grep axis limits
cur_xlim = ax.get_xlim()
cur_ylim = ax.get_ylim()
limits = np.array([np.ceil(cur_xlim[0]),\
np.floor(cur_xlim[1]+0.5), \
np.floor(cur_ylim[1]+0.5),
np.ceil(cur_ylim[0])])
# make sure they are inside the image
inds = limits < 0
limits[inds] = 0
if limits[1] > input_image.shape[1]:
limits[1] = input_image.shape[1]
if limits[2] > input_image.shape[0]:
limits[2] = input_image.shape[0]
print('Chosen limits are (x_min, x_max, y_min, y_max): ',limits)
self.red_rois[self.roi_key] = [ np.array([int(limits[2]), int(limits[0])]), \
np.zeros((int(limits[3]-limits[2]), int(limits[1]-limits[0])))+self.roi_ind+1 ]
self.contour_lines[self.roi_key] = [[limits[0]+0.5, limits[1]+0.5, limits[1]+0.5, \
limits[0]+0.5, limits[0]+0.5], \
[limits[2]+0.5, limits[2]+0.5, limits[3]+0.5, \
limits[3]+0.5, limits[2]+0.5]]
plot_all( self.roi_key, self.contour_lines )
plt.close()
def discard( self, event ):
del self.red_rois[self.roi_key]
del self.contour_lines[self.roi_key]
plot_all( self.roi_key, self.contour_lines )
def prev_roi(self, event):
if self.roi_ind > self.num_ROI_min:
self.roi_ind -= 1
self.roi_key = 'ROI%02d'%self.roi_ind
plot_all( self.roi_key, self.contour_lines )
else:
pass
def next_roi(self, event):
self.roi_ind += 1
self.roi_key = 'ROI%02d'%self.roi_ind
plot_all( self.roi_key, self.contour_lines )
def exit(self, event):
plt.close()
callback = Index(self.roi_obj.red_rois)
# buttons for next/prev roi
axprev_roi = plt.axes([0.58, 0.05, 0.1, 0.075])
axnext_roi = plt.axes([0.7, 0.05, 0.1, 0.075])
bnext_roi = Button(axnext_roi, 'next ROI')
bnext_roi.on_clicked(callback.next_roi)
bprev_roi = Button(axprev_roi, 'prev ROI')
bprev_roi.on_clicked(callback.prev_roi)
# take and next button
axtakeN = plt.axes([0.04, 0.05, 0.17, 0.075])
btakeN = Button(axtakeN, 'take+next\n (mouse wheel)')
btakeN.on_clicked(callback.take_and_next)
# take and exit
axtakeE = plt.axes([0.24, 0.05, 0.17, 0.075])
btakeE = Button(axtakeE, 'take+exit')
btakeE.on_clicked(callback.take_and_exit)
# discard button
axdisc = plt.axes([0.46, 0.05, 0.1, 0.075])
bdisc = Button(axdisc, 'discard')
bdisc.on_clicked(callback.discard)
# finish button
axfin = plt.axes([0.82, 0.05, 0.1, 0.075])
bfin = Button(axfin, 'exit')
bfin.on_clicked( callback.exit )
cid = fig.canvas.mpl_connect('button_press_event', callback.middle_mouse_press)
# show figure
plt.show()
# reassign ROI object
self.roi_obj.red_rois = callback.red_rois
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
#return red_rois_copy
[docs] def refine_rois_RW( self, hydra_obj, scan_numbers, interpolation='nearest', cmap='Blues' ):
""" **refine_rois_CW**
Allows for manual refinement of ROIs by plotting the spectra row-wise.
Loops through the spectra row-by-row and ROI by ROI.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class
that hold scans to be usedfor the refinement
of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
* interpolation (str): Interpolation keyword for matplotlib.imshow.
* cmap (str): Color-map for plotting.
"""
plt.ioff()
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# make sure there are rois defined
if not self.roi_obj.red_rois:
print("Please define ROIs first.")
return
# get EDF-files and cw_data
scans = []
for ii in scannums:
scan = xrs_scans.Scan()
scan.load( hydra_obj.path, hydra_obj.SPECfname, hydra_obj.EDFprefix, hydra_obj.EDFname, \
hydra_obj.EDFpostfix, ii, \
direct=True, roi_obj=self.roi_obj, scaling=None, scan_type='generic', \
en_column=None, moni_column=hydra_obj.moni_column, method='pixel', comp_factor=None,\
rot_angles=None, clean_edf_stack=False, cenom_dict=None, storeInsets=False )
scans.append( scan )
data_dict_norm = {}
# sum normalized raw data, if more than one scan
if len( scans ) > 1:
# undo individual normalization
for scan in scans:
for key2 in scan.raw_signals:
scan.raw_signals[key2] *= scan.monitor[:,None,None]
# sum all monitor signals
monitor_sum = np.zeros_like( scans[0].monitor )
for scan in scans:
monitor_sum += scan.monitor
# sum all signals
for key2 in scans[0].raw_signals:
data_dict_norm[key2] = np.zeros_like( scans[0].raw_signals[key2] )
for scan in scans:
data_dict_norm[key2] += scan.raw_signals[key2]
# normalize summed signals
for key2 in data_dict_norm:
data_dict_norm[key2] /= monitor_sum[:,None,None]
elif len( scans ) == 1:
for key in scans[0].raw_signals:
data_dict_norm[key] = scans[0].raw_signals[key]
#if 1:
# return data_dict_norm
rw_data = {}
for key in data_dict_norm:
rw_data[key] = np.sum( data_dict_norm[key], axis=2 )
# fetch all red_roi keys
roi_keys = [key for key in sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )]
# deep copy all ROIs, set all to zero
red_rois_copy = {}
for key in sorted( self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ):
red_rois_copy[key] = copy.deepcopy( self.roi_obj.red_rois[key] )
red_rois_copy[key][1] = np.zeros_like( self.roi_obj.red_rois[key][1] )
# prepare the figure
fig, (ax1, ax2) = plt.subplots( 2, 1 )
plt.subplots_adjust(bottom=0.2)
title_txt = 'Active ROI is No. %d of %d'%(1, len(rw_data)) + '.'
plt.suptitle(title_txt)
# plot the very first column spectrum
ax1.plot(rw_data[roi_keys[0]][:,0], lw=2)
ax1.set_xlabel( 'points along scan' )
ax1.set_ylabel( 'intensity [arb. units]' )
ax1.legend(['Row No. %02d / %02d' %(1, rw_data[roi_keys[0]].shape[1])],
frameon=False, loc=1, fontsize='x-small')
# plot the very first mask image
ax2.plot([-0.5, data_dict_norm['ROI00'].shape[2]+0.5, data_dict_norm['ROI00'].shape[2]+0.5, -0.5],
[-0.5, -0.5, 0.5, 0.5 ], 'k-')
ax2.imshow( np.sum(data_dict_norm['ROI00'], axis=0), interpolation=interpolation, cmap=cmap )
ax2.imshow( red_rois_copy[roi_keys[0]][1], interpolation=interpolation, cmap='Greys', alpha=0.5 )
# plotter
def plot_all( roi_ind, row_ind, red_mask, row_max ):
fig.canvas.flush_events()
the_key = roi_keys[roi_ind]
# plot the spectra
ax1.cla()
data = rw_data[roi_keys[roi_ind]]
title_txt = 'Active ROI is No. %d of %d.'%(roi_ind+1, len(rw_data))
plt.suptitle(title_txt)
ax1.plot(data[:,row_ind], lw=2)
#offset = np.mean(ax1.get_ylim())
#ax1.plot(np.zeros_like(data[:,column_ind]) + offset ,'k-')
ax1.set_xlabel( 'points along scan' )
ax1.set_ylabel( 'intensity [arb. units]' )
ax1.legend(['Row No. %02d / %02d' %(row_ind+1,data.shape[1])],
frameon=False, loc=1, fontsize='x-small')
# plot the mask
ax2.cla()
ax2.plot([-0.5, data_dict_norm[roi_keys[roi_ind]].shape[0]+0.5, data_dict_norm[roi_keys[roi_ind]].shape[0]+0.5, -0.5, -0.5 ],
[row_ind-0.5, row_ind-0.5, row_ind+0.5, row_ind+0.5, row_ind-0.5 ], 'k-')
ax2.imshow( np.sum(data_dict_norm[roi_keys[roi_ind]], axis=0), interpolation=interpolation, cmap=cmap )
ax2.imshow( red_mask, interpolation=interpolation, alpha=0.5 , cmap='Greys')
#plt.tight_layout()
plt.draw()
plt.pause(0.01)
class Index(object):
def __init__(self, red_rois):
self.red_rois = red_rois
self.roi_ind = 0
self.row_ind = 0
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = np.zeros_like(red_rois_copy[self.roi_key][1])
self.num_ROI_max = len(red_rois)
self.num_ROI_min = 0
self.num_row_max = red_rois_copy[self.roi_key][1].shape[0]
self.num_row_min = 0
def update_shape(self):
self.num_ROI_max = len(self.red_rois)
self.num_ROI_min = 0
self.num_row_max = red_rois_copy[self.roi_key][1].shape[0]
self.num_row_min = 0
def next_roi(self, event):
if self.roi_ind < self.num_ROI_max-1:
red_rois_copy[self.roi_key][1] = self.red_mask
self.roi_ind += 1
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = np.zeros_like(red_rois_copy[self.roi_key][1])
self.row_ind = 0
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind < self.num_row_max and self.row_ind >= self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
else:
pass
def prev_roi(self, event):
if self.roi_ind > self.num_ROI_min:
self.roi_ind -= 1
self.roi_key = roi_keys[self.roi_ind]
self.red_mask = self.red_rois[self.roi_key][1]
self.row_ind = 0
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind < self.num_row_max and self.row_ind >= self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
else:
pass
def next_column( self, event ):
if self.row_ind < self.num_row_max-1:
self.row_ind += 1
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind < self.num_row_max and self.row_ind >= self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
else:
self.row_ind += 0
def prev_column( self, event ):
if self.row_ind > self.num_row_min:
self.row_ind -= 1
self.update_shape()
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind < self.num_row_max and self.row_ind >= self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
else:
self.row_ind -= 0
def finish( self, event ):
for key in sorted(red_rois_copy, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ):
red_rois_copy[key][1] = self.red_rois[key][1]
plt.close()
def take( self, event ):
if self.row_ind > self.num_row_min and self.row_ind < self.num_row_max:
self.red_mask[self.row_ind,:] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
if self.roi_ind < self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind < self.num_row_max and self.row_ind > self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
elif self.row_ind <= self.num_row_min:
self.red_mask[0,:] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
plot_all( self.roi_ind, 0, self.red_mask, self.num_row_max )
elif self.row_ind >= self.num_row_max:
self.red_mask[-1,:] = self.roi_ind+1
self.red_rois[self.roi_key][1] = self.red_mask
plot_all( self.roi_ind, -1, self.red_mask, self.num_row_max )
else:
pass
def discard( self, event ):
if self.row_ind >= self.num_row_min and self.row_ind <= self.num_row_max:
self.red_mask[self.row_ind,:] = 0
self.red_rois[self.roi_key][1] = self.red_mask
if self.roi_ind <= self.num_ROI_max and self.roi_ind >= self.num_ROI_min:
if self.row_ind <= self.num_row_max and self.row_ind >= self.num_row_min:
plot_all( self.roi_ind, self.row_ind, self.red_mask, self.num_row_max )
else:
pass
callback = Index(self.roi_obj.red_rois)
# buttons for next/prev roi
axprev_roi = plt.axes([0.7, 0.05, 0.1, 0.075])
axnext_roi = plt.axes([0.82, 0.05, 0.1, 0.075])
bnext_roi = Button(axnext_roi, 'next ROI')
bnext_roi.on_clicked(callback.next_roi)
bprev_roi = Button(axprev_roi, 'prev ROI')
bprev_roi.on_clicked(callback.prev_roi)
# buttons for xext/prev column
axprev_column = plt.axes([0.1, 0.05, 0.1, 0.075])
axnext_column = plt.axes([0.22, 0.05, 0.1, 0.075])
bnext_column = Button(axnext_column, 'next Row')
bnext_column.on_clicked(callback.next_column)
bprev_prev = Button(axprev_column, 'prev Row')
bprev_prev.on_clicked(callback.prev_column)
# take column button
axtake = plt.axes([0.34, 0.05, 0.1, 0.075])
btake = Button(axtake, 'take')
btake.on_clicked(callback.take)
# discard column button
axdisc = plt.axes([0.46, 0.05, 0.1, 0.075])
bdisc = Button(axdisc, 'discard')
bdisc.on_clicked(callback.discard)
# finish button
axfin = plt.axes([0.58, 0.05, 0.1, 0.075])
bfin = Button(axfin, 'finish')
bfin.on_clicked(callback.finish)
# show figure
plt.show()
#print(len(red_rois_copy))
# reassign ROI object
self.roi_obj.red_rois = red_rois_copy
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact red rois
self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
#return red_rois_copy
[docs] def refine_rois_MF_new( self, hydra_obj, scan_numbers, n_components=2,
method='nnma', cov_thresh=-1, cmap='Blues' ):
""" **refine_rois_MF**
Use decomposition of pixelwise data for each ROI to find which of the pixels holds
data from the sample and which one only has background.
Args:
* hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
for the refinement of the ROIs.
* scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
* n_components (int): Number of components in the decomposition.
* method (string): Keyword describing which decomposition to be used ('pca', 'ica', 'nnma').
"""
# check if scikit learn is available
try:
from sklearn.decomposition import FastICA, PCA, ProjectedGradientNMF
except ImportError:
from sklearn.decomposition import FastICA, PCA
from sklearn.decomposition import NMF as ProjectedGradientNMF
except:
raise ImportError('Please install the scikit-learn package to use this feature.')
return
# try importing a cursor
try:
from matplotlib.widgets import Cursor
except:
pass
# color map for plotting
color_m = plt.cm.get_cmap( name=cmap )
# check if available method is used
if not method in [ 'pca', 'ica', 'nnma' ]:
print('Please use one of the following methods: ' + str(avail_methods) + '!')
return
# make scan_numbers itarable
if isinstance(scan_numbers,list):
scannums = scan_numbers
elif isinstance(scan_numbers,int):
scannums = [scan_numbers]
# make sure there are rois defined
if not self.roi_obj.red_rois:
print("Please define ROIs first.")
return
# get EDF-files and pw_data
scans = []
for ii in scannums:
scan = xrs_scans.Scan()
scan.load( hydra_obj.path, hydra_obj.SPECfname, hydra_obj.EDFprefix, hydra_obj.EDFname, \
hydra_obj.EDFpostfix, ii, \
direct=True, roi_obj=self.roi_obj, scaling=None, scan_type='generic', \
en_column=None, moni_column=hydra_obj.moni_column, method='pixel', comp_factor=None,\
rot_angles=None, clean_edf_stack=False, cenom_dict=None, storeInsets=False )
scans.append( scan )
data_dict_norm = {}
# sum normalized raw data, if more than one scan
if len( scans ) > 1:
# undo individual normalization
for scan in scans:
for key2 in scan.raw_signals:
scan.raw_signals[key2] *= scan.monitor[:,None,None]
# sum all monitor signals
monitor_sum = np.zeros_like( scans[0].monitor )
for scan in scans:
monitor_sum += scan.monitor
# sum all signals
for key2 in scans[0].raw_signals:
data_dict_norm[key2] = np.zeros_like( scans[0].raw_signals[key2] )
for scan in scans:
data_dict_norm[key2] += scan.raw_signals[key2]
# normalize summed signals
for key2 in data_dict_norm:
data_dict_norm[key2] /= monitor_sum[:,None,None]
elif len( scans ) == 1:
for key in scans[0].raw_signals:
data_dict_norm[key] = scans[0].raw_signals[key]
# fetch all red_roi keys
roi_keys = [key for key in sorted(self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) )]
# deep copy all ROIs, set all to zero
red_rois_copy = {}
for key in sorted( self.roi_obj.red_rois, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ):
red_rois_copy[key] = copy.deepcopy( self.roi_obj.red_rois[key] )
red_rois_copy[key][1] = np.zeros_like( self.roi_obj.red_rois[key][1] )
# get pixel-wise data in matrix form (n_samples, n_features)
pw_data = {}
for key in data_dict_norm:
s = data_dict_norm[key].shape
pw_data[key] = data_dict_norm[key].reshape( s[0], s[1]*s[2], order='C' )
# plot the components
plt.ioff()
fig = plt.figure()
ax0 = plt.subplot2grid( (16, 16), (0, 0), colspan=16, rowspan=16 )
new_rois = {}
for counter, key in enumerate(sorted(pw_data, key = lambda x: int(''.join(filter(str.isdigit, str(x) ))) ) ): # go through each matrix (one per ROI)
# decompose data, choose method
if method == 'nnma': # non negative matrix factorisation
nnm = ProjectedGradientNMF( n_components=n_components )
N = nnm.fit_transform( pw_data[key] )
elif method == 'pca': # principal component analysis
pca = PCA( n_components=n_components )
N = pca.fit_transform( pw_data[key] )
elif method == 'ica': # independent component analysis
ica = FastICA( n_components=n_components )
N = ica.fit_transform( pw_data[key] )
else:
print('No method: \'' + method + '\' available. Will stop here.' )
return
# let user decide which component belongs to the data:
user_choise = 0
# prepare figure
plt.cla()
title_txt = 'Click component that resembles the sample spectrum for ROI %02d'%(counter+1) + '.'
plt.title(title_txt)
# try:
# cursor1 = Cursor(ax0, useblit=True, color='black', linewidth=1)
# except:
# pass
legendstr = []
for ii in range(n_components):
ax0.plot(N[:,ii], label='Component No. %01d'%ii, color=color_m( (ii+1)/(n_components+1)-0.01 ) )
ax0.legend( frameon=False )
ax0.set_xlabel('points along scan')
ax0.set_ylabel('intensity [arb. units]')
plt.draw()
# which curve was chosen
user_input = np.array( plt.ginput(1,timeout=-1)[0] )
nearest_points = [(np.abs(N[:,ii]-user_input[1])).argmin() for ii in range(n_components)]
user_choice = (np.abs(nearest_points-user_input[0])).argmin()
# find covariance for all pixels with user choice
covariance = np.array([])
for ii in range(len(pw_data[key][0,:])):
covariance = np.append( covariance, np.cov(pw_data[key][:,ii], N[:,user_choice])[0,0] )
# try with qui-squared test
# covariance = np.array([])
# for ii in range(len(pw_data[key][0,:])):
# chi_s = stats.chisquare( pw_data[key][:,ii], N[:,user_choice] )
# print( chi_s )
# covariance = np.append( covariance, chi_s[0] )
# plot covariance, let user choose the the cutoff in y direction
plt.cla()
title_txt = 'Click to define a y-threshold for ROI %02d'%(counter+1) + '.'
plt.title( title_txt )
ax0.plot( covariance, '-o', color=color_m(0.9) )
ax0.set_xlabel( 'pixels in ROI' )
ax0.set_ylabel( 'covariance [arb. units]' )
plt.draw()
try:
cursor1 = Cursor(ax0, useblit=True, color='black', linewidth=1, vertOn=False )
except:
pass
if cov_thresh < 0:
user_cutoff = np.array( plt.ginput(1,timeout=-1)[0] )
elif cov_thresh>0 and isinstance(cov_thresh,int):
if len( covariance ) < cov_thresh:
print('ROI has fewer pixels than cov_thresh, will break here.')
return
else:
user_cutoff = np.array([0.0, np.sort(covariance)[-cov_thresh]])
else:
print('Please provide cov_thresh as positive integer!')
# find the ROI indices above the cutoff, reassign ROI indices
inds = covariance >= user_cutoff[1]
s = data_dict_norm[key].shape
red_rois_copy[key][1][np.reshape(inds, (s[1],s[2]))] = counter+1
# reassign ROI object
self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix( red_rois_copy, np.zeros(self.roi_obj.input_image.shape))
self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
self.roi_obj.kind = 'refined'
self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# compact the new red_rois
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
self.roi_obj.red_rois = red_rois_copy
# =======
# """
# Class to define ROIs from a 2D image.
# """
# def __init__(self):
# self.roi_obj = xrs_rois.roi_object() # empty roi object
# def appendROIobject(self,roi_object):
# self.roi_obj.append(roi_object)
# def deleterois(self):
# """
# Clear the existing ROIs by creating a fresh roi_object.
# """
# self.roi_obj = xrs_rois.roi_object()
# def roi_widget(self, input_image, layout="2X3-12", shape = [512,768], qapp=None ):
# """ **roi_widget**
# Use the ROI widget to define ROIs.
# input_image = 2D array to define the ROIs from
# layout = detector layout
# shape = image shape/detector shape
# """
# #%matplotlib qt
# # plt.switch_backend('Qt4Agg')
# w4r = roiSelectionWidget.mainwindow(layout=layout)
# w4r.showImage( input_image )
# w4r.show()
# if qapp is not None:
# qapp.exec_()
# assert( w4r.isOK )
# self.roi_obj.load_rois_fromMasksDict( w4r.getMasksDict(), newshape = shape )
# self.roi_obj.input_image = input_image
# return w4r
# def get_linear_rois(self,input_image,logscaling=True,height=5,colormap='Blues',interpolation='nearest'):
# """
# Define ROIs by clicking two points on a 2D image.
# number_of_rois = integer defining how many ROIs should be determined
# input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
# logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
# height = integer defining the height (in pixels) of the ROIs
# """
# # make sure the matplotlib interactive mode is off
# plt.ioff()
# # clear all existing rois
# self.deleterois()
# # check that the input is a 2d matrix
# if not len(input_image.shape) == 2:
# print( 'Please provide a 2D numpy array as input!' )
# return
# # save input image for later use
# self.roi_obj.input_image = copy.deepcopy(input_image)
# # calculate the logarithm if 'logscaling' == True
# if logscaling:
# # set all zeros to ones:
# input_image[input_image[:,:] == 0.0] = 1.0
# input_image = np.log(np.abs(input_image))
# # prepare a figure
# fig, ax = plt.subplots()
# plt.subplots_adjust(bottom=0.2)
# cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# # Initialize suptitle, which will be updated
# titlestring = 'Start by clicking the \'Next\'-button.'
# titleInst=plt.suptitle(titlestring)
# # generate an image to be displayed
# figure_obj = plt.imshow(input_image,interpolation=interpolation)
# # set the colormap for the image
# figure_obj.set_cmap(colormap)
# rois = []
# class Index:
# ind = 0
# def next(self, event):
# titlestring = 'Click two points for ROI Nr. %02d, \'Finish\' to end.' %(self.ind+1)
# titleInst.set_text(titlestring) # Update title
# # Try needed, as FINISH button closes the figure and ginput() generates _tkinter.TclError
# try:
# one_roi = define_lin_roi(height,input_image.shape)
# for index in one_roi:
# input_image[index[0],index[1]] += 1.0e6
# figure_obj.set_data(input_image)
# plt.hold(True)
# plt.draw()
# rois.append(one_roi)
# self.ind += 1
# # Begin defining the next ROI right after current
# self.next(self)
# except KeyboardInterrupt: # to prevent "dead" figures
# plt.close()
# pass
# except:
# pass
# def prev(self, event):
# self.ind -= 1
# try:
# titlestring = 'Click the \'Next\' button again to continue.'
# titleInst.set_text(titlestring) # Update title
# # print titlestring
# for index in rois[-1]:
# input_image[index[0],index[1]] -= 1.0e6
# figure_obj.set_data(input_image)
# plt.hold(True)
# rois.pop()
# except:
# pass
# def close(self, event):
# plt.close()
# def dmy(self, event):
# pass # adding a dummy function for the dummy button
# callback = Index()
# axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
# axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
# axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
# axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
# bdmy = Button(axdmy,'') # which is why I am including a dummy button here
# bdmy.on_clicked(callback.dmy) # this way, the real buttons work
# bnext = Button(axnext, 'Next')
# bnext.on_clicked(callback.next)
# bprev = Button(axprev, 'Back')
# bprev.on_clicked(callback.prev)
# bclose = Button(axclose, 'Finish')
# bclose.on_clicked(callback.close)
# plt.show()
# # assign the defined rois to the roi_object class
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(rois,input_image.shape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = rois
# self.roi_obj.kind = 'linear'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def get_zoom_rois(self,input_image,logscaling=True,colormap='Blues',interpolation='nearest'):
# """
# Define ROIs by clicking two points on a 2D image.
# number_of_rois = integer defining how many ROIs should be determined
# input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
# logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
# height = integer defining the height (in pixels) of the ROIs
# """
# # make sure the matplotlib interactive mode is off
# plt.ioff()
# # clear all existing rois
# self.deleterois()
# # check that the input is a 2d matrix
# if not len(input_image.shape) == 2:
# print( 'please provide a 2D numpy array as input!' )
# return
# # save input image for later use
# self.roi_obj.input_image = copy.deepcopy(input_image)
# # calculate the logarithm if 'logscaling' == True
# if logscaling:
# # set all zeros to ones:
# input_image[input_image[:,:] == 0.0] = 1.0
# input_image = np.log(np.abs(input_image))
# # prepare a figure
# fig, ax = plt.subplots()
# plt.subplots_adjust(bottom=0.2)
# cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# # Initialize suptitle, which will be updated
# titlestring = 'Start by clicking the \'Next\' button.'
# titleInst=plt.suptitle(titlestring)
# # generate an image to be displayed
# figure_obj = plt.imshow(input_image,interpolation=interpolation)
# # activate the zoom function already
# thismanager = plt.get_current_fig_manager()
# thismanager.toolbar.zoom()
# # set the colormap for the image
# figure_obj.set_cmap(colormap)
# #plt.colorbar()
# # initialize a matrix for the rois (will be filled with areas of ones, twos, etc
# rois = []
# # print info to start:
# print( 'Start by clicking the \'Next\' button.' )
# class Index:
# ind = 0
# initstage = True
# next_clicked = False
# def next(self, event):
# # for some reason, the first time this is used, it doesn't work, so here is one dummy round
# if self.initstage:
# #self.ind += 1
# self.initstage = False
# plt.sca(ax)
# one_roi = define_zoom_roi(input_image,verbose=True)
# #for index in one_roi:
# # input_image[index[0],index[1]] *= 1.0
# # reset the matrix to be displayed
# figure_obj.set_data(input_image)
# # reset the zoom
# plt.xlim(0.0,input_image.shape[1])
# plt.ylim(input_image.shape[0],0.0)
# plt.draw()
# titlestring = 'Zoom in to define ROI Nr. %02d, hit \'Next\' to continue.' % (self.ind + 1)
# titleInst.set_text(titlestring) # Update title
# else:
# self.ind += 1
# plt.sca(ax)
# one_roi = define_zoom_roi(input_image)
# for index in one_roi:
# input_image[index[0],index[1]] += 1.0e10
# # reset the matrix to be displayed
# figure_obj.set_data(input_image)
# # reset the zoom
# plt.xlim(0.0,input_image.shape[1])
# plt.ylim(input_image.shape[0],0.0)
# plt.draw()
# rois.append(one_roi)
# titlestring = 'Zoom in to define ROI Nr. %02d, hit \'Next\' to continue, \'Finish\' to end.' % (self.ind + 1)
# titleInst.set_text(titlestring) # Update title
# def prev(self, event):
# self.ind -= 1
# titlestring = 'Undoing ROI Nr. %02d. Zoom again, click the \'Next\' button to continue.' % (self.ind + 1)
# titleInst.set_text(titlestring) # Update title
# #thedata[roimatrix == self.ind+1] -= 1.0e6
# #roi_matrix[roimatrix == self.ind+1] = 0.0
# for index in rois[-1]:
# input_image[index[0],index[1]] -= 1.0e10
# figure_obj.set_data(input_image)
# plt.hold(True)
# rois.pop()
# def close(self, event):
# plt.sca(ax)
# one_roi = define_zoom_roi(input_image)
# for index in one_roi:
# input_image[index[0],index[1]] += 1.0e10
# # reset the matrix to be displayed
# figure_obj.set_data(input_image)
# # reset the zoom
# plt.xlim(0.0,input_image.shape[1])
# plt.ylim(input_image.shape[0],0.0)
# plt.draw()
# rois.append(one_roi)
# titlestring = 'Last ROI is Nr. %02d.' % (self.ind + 1)
# titleInst.set_text(titlestring) # Update title
# plt.close()
# def dmy(self, event):
# pass # adding a dummy function for the dummy button
# callback = Index()
# axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
# axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
# axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
# axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
# bdmy = Button(axdmy,'') # which is why I am including a dummy button here
# bdmy.on_clicked(callback.dmy) # this way, the real buttons work
# bnext = Button(axnext, 'Next')
# bnext.on_clicked(callback.next)
# bprev = Button(axprev, 'Back')
# bprev.on_clicked(callback.prev)
# bclose = Button(axclose, 'Finish')
# bclose.on_clicked(callback.close)
# plt.show()
# # assign the defined rois to the roi_object class
# self.roi_obj.roi_matrix = (xrs_rois.convert_inds_to_matrix(rois,input_image.shape))
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = rois
# self.roi_obj.kind = 'zoom'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def get_auto_rois(self,input_image,kernel_size=5,threshold=100.0,logscaling=True,colormap='Blues',interpolation='bilinear'):
# """
# Define ROIs by choosing a threshold using a slider bar under the figure. In this function, the entire
# detector is shown.
# input_image = 2D numpy array with the image to be displayed
# kernal_size = integer defining the median filter window (has to be odd)
# theshold = initial number defining the upper end value for the slider bar (amax(input_image)/threshold defines this number), can be within GUI
# logscaling = boolean, if True (default) the logarithm of input_image is displayed
# colormap = matplotlib color scheme used in the display
# interpolation = matplotlib interpolation scheme used for the display
# """
# # make sure the matplotlib interactive mode is off
# plt.ioff()
# # clear all existing rois
# self.deleterois()
# # clear existing figure
# # plt.clf()
# # save input image for later use
# self.roi_obj.input_image = copy.deepcopy(input_image)
# # calculate the logarithm if 'logscaling' == True
# if logscaling:
# # set all zeros to ones:
# input_image[input_image[:,:] == 0.0] = 1.0
# input_image = np.log(np.abs(input_image))
# ax = plt.subplot(111)
# plt.subplots_adjust(left=0.05, bottom=0.2)
# # print out some instructions
# plt.suptitle('Use the slider bar to select ROIs, close the plotting window when satisfied.')
# # initial threshold value
# thres0 = 0.0
# # create a figure object
# figure_obj = plt.imshow(input_image,interpolation=interpolation)
# figure_obj.set_cmap(colormap)
# # prepare the slider bar
# thresxcolor = 'lightgoldenrodyellow'
# thresxamp = plt.axes([0.2, 0.10, 0.55, 0.03], axisbg=thresxcolor)
# maxthreshold=np.floor(np.amax(input_image)) # maximum of slider
# sthres = plt.Slider(thresxamp, 'Threshold', 0.0, maxthreshold, valinit=thres0)
# textBox=plt.figtext(0.50, 0.065, 'Multiplier: 1.0',verticalalignment='center')
# # define what happens when the slider is touched
# def update(val):
# # parse a threshold from the slider
# thres = sthres.val*thresMultiplier.factor
# # median filter the image
# newmatrix = signal.medfilt2d(input_image, kernel_size=kernel_size)
# # set pixels below the threshold to zero
# belowthres_indices = newmatrix < thres
# newmatrix[belowthres_indices] = 0
# # identify connected regions (this is already the roi_matrix)
# self.roi_obj.roi_matrix,numfoundrois = measurements.label(newmatrix)
# print( str(numfoundrois) + ' ROIs found!' )
# figure_obj.set_data(newmatrix)
# plt.draw()
# # Buttons for changing multiplier for the value of slider
# class thresMultiplierClass:
# factor = 1.0;
# def __new__(cls):
# return self.factor
# def increase(self,event):
# self.factor *=2.0
# textBox.set_text('Multiplier: ' + str(self.factor))
# return self.factor
# def decrease(self,event):
# self.factor /=2.0
# textBox.set_text('Multiplier: ' + str(self.factor))
# return self.factor
# # call the update function when the slider is touched
# sthres.on_changed(update)
# thresMultiplier = thresMultiplierClass()
# axincrease = plt.axes([0.8, 0.05, 0.05, 0.03])
# axdecrease = plt.axes([0.7, 0.05, 0.05, 0.03])
# bnincrease = Button(axincrease, 'x 2')
# bndecrease = Button(axdecrease, '/ 2')
# bnincrease.on_clicked(thresMultiplier.increase) # First change threshold
# bnincrease.on_clicked(update) # Then update image
# bndecrease.on_clicked(thresMultiplier.decrease)
# bndecrease.on_clicked(update)
# # ADDITION ENDS
# plt.show()
# # assign the defined rois to the roi_object class
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'auto'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def get_auto_rois_eachdet(self, input_image, kernel_size=5, threshold=100.0, logscaling=True, colormap='Blues', interpolation='bilinear'):
# """
# Define ROIs automatically using median filtering and a variable threshold for each detector
# separately.
# scannumbers = either single scannumber or list of scannumbers
# kernel_size = used kernel size for the median filter (must be an odd integer)
# logscaling = set to 'True' if images is to be shown on log-scale (default is True)
# colormap = string to define the colormap which is to be used for display (anything
# supported by matplotlib, 'Blues' by default)
# interpolation = interpolation scheme to be used for displaying the image (anything
# supported by matplotlib, 'nearest' by default)
# """
# # check that kernel_size is odd
# if not kernel_size % 2 == 1:
# print( 'The \'kernal_size\' must be an odd number.' )
# return
# self.roi_obj.input_image = copy.deepcopy(input_image)
# # big many pixels in one detector image
# DET_PIXEL_NUM = input_image.shape[0]//2
# # break down the image into 256x256 pixel images
# det_images, offsets = xrs_rois.break_down_det_image(input_image,DET_PIXEL_NUM)
# # create one roi_object per sub-image
# temp_objs = []
# for ii in range(det_images.shape[0]):
# temp = roi_finder()
# temp.get_auto_rois(det_images[ii,:,:], kernel_size=kernel_size, threshold=threshold, \
# logscaling=logscaling, colormap=colormap, interpolation=interpolation)
# temp_objs.append(temp)
# # merge all roi_objects into one
# merged_obj = xrs_rois.merge_roi_objects_by_matrix(temp_objs,input_image.shape,offsets,DET_PIXEL_NUM)
# # assign the defined rois to the roi_object class
# self.roi_obj.roi_matrix = merged_obj.roi_matrix
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'auto'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def get_polygon_rois(self,input_image,modind=-1,logscaling=True,colormap='Blues',interpolation='nearest'):
# """
# Define ROIs by clicking arbitrary number of points on a 2D image:
# LEFT CLICK to define the corner points of polygon,
# MIDDLE CLICK to finish current ROI and move to the next ROI,
# RIGHT CLICK to cancel the previous point of polygon
# input_object = 2D array, scan_object, or dictionary of scans to define the ROIs from
# modind = integer to identify module, if -1 (default), no module info will be in title (the case of one big image)
# logscaling = boolean, to determine wether the image is shown on a log-scale (default = True)
# """
# # make sure the matplotlib interactive mode is off
# plt.ioff()
# # clear all existing rois
# self.deleterois()
# # check that the input is a 2d matrix
# if not len(input_image.shape) == 2:
# print( 'Please provide a 2D numpy array as input!' )
# return
# # save input image for later use
# self.roi_obj.input_image = copy.deepcopy(input_image)
# # calculate the logarithm if 'logscaling' == True
# if logscaling:
# # set all zeros to ones:
# input_image[input_image[:,:] == 0.0] = 1.0
# input_image = np.log(np.abs(input_image))
# # prepare a figure
# fig, ax = plt.subplots()
# plt.subplots_adjust(bottom=0.2)
# moduleNames='VD:','HR:','VU:','HL:','VB:','HB:','' # for plot title
# # Initialize suptitle, which will be updated
# titlestring = ''
# titleInst=plt.suptitle(titlestring)
# cursor = Cursor(ax, useblit=True, color='red', linewidth=1 )
# # generate an image to be displayed
# figure_obj = plt.imshow(input_image,interpolation=interpolation)
# # set the colormap for the image
# figure_obj.set_cmap(colormap)
# rois = []
# class Index:
# ind = 1
# def next(self, event):
# titlestring = '%s next ROI is Nr. %02d:\n Left button to new points, middle to finish ROI. Hit \'Finish\' to end with this image.' % (moduleNames[modind], self.ind)
# titleInst.set_text(titlestring) # Update title
# # Try needed, as FINISH button closes the figure and ginput() generates _tkinter.TclError
# try:
# one_roi = define_polygon_roi(input_image.shape)
# for index in one_roi:
# input_image[int(index[0]),int(index[1])] += 1.0e6
# figure_obj.set_data(input_image)
# plt.hold(True)
# plt.draw()
# rois.append(one_roi)
# self.ind += 1
# # Begin defining the next ROI right after current
# self.next(self)
# except KeyboardInterrupt: # to prevent "dead" figures
# plt.close()
# pass
# except:
# pass
# def prev(self, event):
# self.ind -= 1
# for index in rois[-1]:
# input_image[index[0],index[1]] -= 1.0e6
# figure_obj.set_data(input_image)
# plt.hold(True)
# plt.draw()
# rois.pop()
# self.next(self)
# def close(self, event):
# plt.close()
# def dmy(self, event):
# pass # adding a dummy function for the dummy button
# callback = Index()
# axprev = plt.axes([0.5, 0.05, 0.1, 0.075])
# axnext = plt.axes([0.61, 0.05, 0.1, 0.075])
# axclose = plt.axes([0.72, 0.05, 0.1, 0.075])
# axdmy = plt.axes([0.001, 0.001, 0.001, 0.001]) # for some reason the first botton disappears when clicked
# bdmy = Button(axdmy,'') # which is why I am including a dummy button here
# bdmy.on_clicked(callback.dmy) # this way, the real buttons work
# bnext = Button(axnext, 'Next')
# bnext.on_clicked(callback.next)
# bprev = Button(axprev, 'Back')
# bprev.on_clicked(callback.prev)
# bclose = Button(axclose, 'Finish')
# bclose.on_clicked(callback.close)
# # START: initiate NEXT button press
# callback.next(self)
# # assign the defined rois to the roi_object class
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(rois,input_image.shape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = rois
# self.roi_obj.kind = 'polygon'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(rois)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(rois)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def show_rois(self,interpolation='nearest',colormap='Blues'):
# """ **show_rois**
# Creates a figure with the defined ROIs as numbered boxes on it.
# Args:
# -----
# interpolation (str) : Interpolation scheme used in the plot.
# colormap (str) : Colormap used in the plot.
# """
# self.roi_obj.show_rois(colormap=colormap,interpolation=interpolation)
# def import_simo_style_rois(self,roiList,detImageShape=(512,768)):
# """ **import_simo_style_rois**
# Converts Simo-style ROIs to the conventions used here.
# Arguments:
# ----------
# roiList (list): List of tuples that have [(xmin, xmax, ymin, ymax), (xmin, xmax, ymin, ymax), ...].
# detImageShape (tuple): Shape of the detector image (for convertion to roiMatrix)
# """
# indices = []
# for roi in roiList:
# inds = []
# for ii in range(roi[0],roi[1]):
# for jj in range(roi[2],roi[3]):
# inds.append((ii,jj))
# indices.append(inds)
# # assign the defined rois to the roi_object class
# if detImageShape:
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(indices,detImageShape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = indices
# self.roi_obj.kind = 'simoStyle'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def refine_pw_rois(self, roi_obj, pw_data, n_components=2, method='nnma', cov_thresh=-1):
# """**refine_pw_rois**
# Use decomposition of pixelwise data for each ROI to find which of the pixels holds
# data from the sample and which one only has background.
# Args:
# -----
# roi_obj (roi_object): ROI object to be refined.
# pw_data (list): List containing one 2D numpy array per ROI holding pixel-wise signals.
# n_components (int): Number of components in the decomposition.
# method (string): Keyword describing which decomposition to be used ('pca', 'ica', 'nnma').
# """
# # check if available method is used
# avail_methods = ['pca','ica','nnma']
# if not method in avail_methods:
# print('Please use one of the following methods: ' + str(avail_methods) + '!')
# return
# # check if scikit learn is available
# try:
# from sklearn.decomposition import FastICA, PCA, ProjectedGradientNMF
# except ImportError:
# raise ImportError('Please install the scikit-learn package to use this feature.')
# return
# counter = 0
# new_rois = {}
# for data, key in zip(pw_data, sorted(roi_obj.red_rois)): # go through each matrix (one per ROI)
# # decompose data, choose method
# if method == 'nnma': # non negative matrix factorisation
# nnm = ProjectedGradientNMF(n_components=n_components)
# N = nnm.fit_transform(data)
# elif method == 'pca': # principal component analysis
# pca = PCA(n_components=n_components)
# N = pca.fit_transform(data)
# elif method == 'ica': # independent component analysis
# ica = FastICA(n_components=n_components)
# N = ica.fit_transform(data)
# else:
# print('No method: \'' + method + '\' available. Will stop here.' )
# # let user decide which component belongs to the data:
# user_choise = 0
# plt.cla()
# title_txt = 'Click component that resembles the sample spectrum for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# legendstr = []
# for ii in range(n_components):
# plt.plot(N[:,ii])
# legendstr.append('Component No. %01d' %ii)
# plt.legend(legendstr)
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# # which curve was chosen
# nearest_points = [(np.abs(N[:,ii]-user_input[1])).argmin() for ii in range(n_components)]
# user_choice = (np.abs(nearest_points-user_input[0])).argmin()
# # find covariance for all pixels with user choice
# covariance = np.array([])
# for ii in range(len(data[0,:])):
# covariance = np.append(covariance, np.cov(data[:,ii],N[:,user_choice])[0,0])
# # plot covariance, let user choose the the cutoff in y direction
# plt.cla()
# title_txt = 'Click to define a y-threshold for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(covariance,'-o')
# plt.xlabel('pixels in ROI')
# plt.ylabel('covariance [arb. units]')
# if cov_thresh < 0:
# user_cutoff = np.array(plt.ginput(1,timeout=-1)[0])
# elif cov_thresh>0 and isinstance(cov_thresh,int):
# if len(covariance) < cov_thresh:
# print('ROI has fewer pixels than cov_thresh, will break here.')
# return
# else:
# user_cutoff = np.array([0.0, np.sort(covariance)[-cov_thresh]])
# else:
# print('Please provide cov_thresh as positive integer!')
# # find the ROI indices above the cutoff, reassign ROI indices
# inds = covariance >= user_cutoff[1]
# #print('inds is ', inds)
# ravel_roi = roi_obj.red_rois[key][1].ravel()
# ravel_roi[~inds] = 0.0
# roi_obj.red_rois[key][1] = np.reshape(ravel_roi, (roi_obj.red_rois[key][1].shape))
# # end loop
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def refine_rois_MF(self, hydra_obj, scan_numbers, n_components=2, method='nnma', cov_thresh=-1):
# """**refine_rois_MF**
# Use decomposition of pixelwise data for each ROI to find which of the pixels holds
# data from the sample and which one only has background.
# Args:
# -----
# hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
# for the refinement of the ROIs.
# scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
# n_components (int): Number of components in the decomposition.
# method (string): Keyword describing which decomposition to be used ('pca', 'ica', 'nnma').
# """
# # check if available method is used
# if not method in ['pca','ica','nnma']:
# print('Please use one of the following methods: ' + str(avail_methods) + '!')
# return
# # check if scikit learn is available
# try:
# from sklearn.decomposition import FastICA, PCA, ProjectedGradientNMF
# except ImportError:
# raise ImportError('Please install the scikit-learn package to use this feature.')
# return
# # make scan_numbers itarable
# if isinstance(scan_numbers,list):
# scannums = scan_numbers
# elif isinstance(scan_numbers,int):
# scannums = [scan_numbers]
# # get EDF-files and pw_data
# hydra_obj.load_scan(scannums, direct=False)
# pw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
# counter = 0
# new_rois = {}
# for data, key in zip(pw_data, sorted(self.roi_obj.red_rois)): # go through each matrix (one per ROI)
# # decompose data, choose method
# if method == 'nnma': # non negative matrix factorisation
# nnm = ProjectedGradientNMF(n_components=n_components)
# N = nnm.fit_transform(data)
# elif method == 'pca': # principal component analysis
# pca = PCA(n_components=n_components)
# N = pca.fit_transform(data)
# elif method == 'ica': # independent component analysis
# ica = FastICA(n_components=n_components)
# N = ica.fit_transform(data)
# else:
# print('No method: \'' + method + '\' available. Will stop here.' )
# # let user decide which component belongs to the data:
# user_choise = 0
# plt.cla()
# title_txt = 'Click component that resembles the sample spectrum for ROI %02d , key %s'%(counter+1, key) + '.'
# plt.title(title_txt)
# legendstr = []
# for ii in range(n_components):
# plt.plot(N[:,ii])
# legendstr.append('Component No. %01d' %ii)
# plt.legend(legendstr)
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# # which curve was chosen
# nearest_points = [(np.abs(N[:,ii]-user_input[1])).argmin() for ii in range(n_components)]
# user_choice = (np.abs(nearest_points-user_input[0])).argmin()
# # find covariance for all pixels with user choice
# covariance = np.array([])
# for ii in range(len(data[0,:])):
# covariance = np.append(covariance, np.cov(data[:,ii],N[:,user_choice])[0,0])
# # plot covariance, let user choose the the cutoff in y direction
# plt.cla()
# title_txt = 'Click to define a y-threshold for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(covariance,'-o')
# plt.xlabel('pixels in ROI')
# plt.ylabel('covariance [arb. units]')
# if cov_thresh < 0:
# user_cutoff = np.array(plt.ginput(1,timeout=-1)[0])
# elif cov_thresh>0 and isinstance(cov_thresh,int):
# if len(covariance) < cov_thresh:
# print('ROI has fewer pixels than cov_thresh, will break here.')
# return
# else:
# user_cutoff = np.array([0.0, np.sort(covariance)[-cov_thresh]])
# else:
# print('Please provide cov_thresh as positive integer!')
# # find the ROI indices above the cutoff, reassign ROI indices
# inds = covariance >= user_cutoff[1]
# #print('inds is ', inds)
# ravel_roi = self.roi_obj.red_rois[key][1].ravel()
# ravel_roi[~inds] = 0.0
# self.roi_obj.red_rois[key][1] = np.reshape(ravel_roi, (self.roi_obj.red_rois[key][1].shape))
# # end loop
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# # compact the new red_rois
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
# def find_pw_rois(self,roi_obj,pw_data,save_dataset=False):
# """
# **find_pw_rois**
# Allows for manual refinement of ROIs by plotting the spectra pixel-wise.
# Loops through the spectra pixel-by-pixel and ROI by ROI, click above the
# black line to keep the pixel plotted, click below the black line to discard
# the pixel.
# Args:
# -----
# roi_obj (roi_object): ROI object from the XRStools.xrs_rois module with roughly defined ROIs.
# pw_data (np.array): List containing one 2D numpy array per ROI holding pixel-wise signals.
# """
# counter = 0
# new_indices = []
# pixelCounter = 0
# for data in pw_data: # go through each ROI
# refined_indices = []
# for ii in range(len(data[0,:])):
# user_choice = 1
# plt.cla()
# title_txt = 'Click above to keep/below black line to discard pixel for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(data[:,ii],'b-')
# axes = plt.gca()
# offset = np.mean(axes.get_ylim())
# plt.plot(np.zeros(len(data[:,ii])) + offset,'k-')
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# plt.legend(['Pixel No. %02d'%ii])
# # let user click a point on figure
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# if user_input[1] >= offset:
# refined_indices.append(roi_obj.indices[counter][ii])
# elif user_input[1] < offset:
# user_choice = 0
# else:
# print('Something fishy happened!')
# # save spectra and decisions for NN learning
# if save_dataset:
# s = shelve.open(save_dataset)
# try:
# thekey = 'PixelNo' + str(pixelCounter)
# s[thekey] = { 'spectrum': data[:,ii], 'decision': user_choice }
# finally:
# s.close()
# pixelCounter += 1
# # reorganize pixels inside ROI
# new_indices.append(refined_indices)
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = new_indices
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def refine_rois_PW_old(self, hydra_obj, scan_numbers, save_dataset=False):
# """ **refine_rois_PW**
# Allows for manual refinement of ROIs by plotting the spectra pixel-wise.
# Loops through the spectra pixel-by-pixel and ROI by ROI, click above the
# black line to keep the pixel plotted, click below the black line to discard
# the pixel.
# Args:
# -----
# hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
# for the refinement of the ROIs.
# scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
# """
# # make scan_numbers itarable
# if isinstance(scan_numbers,list):
# scannums = scan_numbers
# elif isinstance(scan_numbers,int):
# scannums = [scan_numbers]
# # get EDF-files and pw_data
# hydra_obj.load_scan(scannums, direct=False)
# pw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
# counter = 0
# new_indices = []
# pixelCounter = 0
# for data in pw_data: # go through each ROI
# refined_indices = []
# for ii in range(len(data[0,:])):
# user_choice = 1
# plt.cla()
# title_txt = 'Click above to keep/below black line to discard pixel for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(data[:,ii],'b-')
# axes = plt.gca()
# offset = np.mean(axes.get_ylim())
# plt.plot(np.zeros(len(data[:,ii])) + offset,'k-')
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# plt.legend(['Pixel No. %02d'%ii])
# # let user click a point on figure
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# if user_input[1] >= offset:
# refined_indices.append(self.roi_obj.indices[counter][ii])
# elif user_input[1] < offset:
# user_choice = 0
# else:
# print('Something fishy happened!')
# # save spectra and decisions for NN learning
# if save_dataset:
# s = shelve.open(save_dataset)
# try:
# thekey = 'PixelNo' + str(pixelCounter)
# s[thekey] = { 'spectrum': data[:,ii], 'decision': user_choice }
# finally:
# s.close()
# pixelCounter += 1
# # reorganize pixels inside ROI
# new_indices.append(refined_indices)
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = new_indices
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def refine_rois_PW(self, hydra_obj, scan_numbers):
# """ **refine_rois_PW**
# Allows for manual refinement of ROIs by plotting the spectra column-wise.
# Loops through the spectra column-by-column and ROI by ROI, click above the
# black line to keep the column plotted, click below the black line to discard
# the column of pixels.
# Args:
# -----
# hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
# for the refinement of the ROIs.
# scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
# """
# # make scan_numbers itarable
# if isinstance(scan_numbers,list):
# scannums = scan_numbers
# elif isinstance(scan_numbers,int):
# scannums = [scan_numbers]
# # get EDF-files and pw_data
# hydra_obj.load_scan(scannums, direct=False)
# cw_data = hydra_obj.get_pw_matrices( scannums, method='pixel' )
# plt.ioff()
# counter = 0
# for data, key in zip(cw_data, sorted(self.roi_obj.red_rois)):
# for ii in range(data.shape[1]):
# plt.cla()
# title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(data[:,ii],'b-')
# axes = plt.gca()
# offset = np.mean(axes.get_ylim())
# plt.plot(np.zeros_like(data[:,ii]) + offset,'k-')
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# plt.legend(['Pixel No. %02d / %02d' %(ii+1,data.shape[1])])
# # let user click a point on figure
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# if user_input[1] >= offset:
# pass
# elif user_input[1] < offset:
# self.roi_obj.red_rois[key][1].ravel()[ii] = 0
# else:
# print('Something fishy happened!')
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# # compact red rois
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
# def find_cw_rois(self,roi_obj,pw_data):
# """
# **find_cw_rois**
# Allows for manual refinement of ROIs by plotting the spectra column-wise.
# Loops through the spectra column-by-column and ROI by ROI, click above the
# black line to keep the column plotted, click below the black line to discard
# the column of pixels.
# Args:
# -----
# roi_obj (roi_object): ROI object from the XRStools.xrs_rois module with roughly defined ROIs.
# pw_data (np.array): List containing one 2D numpy array per ROI holding pixel-wise signals.
# """
# counter = 0
# new_indices = []
# for data,ind in zip(pw_data,range(len(pw_data))): # go through each ROI
# refined_indices = []
# # find the range/number of columns
# y_indices = roi_obj.y_indices[ind]
# y_min = np.amin(y_indices)
# y_max = np.amax(y_indices)
# for ii,col in zip(range(y_min,y_max+1),range(len(range(y_min,y_max+1)))):
# theindices = []
# cw_data = np.zeros_like(data[:,0])
# for yind,xind in zip(roi_obj.y_indices[ind],roi_obj.x_indices[ind]):
# if yind == ii:
# cw_data += data[:,col]
# theindices.append((xind,yind))
# plt.cla()
# title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(cw_data,'b-')
# axes = plt.gca()
# offset = np.mean(axes.get_ylim())
# plt.plot(np.zeros_like(cw_data) + offset,'k-')
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# plt.legend(['Column No. %02d'%col])
# # let user click a point on figure
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# if user_input[1] >= offset:
# for index in theindices:
# refined_indices.append(index)
# elif user_input[1] < offset:
# pass
# else:
# print('Something fishy happened!')
# # reorganize pixels inside ROI
# new_indices.append(refined_indices)
# counter += 1
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_inds_to_matrix(new_indices,self.roi_obj.input_image.shape)
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix)
# self.roi_obj.indices = new_indices
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(new_indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(new_indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# def refine_rois_CW(self, hydra_obj, scan_numbers):
# """ **refine_rois_CW**
# Allows for manual refinement of ROIs by plotting the spectra column-wise.
# Loops through the spectra column-by-column and ROI by ROI, click above the
# black line to keep the column plotted, click below the black line to discard
# the column of pixels.
# Args:
# -----
# hydra_obj (hydra_object): Object from the xrs_read.Hydra class that hold scans to be used
# for the refinement of the ROIs.
# scan_numbers (int or list): Scan numbers of scans to be used in the refinement.
# """
# # make scan_numbers itarable
# if isinstance(scan_numbers,list):
# scannums = scan_numbers
# elif isinstance(scan_numbers,int):
# scannums = [scan_numbers]
# # get EDF-files and pw_data
# hydra_obj.load_scan(scannums, direct=False)
# cw_data = hydra_obj.get_pw_matrices( scannums, method='column' )
# plt.ioff()
# counter = 0
# for data, key in zip(cw_data, sorted(self.roi_obj.red_rois)):
# for ii in range(data.shape[1]):
# plt.cla()
# title_txt = 'Click above to keep/below black line to discard column for ROI %02d'%(counter+1) + '.'
# plt.title(title_txt)
# plt.plot(data[:,ii],'b-')
# axes = plt.gca()
# offset = np.mean(axes.get_ylim())
# plt.plot(np.zeros_like(data[:,ii]) + offset,'k-')
# plt.xlabel('points along scan')
# plt.ylabel('intensity [arb. units]')
# plt.legend(['Column No. %02d / %02d' %(ii+1,data.shape[1])])
# # let user click a point on figure
# user_input = np.array(plt.ginput(1,timeout=-1)[0])
# if user_input[1] >= offset:
# pass
# elif user_input[1] < offset:
# self.roi_obj.red_rois[key][1][:,ii] = 0
# else:
# print('Something fishy happened!')
# counter += 1
# # go through all ROIs and delete empty ones
# for key in self.roi_obj.red_rois.keys():
# if self.roi_obj.red_rois[key][1].shape == (0,0):
# del self.roi_obj.red_rois[key]
# # reassign ROI object
# self.roi_obj.roi_matrix = xrs_rois.convert_redmatrix_to_matrix(self.roi_obj.red_rois, np.zeros(self.roi_obj.input_image.shape))
# self.roi_obj.indices = xrs_rois.convert_matrix_rois_to_inds(self.roi_obj.roi_matrix)
# self.roi_obj.kind = 'refined'
# self.roi_obj.x_indices = xrs_rois.convert_inds_to_xinds(self.roi_obj.indices)
# self.roi_obj.y_indices = xrs_rois.convert_inds_to_yinds(self.roi_obj.indices)
# self.roi_obj.masks = xrs_rois.convert_roi_matrix_to_masks(self.roi_obj.roi_matrix)
# self.roi_obj.number_of_rois = int(np.amax(self.roi_obj.roi_matrix))
# # compact red rois
# self.roi_obj.red_rois = xrs_rois.convert_matrix_to_redmatrix(self.roi_obj.roi_matrix, labelformat= 'ROI%02d')
[docs]def define_lin_roi(height,image_shape,verbose=False):
"""
Lets you pick 2 points on a current image and returns a linear ROI of
height (2*height+1).
height = number of pixels that define the height of the ROI
image_shape = tuple with shape of the current image (i.e. (256,256))
"""
endpoints = list(np.round(plt.ginput(2,timeout=-1)))
# check that selected points are in the image
for point in endpoints:
if point[0] < 0.0:
point = 0
if point[0] > image_shape[1]:
point = image_shape[1]
if point[1] < 0.0:
point[1] = 0
if point[1] > image_shape[0]:
point[1] = image_shape[0]
# check that point 2 is bigger than point 1 in the x direction
if endpoints[1][0]< endpoints[0][0]:
endpoints[0],endpoints[1] = endpoints[1],endpoints[0]
# print the limits of the rectangle in the shell
if not verbose:
print( 'The selected points are: ', [[endpoints[0][1],endpoints[0][0]],[endpoints[1][1],endpoints[1][0]]] )
roix = np.arange(endpoints[0][0],endpoints[1][0])
roiy = [round(num) for num in np.polyval(np.polyfit([endpoints[0][0],endpoints[1][0]],[endpoints[0][1],endpoints[1][1]],1),roix)]
roi = []
height = np.arange(-height,height)
for n in range(len(roix)):
for ind in height:
roi.append((int(roiy[n]+ind),int(roix[n])))
return roi
[docs]def define_zoom_roi(input_image,verbose=False):
"""
Parses the current figure limits and uses them to define a rectangle of "
roi_number"s in the matrix given by roi_matrix.
input_image = unzoomed figure
roi_matrix = current roi matrix which will be altered
"""
# input_image.shape prints (y-length, x-length)
# parse the figure limits from the current zoom
# limits = np.round(plt.axis()) # x-min, x-max, y-max, y-min
frac_limits = plt.axis() # x-min, x-max, y-max, y-min as floats
print( frac_limits )
limits = np.array([np.ceil(frac_limits[0]), np.floor(frac_limits[1]+0.5), np.floor(frac_limits[2]+0.5), np.ceil(frac_limits[3])]) # x-min, x-max, y-max, y-min as ints
# check that selected zoom area is not outside the image
inds = limits < 0
limits[inds] = 0
if limits[1] > input_image.shape[1]:
limits[1] = input_image.shape[1]
if limits[2] > input_image.shape[0]:
limits[2] = input_image.shape[0]
# sort the limits in ascenging order
limitsy = limits[2:4] # vertical
limitsy.sort()
limitsx = limits[0:2] # horizontal
limitsx.sort()
# print the limits of the rectangle in the shell
if not verbose:
print( 'The selected limits are: ', limitsx, limitsy )
# prepare a n*m matrix with one roi
T = np.zeros(input_image.shape)
T[int(limitsy[0]):int(limitsy[1]),int(limitsx[0]):int(limitsx[1])] = 1
indsy,indsx = np.where(T == 1)
roi = []
for n in range(len(indsx)):
roi.append((int(indsy[n]),int(indsx[n])))
return roi
[docs]def show_rois(roi_matrix):
"""
Creates a figure with the defined ROIs as numbered boxes on it.
"""
roi_matrix
# check if there are ROIs defined
if not np.any(roi_matrix):
print( 'Please select some rois first.' )
# make a figure
else:
plt.ioff()
plt.imshow(roi_matrix)
plt.xlabel('x-axis [pixel]')
plt.ylabel('y-axis [pixel]')
# add a label with the number to the center of each ROI
for ii in range(int(np.amax(roi_matrix))):
# find center of the ROI and write the label
inds = np.where(roi_matrix[:,:] == ii+1)
xcenter = np.mean(inds[1])
ycenter = np.mean(inds[0])
string = '%02d' % (ii+1)
plt.text(xcenter,ycenter,string)
plt.show()
plt.ion()
[docs]def test_roifinder(roi_type_str, imagesize = [512,768], scan = None ):
"""
Runs the roi_finder class on a random image of given type for
testing purposes.
scan[0] = absolute path to a spec file
scan[1] = energycolumn='energy'
scan[2] = monitorcolumn='kap4dio'
scan[3] = scan number from which to take images
"""
strings = ['zoom','linear','auto']
if not roi_type_str in strings:
print( 'Only ' + str(strings) + ' testable, choose one of them!' )
return
# make a random image
if not scan:
rand_image = np.random.rand(imagesize[0],imagesize[1])
else:
import xrs_read, xrs_utilities
read_obj = xrs_read.read_id20(scan[0],energycolumn=scan[1],monitorcolumn=scan[2])
read_obj.loadelastic(scan[3])
key = 'Scan%03d' % scan[3]
rand_image = xrs_utilities.sumx(read_obj.scans[key].edfmats)
# create a roi_finder object
roi_finder_obj = roi_finder()
if roi_type_str == 'zoom':
roi_finder_obj.get_zoom_rois(rand_image,logscaling=True,colormap='Blues',interpolation='nearest')
roi_finder_obj.show_rois()
elif roi_type_str == 'linear':
roi_finder_obj.get_linear_rois(rand_image,logscaling=True,height=5,colormap='Blues',interpolation='nearest')
roi_finder_obj.show_rois()
elif roi_type_str == 'auto':
roi_finder_obj.get_auto_rois(rand_image,kernel_size=5,threshold=1.0,logscaling=True,colormap='Blues',interpolation='nearest')
roi_finder_obj.show_rois()
[docs]def create_diff_image(scans,scannumbers,energy_keV):
"""
Returns a summed image from all scans with numbers 'scannumbers'.
scans = dictionary of objects from the scan-class
scannumbers = single scannumber, or list of scannumbers from which an image should be constructed
"""
# make 'scannumbers' iterable (even if it is just an integer)
numbers = []
if not isinstance(scannumbers,list):
numbers.append(scannumbers)
else:
numbers = scannumbers
key = 'Scan%03d' % numbers[0]
below_image = np.zeros_like(scans[key].edfmats[0,:,:])
above_image = np.zeros_like(scans[key].edfmats[0,:,:])
# find indices below and above 'energy'
below_inds = scans[key].energy < energy_keV
above_inds = scans[key].energy > energy_keV
for number in numbers:
key = 'Scan%03d' % number
for ii in below_inds:
below_image += scans[key].edfmats[ii,:,:]
for ii in above_inds:
above_image += scans[key].edfmats[ii,:,:]
return (above_image - below_image)
[docs]def define_polygon_roi(image_shape,verbose=False):
"""
Define a polygon shaped ROI from a current image by
selecting points.
"""
tmptuple=plt.ginput(0,timeout=-1,show_clicks=True)
pnts=np.array(tmptuple)
if verbose:
print( 'The selected points are:' )
print( pnts )
# Create the polygon path from points clicked
path=Path(pnts)
# bounding box: everything outside this is necessarily zero
bbx = np.arange( np.floor(min( pnts[:,0])), np.ceil(max( pnts[:,0])))
bby = np.arange( np.floor(min( pnts[:,1])), np.ceil(max( pnts[:,1])))
roi=[]
for ii in bbx:
for jj in bby:
# Test point
if path.contains_point([ii, jj]):
roi.append( (jj, ii))
return roi