-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunctions_lic.py
149 lines (120 loc) · 4.83 KB
/
functions_lic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import aplpy
import numpy as np
import matplotlib.pyplot as plt
import astropy.wcs as wcs
from astropy.io import fits
from licpy.lic import runlic
def astroLIC(I_dir,Q_dir,U_dir,length=0.25,toIAU=False,wcs=True):
'''
Runs the astro-LIC package.
Input
I_dir : path to Stokes I file [str]
Q_fir : path to Stokes Q file [str]
U_dir : path to Stokes U file [str]
length : fraction of image length to compute LIC across [default=0.25]
toIAU : if True, convert Stokes Q and U to IAU convention [default=False]
wcs : if True, plot results using WCS as defined by the Stokes I FITS header [default=True]
'''
# extract Stokes images
I_data = fits.getdata(I_dir)
Q_data = fits.getdata(Q_dir)
U_data = fits.getdata(U_dir)
# compute the plane-of-sky magnetic field orientation in IAU convention
Bangle = fBangle(Q_data,U_data,toIAU=toIAU)
# compute the LIC texture
texture = fLICtexture(Bangle,length)
# plot!
fplotLIC(I_dir,texture,wcs)
def fBangle(Q_data,U_data,toIAU=False):
'''
Computes the plane-of-sky magnetic field angle. Stokes maps must be in IAU convention!
Input
Q_data : Stokes Q map [float]
U_data : Stokes U map [float]
toIAU : if True, converts Stokes Q and U maps from COSMO to IAU convention [default=False]
Output
Bangle : magnetic field angles between 0 and pi [radians]
'''
# copy to ensure we're not rotating original data
Q = np.copy(Q_data)
U = np.copy(U_data)
# flip both Q and U to convert from electric field to magnetic field orientation
Q *= -1.
U *= -1.
if toIAU==True:
# if converting from COSMOS to IAU convention, flip sign of Stokes U
U *= -1.
# compute magnetic field angle on the domain [0,pi)
Bangle = np.mod(0.5*np.arctan2(U,Q), np.pi)
return Bangle
def fLICtexture(Bangle,length=0.25):
'''
Computes the LIC texture to be overplotted on an image using LicPy.
Input
Bangle : plane-of-sky magnetic field angles on the domain 0 and pi [radians]
length : fraction of image length to compute LIC across [default=0.25]
Output
texture : LIC texture [float]
'''
# LIC measures angles from the horizontal while IAU polarization angles are
# measured from the vertical; this translates the magnetic field angle accordingly
Bangle += (np.pi/2.)
# x- and y-components of magnetic field
b_x = np.sin(Bangle)
b_y = np.cos(Bangle)
# length scale; typically 25% of image size but can be adjusted
L_z = np.shape(Bangle)
L = int(length*L_z[0])
# run licpy for texture
texture = runlic(b_x,b_y,L)
return texture
def fplotLIC(I_dir,texture,wcs=True):
'''
Plots the LIC texture overlaid on the Stokes I image and saves the image in the working directory with "_LIC.pdf" appended to the file name.
Input:
I_file : path to Stokes I file [str]
texture : LIC texture [float]
wcs : if True, plots using the WCS defined by the Stokes I header [default=True]
'''
# extract Stokes I data
I_data = fits.getdata(I_dir)
if wcs==True:
# use WCS defined by Stokes I FITS header
fig = plt.figure(figsize=(5,5))
f1 = aplpy.FITSFigure(I_dir,figure=fig,subplot=(1,1,1))
f1.show_colorscale(cmap="plasma")
# texture
plt.imshow(texture, origin="lower",alpha=0.4,cmap="binary",clim=[np.mean(texture)-np.std(texture),np.mean(texture)+np.std(texture)])
# axis labels
f1.axis_labels.set_font(size=20)
# tick labels
f1.tick_labels.show()
f1.tick_labels.set_font(size=20)
# colour bar
f1.add_colorbar()
f1.colorbar.set_axis_label_text(r"$I_{353}\,(\mathrm{MJy/sr})$")
f1.colorbar.set_axis_label_font(size=20)
# remove whitespace
plt.subplots_adjust(top=1,bottom=0,right=1,left=0,hspace=0,wspace=0)
# save + show
fig.canvas.draw()
f1.save(I_dir.split(".fits")[0]+"_LIC.pdf")
else:
# use pixel coordinates
fig = plt.figure(figsize=(6,4))
ax = fig.add_subplot(111)
im = ax.imshow(I_data,cmap="plasma",origin="lower")
plt.imshow(texture, origin="lower",alpha=0.4,cmap="binary",clim=[np.mean(texture)-np.std(texture),np.mean(texture)+np.std(texture)])
# axis labels
plt.xlabel("x (pixels)",fontsize=20)
plt.ylabel("y (pixels)",fontsize=20)
# tick labels
ax.tick_params(axis="both",which="major",labelsize=15)
# colour bar
cbar = plt.colorbar(im,ax=ax,orientation="vertical")
cbar.set_label(r"$I_{353}\,(\mathrm{MJy/sr})$",fontsize=20)
# remove whitespace
plt.subplots_adjust(top=1,bottom=0,right=1,left=0.1,hspace=0,wspace=0)
# save + show
plt.savefig(I_dir.split(".fits")[0]+"_LIC.pdf")
plt.show()