propagate statistical error with single covariance matrix
This commit is contained in:
@@ -41,12 +41,12 @@ def main(target=None, proposal_id=None, infiles=None, output_dir="./data", crop=
|
|||||||
|
|
||||||
# Background estimation
|
# Background estimation
|
||||||
error_sub_type = "scott" # sqrt, sturges, rice, scott, freedman-diaconis (default) or shape (example (51, 51))
|
error_sub_type = "scott" # sqrt, sturges, rice, scott, freedman-diaconis (default) or shape (example (51, 51))
|
||||||
subtract_error = 1.50
|
subtract_error = 0.50
|
||||||
display_bkg = True
|
display_bkg = True
|
||||||
|
|
||||||
# Data binning
|
# Data binning
|
||||||
pxsize = 0.10
|
pxsize = 4
|
||||||
pxscale = "arcsec" # pixel, arcsec or full
|
pxscale = "px" # pixel, arcsec or full
|
||||||
rebin_operation = "sum" # sum or average
|
rebin_operation = "sum" # sum or average
|
||||||
|
|
||||||
# Alignement
|
# Alignement
|
||||||
@@ -59,8 +59,8 @@ def main(target=None, proposal_id=None, infiles=None, output_dir="./data", crop=
|
|||||||
|
|
||||||
# Smoothing
|
# Smoothing
|
||||||
smoothing_function = "combine" # gaussian_after, weighted_gaussian_after, gaussian, weighted_gaussian or combine
|
smoothing_function = "combine" # gaussian_after, weighted_gaussian_after, gaussian, weighted_gaussian or combine
|
||||||
smoothing_FWHM = 0.150 # If None, no smoothing is done
|
smoothing_FWHM = 1.5 # If None, no smoothing is done
|
||||||
smoothing_scale = "arcsec" # pixel or arcsec
|
smoothing_scale = "px" # pixel or arcsec
|
||||||
|
|
||||||
# Rotation
|
# Rotation
|
||||||
rotate_North = True
|
rotate_North = True
|
||||||
@@ -216,29 +216,27 @@ def main(target=None, proposal_id=None, infiles=None, output_dir="./data", crop=
|
|||||||
# FWHM of FOC have been estimated at about 0.03" across 1500-5000 Angstrom band, which is about 2 detector pixels wide
|
# FWHM of FOC have been estimated at about 0.03" across 1500-5000 Angstrom band, which is about 2 detector pixels wide
|
||||||
# see Jedrzejewski, R.; Nota, A.; Hack, W. J., A Comparison Between FOC and WFPC2
|
# see Jedrzejewski, R.; Nota, A.; Hack, W. J., A Comparison Between FOC and WFPC2
|
||||||
# Bibcode : 1995chst.conf...10J
|
# Bibcode : 1995chst.conf...10J
|
||||||
I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_stokes, sigma_flux = proj_red.compute_Stokes(
|
I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, s_IQU_stat = proj_red.compute_Stokes(
|
||||||
data_array, error_array, data_mask, headers, FWHM=smoothing_FWHM, scale=smoothing_scale, smoothing=smoothing_function, transmitcorr=transmitcorr
|
data_array, error_array, data_mask, headers, FWHM=smoothing_FWHM, scale=smoothing_scale, smoothing=smoothing_function, transmitcorr=transmitcorr
|
||||||
)
|
)
|
||||||
I_bkg, Q_bkg, U_bkg, S_cov_bkg, header_bkg, coeff_stokes, sigma_flux_bkg = proj_red.compute_Stokes(
|
I_bkg, Q_bkg, U_bkg, S_cov_bkg, header_bkg, s_IQU_stat_bkg = proj_red.compute_Stokes(
|
||||||
background, background_error, np.array(True).reshape(1, 1), headers, FWHM=None, scale=smoothing_scale, smoothing=smoothing_function, transmitcorr=False
|
background, background_error, np.array(True).reshape(1, 1), headers, FWHM=None, scale=smoothing_scale, smoothing=smoothing_function, transmitcorr=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# Step 3:
|
# Step 3:
|
||||||
# Rotate images to have North up
|
# Rotate images to have North up
|
||||||
if rotate_North:
|
if rotate_North:
|
||||||
I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, sigma_flux = proj_red.rotate_Stokes(
|
I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, s_IQU_stat = proj_red.rotate_Stokes(
|
||||||
I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, sigma_flux=sigma_flux, SNRi_cut=None
|
I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, s_IQU_stat=s_IQU_stat, SNRi_cut=None
|
||||||
)
|
)
|
||||||
I_bkg, Q_bkg, U_bkg, S_cov_bkg, data_mask_bkg, header_bkg, sigma_flux_bkg = proj_red.rotate_Stokes(
|
I_bkg, Q_bkg, U_bkg, S_cov_bkg, data_mask_bkg, header_bkg, s_IQU_stat_bkg = proj_red.rotate_Stokes(
|
||||||
I_bkg, Q_bkg, U_bkg, S_cov_bkg, np.array(True).reshape(1, 1), header_bkg, sigma_flux=sigma_flux_bkg, SNRi_cut=None
|
I_bkg, Q_bkg, U_bkg, S_cov_bkg, np.array(True).reshape(1, 1), header_bkg, s_IQU_stat=s_IQU_stat_bkg, SNRi_cut=None
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compute polarimetric parameters (polarization degree and angle).
|
# Compute polarimetric parameters (polarization degree and angle).
|
||||||
P, debiased_P, s_P, s_P_P, PA, s_PA, s_PA_P = proj_red.compute_pol(
|
P, debiased_P, s_P, s_P_P, PA, s_PA, s_PA_P = proj_red.compute_pol(I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, s_IQU_stat=s_IQU_stat)
|
||||||
I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_stokes=coeff_stokes, sigma_flux=sigma_flux
|
|
||||||
)
|
|
||||||
P_bkg, debiased_P_bkg, s_P_bkg, s_P_P_bkg, PA_bkg, s_PA_bkg, s_PA_P_bkg = proj_red.compute_pol(
|
P_bkg, debiased_P_bkg, s_P_bkg, s_P_P_bkg, PA_bkg, s_PA_bkg, s_PA_P_bkg = proj_red.compute_pol(
|
||||||
I_bkg, Q_bkg, U_bkg, S_cov_bkg, header_bkg, coeff_stokes=coeff_stokes, sigma_flux=sigma_flux_bkg
|
I_bkg, Q_bkg, U_bkg, S_cov_bkg, header_bkg, s_IQU_stat=s_IQU_stat_bkg
|
||||||
)
|
)
|
||||||
|
|
||||||
# Step 4:
|
# Step 4:
|
||||||
|
|||||||
@@ -1462,10 +1462,10 @@ def compute_Stokes(data_array, error_array, data_mask, headers, FWHM=None, scale
|
|||||||
header_stokes["PA_int"] = (PA_diluted, "Integrated polarization angle")
|
header_stokes["PA_int"] = (PA_diluted, "Integrated polarization angle")
|
||||||
header_stokes["sPA_int"] = (np.ceil(PA_diluted_err * 10.0) / 10.0, "Integrated polarization angle error")
|
header_stokes["sPA_int"] = (np.ceil(PA_diluted_err * 10.0) / 10.0, "Integrated polarization angle error")
|
||||||
|
|
||||||
return I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_stokes, sigma_flux
|
return I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, s_IQU_stat
|
||||||
|
|
||||||
|
|
||||||
def compute_pol(I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_stokes=None, sigma_flux=None):
|
def compute_pol(I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, s_IQU_stat=None):
|
||||||
"""
|
"""
|
||||||
Compute the polarization degree (in %) and angle (in deg) and their
|
Compute the polarization degree (in %) and angle (in deg) and their
|
||||||
respective errors from given Stokes parameters.
|
respective errors from given Stokes parameters.
|
||||||
@@ -1548,20 +1548,19 @@ def compute_pol(I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_s
|
|||||||
s_P_P = np.ones(I_stokes.shape) * fmax
|
s_P_P = np.ones(I_stokes.shape) * fmax
|
||||||
s_PA_P = np.ones(I_stokes.shape) * fmax
|
s_PA_P = np.ones(I_stokes.shape) * fmax
|
||||||
maskP = np.logical_and(mask, P > 0.0)
|
maskP = np.logical_and(mask, P > 0.0)
|
||||||
if coeff_stokes is not None and sigma_flux is not None:
|
if s_IQU_stat is not None:
|
||||||
s_P_P[maskP] = (
|
s_P_P[maskP] = (
|
||||||
P[maskP]
|
P[maskP]
|
||||||
/ I_stokes[maskP]
|
/ I_stokes[maskP]
|
||||||
* np.sqrt(
|
* np.sqrt(
|
||||||
np.sum(
|
s_IQU_stat[0, 0][maskP]
|
||||||
[
|
- 2.0 / (I_stokes[maskP] * P[maskP] ** 2) * (Q_stokes[maskP] * s_IQU_stat[0, 1][maskP] + U_stokes[maskP] * s_IQU_stat[0, 2][maskP])
|
||||||
((coeff_stokes[1, i] * Q_stokes[maskP] + coeff_stokes[2, i] * U_stokes[maskP]) / (I_stokes[maskP] * P[maskP] ** 2) - coeff_stokes[0, i])
|
+ 1.0
|
||||||
** 2
|
/ (I_stokes[maskP] ** 2 * P[maskP] ** 4)
|
||||||
* sigma_flux[i][maskP] ** 2
|
* (
|
||||||
for i in range(sigma_flux.shape[0])
|
Q_stokes[maskP] ** 2 * s_IQU_stat[1, 1][maskP]
|
||||||
],
|
+ U_stokes[maskP] ** 2 * s_IQU_stat[2, 2][maskP] * Q_stokes[maskP] * U_stokes[maskP] * s_IQU_stat[1, 2][maskP]
|
||||||
axis=0,
|
)
|
||||||
)[0]
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -1588,7 +1587,7 @@ def compute_pol(I_stokes, Q_stokes, U_stokes, Stokes_cov, header_stokes, coeff_s
|
|||||||
return P, debiased_P, s_P, s_P_P, PA, s_PA, s_PA_P
|
return P, debiased_P, s_P, s_P_P, PA, s_PA, s_PA_P
|
||||||
|
|
||||||
|
|
||||||
def rotate_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, sigma_flux=None, SNRi_cut=None):
|
def rotate_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_stokes, s_IQU_stat=None, SNRi_cut=None):
|
||||||
"""
|
"""
|
||||||
Use scipy.ndimage.rotate to rotate I_stokes to an angle, and a rotation
|
Use scipy.ndimage.rotate to rotate I_stokes to an angle, and a rotation
|
||||||
matrix to rotate Q, U of a given angle in degrees and update header
|
matrix to rotate Q, U of a given angle in degrees and update header
|
||||||
@@ -1681,8 +1680,16 @@ def rotate_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_st
|
|||||||
new_I_stokes[i, j], new_Q_stokes[i, j], new_U_stokes[i, j] = np.dot(mrot, np.array([new_I_stokes[i, j], new_Q_stokes[i, j], new_U_stokes[i, j]])).T
|
new_I_stokes[i, j], new_Q_stokes[i, j], new_U_stokes[i, j] = np.dot(mrot, np.array([new_I_stokes[i, j], new_Q_stokes[i, j], new_U_stokes[i, j]])).T
|
||||||
new_Stokes_cov[:, :, i, j] = np.dot(mrot, np.dot(new_Stokes_cov[:, :, i, j], mrot.T))
|
new_Stokes_cov[:, :, i, j] = np.dot(mrot, np.dot(new_Stokes_cov[:, :, i, j], mrot.T))
|
||||||
|
|
||||||
if sigma_flux is not None:
|
if s_IQU_stat is not None:
|
||||||
new_sigma_flux = sc_rotate(zeropad(sigma_flux, (sigma_flux.shape[0], *shape)), ang, order=1, reshape=False, cval=0.0)
|
s_IQU_stat = zeropad(s_IQU_stat, [*s_IQU_stat.shape[:-2], *shape])
|
||||||
|
new_s_IQU_stat = np.zeros((*s_IQU_stat.shape[:-2], *shape))
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
new_s_IQU_stat[i, j] = sc_rotate(s_IQU_stat[i, j], ang, order=1, reshape=False, cval=0.0)
|
||||||
|
new_s_IQU_stat[i, i] = np.abs(new_s_IQU_stat[i, i])
|
||||||
|
for i in range(shape[0]):
|
||||||
|
for j in range(shape[1]):
|
||||||
|
new_s_IQU_stat[:, :, i, j] = np.dot(mrot, np.dot(new_s_IQU_stat[:, :, i, j], mrot.T))
|
||||||
|
|
||||||
# Update headers to new angle
|
# Update headers to new angle
|
||||||
mrot = np.array([[np.cos(-alpha), -np.sin(-alpha)], [np.sin(-alpha), np.cos(-alpha)]])
|
mrot = np.array([[np.cos(-alpha), -np.sin(-alpha)], [np.sin(-alpha), np.cos(-alpha)]])
|
||||||
@@ -1737,8 +1744,8 @@ def rotate_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, data_mask, header_st
|
|||||||
new_header_stokes["PA_int"] = (PA_diluted, "Integrated polarization angle")
|
new_header_stokes["PA_int"] = (PA_diluted, "Integrated polarization angle")
|
||||||
new_header_stokes["sPA_int"] = (np.ceil(PA_diluted_err * 10.0) / 10.0, "Integrated polarization angle error")
|
new_header_stokes["sPA_int"] = (np.ceil(PA_diluted_err * 10.0) / 10.0, "Integrated polarization angle error")
|
||||||
|
|
||||||
if sigma_flux is not None:
|
if s_IQU_stat is not None:
|
||||||
return new_I_stokes, new_Q_stokes, new_U_stokes, new_Stokes_cov, new_data_mask, new_header_stokes, new_sigma_flux
|
return new_I_stokes, new_Q_stokes, new_U_stokes, new_Stokes_cov, new_data_mask, new_header_stokes, new_s_IQU_stat
|
||||||
else:
|
else:
|
||||||
return new_I_stokes, new_Q_stokes, new_U_stokes, new_Stokes_cov, new_data_mask, new_header_stokes
|
return new_I_stokes, new_Q_stokes, new_U_stokes, new_Stokes_cov, new_data_mask, new_header_stokes
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user