Skip to content
Snippets Groups Projects

Improved BOZ flat field

Merged Loïc Le Guyader requested to merge boz_flat_field into master
1 file
+ 39
30
Compare changes
  • Side-by-side
  • Inline
@@ -18,6 +18,7 @@ from matplotlib.colors import LogNorm
@@ -18,6 +18,7 @@ from matplotlib.colors import LogNorm
from matplotlib import cm
from matplotlib import cm
from extra_data import open_run
from extra_data import open_run
 
from extra_geom import DSSC_1MGeometry
__all__ = [
__all__ = [
'load_dssc_module',
'load_dssc_module',
@@ -235,6 +236,15 @@ class parameters():
@@ -235,6 +236,15 @@ class parameters():
return f
return f
 
def _get_pixel_pos():
 
"""Compute the pixel position on hexagonal lattice of DSSC module 15"""
 
# module pixel position
 
dummy_quad_pos = [(-130, 5), (-130, -125), (5, -125), (5, 5)]
 
g = DSSC_1MGeometry.from_quad_positions(dummy_quad_pos)
 
 
# keeping only module 15 pixel X,Y position
 
return g.get_pixel_positions()[15][:, :, :2]
 
def _plane_flat_field(p, roi):
def _plane_flat_field(p, roi):
"""Compute the p plane over the given roi.
"""Compute the p plane over the given roi.
@@ -252,19 +262,14 @@ def _plane_flat_field(p, roi):
@@ -252,19 +262,14 @@ def _plane_flat_field(p, roi):
-------
-------
the plane field given by p evaluated on the roi
the plane field given by p evaluated on the roi
extend.
extend.
TODO
----
the hexagonal lattice is currently ignored.
"""
"""
a, b, c, d = p
a, b, c, d = p
nY, nX = roi['yh'] - roi['yl'], roi['xh'] - roi['xl']
# DSSC pixel position on hexagonal lattice
 
pixel_pos = _get_pixel_pos()
 
pos = pixel_pos[roi['yl']:roi['yh'], roi['xl']:roi['xh'], :]
X = np.arange(nX)/100
Z = -(a*pos[:, :, 0] + b*pos[:, :, 1] + d)/c
Y = np.arange(nY)[:, np.newaxis]/100
Z = -(a*X + b*Y + d)/c
return Z
return Z
@@ -287,10 +292,10 @@ def compute_flat_field_correction(rois, p, plot=False):
@@ -287,10 +292,10 @@ def compute_flat_field_correction(rois, p, plot=False):
r = 'n'
r = 'n'
flat_field[rois[r]['yl']:rois[r]['yh'], rois[r]['xl']:rois[r]['xh']] = \
flat_field[rois[r]['yl']:rois[r]['yh'], rois[r]['xl']:rois[r]['xh']] = \
_plane_flat_field(p, rois[r])
_plane_flat_field(p[:4], rois[r])
r = 'p'
r = 'p'
flat_field[rois[r]['yl']:rois[r]['yh'], rois[r]['xl']:rois[r]['xh']] = \
flat_field[rois[r]['yl']:rois[r]['yh'], rois[r]['xl']:rois[r]['xh']] = \
np.fliplr(_plane_flat_field(p, rois[r]))
_plane_flat_field(p[4:], rois[r])
if plot:
if plot:
f, ax = plt.subplots(1, 1, figsize=(6, 2))
f, ax = plt.subplots(1, 1, figsize=(6, 2))
@@ -809,14 +814,16 @@ def inspect_dark(arr, mean_th=(None, None), std_th=(None, None)):
@@ -809,14 +814,16 @@ def inspect_dark(arr, mean_th=(None, None), std_th=(None, None)):
return fig
return fig
def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
def inspect_flat_field_domain(avg, rois, prod_th, ratio_th, vmin=None, vmax=None):
"""Extract beams roi from average image and compute the ratio.
"""Extract beams roi from average image and compute the ratio.
Inputs
Inputs
------
------
avg: module average image with no saturated shots for the flat field
avg: module average image with no saturated shots for the flat field
determination
determination
params: dictionnary, boz parameters
rois: dictionnary or ROIs
 
prod_th, ratio_th: tuple of floats for low and high threshold on
 
product and ratio
vmin: imshow vmin level, default None will use 5 percentile value
vmin: imshow vmin level, default None will use 5 percentile value
vmax: imshow vmax level, default None will use 99.8 percentile value
vmax: imshow vmax level, default None will use 99.8 percentile value
@@ -834,7 +841,6 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
@@ -834,7 +841,6 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
img_rois = {}
img_rois = {}
centers = {}
centers = {}
rois = params.rois
for k, r in enumerate(['n', '0', 'p']):
for k, r in enumerate(['n', '0', 'p']):
roi = rois[r]
roi = rois[r]
@@ -850,8 +856,7 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
@@ -850,8 +856,7 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
vmin=vmin,
vmin=vmin,
vmax=vmax)
vmax=vmax)
n, n_m, p, p_m = plane_fitting_domain(avg, rois,
n, n_m, p, p_m = plane_fitting_domain(avg, rois, prod_th, ratio_th)
params.flat_field_prod_th, params.flat_field_ratio_th)
prod_vmin, prod_vmax, ratio_vmin, ratio_vmax = [None]*4
prod_vmin, prod_vmax, ratio_vmin, ratio_vmax = [None]*4
for k, r in enumerate(['n', '0', 'p']):
for k, r in enumerate(['n', '0', 'p']):
@@ -860,14 +865,14 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
@@ -860,14 +865,14 @@ def inspect_flat_field_domain(avg, params, vmin=None, vmax=None):
prod_vmin = np.percentile(v, .5)
prod_vmin = np.percentile(v, .5)
prod_vmax = np.percentile(v, 20) # we look for low intensity region
prod_vmax = np.percentile(v, 20) # we look for low intensity region
im2 = axs[1, k].imshow(v, vmin=prod_vmin, vmax=prod_vmax, cmap='magma')
im2 = axs[1, k].imshow(v, vmin=prod_vmin, vmax=prod_vmax, cmap='magma')
axs[1,k].contour(v, params.flat_field_prod_th, cmap=cm.get_cmap(cm.cool, 2))
axs[1,k].contour(v, prod_th, cmap=cm.get_cmap(cm.cool, 2))
v = img_rois[r]/img_rois['0']
v = img_rois[r]/img_rois['0']
if ratio_vmin is None:
if ratio_vmin is None:
ratio_vmin = np.percentile(v, 5)
ratio_vmin = np.percentile(v, 5)
ratio_vmax = np.percentile(v, 99.8)
ratio_vmax = np.percentile(v, 99.8)
im3 = axs[2, k].imshow(v, vmin=ratio_vmin, vmax=ratio_vmax, cmap='RdBu_r')
im3 = axs[2, k].imshow(v, vmin=ratio_vmin, vmax=ratio_vmax, cmap='RdBu_r')
axs[2,k].contour(v, params.flat_field_ratio_th, cmap=cm.get_cmap(cm.cool, 2))
axs[2,k].contour(v, ratio_th, cmap=cm.get_cmap(cm.cool, 2))
cbar = fig.colorbar(im, ax=axs[0, :], orientation="horizontal")
cbar = fig.colorbar(im, ax=axs[0, :], orientation="horizontal")
cbar.ax.set_xlabel('data mean')
cbar.ax.set_xlabel('data mean')
@@ -1026,24 +1031,28 @@ def plane_fitting(params):
@@ -1026,24 +1031,28 @@ def plane_fitting(params):
Inputs
Inputs
------
------
x: vector [a, b, c, d] defining the plane as
x: 2 vector [a, b, c, d] concatenated defining the plane as
a*x + b*y + c*z + d = 0
a*x + b*y + c*z + d = 0
"""
"""
a, b, c, d = x
num = a**2 + b**2 + c**2
a_n, b_n, c_n, d_n, a_p, b_p, c_p, d_p = x
 
 
num_n = a_n**2 + b_n**2 + c_n**2
nY, nX = n.shape
roi = params.rois['n']
X = np.arange(nX)/100
pixel_pos = _get_pixel_pos()
Y = np.arange(nY)[:, np.newaxis]/100
# DSSC pixel position on hexagonal lattice
d0_2 = np.sum(n_m*(a*X + b*Y + c*n + d)**2)/num
pos = pixel_pos[roi['yl']:roi['yh'], roi['xl']:roi['xh'], :]
 
d0_2 = np.sum(n_m*(a_n*pos[:, :, 0] + b_n*pos[:, :, 1]
 
+ c_n*n + d_n)**2)/num_n
nY, nX = p.shape
num_p = a_p**2 + b_p**2 + c_p**2
X = np.arange(nX)/100
Y = np.arange(nY)[:, np.newaxis]/100
d2_2 = np.sum(np.fliplr(p_m)*(a*X + b*Y + c*np.fliplr(p) + d)**2)/num
return d2_2 + d0_2
roi = params.rois['p']
 
# DSSC pixel position on hexagonal lattice
 
pos = pixel_pos[roi['yl']:roi['yh'], roi['xl']:roi['xh'], :]
 
d2_2 = np.sum(p_m*(a_p*pos[:, :, 0] + b_p*pos[:, :, 1]
 
+ c_p*p + d_p)**2)/num_p
return 1e3*(d2_2 + d0_2)
return 1e3*(d2_2 + d0_2)
Loading