update user privileges, correct and add axis error estimation, replot for NGC1068

This commit is contained in:
Thibault Barnouin
2021-09-13 17:38:22 +02:00
parent 4e0861129d
commit 5f3d86a55c
311 changed files with 172 additions and 36 deletions

View File

@@ -17,11 +17,11 @@ from lib.convex_hull import image_hull
def main():
##### User inputs
## Input and output locations
# globals()['data_folder'] = "../data/NGC1068_x274020/"
# infiles = ['x274020at.c0f.fits','x274020bt.c0f.fits','x274020ct.c0f.fits',
# 'x274020dt.c0f.fits','x274020et.c0f.fits','x274020ft.c0f.fits',
# 'x274020gt.c0f.fits','x274020ht.c0f.fits','x274020it.c0f.fits']
# globals()['plots_folder'] = "../plots/NGC1068_x274020/"
globals()['data_folder'] = "../data/NGC1068_x274020/"
infiles = ['x274020at.c0f.fits','x274020bt.c0f.fits','x274020ct.c0f.fits',
'x274020dt.c0f.fits','x274020et.c0f.fits','x274020ft.c0f.fits',
'x274020gt.c0f.fits','x274020ht.c0f.fits','x274020it.c0f.fits']
globals()['plots_folder'] = "../plots/NGC1068_x274020/"
# globals()['data_folder'] = "../data/NGC1068_x14w010/"
# infiles = ['x14w0101t_c0f.fits','x14w0102t_c0f.fits','x14w0103t_c0f.fits',
@@ -77,9 +77,9 @@ def main():
# infiles = ['x3nl0201r_c0f.fits','x3nl0202r_c0f.fits','x3nl0203r_c0f.fits']
# globals()['plots_folder'] = "../plots/MKN78_x3nl020/"
globals()['data_folder'] = "../data/PictorA_x25d040/"
infiles = ['x25d0401t_c0f.fits','x25d0402t_c0f.fits','x25d0403t_c0f.fits']
globals()['plots_folder'] = "../plots/PictorA_x25d040/"
# globals()['data_folder'] = "../data/PictorA_x25d040/"
# infiles = ['x25d0401t_c0f.fits','x25d0402t_c0f.fits','x25d0403t_c0f.fits']
# globals()['plots_folder'] = "../plots/PictorA_x25d040/"
## Reduction parameters
# Deconvolution
@@ -112,10 +112,10 @@ def main():
rotate_stokes = True #rotation to North convention can give erroneous results
rotate_data = False #rotation to North convention can give erroneous results
# Polarization map output
figname = 'PictorA_FOC' #target/intrument name
figname = 'NGC1068_FOC' #target/intrument name
figtype = '_combine_FWHM020_rot' #additionnal informations
SNRp_cut = 20. #P measurments with SNR>3
SNRi_cut = 120. #I measurments with SNR>30, which implies an uncertainty in P of 4.7%.
SNRp_cut = 15. #P measurments with SNR>3
SNRi_cut = 80. #I measurments with SNR>30, which implies an uncertainty in P of 4.7%.
step_vec = 1 #plot all vectors in the array. if step_vec = 2, then every other vector will be plotted
##### Pipeline start
@@ -144,7 +144,7 @@ def main():
for data in data_array:
if (data < 0.).any():
print("ETAPE 4 : ", data)
#Align and rescale images with oversampling.
# Align and rescale images with oversampling.
data_array, error_array, data_mask = proj_red.align_data(data_array, headers, error_array, upsample_factor=int(Dxy.min()), ref_center=align_center, return_shifts=False)
for data in data_array:
if (data < 0.).any():
@@ -154,7 +154,7 @@ def main():
shape = np.array([vertex[1]-vertex[0],vertex[3]-vertex[2]])
rectangle = [vertex[2], vertex[0], shape[1], shape[0], 0., 'w']
# Rotate data to have North up
# Rotate data to have North up
ref_header = copy.deepcopy(headers[0])
if rotate_data:
alpha = ref_header['orientat']
@@ -196,6 +196,11 @@ def main():
Stokes_test = proj_fits.save_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, P, debiased_P, s_P, s_P_P, PA, s_PA, s_PA_P, headers, figname+figtype, data_folder=data_folder, return_hdul=True)
## Step 5:
# Crop to desired Region of Interest (ROI)
# StokesCrop = proj_plots.crop_map(copy.deepcopy(Stokes_test), copy.deepcopy(data_mask), SNRp_cut=SNRp_cut, SNRi_cut=SNRi_cut)
# StokesCrop.run()
# Stokes_crop, data_mask = StokesCrop.crop()
# Plot polarization map (Background is either total Flux, Polarization degree or Polarization degree error).
proj_plots.polarization_map(copy.deepcopy(Stokes_test), data_mask, rectangle=None, SNRp_cut=SNRp_cut, SNRi_cut=SNRi_cut, step_vec=step_vec, savename=figname+figtype, plots_folder=plots_folder, display=None)
proj_plots.polarization_map(copy.deepcopy(Stokes_test), data_mask, rectangle=None, SNRp_cut=SNRp_cut, SNRi_cut=SNRi_cut, step_vec=step_vec, savename=figname+figtype+"_P_flux", plots_folder=plots_folder, display='Pol_Flux')

0
src/lib/Derivative.cpp Normal file → Executable file
View File

View File

@@ -9,9 +9,11 @@ prototypes :
Plots polarization map of polarimetric parameters saved in an HDUList
"""
import copy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.widgets import RectangleSelector
import matplotlib.font_manager as fm
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar, AnchoredDirectionArrows
from astropy.wcs import WCS
@@ -167,8 +169,102 @@ def plot_Stokes(Stokes, savename=None, plots_folder=""):
return 0
def polarization_map(Stokes, data_mask, rectangle=None, SNRp_cut=3., SNRi_cut=30., step_vec=1,
savename=None, plots_folder="", display=None):
class crop_map(object):
"""
Class to interactively crop I_stokes map to desired Region of Interest
"""
def __init__(self, Stokes, data_mask, SNRp_cut=3., SNRi_cut=30.):
#Get data
stkI = Stokes[np.argmax([Stokes[i].header['datatype']=='I_stokes' for i in range(len(Stokes))])]
stk_cov = Stokes[np.argmax([Stokes[i].header['datatype']=='IQU_cov_matrix' for i in range(len(Stokes))])]
pol = Stokes[np.argmax([Stokes[i].header['datatype']=='Pol_deg_debiased' for i in range(len(Stokes))])]
pol_err = Stokes[np.argmax([Stokes[i].header['datatype']=='Pol_deg_err' for i in range(len(Stokes))])]
self.Stokes = Stokes
self.data_mask = data_mask
wcs = WCS(Stokes[0]).deepcopy()
#Compute SNR and apply cuts
pol.data[pol.data == 0.] = np.nan
SNRp = pol.data/pol_err.data
SNRp[np.isnan(SNRp)] = 0.
pol.data[SNRp < SNRp_cut] = np.nan
SNRi = stkI.data/np.sqrt(stk_cov.data[0,0])
SNRi[np.isnan(SNRi)] = 0.
pol.data[SNRi < SNRi_cut] = np.nan
convert_flux = Stokes[0].header['photflam']
#Plot the map
plt.rcParams.update({'font.size': 16})
self.fig = plt.figure(figsize=(15,15))
self.ax = self.fig.add_subplot(111, projection=wcs)
self.ax.set_facecolor('k')
self.fig.subplots_adjust(hspace=0, wspace=0, right=0.9)
cbar_ax = self.fig.add_axes([0.95, 0.12, 0.01, 0.75])
self.extent = [-stkI.data.shape[1]/2.,stkI.data.shape[1]/2.,-stkI.data.shape[0]/2.,stkI.data.shape[0]/2.]
self.center = [stkI.data.shape[1]/2.,stkI.data.shape[0]/2.]
vmin, vmax = 0., np.max(stkI.data[stkI.data > 0.]*convert_flux)
im = self.ax.imshow(stkI.data*convert_flux,extent=self.extent, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno', alpha=1.)
cbar = plt.colorbar(im, cax=cbar_ax, label=r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]")
levelsI = np.linspace(SNRi_cut, np.max(SNRi[SNRi > 0.]), 10)
cont = self.ax.contour(SNRi, extent=self.extent, levels=levelsI, colors='grey', linewidths=0.5)
fontprops = fm.FontProperties(size=16)
px_size = wcs.wcs.get_cdelt()[0]
px_sc = AnchoredSizeBar(self.ax.transData, 1./px_size, '1 arcsec', 3, pad=0.5, sep=5, borderpad=0.5, frameon=False, size_vertical=0.005, color='w', fontproperties=fontprops)
self.ax.add_artist(px_sc)
self.ax.set_title(
"Click and drag to crop to desired Region of Interest.\n"
"Press 'c' to toggle the selector on and off")
def onselect_crop(self, eclick, erelease) -> None:
# Obtain (xmin, xmax, ymin, ymax) values
self.RSextent = self.rect_selector.extents
self.RScenter = [self.center[i]+self.rect_selector.center[i] for i in range(2)]
# Zoom to selection
print("CROP TO : ",self.RSextent)
print("CENTER : ",self.RScenter)
#self.ax.set_xlim(self.extent[0], self.extent[1])
#self.ax.set_ylim(self.extent[2], self.extent[3])
def run(self) -> None:
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
drawtype='box', button=[1], interactive=True)
#self.fig.canvas.mpl_connect('key_press_event', self.toggle_selector)
plt.show()
def crop(self):
Stokes_crop = copy.deepcopy(self.Stokes)
# Data sets to crop
stkI = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='I_stokes' for i in range(len(Stokes_crop))])]
stkQ = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='Q_stokes' for i in range(len(Stokes_crop))])]
stkU = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='U_stokes' for i in range(len(Stokes_crop))])]
stk_cov = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='IQU_cov_matrix' for i in range(len(Stokes_crop))])]
pol = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='Pol_deg_debiased' for i in range(len(Stokes_crop))])]
pol_err = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='Pol_deg_err' for i in range(len(Stokes_crop))])]
pang = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='Pol_ang' for i in range(len(Stokes_crop))])]
pang_err = Stokes_crop[np.argmax([Stokes_crop[i].header['datatype']=='Pol_ang_err' for i in range(len(Stokes_crop))])]
# Crop datasets
vertex = [int(self.RScenter[0]+self.RSextent[0]), int(self.RScenter[0]+self.RSextent[1]), int(self.RScenter[1]+self.RSextent[2]), int(self.RScenter[1]+self.RSextent[3])]
for dataset in [stkI, stkQ, stkU, pol, pol_err, pang, pang_err]:
dataset.data = dataset.data[vertex[2]:vertex[3], vertex[0]:vertex[1]]
data_mask = self.data_mask[vertex[2]:vertex[3], vertex[0]:vertex[1]]
new_stk_cov = np.zeros((3,3,stkI.data.shape[0],stkI.data.shape[1]))
for i in range(3):
for j in range(3):
new_stk_cov[i,j] = stk_cov.data[i,j][vertex[2]:vertex[3], vertex[0]:vertex[1]]
stk_cov.data = new_stk_cov
return Stokes_crop, data_mask
def polarization_map(Stokes, data_mask, rectangle=None, SNRp_cut=3., SNRi_cut=30.,
step_vec=1, savename=None, plots_folder="", display=None):
"""
Plots polarization map from Stokes HDUList.
----------

View File

@@ -1143,28 +1143,63 @@ def compute_Stokes(data_array, error_array, data_mask, headers,
Stokes_cov[0,2] = Stokes_cov[2,0] = coeff_stokes[0,0]*coeff_stokes[2,0]*pol_cov[0,0]+coeff_stokes[0,1]*coeff_stokes[2,1]*pol_cov[1,1]+coeff_stokes[0,2]*coeff_stokes[2,2]*pol_cov[2,2]+(coeff_stokes[0,0]*coeff_stokes[2,1]+coeff_stokes[2,0]*coeff_stokes[0,1])*pol_cov[0,1]+(coeff_stokes[0,0]*coeff_stokes[2,2]+coeff_stokes[2,0]*coeff_stokes[0,2])*pol_cov[0,2]+(coeff_stokes[0,1]*coeff_stokes[2,2]+coeff_stokes[2,1]*coeff_stokes[0,2])*pol_cov[1,2]
Stokes_cov[1,2] = Stokes_cov[2,1] = coeff_stokes[1,0]*coeff_stokes[2,0]*pol_cov[0,0]+coeff_stokes[1,1]*coeff_stokes[2,1]*pol_cov[1,1]+coeff_stokes[1,2]*coeff_stokes[2,2]*pol_cov[2,2]+(coeff_stokes[1,0]*coeff_stokes[2,1]+coeff_stokes[2,0]*coeff_stokes[1,1])*pol_cov[0,1]+(coeff_stokes[1,0]*coeff_stokes[2,2]+coeff_stokes[2,0]*coeff_stokes[1,2])*pol_cov[0,2]+(coeff_stokes[1,1]*coeff_stokes[2,2]+coeff_stokes[2,1]*coeff_stokes[1,2])*pol_cov[1,2]
dI_dtheta1 = 2.*pol_eff[0]/A*(pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0])*(pol_flux[1]-I_stokes) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1])*(pol_flux[2]-I_stokes) + A*coeff_stokes[0,0]*(np.sin(2.*theta[0]*Q_stokes) - np.cos(2.*theta[0]*U_stokes)))
dI_dtheta2 = 2.*pol_eff[1]/A*(pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1])*(pol_flux[2]-I_stokes) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2])*(pol_flux[0]-I_stokes) + A*coeff_stokes[0,1]*(np.sin(2.*theta[1]*Q_stokes) - np.cos(2.*theta[1]*U_stokes)))
dI_dtheta3 = 2.*pol_eff[2]/A*(pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2])*(pol_flux[0]-I_stokes) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0])*(pol_flux[1]-I_stokes) + A*coeff_stokes[0,2]*(np.sin(2.*theta[2]*Q_stokes) - np.cos(2.*theta[2]*U_stokes)))
dQ_dtheta1 = 2.*pol_eff[0]/A*(np.cos(2.*theta[0])*(pol_flux[1]-pol_flux[2]) - (pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0]) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1]))*Q_stokes + A*coeff_stokes[1,0]*(np.sin(2.*theta[0]*Q_stokes) - np.cos(2.*theta[0]*U_stokes)))
dQ_dtheta2 = 2.*pol_eff[1]/A*(np.cos(2.*theta[1])*(pol_flux[2]-pol_flux[0]) - (pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1]) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2]))*Q_stokes + A*coeff_stokes[1,1]*(np.sin(2.*theta[1]*Q_stokes) - np.cos(2.*theta[1]*U_stokes)))
dQ_dtheta3 = 2.*pol_eff[2]/A*(np.cos(2.*theta[2])*(pol_flux[0]-pol_flux[1]) - (pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2]) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0]))*Q_stokes + A*coeff_stokes[1,2]*(np.sin(2.*theta[2]*Q_stokes) - np.cos(2.*theta[2]*U_stokes)))
dU_dtheta1 = 2.*pol_eff[0]/A*(np.sin(2.*theta[0])*(pol_flux[1]-pol_flux[2]) - (pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0]) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1]))*U_stokes + A*coeff_stokes[2,0]*(np.sin(2.*theta[0]*Q_stokes) - np.cos(2.*theta[0]*U_stokes)))
dU_dtheta2 = 2.*pol_eff[1]/A*(np.sin(2.*theta[1])*(pol_flux[2]-pol_flux[0]) - (pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1]) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2]))*U_stokes + A*coeff_stokes[2,1]*(np.sin(2.*theta[1]*Q_stokes) - np.cos(2.*theta[1]*U_stokes)))
dU_dtheta3 = 2.*pol_eff[2]/A*(np.sin(2.*theta[2])*(pol_flux[0]-pol_flux[1]) - (pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2]) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0]))*U_stokes + A*coeff_stokes[2,2]*(np.sin(2.*theta[2]*Q_stokes) - np.cos(2.*theta[2]*U_stokes)))
dI_dtheta1 = 2.*pol_eff[0]/A*(pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0])*(pol_flux[1]-I_stokes) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1])*(pol_flux[2]-I_stokes))
dI_dtheta2 = 2.*pol_eff[1]/A*(pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1])*(pol_flux[2]-I_stokes) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2])*(pol_flux[0]-I_stokes))
dI_dtheta3 = 2.*pol_eff[2]/A*(pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2])*(pol_flux[0]-I_stokes) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0])*(pol_flux[1]-I_stokes))
dQ_dtheta1 = 2.*pol_eff[0]/A*(np.cos(2.*theta[0])*(pol_flux[1]-pol_flux[2]) - (pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0]) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1]))*Q_stokes)
dQ_dtheta2 = 2.*pol_eff[1]/A*(np.cos(2.*theta[1])*(pol_flux[2]-pol_flux[0]) - (pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1]) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2]))*Q_stokes)
dQ_dtheta3 = 2.*pol_eff[2]/A*(np.cos(2.*theta[2])*(pol_flux[0]-pol_flux[1]) - (pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2]) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0]))*Q_stokes)
dU_dtheta1 = 2.*pol_eff[0]/A*(np.sin(2.*theta[0])*(pol_flux[1]-pol_flux[2]) - (pol_eff[2]*np.cos(-2.*theta[2]+2.*theta[0]) - pol_eff[1]*np.cos(-2.*theta[0]+2.*theta[1]))*U_stokes)
dU_dtheta2 = 2.*pol_eff[1]/A*(np.sin(2.*theta[1])*(pol_flux[2]-pol_flux[0]) - (pol_eff[0]*np.cos(-2.*theta[0]+2.*theta[1]) - pol_eff[2]*np.cos(-2.*theta[1]+2.*theta[2]))*U_stokes)
dU_dtheta3 = 2.*pol_eff[2]/A*(np.sin(2.*theta[2])*(pol_flux[0]-pol_flux[1]) - (pol_eff[1]*np.cos(-2.*theta[1]+2.*theta[2]) - pol_eff[0]*np.cos(-2.*theta[2]+2.*theta[0]))*U_stokes)
#Stokes_cov[0,0] += (dI_dtheta1**2*sigma_theta[0]**2 + dI_dtheta2**2*sigma_theta[1]**2 + dI_dtheta3**2*sigma_theta[2]**2)
#Stokes_cov[1,1] += (dQ_dtheta1**2*sigma_theta[0]**2 + dQ_dtheta2**2*sigma_theta[1]**2 + dQ_dtheta3**2*sigma_theta[2]**2)
#Stokes_cov[2,2] += (dU_dtheta1**2*sigma_theta[0]**2 + dU_dtheta2**2*sigma_theta[1]**2 + dU_dtheta3**2*sigma_theta[2]**2)
plt.imshow(np.abs(Stokes_cov[0,0]/I_stokes)*100., origin='lower')
plt.colorbar()
plt.show()
plt.imshow(np.abs(Stokes_cov[1,1]/Q_stokes)*100., origin='lower')
plt.colorbar()
plt.show()
plt.imshow(np.abs(Stokes_cov[2,2]/U_stokes)*100., origin='lower')
plt.colorbar()
plt.show()
s_I2_axis = (dI_dtheta1**2*sigma_theta[0]**2 + dI_dtheta2**2*sigma_theta[1]**2 + dI_dtheta3**2*sigma_theta[2]**2)
s_Q2_axis = (dQ_dtheta1**2*sigma_theta[0]**2 + dQ_dtheta2**2*sigma_theta[1]**2 + dQ_dtheta3**2*sigma_theta[2]**2)
s_U2_axis = (dU_dtheta1**2*sigma_theta[0]**2 + dU_dtheta2**2*sigma_theta[1]**2 + dU_dtheta3**2*sigma_theta[2]**2)
Stokes_cov[0,0] += s_I2_axis
Stokes_cov[1,1] += s_Q2_axis
Stokes_cov[2,2] += s_U2_axis
# s_I_I = np.sqrt(Stokes_cov[0,0])/I_stokes*100.
# s_I_axis_I = np.sqrt(s_I2_axis)/I_stokes*100.
# s_Q_Q = np.sqrt(Stokes_cov[1,1])/Q_stokes*100.
# s_Q_axis_Q = np.sqrt(s_Q2_axis)/Q_stokes*100.
# s_U_U = np.sqrt(Stokes_cov[2,2])/U_stokes*100.
# s_U_axis_U = np.sqrt(s_U2_axis)/U_stokes*100.
#
# fig, ax = plt.subplots(3,3)
# im = ax[0,0].imshow(s_I_I, origin='lower')
# ax[0,0].set_title(r"$\frac{\sigma_{I}}{I}$")
# fig.colorbar(im, ax=ax[0,0])
# im = ax[0,1].imshow(s_I_axis_I, origin='lower')
# ax[0,1].set_title(r"$\frac{\sigma_{I}^{axis}}{I}$")
# fig.colorbar(im, ax=ax[0,1])
# im = ax[0,2].imshow(s_I_axis_I/s_I_I, origin='lower')
# ax[0,2].set_title(r"$\frac{\sigma_{I}^{axis}}{\sigma_{I}}$")
# fig.colorbar(im, ax=ax[0,2])
# im = ax[1,0].imshow(s_Q_Q, origin='lower')
# ax[1,0].set_title(r"$\frac{\sigma_{Q}}{Q}$")
# fig.colorbar(im, ax=ax[1,0])
# im = ax[1,1].imshow(s_Q_axis_Q, origin='lower')
# ax[1,1].set_title(r"$\frac{\sigma_{Q}^{axis}}{Q}$")
# fig.colorbar(im, ax=ax[1,1])
# im = ax[1,2].imshow(s_Q_axis_Q/s_Q_Q, origin='lower')
# ax[1,2].set_title(r"$\frac{\sigma_{Q}^{axis}}{\sigma_{Q}}$")
# fig.colorbar(im, ax=ax[1,2])
# im = ax[2,0].imshow(s_U_U, origin='lower')
# ax[2,0].set_title(r"$\frac{\sigma_{U}}{U}$")
# fig.colorbar(im, ax=ax[2,0])
# im = ax[2,1].imshow(s_U_axis_U, origin='lower')
# ax[2,1].set_title(r"$\frac{\sigma_{U}^{axis}}{U}$")
# fig.colorbar(im, ax=ax[2,1])
# im = ax[2,2].imshow(s_U_axis_U/s_U_U, origin='lower')
# ax[2,2].set_title(r"$\frac{\sigma_{U}^{axis}}{\sigma_{U}}$")
# fig.colorbar(im, ax=ax[2,2])
# plt.show()
# print("s_I/I = {}% ; s_I_axis/I = {}%".format(np.mean(s_I_I[I_stokes > 0.]), np.mean(s_I_axis_I[I_stokes > 0.])))
# print("s_Q/Q = {}% ; s_Q_axis/Q = {}%".format(np.mean(s_Q_Q[Q_stokes > 0.]), np.mean(s_Q_axis_Q[Q_stokes > 0.])))
# print("s_U/U = {}% ; s_U_axis/U = {}%".format(np.mean(s_U_U[U_stokes > 0.]), np.mean(s_U_axis_U[U_stokes > 0.])))
if not(FWHM is None) and (smoothing.lower() in ['gaussian_after','gauss_after']):
Stokes_array = np.array([I_stokes, Q_stokes, U_stokes])