/
clump_imag_velocity_apl.py
executable file
·294 lines (252 loc) · 11.9 KB
/
clump_imag_velocity_apl.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/usr/bin/python3
# copy from clump_plot_all.py
# to only create the overall image with leaves and branches on m0 map
# choose to overlay sources in csv catalog
import argparse, os, time, copy
import aplpy
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from astropy.coordinates import SkyCoord, Galactic
from astropy.io import fits
#from astropy import units as u
from astrodendro import Dendrogram
#from toolkit import smooth
#mpl.rcParams['xtick.labelsize']='xx-large'
#mpl.rcParams['ytick.labelsize']='xx-large'
def plot_image(file_fits,file_velo,file_out=None,file_sour=None,file_contour=None,file_reg=None,\
resize=None,contour=False,levels=None,contour_color='#d0d0d0',plot=False,oformat='png',\
skycoor='equ',vmin=None,vmax=None,pmin=0.25,pmax=99.75,stretch='linear',vmid=None,\
exponent=2,beam=None,colorbar=None,dendro=None,addgal=True,save=True):
fig = aplpy.FITSFigure(file_fits)
fig.show_colorscale(vmin=vmin,vmax=vmax,pmin=pmin,pmax=pmax,aspect='equal',smooth=1,stretch=stretch,vmid=vmid,exponent=exponent)
fig.hide_colorscale()
# fig.hide_colorscale()
if resize is not None:
fig.recenter(resize[0],resize[1],width=resize[2],height=resize[3])
#-------------------------------------------------------------------
# ADD beam
if beam is not None:
fig.add_beam(major=beam/60,minor=beam/60,angle=0,corner='bottom left')
#fig.beam.set_alpha(0.5)
fig.beam.set_edgecolor('black')
fig.beam.set_facecolor('white')
fig.beam.set_linewidth(1.5)
#-------------------------------------------------------------------
# fig.show_circles([50.05,], [-0.85,], 0.028,color='white',linewidth=1)
# fig.add_label(50.05, -0.95,"FWHM 3.4'",color='white')
#-------------------------------------------------------------------
if addgal:
l = np.arange(30,70,0.05)
b0 = np.zeros(int((70-30)/0.05))
bp = np.zeros(int((70-30)/0.05)) + 0.5
bm = np.zeros(int((70-30)/0.05)) - 0.5
gal_c0 = SkyCoord(l,b0,frame=Galactic,unit="deg")
gal_cp = SkyCoord(l,bp,frame=Galactic,unit="deg")
gal_cm = SkyCoord(l,bm,frame=Galactic,unit="deg")
ra0 = gal_c0.icrs.ra.value
rap = gal_cp.icrs.ra.value
ram = gal_cm.icrs.ra.value
dec0 = gal_c0.icrs.dec.value
decp = gal_cp.icrs.dec.value
decm = gal_cm.icrs.dec.value
fig.show_lines([np.array([ra0,dec0]),np.array([rap,decp]),np.array([ram,decm])], \
color='darkgrey', linewidths=2, linestyle=['-','--','--'])
fig.add_label(283.95, 2.18,r"b=$0^{\circ}$",color='black',fontsize=14)
fig.add_label(283.38, 2.18,r"b=$0.5^{\circ}$",color='black',fontsize=14)
fig.add_label(284.42, 1.8,r"b=$-0.5^{\circ}$",color='black',fontsize=14)
if skycoor == 'gal':
fig.axis_labels.set_xtext('Galactic Longitude')
fig.axis_labels.set_ytext('Galactic Latitude')
fig.tick_labels.set_xformat('dd.d')
fig.tick_labels.set_yformat('dd.d')
fig.ticks.set_xspacing(0.5)
fig.ticks.set_yspacing(0.5)
#fig.ticks.set_minor_frequency(5)
else:
z=0
fig.axis_labels.set_font(size='xx-large')
fig.tick_labels.set_font(size='xx-large')
fig.ticks.show_x()
fig.ticks.show_y()
fig.ticks.set_linewidth(1)
fig.ticks.set_length(2)
fig.ticks.set_color('black')
fig.ticks.show()
if colorbar is not None:
fig.add_colorbar()
fig.colorbar.show()
fig.colorbar.set_axis_label_text(colorbar)
fig.colorbar.set_axis_label_font(size='xx-large')
fig.colorbar.set_font(size='xx-large')
#-------------------------------------------
# DS9 regions
if file_reg is not None:
fig.show_regions(file_reg)
#-------------------------------------------
# add contour
#-------------------------------------------
if contour:
if levels is not None:
if file_contour is None:
file_contour = file_fits
fig.show_contour(file_contour,levels=levels,smooth=1,colors=contour_color, linewidths=1)
else:
print("contour levels is not set")
#------------------------
# Plot all leaves and branches on full frame of Moment0 map.
#------------------------
# ------------------------
# leaf label
list_idx = [] # raw index
list_idv = [] # sorted index
list_peak= [] # raw peaks
for i, struc in enumerate(dendro.leaves):
peak = struc.get_peak()[1]
list_peak.append(peak)
list_idx.append(struc.idx)
peak_ind = np.argsort(np.array(list_peak))[::-1]
leaves_idx_arr = np.array(list_idx)[peak_ind]
# ------------------------
colors = ['blue','red','green']
v_cmap = copy.copy(mpl.cm.get_cmap('viridis'))
v_cmap = copy.copy(mpl.cm.get_cmap('plasma'))
v_cmap = copy.copy(mpl.cm.get_cmap('cividis'))
v_cmap = copy.copy(mpl.cm.get_cmap('seismic'))
v_cmap = copy.copy(mpl.cm.get_cmap('Reds'))
v_cmap = copy.copy(mpl.cm.get_cmap('coolwarm'))
cata_velo = load_csv(file_velo)
add_source_velo(fig,cata_velo)
norm = mpl.colors.Normalize(vmin=45,vmax=60)
count_branch=0
for i, struc in enumerate(dendro.trunk):
if struc.is_leaf:
leaf_label = add_leaf_label(fig,leaves_idx_arr,struc,draw=False)
leaf_velo = get_source_velo(leaf_label,cata_velo)
color = colors[0]
subtree = []
line = 'solid'
mask = struc.get_mask().mean(axis=0)
if leaf_label == 19:
continue
fig.show_contour(mask,levels=[0.001,1000],alpha=0.95,filled=True,colors=[v_cmap(norm(leaf_velo))],linestyles=line)#,smooth=1)
elif struc.is_branch: # branch
count_branch=count_branch+1
color=colors[count_branch]
subtree = struc.descendants
line = 'dashed'
for j, sub_struc in enumerate(subtree):
if sub_struc.is_leaf:
leaf_label = add_leaf_label(fig,leaves_idx_arr,sub_struc,draw=False)
leaf_velo = get_source_velo(leaf_label,cata_velo)
if leaf_label == 14 or leaf_label == 15:
continue
mask = sub_struc.get_mask().mean(axis=0)
fig.show_contour(mask,levels=[0.001,1000],alpha=0.95,filled=True,colors=[v_cmap(norm(leaf_velo))])#,smooth=1)
# add sources in catalog
if file_sour is not None:
add_source(fig,file_sour,v_cmap,norm)
if save:
if file_out is None:
file_out='clumps_velo_dist.png'
fig.save(file_out,dpi=300,format=oformat,adjust_bbox=True)
if plot:
plt.show()
fig.close()
return 0
def add_leaf_label(fig, idx_arr, struc,draw=True):
leaf_label = np.argwhere(idx_arr == struc.idx)[0][0]+1
peak = struc.get_peak()[0]
x_p = peak[2]
y_p = peak[1]
xw, yw = fig.pixel2world(x_p-1,y_p+1)
if draw:
fig.add_label(float(xw),float(yw),str(leaf_label),fontsize='x-large',color='k')
return leaf_label
def load_csv(file_csv):
import csv
catalog=[]
with open(file_csv,'rt') as fcsv:
reader = csv.DictReader(fcsv)
for row in reader:
catalog.append({'Index':int(row['Index']),'GLon':float(row['GLon']),'GLat':float(row['GLat']),'VLSR':float(row['VLSR'])})
return catalog
def get_source_velo(ind0, catalog):
for item in catalog:
v = item['VLSR']
ind = item['Index']
if ind == ind0:
return v
print('Index not matching with Catalog, -1')
return -1
def add_source(fig, file_catalog,cmap,norm):
catalog = load_csv(file_catalog)
for item in catalog:
l = item['GLon']
b = item['GLat']
v = item['VLSR']
ind = item['Index']
if ind == 3:
offset = -0.03
else:
offset = 0.03
pos = SkyCoord(l,b,frame=Galactic,unit='deg')
#fig.show_markers(pos.icrs.ra.value, pos.icrs.dec.value,marker='o',s=200,facecolor=cmap(norm(v)))
fig.show_markers(pos.icrs.ra.value, pos.icrs.dec.value,marker='o',s=100,edgecolor='gray',facecolor='green')
fig.add_label(pos.icrs.ra.value, pos.icrs.dec.value+offset,'{:4.1f}'.format(v),fontsize=12,color='green')
def add_source_velo(fig, catalog):
for item in catalog:
l = item['GLon']
b = item['GLat']
v = item['VLSR']
ind = item['Index']
pos = SkyCoord(l,b,frame=Galactic,unit='deg')
if ind == 14 or ind == 15 or ind == 19:
continue
fig.add_label(pos.icrs.ra.value, pos.icrs.dec.value,'{:4.1f}'.format(v),fontsize='x-large',color='k')
def main(args):
#------------------------
# Load dendrogram
#------------------------
print('Load Dendrogram')
d = Dendrogram.load_from(args.file_dend+'.hdf5')
print('')
plot_image(args.file_map,args.file_velo,file_out=args.file_out,file_reg=args.file_reg,file_contour=args.file_contour,\
plot=args.plot,save=args.save,oformat=args.format,resize=args.resize,\
contour=args.contour,contour_color=args.contour_color,\
levels=args.levels,skycoor=args.skycoor,beam=args.beam,\
vmin=args.vmin,vmax=args.vmax,pmin=args.pmin,pmax=args.pmax,\
stretch=args.stretch,\
dendro=d,file_sour=args.file_sour)
return 0
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('file_map', type=str, help='the input data file')
parser.add_argument('file_velo', type=str, help='the catalog file to add source on map')
parser.add_argument('file_dend', type=str, default='my_dendrogram', help='the dendrogram file')
parser.add_argument('--file_sour', type=str, help='the catalog file to add source on map')
parser.add_argument('--chan_0', type=int, default=0, help='channel index start')
parser.add_argument('--chan_1', type=int, default=-1, help='channel index end')
parser.add_argument('--beam', type=float, help='set to add beam to image, size in pixel. 4.7 for FAST rrl cube')
parser.add_argument('--proj', type=str, default='equ', help='equ or gal, projection of the map coordinate system')
parser.add_argument('--file_out', type=str, help='Output file name for the figure')
parser.add_argument('--file_contour', type=str, help='File name for the contour, use file_in if not set')
parser.add_argument('--file_reg', type=str, help='DS9 region file to plot')
parser.add_argument('--format', type=str, default='png', help='output file format')
parser.add_argument('--skycoor', type=str, default='equ', help='sky coordinate system')
parser.add_argument('--resize', metavar='Deg', type=float, nargs=4, help='resize the map: x_center, y_center, x_size, y_size')
parser.add_argument('--contour', action='store_true', help='set to add contour')
parser.add_argument('--levels', nargs='+', type=float, help='set contour levels')
parser.add_argument('--contour_color', type=str, default='#d0d0d0', help='contour color')
parser.add_argument('--plot', action='store_true', help='set to show plot')
parser.add_argument('--save', action='store_true', help='set to save plot')
parser.add_argument('--vmin', type=float, help='Minimum pixel value to use for the colorscale.')
parser.add_argument('--vmax', type=float, help='Maximum pixel value to use for the colorscale.')
parser.add_argument('--colorbar', type=str, help='the colorbar title if is to show')
parser.add_argument('--pmin', type=float, help='Percentile value used to determine the Minimum pixel value to use for the colorscale.')
parser.add_argument('--pmax', type=float, help='Percentile value used to determine the Maximum pixel value to use for the colorscale.')
parser.add_argument('--stretch', type=str, default='linear', help='the stretch function to use')
args = parser.parse_args()
start_time = time.time()
main(args)
print("--- {:.3f} seconds ---".format(time.time() - start_time))