Create analysis tool
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010.png
Normal file
|
After Width: | Height: | Size: 282 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_IQU.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_I_err.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_P.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_P_err.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_P_flux.png
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_SNRi.png
Normal file
|
After Width: | Height: | Size: 352 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_combine_FWHM010_SNRp.png
Normal file
|
After Width: | Height: | Size: 597 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_full.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
plots/NGC1068_x274020/NGC1068_FOC_full_IQU.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
#-*- coding:utf-8 -*-
|
#-*- coding:utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Main script where are progressively added the steps for the FOC pipeline reduction.
|
Main script where are progressively added the steps for the FOC pipeline reduction.
|
||||||
@@ -19,12 +19,12 @@ import matplotlib.pyplot as plt
|
|||||||
def main():
|
def main():
|
||||||
##### User inputs
|
##### User inputs
|
||||||
## Input and output locations
|
## Input and output locations
|
||||||
# globals()['data_folder'] = "../data/NGC1068_x274020/"
|
globals()['data_folder'] = "../data/NGC1068_x274020/"
|
||||||
# infiles = ['x274020at.c0f.fits','x274020bt.c0f.fits','x274020ct.c0f.fits',
|
infiles = ['x274020at.c0f.fits','x274020bt.c0f.fits','x274020ct.c0f.fits',
|
||||||
# 'x274020dt.c0f.fits','x274020et.c0f.fits','x274020ft.c0f.fits',
|
'x274020dt.c0f.fits','x274020et.c0f.fits','x274020ft.c0f.fits',
|
||||||
# 'x274020gt.c0f.fits','x274020ht.c0f.fits','x274020it.c0f.fits']
|
'x274020gt.c0f.fits','x274020ht.c0f.fits','x274020it.c0f.fits']
|
||||||
# psf_file = 'NGC1068_f253m00.fits'
|
psf_file = 'NGC1068_f253m00.fits'
|
||||||
# globals()['plots_folder'] = "../plots/NGC1068_x274020/"
|
globals()['plots_folder'] = "../plots/NGC1068_x274020/"
|
||||||
|
|
||||||
# globals()['data_folder'] = "../data/NGC1068_x14w010/"
|
# globals()['data_folder'] = "../data/NGC1068_x14w010/"
|
||||||
# infiles = ['x14w0101t_c0f.fits','x14w0102t_c0f.fits','x14w0103t_c0f.fits',
|
# infiles = ['x14w0101t_c0f.fits','x14w0102t_c0f.fits','x14w0103t_c0f.fits',
|
||||||
@@ -63,10 +63,10 @@ def main():
|
|||||||
# 'x3995202r_c0f.fits','x3995206r_c0f.fits']
|
# 'x3995202r_c0f.fits','x3995206r_c0f.fits']
|
||||||
# globals()['plots_folder'] = "../plots/PG1630+377_x39510/"
|
# globals()['plots_folder'] = "../plots/PG1630+377_x39510/"
|
||||||
|
|
||||||
globals()['data_folder'] = "../data/IC5063_x3nl030/"
|
# globals()['data_folder'] = "../data/IC5063_x3nl030/"
|
||||||
infiles = ['x3nl0301r_c0f.fits','x3nl0302r_c0f.fits','x3nl0303r_c0f.fits']
|
# infiles = ['x3nl0301r_c0f.fits','x3nl0302r_c0f.fits','x3nl0303r_c0f.fits']
|
||||||
psf_file = 'IC5063_f502m00.fits'
|
# psf_file = 'IC5063_f502m00.fits'
|
||||||
globals()['plots_folder'] = "../plots/IC5063_x3nl030/"
|
# globals()['plots_folder'] = "../plots/IC5063_x3nl030/"
|
||||||
|
|
||||||
# globals()['data_folder'] = "../data/MKN3_x3nl010/"
|
# globals()['data_folder'] = "../data/MKN3_x3nl010/"
|
||||||
# infiles = ['x3nl0101r_c0f.fits','x3nl0102r_c0f.fits','x3nl0103r_c0f.fits']
|
# infiles = ['x3nl0101r_c0f.fits','x3nl0102r_c0f.fits','x3nl0103r_c0f.fits']
|
||||||
@@ -104,14 +104,14 @@ def main():
|
|||||||
rebin = True
|
rebin = True
|
||||||
if rebin:
|
if rebin:
|
||||||
pxsize = 0.10
|
pxsize = 0.10
|
||||||
px_scale = 'arcsec' #pixel, arcsec or full
|
px_scale = 'full' #pixel, arcsec or full
|
||||||
rebin_operation = 'sum' #sum or average
|
rebin_operation = 'sum' #sum or average
|
||||||
# Alignement
|
# Alignement
|
||||||
align_center = 'image' #If None will align image to image center
|
align_center = 'image' #If None will align image to image center
|
||||||
display_data = False
|
display_data = False
|
||||||
# Smoothing
|
# Smoothing
|
||||||
smoothing_function = 'combine' #gaussian_after, gaussian or combine
|
smoothing_function = 'combine' #gaussian_after, gaussian or combine
|
||||||
smoothing_FWHM = 0.20 #If None, no smoothing is done
|
smoothing_FWHM = None #If None, no smoothing is done
|
||||||
smoothing_scale = 'arcsec' #pixel or arcsec
|
smoothing_scale = 'arcsec' #pixel or arcsec
|
||||||
# Rotation
|
# Rotation
|
||||||
rotate_stokes = True #rotation to North convention can give erroneous results
|
rotate_stokes = True #rotation to North convention can give erroneous results
|
||||||
@@ -119,8 +119,8 @@ def main():
|
|||||||
# Final crop
|
# Final crop
|
||||||
crop = False #Crop to desired ROI
|
crop = False #Crop to desired ROI
|
||||||
# Polarization map output
|
# Polarization map output
|
||||||
figname = 'IC5063_FOC' #target/intrument name
|
figname = 'NGC1068_FOC' #target/intrument name
|
||||||
figtype = '_combine_FWHM020' #additionnal informations
|
figtype = '_full' #additionnal informations
|
||||||
SNRp_cut = 10. #P measurments with SNR>3
|
SNRp_cut = 10. #P measurments with SNR>3
|
||||||
SNRi_cut = 100. #I measurments with SNR>30, which implies an uncertainty in P of 4.7%.
|
SNRi_cut = 100. #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
|
step_vec = 1 #plot all vectors in the array. if step_vec = 2, then every other vector will be plotted
|
||||||
|
|||||||
62
src/analysis.py
Executable file
@@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
from getopt import getopt, error as get_error
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
arglist = argv[1:]
|
||||||
|
options = "hf:p:i:o:"
|
||||||
|
long_options = ["help","fits=","snrp=","snri=","output="]
|
||||||
|
|
||||||
|
fits_path = None
|
||||||
|
SNRp_cut, SNRi_cut = 3, 30
|
||||||
|
out_txt = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
arg, val = getopt(arglist, options, long_options)
|
||||||
|
|
||||||
|
for curr_arg, curr_val in arg:
|
||||||
|
if curr_arg in ("-h", "--help"):
|
||||||
|
print("python3 analysis.py -f <path_to_reduced_fits> -p <SNRp_cut> -i <SNRi_cut> -o <path_to_output_txt>")
|
||||||
|
elif curr_arg in ("-f", "--fits"):
|
||||||
|
fits_path = str(curr_val)
|
||||||
|
elif curr_arg in ("-p", "--snrp"):
|
||||||
|
SNRp_cut = int(curr_val)
|
||||||
|
elif curr_arg in ("-i", "--snri"):
|
||||||
|
SNRi_cut = int(curr_val)
|
||||||
|
elif curr_arg in ("-o", "--output"):
|
||||||
|
out_txt = str(curr_val)
|
||||||
|
except get_error as err:
|
||||||
|
print(str(err))
|
||||||
|
|
||||||
|
if not fits_path is None:
|
||||||
|
from astropy.io import fits
|
||||||
|
from lib.plots import pol_map
|
||||||
|
|
||||||
|
Stokes_UV = fits.open(fits_path)
|
||||||
|
p = pol_map(Stokes_UV, SNRp_cut=SNRp_cut, SNRi_cut=SNRi_cut)
|
||||||
|
|
||||||
|
if not out_txt is None:
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
conv = p.Stokes[0].header['photflam']
|
||||||
|
I = p.Stokes[0].data*conv
|
||||||
|
Q = p.Stokes[1].data*conv
|
||||||
|
U = p.Stokes[2].data*conv
|
||||||
|
P = np.zeros(I.shape)
|
||||||
|
P[p.cut] = p.Stokes[5].data[p.cut]
|
||||||
|
PA = np.zeros(I.shape)
|
||||||
|
PA[p.cut] = p.Stokes[8].data[p.cut]
|
||||||
|
|
||||||
|
shape = np.array(I.shape)
|
||||||
|
center = (shape/2).astype(int)
|
||||||
|
cdelt_arcsec = p.wcs.wcs.cdelt*3600
|
||||||
|
xx, yy = np.indices(shape)
|
||||||
|
x, y = (xx-center[0])*cdelt_arcsec[0], (yy-center[1])*cdelt_arcsec[1]
|
||||||
|
|
||||||
|
data_list = []
|
||||||
|
for i in range(shape[0]):
|
||||||
|
for j in range(shape[1]):
|
||||||
|
data_list.append([x[i,j], y[i,j], I[i,j], Q[i,j], U[i,j], P[i,j], PA[i,j]])
|
||||||
|
data = np.array(data_list)
|
||||||
|
np.savetxt(out_txt,data)
|
||||||
|
else:
|
||||||
|
print("python3 analysis.py -f <path_to_reduced_fits> -p <SNRp_cut> -i <SNRi_cut> -o <path_to_output_txt>")
|
||||||
@@ -118,10 +118,11 @@ def save_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, P, debiased_P, s_P,
|
|||||||
exp_tot = np.array([header['exptime'] for header in headers]).sum()
|
exp_tot = np.array([header['exptime'] for header in headers]).sum()
|
||||||
new_wcs = wcs.WCS(ref_header).deepcopy()
|
new_wcs = wcs.WCS(ref_header).deepcopy()
|
||||||
|
|
||||||
vertex = clean_ROI(data_mask)
|
if data_mask.shape != (1,1):
|
||||||
shape = vertex[1::2]-vertex[0::2]
|
vertex = clean_ROI(data_mask)
|
||||||
new_wcs.array_shape = shape
|
shape = vertex[1::2]-vertex[0::2]
|
||||||
new_wcs.wcs.crpix = np.array(new_wcs.wcs.crpix) - vertex[0::-2]
|
new_wcs.array_shape = shape
|
||||||
|
new_wcs.wcs.crpix = np.array(new_wcs.wcs.crpix) - vertex[0::-2]
|
||||||
|
|
||||||
header = new_wcs.to_header()
|
header = new_wcs.to_header()
|
||||||
header['instrume'] = (ref_header['instrume'], 'Instrument from which data is reduced')
|
header['instrume'] = (ref_header['instrume'], 'Instrument from which data is reduced')
|
||||||
@@ -138,25 +139,27 @@ def save_Stokes(I_stokes, Q_stokes, U_stokes, Stokes_cov, P, debiased_P, s_P,
|
|||||||
header['PA_int_err'] = (ref_header['PA_int_err'], 'Integrated polarization angle error')
|
header['PA_int_err'] = (ref_header['PA_int_err'], 'Integrated polarization angle error')
|
||||||
|
|
||||||
#Crop Data to mask
|
#Crop Data to mask
|
||||||
I_stokes = I_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
if data_mask.shape != (1,1):
|
||||||
Q_stokes = Q_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
I_stokes = I_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
U_stokes = U_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
Q_stokes = Q_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
P = P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
U_stokes = U_stokes[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
debiased_P = debiased_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
P = P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
s_P = s_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
debiased_P = debiased_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
s_P_P = s_P_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
s_P = s_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
PA = PA[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
s_P_P = s_P_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
s_PA = s_PA[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
PA = PA[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
s_PA_P = s_PA_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
s_PA = s_PA[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
|
s_PA_P = s_PA_P[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
|
|
||||||
new_Stokes_cov = np.zeros((3,3,shape[0],shape[1]))
|
new_Stokes_cov = np.zeros((3,3,shape[0],shape[1]))
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
for j in range(3):
|
for j in range(3):
|
||||||
Stokes_cov[i,j][(1-data_mask).astype(bool)] = 0.
|
Stokes_cov[i,j][(1-data_mask).astype(bool)] = 0.
|
||||||
new_Stokes_cov[i,j] = Stokes_cov[i,j][vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
new_Stokes_cov[i,j] = Stokes_cov[i,j][vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
Stokes_cov = new_Stokes_cov
|
Stokes_cov = new_Stokes_cov
|
||||||
|
|
||||||
data_mask = data_mask[vertex[0]:vertex[1],vertex[2]:vertex[3]].astype(float, copy=False)
|
data_mask = data_mask[vertex[0]:vertex[1],vertex[2]:vertex[3]]
|
||||||
|
data_mask = data_mask.astype(float, copy=False)
|
||||||
|
|
||||||
#Create HDUList object
|
#Create HDUList object
|
||||||
hdul = fits.HDUList([])
|
hdul = fits.HDUList([])
|
||||||
|
|||||||
683
src/lib/plots.py
@@ -13,8 +13,8 @@ from copy import deepcopy
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from matplotlib.patches import Rectangle
|
from matplotlib.patches import Rectangle
|
||||||
from matplotlib.widgets import RectangleSelector, Button, Slider
|
from matplotlib.path import Path
|
||||||
from matplotlib.transforms import Bbox
|
from matplotlib.widgets import RectangleSelector, Button, Slider, TextBox, LassoSelector
|
||||||
import matplotlib.font_manager as fm
|
import matplotlib.font_manager as fm
|
||||||
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar, AnchoredDirectionArrows
|
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar, AnchoredDirectionArrows
|
||||||
from astropy.wcs import WCS
|
from astropy.wcs import WCS
|
||||||
@@ -682,44 +682,72 @@ class crop_map(object):
|
|||||||
"""
|
"""
|
||||||
Class to interactively crop a map to desired Region of Interest
|
Class to interactively crop a map to desired Region of Interest
|
||||||
"""
|
"""
|
||||||
def __init__(self, hdul):
|
def __init__(self, hdul, fig=None, ax=None):
|
||||||
#Get data
|
#Get data
|
||||||
|
self.cropped=False
|
||||||
self.hdul = hdul
|
self.hdul = hdul
|
||||||
self.header = deepcopy(self.hdul[0].header)
|
self.header = deepcopy(self.hdul[0].header)
|
||||||
self.wcs = WCS(self.header).deepcopy()
|
self.wcs = WCS(self.header).deepcopy()
|
||||||
|
|
||||||
self.data = deepcopy(self.hdul[0].data)
|
self.data = deepcopy(self.hdul[0].data)
|
||||||
try:
|
try:
|
||||||
convert_flux = self.header['photflam']
|
self.convert_flux = self.header['photflam']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
convert_flux = 1.
|
self.convert_flux = 1.
|
||||||
|
|
||||||
#Plot the map
|
#Plot the map
|
||||||
plt.rcParams.update({'font.size': 16})
|
plt.rcParams.update({'font.size': 12})
|
||||||
self.fig = plt.figure(figsize=(15,15))
|
plt.ioff()
|
||||||
self.ax = self.fig.add_subplot(111, projection=self.wcs)
|
if fig is None:
|
||||||
self.ax.set_facecolor('k')
|
self.fig = plt.figure(figsize=(15,15))
|
||||||
self.fig.subplots_adjust(hspace=0, wspace=0, right=0.9)
|
self.fig.suptitle("Click and drag to crop to desired Region of Interest.")
|
||||||
cbar_ax = self.fig.add_axes([0.95, 0.12, 0.01, 0.75])
|
else:
|
||||||
|
self.fig = fig
|
||||||
|
if ax is None:
|
||||||
|
self.ax = self.fig.add_subplot(111, projection=self.wcs)
|
||||||
|
self.mask_alpha=1.
|
||||||
|
#Selection button
|
||||||
|
self.axapply = self.fig.add_axes([0.80, 0.01, 0.1, 0.04])
|
||||||
|
self.bapply = Button(self.axapply, 'Apply')
|
||||||
|
self.axreset = self.fig.add_axes([0.60, 0.01, 0.1, 0.04])
|
||||||
|
self.breset = Button(self.axreset, 'Reset')
|
||||||
|
self.embedded = False
|
||||||
|
else:
|
||||||
|
self.ax = ax
|
||||||
|
self.mask_alpha = 0.75
|
||||||
|
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
||||||
|
drawtype='box', button=[1], interactive=True)
|
||||||
|
self.embedded = True
|
||||||
|
self.display()
|
||||||
|
plt.ion()
|
||||||
|
|
||||||
self.ax.plot(*self.wcs.wcs.crpix, 'r+')
|
|
||||||
self.extent = np.array([0.,self.data.shape[0],0., self.data.shape[1]])
|
self.extent = np.array([0.,self.data.shape[0],0., self.data.shape[1]])
|
||||||
self.center = np.array(self.data.shape)/2
|
self.center = np.array(self.data.shape)/2
|
||||||
self.RSextent = deepcopy(self.extent)
|
self.RSextent = deepcopy(self.extent)
|
||||||
self.RScenter = deepcopy(self.center)
|
self.RScenter = deepcopy(self.center)
|
||||||
|
|
||||||
vmin, vmax = 0., np.max(self.data[self.data > 0.]*convert_flux)
|
plt.show()
|
||||||
im = self.ax.imshow(self.data*convert_flux, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno', alpha=1., origin='lower')
|
|
||||||
cbar = plt.colorbar(im, cax=cbar_ax, label=r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]")
|
|
||||||
|
|
||||||
#Selection button
|
def display(self, data=None, wcs=None, convert_flux=None):
|
||||||
self.axapply = self.fig.add_axes([0.80, 0.01, 0.1, 0.04])
|
if data is None:
|
||||||
self.bapply = Button(self.axapply, 'Apply crop')
|
data = self.data
|
||||||
self.axreset = self.fig.add_axes([0.60, 0.01, 0.1, 0.04])
|
if wcs is None:
|
||||||
self.breset = Button(self.axreset, 'Reset')
|
wcs = self.wcs
|
||||||
|
if convert_flux is None:
|
||||||
|
convert_flux = self.convert_flux
|
||||||
|
|
||||||
self.ax.set_title("Click and drag to crop to desired Region of Interest.")
|
vmin, vmax = 0., np.max(data[data > 0.]*convert_flux)
|
||||||
|
if hasattr(self, 'im'):
|
||||||
|
self.im.remove()
|
||||||
|
self.im = self.ax.imshow(data*convert_flux, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno', alpha=self.mask_alpha, origin='lower')
|
||||||
|
if hasattr(self, 'cr'):
|
||||||
|
self.cr[0].set_data(*wcs.wcs.crpix)
|
||||||
|
else:
|
||||||
|
self.cr = self.ax.plot(*wcs.wcs.crpix, 'r+')
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
return self.im
|
||||||
|
|
||||||
|
@property
|
||||||
def crpix_in_RS(self):
|
def crpix_in_RS(self):
|
||||||
crpix = self.wcs.wcs.crpix
|
crpix = self.wcs.wcs.crpix
|
||||||
x_lim, y_lim = self.RSextent[:2], self.RSextent[2:]
|
x_lim, y_lim = self.RSextent[:2], self.RSextent[2:]
|
||||||
@@ -729,64 +757,93 @@ class crop_map(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def reset_crop(self, event):
|
def reset_crop(self, event):
|
||||||
|
self.ax.reset_wcs(self.wcs)
|
||||||
|
if hasattr(self, 'hdul_crop'):
|
||||||
|
del self.hdul_crop, self.data_crop
|
||||||
|
self.display()
|
||||||
|
|
||||||
|
if self.fig.canvas.manager.toolbar.mode == '':
|
||||||
|
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
||||||
|
drawtype='box', button=[1], interactive=True)
|
||||||
|
|
||||||
self.RSextent = deepcopy(self.extent)
|
self.RSextent = deepcopy(self.extent)
|
||||||
self.RScenter = deepcopy(self.center)
|
self.RScenter = deepcopy(self.center)
|
||||||
self.ax.set_xlim(*self.extent[:2])
|
self.ax.set_xlim(*self.extent[:2])
|
||||||
self.ax.set_ylim(*self.extent[2:])
|
self.ax.set_ylim(*self.extent[2:])
|
||||||
self.rect_selector.clear()
|
|
||||||
self.fig.canvas.draw_idle()
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
def onselect_crop(self, eclick, erelease) -> None:
|
def onselect_crop(self, eclick, erelease) -> None:
|
||||||
# Obtain (xmin, xmax, ymin, ymax) values
|
# Obtain (xmin, xmax, ymin, ymax) values
|
||||||
self.RSextent = np.array(self.rect_selector.extents)
|
self.RSextent = np.array(self.rect_selector.extents)
|
||||||
self.RScenter = np.array(self.rect_selector.center)
|
self.RScenter = np.array(self.rect_selector.center)
|
||||||
|
if self.embedded:
|
||||||
|
self.apply_crop(erelease)
|
||||||
|
|
||||||
def apply_crop(self, event):
|
def apply_crop(self, event):
|
||||||
|
if hasattr(self, 'hdul_crop'):
|
||||||
|
header = self.header_crop
|
||||||
|
data = self.data_crop
|
||||||
|
wcs = self.wcs_crop
|
||||||
|
else:
|
||||||
|
header = self.header
|
||||||
|
data = self.data
|
||||||
|
wcs = self.wcs
|
||||||
|
|
||||||
vertex = self.RSextent.astype(int)
|
vertex = self.RSextent.astype(int)
|
||||||
shape = vertex[1::2] - vertex[0::2]
|
shape = vertex[1::2] - vertex[0::2]
|
||||||
#Update WCS and header in new cropped image
|
|
||||||
crpix = np.array(self.wcs.wcs.crpix)
|
|
||||||
self.wcs_crop = self.wcs.deepcopy()
|
|
||||||
self.wcs_crop.array_shape = shape
|
|
||||||
if self.crpix_in_RS():
|
|
||||||
self.wcs_crop.wcs.crpix = np.array(self.wcs_crop.wcs.crpix) - self.RSextent[::2]
|
|
||||||
else:
|
|
||||||
self.wcs_crop.wcs.crval = self.wcs.wcs_pix2world([self.RScenter],1)[0]
|
|
||||||
self.wcs_crop.wcs.crpix = self.RScenter-self.RSextent[::2]
|
|
||||||
|
|
||||||
# Crop dataset
|
extent = np.array(self.im.get_extent())
|
||||||
self.data_crop = self.data[vertex[2]:vertex[3], vertex[0]:vertex[1]]
|
shape_im = extent[1::2] - extent[0::2]
|
||||||
|
if (shape_im.astype(int) != shape).any() and (self.RSextent != self.extent).any():
|
||||||
|
#Update WCS and header in new cropped image
|
||||||
|
crpix = np.array(wcs.wcs.crpix)
|
||||||
|
self.wcs_crop = wcs.deepcopy()
|
||||||
|
self.wcs_crop.array_shape = shape
|
||||||
|
if self.crpix_in_RS:
|
||||||
|
self.wcs_crop.wcs.crpix = np.array(self.wcs_crop.wcs.crpix) - self.RSextent[::2]
|
||||||
|
else:
|
||||||
|
self.wcs_crop.wcs.crval = wcs.wcs_pix2world([self.RScenter],1)[0]
|
||||||
|
self.wcs_crop.wcs.crpix = self.RScenter-self.RSextent[::2]
|
||||||
|
|
||||||
#Write cropped map to new HDUList
|
# Crop dataset
|
||||||
self.header_crop = deepcopy(self.header)
|
self.data_crop = deepcopy(data[vertex[2]:vertex[3], vertex[0]:vertex[1]])
|
||||||
self.header_crop.update(self.wcs_crop.to_header())
|
|
||||||
self.hdul_crop = fits.HDUList([fits.PrimaryHDU(self.data_crop,self.header_crop)])
|
|
||||||
|
|
||||||
try:
|
#Write cropped map to new HDUList
|
||||||
convert_flux = self.header_crop['photflam']
|
self.header_crop = deepcopy(header)
|
||||||
except KeyError:
|
self.header_crop.update(self.wcs_crop.to_header())
|
||||||
convert_flux = 1.
|
self.hdul_crop = fits.HDUList([fits.PrimaryHDU(self.data_crop,self.header_crop)])
|
||||||
|
|
||||||
self.fig.clear()
|
try:
|
||||||
self.ax = self.fig.add_subplot(111,projection=self.wcs_crop)
|
convert_flux = self.header_crop['photflam']
|
||||||
vmin, vmax = 0., np.max(self.data_crop[self.data_crop > 0.]*convert_flux)
|
except KeyError:
|
||||||
im = self.ax.imshow(self.data_crop*convert_flux, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno', alpha=1., origin='lower')
|
convert_flux = 1.
|
||||||
self.ax.plot(*self.wcs_crop.wcs.crpix, 'r+')
|
|
||||||
cbar_ax = self.fig.add_axes([0.95, 0.12, 0.01, 0.75])
|
|
||||||
cbar = plt.colorbar(im, cax=cbar_ax, label=r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]")
|
|
||||||
xlim, ylim = self.RSextent[1::2]-self.RSextent[0::2]
|
|
||||||
self.ax.set_xlim(0,xlim)
|
|
||||||
self.ax.set_ylim(0,ylim)
|
|
||||||
self.rect_selector.clear()
|
|
||||||
|
|
||||||
|
self.rect_selector.clear()
|
||||||
|
self.ax.reset_wcs(self.wcs_crop)
|
||||||
|
self.display(data=self.data_crop, wcs=self.wcs_crop, convert_flux=convert_flux)
|
||||||
|
|
||||||
|
xlim, ylim = self.RSextent[1::2]-self.RSextent[0::2]
|
||||||
|
self.ax.set_xlim(0,xlim)
|
||||||
|
self.ax.set_ylim(0,ylim)
|
||||||
|
|
||||||
|
if self.fig.canvas.manager.toolbar.mode == '':
|
||||||
|
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
||||||
|
drawtype='box', button=[1], interactive=True)
|
||||||
self.fig.canvas.draw_idle()
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
def on_close(self, event) -> None:
|
||||||
|
if not hasattr(self, 'hdul_crop'):
|
||||||
|
self.hdul_crop = self.hdul
|
||||||
|
self.rect_selector.disconnect_events()
|
||||||
|
self.cropped = True
|
||||||
|
|
||||||
def crop(self) -> None:
|
def crop(self) -> None:
|
||||||
if self.fig.canvas.manager.toolbar.mode == '':
|
if self.fig.canvas.manager.toolbar.mode == '':
|
||||||
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
||||||
drawtype='box', button=[1], interactive=True)
|
drawtype='box', button=[1], interactive=True)
|
||||||
self.bapply.on_clicked(self.apply_crop)
|
self.bapply.on_clicked(self.apply_crop)
|
||||||
self.breset.on_clicked(self.reset_crop)
|
self.breset.on_clicked(self.reset_crop)
|
||||||
|
self.fig.canvas.mpl_connect('close_event', self.on_close)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
def writeto(self, filename):
|
def writeto(self, filename):
|
||||||
@@ -802,146 +859,384 @@ class crop_Stokes(crop_map):
|
|||||||
"""
|
"""
|
||||||
Redefine apply_crop method for the Stokes HDUList.
|
Redefine apply_crop method for the Stokes HDUList.
|
||||||
"""
|
"""
|
||||||
self.hdul_crop = deepcopy(self.hdul)
|
if hasattr(self, 'hdul_crop'):
|
||||||
|
hdul = self.hdul_crop
|
||||||
|
data = self.data_crop
|
||||||
|
wcs = self.wcs_crop
|
||||||
|
else:
|
||||||
|
hdul = self.hdul
|
||||||
|
data = self.data
|
||||||
|
wcs = self.wcs
|
||||||
|
|
||||||
vertex = self.RSextent.astype(int)
|
vertex = self.RSextent.astype(int)
|
||||||
shape = vertex[1::2] - vertex[0::2]
|
shape = vertex[1::2] - vertex[0::2]
|
||||||
#Update WCS and header in new cropped image
|
|
||||||
crpix = np.array(self.wcs.wcs.crpix)
|
|
||||||
self.wcs_crop = self.wcs.deepcopy()
|
|
||||||
self.wcs_crop.array_shape = shape
|
|
||||||
if self.crpix_in_RS():
|
|
||||||
self.wcs_crop.wcs.crpix = np.array(self.wcs_crop.wcs.crpix) - self.RSextent[::2]
|
|
||||||
else:
|
|
||||||
self.wcs_crop.wcs.crval = self.wcs.wcs_pix2world([self.RScenter],1)[0]
|
|
||||||
self.wcs_crop.wcs.crpix = self.RScenter-self.RSextent[::2]
|
|
||||||
|
|
||||||
# Crop dataset
|
extent = np.array(self.im.get_extent())
|
||||||
for dataset in self.hdul_crop:
|
shape_im = extent[1::2] - extent[0::2]
|
||||||
if dataset.header['datatype']=='IQU_cov_matrix':
|
if (shape_im.astype(int) != shape).any() and (self.RSextent != self.extent).any():
|
||||||
stokes_cov = np.zeros((3,3,shape[1],shape[0]))
|
#Update WCS and header in new cropped image
|
||||||
for i in range(3):
|
self.hdul_crop = deepcopy(hdul)
|
||||||
for j in range(3):
|
crpix = np.array(wcs.wcs.crpix)
|
||||||
stokes_cov[i,j] = dataset.data[i,j][vertex[2]:vertex[3], vertex[0]:vertex[1]]
|
self.wcs_crop = wcs.deepcopy()
|
||||||
dataset.data = stokes_cov
|
self.wcs_crop.array_shape = shape
|
||||||
|
if self.crpix_in_RS:
|
||||||
|
self.wcs_crop.wcs.crpix = np.array(self.wcs_crop.wcs.crpix) - self.RSextent[::2]
|
||||||
else:
|
else:
|
||||||
dataset.data = dataset.data[vertex[2]:vertex[3], vertex[0]:vertex[1]]
|
self.wcs_crop.wcs.crval = wcs.wcs_pix2world([self.RScenter],1)[0]
|
||||||
dataset.header.update(self.wcs_crop.to_header())
|
self.wcs_crop.wcs.crpix = self.RScenter-self.RSextent[::2]
|
||||||
|
|
||||||
try:
|
# Crop dataset
|
||||||
convert_flux = self.hdul_crop[0].header['photflam']
|
for dataset in self.hdul_crop:
|
||||||
except KeyError:
|
if dataset.header['datatype']=='IQU_cov_matrix':
|
||||||
convert_flux = 1.
|
stokes_cov = np.zeros((3,3,shape[1],shape[0]))
|
||||||
|
for i in range(3):
|
||||||
|
for j in range(3):
|
||||||
|
stokes_cov[i,j] = deepcopy(dataset.data[i,j][vertex[2]:vertex[3], vertex[0]:vertex[1]])
|
||||||
|
dataset.data = stokes_cov
|
||||||
|
else:
|
||||||
|
dataset.data = deepcopy(dataset.data[vertex[2]:vertex[3], vertex[0]:vertex[1]])
|
||||||
|
dataset.header.update(self.wcs_crop.to_header())
|
||||||
|
|
||||||
data_crop = self.hdul_crop[0].data
|
try:
|
||||||
self.fig.clear()
|
convert_flux = self.hdul_crop[0].header['photflam']
|
||||||
self.ax = self.fig.add_subplot(111,projection=self.wcs_crop)
|
except KeyError:
|
||||||
vmin, vmax = 0., np.max(data_crop[data_crop > 0.]*convert_flux)
|
convert_flux = 1.
|
||||||
im = self.ax.imshow(data_crop*convert_flux, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno', alpha=1., origin='lower')
|
|
||||||
self.ax.plot(*self.wcs_crop.wcs.crpix, 'r+')
|
|
||||||
cbar_ax = self.fig.add_axes([0.95, 0.12, 0.01, 0.75])
|
|
||||||
cbar = plt.colorbar(im, cax=cbar_ax, label=r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]")
|
|
||||||
xlim, ylim = self.RSextent[1::2]-self.RSextent[0::2]
|
|
||||||
self.ax.set_xlim(0,xlim)
|
|
||||||
self.ax.set_ylim(0,ylim)
|
|
||||||
self.rect_selector.clear()
|
|
||||||
|
|
||||||
|
self.data_crop = self.hdul_crop[0].data
|
||||||
|
self.rect_selector.clear()
|
||||||
|
if not self.embedded:
|
||||||
|
self.ax.reset_wcs(self.wcs_crop)
|
||||||
|
self.display(data=self.data_crop, wcs=self.wcs_crop, convert_flux=convert_flux)
|
||||||
|
|
||||||
|
xlim, ylim = self.RSextent[1::2]-self.RSextent[0::2]
|
||||||
|
self.ax.set_xlim(0,xlim)
|
||||||
|
self.ax.set_ylim(0,ylim)
|
||||||
|
else:
|
||||||
|
self.on_close(event)
|
||||||
|
|
||||||
|
if self.fig.canvas.manager.toolbar.mode == '':
|
||||||
|
self.rect_selector = RectangleSelector(self.ax, self.onselect_crop,
|
||||||
|
drawtype='box', button=[1], interactive=True)
|
||||||
self.fig.canvas.draw_idle()
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data_mask(self):
|
def data_mask(self):
|
||||||
return self.hdul_crop[-1].data
|
return self.hdul_crop[-1].data
|
||||||
|
|
||||||
|
class image_lasso_selector:
|
||||||
|
def __init__(self, img, fig=None, ax=None):
|
||||||
|
"""
|
||||||
|
img must have shape (X, Y)
|
||||||
|
"""
|
||||||
|
self.selected = False
|
||||||
|
self.img = img
|
||||||
|
self.vmin, self.vmax = 0., np.max(self.img[self.img>0.])
|
||||||
|
plt.ioff() # see https://github.com/matplotlib/matplotlib/issues/17013
|
||||||
|
if fig is None:
|
||||||
|
self.fig = plt.figure(figsize=(15,15))
|
||||||
|
else:
|
||||||
|
self.fig = fig
|
||||||
|
if ax is None:
|
||||||
|
self.ax = self.fig.gca()
|
||||||
|
self.mask_alpha = 1.
|
||||||
|
self.embedded = False
|
||||||
|
else:
|
||||||
|
self.ax = ax
|
||||||
|
self.mask_alpha = 0.1
|
||||||
|
self.embedded = True
|
||||||
|
self.displayed = self.ax.imshow(self.img, vmin=self.vmin, vmax=self.vmax, aspect='auto', cmap='inferno',alpha=self.mask_alpha)
|
||||||
|
plt.ion()
|
||||||
|
|
||||||
|
lineprops = {'color': 'grey', 'linewidth': 1, 'alpha': 0.8}
|
||||||
|
self.lasso = LassoSelector(self.ax, self.onselect,props=lineprops, useblit=False)
|
||||||
|
self.lasso.set_visible(True)
|
||||||
|
|
||||||
|
pix_x = np.arange(self.img.shape[0])
|
||||||
|
pix_y = np.arange(self.img.shape[1])
|
||||||
|
xv, yv = np.meshgrid(pix_y,pix_x)
|
||||||
|
self.pix = np.vstack( (xv.flatten(), yv.flatten()) ).T
|
||||||
|
|
||||||
|
self.fig.canvas.mpl_connect('close_event', self.on_close)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
def on_close(self, event=None) -> None:
|
||||||
|
if not hasattr(self, 'mask'):
|
||||||
|
self.mask = np.zeros(self.img.shape[:2],dtype=bool)
|
||||||
|
self.lasso.disconnect_events()
|
||||||
|
self.selected = True
|
||||||
|
|
||||||
|
def onselect(self, verts):
|
||||||
|
self.verts = verts
|
||||||
|
p = Path(verts)
|
||||||
|
self.indices = p.contains_points(self.pix, radius=0).reshape(self.img.shape[:2])
|
||||||
|
self.update_mask()
|
||||||
|
|
||||||
|
def update_mask(self):
|
||||||
|
self.displayed.remove()
|
||||||
|
self.displayed = self.ax.imshow(self.img, vmin=self.vmin, vmax=self.vmax, aspect='auto', cmap='inferno',alpha=self.mask_alpha)
|
||||||
|
array = self.displayed.get_array().data
|
||||||
|
|
||||||
|
self.mask = np.zeros(self.img.shape[:2],dtype=bool)
|
||||||
|
self.mask[self.indices] = True
|
||||||
|
if hasattr(self, 'cont'):
|
||||||
|
for coll in self.cont.collections:
|
||||||
|
coll.remove()
|
||||||
|
self.cont = self.ax.contour(self.mask.astype(float),levels=[0.5], colors='white', linewidths=1)
|
||||||
|
if not self.embedded:
|
||||||
|
self.displayed.set_data(array)
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
else:
|
||||||
|
self.on_close()
|
||||||
|
|
||||||
class pol_map(object):
|
class pol_map(object):
|
||||||
"""
|
"""
|
||||||
Class to interactively study polarization maps.
|
Class to interactively study polarization maps.
|
||||||
"""
|
"""
|
||||||
def __init__(self,Stokes, SNRp_cut=3., SNRi_cut=30.):
|
def __init__(self,Stokes, SNRp_cut=3., SNRi_cut=30., selection=None):
|
||||||
|
|
||||||
self.Stokes = Stokes
|
self.Stokes = deepcopy(Stokes)
|
||||||
self.wcs = deepcopy(WCS(Stokes[0].header))
|
|
||||||
self.SNRp_cut = SNRp_cut
|
self.SNRp_cut = SNRp_cut
|
||||||
self.SNRi_cut = SNRi_cut
|
self.SNRi_cut = SNRi_cut
|
||||||
self.SNRi = deepcopy(self.SNRi_cut)
|
self.SNRi = deepcopy(self.SNRi_cut)
|
||||||
self.SNRp = deepcopy(self.SNRp_cut)
|
self.SNRp = deepcopy(self.SNRp_cut)
|
||||||
self.region = None
|
self.region = None
|
||||||
|
self.data = None
|
||||||
|
self.display_selection = selection
|
||||||
|
|
||||||
#Get data
|
#Get data
|
||||||
|
self.targ = self.Stokes[0].header['targname']
|
||||||
self.pivot_wav = self.Stokes[0].header['photplam']
|
self.pivot_wav = self.Stokes[0].header['photplam']
|
||||||
self.convert_flux = self.Stokes[0].header['photflam']
|
self.convert_flux = self.Stokes[0].header['photflam']
|
||||||
self.I = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='I_stokes' for i in range(len(Stokes))])].data
|
|
||||||
self.Q = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Q_stokes' for i in range(len(Stokes))])].data
|
|
||||||
self.U = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='U_stokes' for i in range(len(Stokes))])].data
|
|
||||||
self.IQU_cov = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='IQU_cov_matrix' for i in range(len(Stokes))])].data
|
|
||||||
self.P = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_deg_debiased' for i in range(len(Stokes))])].data
|
|
||||||
self.s_P = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_deg_err' for i in range(len(Stokes))])].data
|
|
||||||
self.PA = self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_ang' for i in range(len(Stokes))])].data
|
|
||||||
|
|
||||||
#Create figure
|
#Create figure
|
||||||
fontprops = fm.FontProperties(size=16)
|
plt.rcParams.update({'font.size': 10})
|
||||||
self.fig = plt.figure(figsize=(15,15))
|
self.fig = plt.figure(figsize=(15,15))
|
||||||
self.fig.subplots_adjust(hspace=0, wspace=0, right=0.9)
|
self.fig.subplots_adjust(hspace=0, wspace=0, right=0.88)
|
||||||
self.ax = self.fig.add_subplot(111,projection=self.wcs)
|
self.ax = self.fig.add_subplot(111,projection=self.wcs)
|
||||||
self.ax.set_facecolor('black')
|
self.ax_cosmetics()
|
||||||
|
self.cbar_ax = self.fig.add_axes([0.925, 0.12, 0.01, 0.75])
|
||||||
|
|
||||||
self.ax.coords.grid(True, color='white', ls='dotted', alpha=0.5)
|
#Display selected data (Default to total flux)
|
||||||
self.ax.coords[0].set_axislabel('Right Ascension (J2000)')
|
self.display()
|
||||||
self.ax.coords[0].set_axislabel_position('t')
|
|
||||||
self.ax.coords[0].set_ticklabel_position('t')
|
|
||||||
self.ax.coords[1].set_axislabel('Declination (J2000)')
|
|
||||||
self.ax.coords[1].set_axislabel_position('l')
|
|
||||||
self.ax.coords[1].set_ticklabel_position('l')
|
|
||||||
self.ax.axis('equal')
|
|
||||||
|
|
||||||
#Display total flux
|
|
||||||
im = self.ax.imshow(self.I*self.convert_flux, vmin=0., vmax=self.I[self.I > 0.].max()*self.convert_flux, aspect='auto', cmap='inferno')
|
|
||||||
cbar_ax = self.fig.add_axes([0.95, 0.12, 0.01, 0.75])
|
|
||||||
cbar = plt.colorbar(im, cax=cbar_ax, label=r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]")
|
|
||||||
#Display polarization vectors in SNR_cut
|
#Display polarization vectors in SNR_cut
|
||||||
self.pol_vector()
|
self.pol_vector()
|
||||||
|
|
||||||
#Display scales and orientation
|
|
||||||
px_size = self.wcs.wcs.cdelt[0]*3600.
|
|
||||||
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='white', fontproperties=fontprops)
|
|
||||||
self.ax.add_artist(px_sc)
|
|
||||||
pol_sc = AnchoredSizeBar(self.ax.transData, 2., r"$P$= 100%", 4, pad=0.5, sep=5, borderpad=0.5, frameon=False, size_vertical=0.005, color='white', fontproperties=fontprops)
|
|
||||||
self.ax.add_artist(pol_sc)
|
|
||||||
north_dir = AnchoredDirectionArrows(self.ax.transAxes, "E", "N", length=-0.08, fontsize=0.025, loc=1, aspect_ratio=-1, sep_y=0.01, sep_x=0.01, back_length=0., head_length=10., head_width=10., angle=-self.Stokes[0].header['orientat'], color='white', text_props={'ec': None, 'fc': 'w', 'alpha': 1, 'lw': 0.4}, arrow_props={'ec': None,'fc':'w','alpha': 1,'lw': 1})
|
|
||||||
self.ax.add_artist(north_dir)
|
|
||||||
|
|
||||||
#Display integrated values in ROI
|
#Display integrated values in ROI
|
||||||
self.pol_int
|
self.pol_int()
|
||||||
|
|
||||||
#Set axes for sliders (SNRp_cut, SNRi_cut)
|
#Set axes for sliders (SNRp_cut, SNRi_cut)
|
||||||
ax_I_cut = self.fig.add_axes([0.125, 0.080, 0.35, 0.01])
|
ax_I_cut = self.fig.add_axes([0.125, 0.080, 0.35, 0.01])
|
||||||
ax_P_cut = self.fig.add_axes([0.125, 0.055, 0.35, 0.01])
|
ax_P_cut = self.fig.add_axes([0.125, 0.055, 0.35, 0.01])
|
||||||
ax_reset = self.fig.add_axes([0.125, 0.020, 0.05, 0.02])
|
ax_snr_reset = self.fig.add_axes([0.125, 0.020, 0.05, 0.02])
|
||||||
SNRi_max = np.max(self.I[self.IQU_cov[0,0]>0.]/np.sqrt(self.IQU_cov[0,0][self.IQU_cov[0,0]>0.]))
|
SNRi_max = np.max(self.I[self.IQU_cov[0,0]>0.]/np.sqrt(self.IQU_cov[0,0][self.IQU_cov[0,0]>0.]))
|
||||||
SNRp_max = np.max(self.P[self.s_P>0.]/self.s_P[self.s_P > 0.])
|
SNRp_max = np.max(self.P[self.s_P>0.]/self.s_P[self.s_P > 0.])
|
||||||
s_I_cut = Slider(ax_I_cut,r"$SNR^{I}_{cut}$",1.,SNRi_max,valstep=1,valinit=self.SNRi_cut)
|
s_I_cut = Slider(ax_I_cut,r"$SNR^{I}_{cut}$",1.,int(SNRi_max*0.95),valstep=1,valinit=self.SNRi_cut)
|
||||||
s_P_cut = Slider(ax_P_cut,r"$SNR^{P}_{cut}$",1.,SNRp_max,valstep=1,valinit=self.SNRp_cut)
|
s_P_cut = Slider(ax_P_cut,r"$SNR^{P}_{cut}$",1.,int(SNRp_max*0.95),valstep=1,valinit=self.SNRp_cut)
|
||||||
b_reset = Button(ax_reset,"Reset")
|
b_snr_reset = Button(ax_snr_reset,"Reset")
|
||||||
|
|
||||||
def update_snri(val):
|
def update_snri(val):
|
||||||
self.SNRi = val
|
self.SNRi = val
|
||||||
self.quiver.remove()
|
|
||||||
self.pol_vector()
|
self.pol_vector()
|
||||||
self.fig.canvas.draw_idle()
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
def update_snrp(val):
|
def update_snrp(val):
|
||||||
self.SNRp = val
|
self.SNRp = val
|
||||||
self.quiver.remove()
|
|
||||||
self.pol_vector()
|
self.pol_vector()
|
||||||
self.fig.canvas.draw_idle()
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
def reset(event):
|
def reset_snr(event):
|
||||||
s_I_cut.reset()
|
s_I_cut.reset()
|
||||||
s_P_cut.reset()
|
s_P_cut.reset()
|
||||||
|
|
||||||
s_I_cut.on_changed(update_snri)
|
s_I_cut.on_changed(update_snri)
|
||||||
s_P_cut.on_changed(update_snrp)
|
s_P_cut.on_changed(update_snrp)
|
||||||
b_reset.on_clicked(reset)
|
b_snr_reset.on_clicked(reset_snr)
|
||||||
|
|
||||||
plt.show(block=True)
|
#Set axe for ROI selection
|
||||||
|
ax_select = self.fig.add_axes([0.55, 0.070, 0.05, 0.02])
|
||||||
|
ax_roi_reset = self.fig.add_axes([0.605, 0.070, 0.05, 0.02])
|
||||||
|
b_select = Button(ax_select,"Select")
|
||||||
|
self.selected = False
|
||||||
|
b_roi_reset = Button(ax_roi_reset,"Reset")
|
||||||
|
|
||||||
|
def select_roi(event):
|
||||||
|
if self.data is None:
|
||||||
|
self.data = self.Stokes[0].data
|
||||||
|
if self.selected:
|
||||||
|
self.selected = False
|
||||||
|
self.region = deepcopy(self.select_instance.mask.astype(bool))
|
||||||
|
self.select_instance.displayed.remove()
|
||||||
|
for coll in self.select_instance.cont.collections:
|
||||||
|
coll.remove()
|
||||||
|
self.select_instance.lasso.set_active(False)
|
||||||
|
self.set_data_mask(deepcopy(self.region))
|
||||||
|
self.pol_int()
|
||||||
|
else:
|
||||||
|
self.selected = True
|
||||||
|
self.region = None
|
||||||
|
self.select_instance = image_lasso_selector(self.data, fig=self.fig, ax=self.ax)
|
||||||
|
self.select_instance.lasso.set_active(True)
|
||||||
|
k = 0
|
||||||
|
while not self.select_instance.selected and k<60:
|
||||||
|
self.fig.canvas.start_event_loop(timeout=1)
|
||||||
|
k+=1
|
||||||
|
select_roi(event)
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
def reset_roi(event):
|
||||||
|
self.region = None
|
||||||
|
self.pol_int()
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
b_select.on_clicked(select_roi)
|
||||||
|
b_roi_reset.on_clicked(reset_roi)
|
||||||
|
|
||||||
|
#Set axe for crop Stokes
|
||||||
|
ax_crop = self.fig.add_axes([0.70, 0.070, 0.05, 0.02])
|
||||||
|
ax_crop_reset = self.fig.add_axes([0.755, 0.070, 0.05, 0.02])
|
||||||
|
b_crop = Button(ax_crop,"Crop")
|
||||||
|
self.cropped = False
|
||||||
|
b_crop_reset = Button(ax_crop_reset,"Reset")
|
||||||
|
|
||||||
|
def crop(event):
|
||||||
|
if self.cropped:
|
||||||
|
self.cropped = False
|
||||||
|
self.crop_instance.im.remove()
|
||||||
|
self.crop_instance.cr.pop(0).remove()
|
||||||
|
self.crop_instance.rect_selector.set_active(False)
|
||||||
|
self.Stokes = self.crop_instance.hdul_crop
|
||||||
|
self.region = deepcopy(self.data_mask.astype(bool))
|
||||||
|
self.pol_int()
|
||||||
|
self.ax.reset_wcs(self.wcs)
|
||||||
|
self.ax_cosmetics()
|
||||||
|
self.display()
|
||||||
|
self.pol_vector()
|
||||||
|
else:
|
||||||
|
self.cropped = True
|
||||||
|
self.crop_instance = crop_Stokes(self.Stokes, fig=self.fig, ax=self.ax)
|
||||||
|
self.crop_instance.rect_selector.set_active(True)
|
||||||
|
k = 0
|
||||||
|
while not self.crop_instance.cropped and k<60:
|
||||||
|
self.fig.canvas.start_event_loop(timeout=1)
|
||||||
|
k+=1
|
||||||
|
crop(event)
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
def reset_crop(event):
|
||||||
|
self.Stokes = deepcopy(Stokes)
|
||||||
|
self.region = None
|
||||||
|
self.pol_int()
|
||||||
|
self.ax.reset_wcs(self.wcs)
|
||||||
|
self.ax_cosmetics()
|
||||||
|
self.display()
|
||||||
|
self.pol_vector()
|
||||||
|
|
||||||
|
b_crop.on_clicked(crop)
|
||||||
|
b_crop_reset.on_clicked(reset_crop)
|
||||||
|
|
||||||
|
#Set axe for saving plot
|
||||||
|
ax_save = self.fig.add_axes([0.850, 0.070, 0.05, 0.02])
|
||||||
|
b_save = Button(ax_save, "Save")
|
||||||
|
ax_text_save = self.fig.add_axes([0.3, 0.020, 0.5, 0.025],visible=False)
|
||||||
|
text_box = TextBox(ax_text_save, "Save to:", initial='')
|
||||||
|
|
||||||
|
def saveplot(event):
|
||||||
|
ax_text_save.set(visible=True)
|
||||||
|
ax_snr_reset.set(visible=False)
|
||||||
|
ax_save.set(visible=False)
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
b_save.on_clicked(saveplot)
|
||||||
|
|
||||||
|
def submit(expression):
|
||||||
|
ax_text_save.set(visible=False)
|
||||||
|
if expression != '':
|
||||||
|
save_fig = plt.figure(figsize=(15,15))
|
||||||
|
save_ax = save_fig.add_subplot(111, projection=self.wcs)
|
||||||
|
self.ax_cosmetics(ax=save_ax)
|
||||||
|
self.display(fig=save_fig,ax=save_ax)
|
||||||
|
self.pol_vector(fig=save_fig,ax=save_ax)
|
||||||
|
self.pol_int(fig=save_fig,ax=save_ax)
|
||||||
|
save_fig.suptitle(r"{0:s} with $SNR_{{p}} \geq$ {1:d} and $SNR_{{I}} \geq$ {2:d}".format(self.targ, int(self.SNRp), int(self.SNRi)))
|
||||||
|
if not expression[-4:] in ['.png', '.jpg']:
|
||||||
|
expression += '.png'
|
||||||
|
save_fig.savefig(expression, bbox_inches='tight', dpi=200)
|
||||||
|
plt.close(save_fig)
|
||||||
|
text_box.set_val('')
|
||||||
|
ax_snr_reset.set(visible=True)
|
||||||
|
ax_save.set(visible=True)
|
||||||
|
self.fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
text_box.on_submit(submit)
|
||||||
|
|
||||||
|
#Set axes for display buttons
|
||||||
|
ax_tf = self.fig.add_axes([0.925, 0.085, 0.05, 0.02])
|
||||||
|
ax_pf = self.fig.add_axes([0.925, 0.065, 0.05, 0.02])
|
||||||
|
ax_p = self.fig.add_axes([0.925, 0.045, 0.05, 0.02])
|
||||||
|
ax_snri = self.fig.add_axes([0.925, 0.025, 0.05, 0.02])
|
||||||
|
ax_snrp = self.fig.add_axes([0.925, 0.005, 0.05, 0.02])
|
||||||
|
b_tf = Button(ax_tf,r"$F_{\lambda}$")
|
||||||
|
b_pf = Button(ax_pf,r"$F_{\lambda} \cdot P$")
|
||||||
|
b_p = Button(ax_p,r"$P$")
|
||||||
|
b_snri = Button(ax_snri,r"$I / \sigma_{I}$")
|
||||||
|
b_snrp = Button(ax_snrp,r"$P / \sigma_{P}$")
|
||||||
|
|
||||||
|
def d_tf(event):
|
||||||
|
self.display_selection = 'total_flux'
|
||||||
|
self.display()
|
||||||
|
b_tf.on_clicked(d_tf)
|
||||||
|
|
||||||
|
def d_pf(event):
|
||||||
|
self.display_selection = 'pol_flux'
|
||||||
|
self.display()
|
||||||
|
b_pf.on_clicked(d_pf)
|
||||||
|
|
||||||
|
def d_p(event):
|
||||||
|
self.display_selection = 'pol_deg'
|
||||||
|
self.display()
|
||||||
|
b_p.on_clicked(d_p)
|
||||||
|
|
||||||
|
def d_snri(event):
|
||||||
|
self.display_selection = 'snri'
|
||||||
|
self.display()
|
||||||
|
b_snri.on_clicked(d_snri)
|
||||||
|
|
||||||
|
def d_snrp(event):
|
||||||
|
self.display_selection = 'snrp'
|
||||||
|
self.display()
|
||||||
|
b_snrp.on_clicked(d_snrp)
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wcs(self):
|
||||||
|
return deepcopy(WCS(self.Stokes[0].header))
|
||||||
|
@property
|
||||||
|
def I(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='I_stokes' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def Q(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Q_stokes' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def U(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='U_stokes' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def IQU_cov(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='IQU_cov_matrix' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def P(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_deg_debiased' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def s_P(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_deg_err' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def PA(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Pol_ang' for i in range(len(self.Stokes))])].data
|
||||||
|
@property
|
||||||
|
def data_mask(self):
|
||||||
|
return self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Data_mask' for i in range(len(self.Stokes))])].data
|
||||||
|
|
||||||
|
def set_data_mask(self, mask):
|
||||||
|
self.Stokes[np.argmax([self.Stokes[i].header['datatype']=='Data_mask' for i in range(len(self.Stokes))])].data = mask.astype(float)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cut(self):
|
def cut(self):
|
||||||
@@ -951,17 +1246,105 @@ class pol_map(object):
|
|||||||
SNRi_mask[s_I > 0.] = self.I[s_I > 0.] / s_I[s_I > 0.] > self.SNRi
|
SNRi_mask[s_I > 0.] = self.I[s_I > 0.] / s_I[s_I > 0.] > self.SNRi
|
||||||
return np.logical_and(SNRi_mask,SNRp_mask)
|
return np.logical_and(SNRi_mask,SNRp_mask)
|
||||||
|
|
||||||
def pol_vector(self):
|
def ax_cosmetics(self, ax=None):
|
||||||
|
if ax is None:
|
||||||
|
ax = self.ax
|
||||||
|
ax.set_facecolor('black')
|
||||||
|
|
||||||
|
ax.coords.grid(True, color='white', ls='dotted', alpha=0.5)
|
||||||
|
ax.coords[0].set_axislabel('Right Ascension (J2000)')
|
||||||
|
ax.coords[0].set_axislabel_position('t')
|
||||||
|
ax.coords[0].set_ticklabel_position('t')
|
||||||
|
ax.coords[1].set_axislabel('Declination (J2000)')
|
||||||
|
ax.coords[1].set_axislabel_position('l')
|
||||||
|
ax.coords[1].set_ticklabel_position('l')
|
||||||
|
ax.axis('equal')
|
||||||
|
|
||||||
|
#Display scales and orientation
|
||||||
|
fontprops = fm.FontProperties(size=14)
|
||||||
|
px_size = self.wcs.wcs.cdelt[0]*3600.
|
||||||
|
if hasattr(self,'px_sc'):
|
||||||
|
self.px_sc.remove()
|
||||||
|
self.px_sc = AnchoredSizeBar(ax.transData, 1./px_size, '1 arcsec', 3, pad=0.5, sep=5, borderpad=0.5, frameon=False, size_vertical=0.005, color='white', fontproperties=fontprops)
|
||||||
|
ax.add_artist(self.px_sc)
|
||||||
|
if hasattr(self,'pol_sc'):
|
||||||
|
self.pol_sc.remove()
|
||||||
|
self.pol_sc = AnchoredSizeBar(ax.transData, 2., r"$P$= 100%", 4, pad=0.5, sep=5, borderpad=0.5, frameon=False, size_vertical=0.005, color='white', fontproperties=fontprops)
|
||||||
|
ax.add_artist(self.pol_sc)
|
||||||
|
if hasattr(self,'north_dir'):
|
||||||
|
self.north_dir.remove()
|
||||||
|
self.north_dir = AnchoredDirectionArrows(ax.transAxes, "E", "N", length=-0.08, fontsize=0.025, loc=1, aspect_ratio=-1, sep_y=0.01, sep_x=0.01, back_length=0., head_length=10., head_width=10., angle=-self.Stokes[0].header['orientat'], color='white', text_props={'ec': None, 'fc': 'w', 'alpha': 1, 'lw': 0.4}, arrow_props={'ec': None,'fc':'w','alpha': 1,'lw': 1})
|
||||||
|
ax.add_artist(self.north_dir)
|
||||||
|
|
||||||
|
def display(self, fig=None, ax=None):
|
||||||
|
if self.display_selection is None:
|
||||||
|
self.display_selection = "total_flux"
|
||||||
|
|
||||||
|
if self.display_selection.lower() in ['total_flux']:
|
||||||
|
self.data = self.I*self.convert_flux
|
||||||
|
vmin, vmax = 0., np.max(self.data[self.data > 0.])
|
||||||
|
label = r"$F_{\lambda}$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]"
|
||||||
|
elif self.display_selection.lower() in ['pol_flux']:
|
||||||
|
self.data = self.I*self.convert_flux*self.P
|
||||||
|
vmin, vmax = 0., np.max(self.data[self.data > 0.])
|
||||||
|
label = r"$F_{\lambda} \cdot P$ [$ergs \cdot cm^{-2} \cdot s^{-1} \cdot \AA^{-1}$]"
|
||||||
|
elif self.display_selection.lower() in ['pol_deg']:
|
||||||
|
self.data = self.P*100.
|
||||||
|
vmin, vmax = 0., np.max(self.data[self.data > 0.])
|
||||||
|
label = r"$P$ [%]"
|
||||||
|
elif self.display_selection.lower() in ['snri']:
|
||||||
|
s_I = np.sqrt(self.IQU_cov[0,0])
|
||||||
|
SNRi = np.zeros(self.I.shape)
|
||||||
|
SNRi[s_I > 0.] = self.I[s_I > 0.]/s_I[s_I > 0.]
|
||||||
|
self.data = SNRi
|
||||||
|
vmin, vmax = 0., np.max(self.data[self.data > 0.])
|
||||||
|
label = r"$I_{Stokes}/\sigma_{I}$"
|
||||||
|
elif self.display_selection.lower() in ['snrp']:
|
||||||
|
SNRp = np.zeros(self.P.shape)
|
||||||
|
SNRp[self.s_P > 0.] = self.P[self.s_P > 0.]/self.s_P[self.s_P > 0.]
|
||||||
|
self.data = SNRp
|
||||||
|
vmin, vmax = 0., np.max(self.data[self.data > 0.])
|
||||||
|
label = r"$P/\sigma_{P}$"
|
||||||
|
|
||||||
|
if fig is None:
|
||||||
|
fig = self.fig
|
||||||
|
if ax is None:
|
||||||
|
ax = self.ax
|
||||||
|
if hasattr(self, 'im'):
|
||||||
|
self.im.remove()
|
||||||
|
self.im = ax.imshow(self.data, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno')
|
||||||
|
ax.set_xlim(0,self.data.shape[1])
|
||||||
|
ax.set_ylim(0,self.data.shape[0])
|
||||||
|
self.cbar = plt.colorbar(self.im, cax=self.cbar_ax, label=label)
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
return self.im
|
||||||
|
else:
|
||||||
|
im = ax.imshow(self.data, vmin=vmin, vmax=vmax, aspect='auto', cmap='inferno')
|
||||||
|
ax.set_xlim(0,self.data.shape[1])
|
||||||
|
ax.set_ylim(0,self.data.shape[0])
|
||||||
|
plt.colorbar(im, pad=0.025, aspect=80, label=label)
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
|
||||||
|
def pol_vector(self, fig=None, ax=None):
|
||||||
P_cut = np.ones(self.P.shape)*np.nan
|
P_cut = np.ones(self.P.shape)*np.nan
|
||||||
P_cut[self.cut] = self.P[self.cut]
|
P_cut[self.cut] = self.P[self.cut]
|
||||||
X, Y = np.meshgrid(np.arange(self.I.shape[1]),np.arange(self.I.shape[0]))
|
X, Y = np.meshgrid(np.arange(self.I.shape[1]),np.arange(self.I.shape[0]))
|
||||||
XY_U, XY_V = P_cut*np.cos(np.pi/2. + self.PA*np.pi/180.), P_cut*np.sin(np.pi/2. + self.PA*np.pi/180.)
|
XY_U, XY_V = P_cut*np.cos(np.pi/2. + self.PA*np.pi/180.), P_cut*np.sin(np.pi/2. + self.PA*np.pi/180.)
|
||||||
|
|
||||||
self.quiver = self.ax.quiver(X, Y, XY_U, XY_V, units='xy', scale=0.5, scale_units='xy', pivot='mid', headwidth=0., headlength=0., headaxislength=0., width=0.1, color='white')
|
if fig is None:
|
||||||
return self.quiver
|
fig = self.fig
|
||||||
|
if ax is None:
|
||||||
|
ax = self.ax
|
||||||
|
if hasattr(self, 'quiver'):
|
||||||
|
self.quiver.remove()
|
||||||
|
self.quiver = ax.quiver(X, Y, XY_U, XY_V, units='xy', scale=0.5, scale_units='xy', pivot='mid', headwidth=0., headlength=0., headaxislength=0., width=0.1, color='white')
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
return self.quiver
|
||||||
|
else:
|
||||||
|
ax.quiver(X, Y, XY_U, XY_V, units='xy', scale=0.5, scale_units='xy', pivot='mid', headwidth=0., headlength=0., headaxislength=0., width=0.1, color='white')
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
|
||||||
@property
|
def pol_int(self, fig=None, ax=None):
|
||||||
def pol_int(self):
|
|
||||||
if self.region is None:
|
if self.region is None:
|
||||||
n_pix = self.I.size
|
n_pix = self.I.size
|
||||||
s_I = np.sqrt(self.IQU_cov[0,0])
|
s_I = np.sqrt(self.IQU_cov[0,0])
|
||||||
@@ -996,4 +1379,24 @@ class pol_map(object):
|
|||||||
PA_reg = princ_angle((90./np.pi)*np.arctan2(U_reg,Q_reg))
|
PA_reg = princ_angle((90./np.pi)*np.arctan2(U_reg,Q_reg))
|
||||||
PA_reg_err = (90./(np.pi*(Q_reg**2+U_reg**2)))*np.sqrt(U_reg**2*Q_reg_err**2 + Q_reg**2*U_reg_err**2 - 2.*Q_reg*U_reg*QU_reg_err)
|
PA_reg_err = (90./(np.pi*(Q_reg**2+U_reg**2)))*np.sqrt(U_reg**2*Q_reg_err**2 + Q_reg**2*U_reg_err**2 - 2.*Q_reg*U_reg*QU_reg_err)
|
||||||
|
|
||||||
return self.ax.annotate(r"$F_{{\lambda}}^{{int}}$({0:.0f} $\AA$) = {1} $ergs \cdot cm^{{-2}} \cdot s^{{-1}} \cdot \AA^{{-1}}$".format(self.pivot_wav,sci_not(I_reg*self.convert_flux,I_reg_err*self.convert_flux,2))+"\n"+r"$P^{{int}}$ = {0:.1f} $\pm$ {1:.1f} %".format(P_reg*100.,P_reg_err*100.)+"\n"+r"$\theta_{{P}}^{{int}}$ = {0:.1f} $\pm$ {1:.1f} °".format(PA_reg,PA_reg_err), color='white', fontsize=12, xy=(0.01, 0.90), xycoords='axes fraction')
|
if hasattr(self, 'cont'):
|
||||||
|
for coll in self.cont.collections:
|
||||||
|
coll.remove()
|
||||||
|
del self.cont
|
||||||
|
if fig is None:
|
||||||
|
fig = self.fig
|
||||||
|
if ax is None:
|
||||||
|
ax = self.ax
|
||||||
|
if hasattr(self, 'an_int'):
|
||||||
|
self.an_int.remove()
|
||||||
|
self.an_int = ax.annotate(r"$F_{{\lambda}}^{{int}}$({0:.0f} $\AA$) = {1} $ergs \cdot cm^{{-2}} \cdot s^{{-1}} \cdot \AA^{{-1}}$".format(self.pivot_wav,sci_not(I_reg*self.convert_flux,I_reg_err*self.convert_flux,2))+"\n"+r"$P^{{int}}$ = {0:.1f} $\pm$ {1:.1f} %".format(P_reg*100.,P_reg_err*100.)+"\n"+r"$\theta_{{P}}^{{int}}$ = {0:.1f} $\pm$ {1:.1f} °".format(PA_reg,PA_reg_err), color='white', fontsize=12, xy=(0.01, 0.90), xycoords='axes fraction')
|
||||||
|
if not self.region is None:
|
||||||
|
self.cont = ax.contour(self.region.astype(float),levels=[0.5], colors='white', linewidths=0.8)
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
return self.an_int
|
||||||
|
else:
|
||||||
|
ax.annotate(r"$F_{{\lambda}}^{{int}}$({0:.0f} $\AA$) = {1} $ergs \cdot cm^{{-2}} \cdot s^{{-1}} \cdot \AA^{{-1}}$".format(self.pivot_wav,sci_not(I_reg*self.convert_flux,I_reg_err*self.convert_flux,2))+"\n"+r"$P^{{int}}$ = {0:.1f} $\pm$ {1:.1f} %".format(P_reg*100.,P_reg_err*100.)+"\n"+r"$\theta_{{P}}^{{int}}$ = {0:.1f} $\pm$ {1:.1f} °".format(PA_reg,PA_reg_err), color='white', fontsize=12, xy=(0.01, 0.94), xycoords='axes fraction')
|
||||||
|
if not self.region is None:
|
||||||
|
ax.contour(self.region.astype(float),levels=[0.5], colors='white', linewidths=0.8)
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
from astropy.io import fits
|
from astropy.io import fits
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from plots import overplot_radio
|
from lib.plots import overplot_radio
|
||||||
|
|
||||||
Stokes_UV = fits.open("../../data/IC5063_x3nl030/IC5063_FOC_combine_FWHM020.fits")
|
Stokes_UV = fits.open("../../data/IC5063_x3nl030/IC5063_FOC_combine_FWHM020.fits")
|
||||||
Stokes_18GHz = fits.open("../../data/IC5063_x3nl030/radio/IC5063.18GHz.fits")
|
Stokes_18GHz = fits.open("../../data/IC5063_x3nl030/radio/IC5063.18GHz.fits")
|
||||||