pymakeplots 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymakeplots/pymakeplots.py +151 -96
- {pymakeplots-0.2.1.dist-info → pymakeplots-0.2.2.dist-info}/METADATA +1 -1
- pymakeplots-0.2.2.dist-info/RECORD +9 -0
- pymakeplots-0.2.1.dist-info/RECORD +0 -9
- {pymakeplots-0.2.1.dist-info → pymakeplots-0.2.2.dist-info}/LICENSE.md +0 -0
- {pymakeplots-0.2.1.dist-info → pymakeplots-0.2.2.dist-info}/WHEEL +0 -0
- {pymakeplots-0.2.1.dist-info → pymakeplots-0.2.2.dist-info}/top_level.txt +0 -0
- {pymakeplots-0.2.1.dist-info → pymakeplots-0.2.2.dist-info}/zip-safe +0 -0
pymakeplots/pymakeplots.py
CHANGED
|
@@ -12,8 +12,8 @@ from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
|
12
12
|
from matplotlib.patches import Ellipse,Rectangle
|
|
13
13
|
from matplotlib import cm
|
|
14
14
|
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
|
|
15
|
-
from matplotlib.offsetbox import AnchoredText
|
|
16
|
-
from mpl_toolkits.axes_grid1.anchored_artists import
|
|
15
|
+
from matplotlib.offsetbox import AnchoredText,AuxTransformBox, AnchoredOffsetbox
|
|
16
|
+
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
|
|
17
17
|
from astropy.coordinates import ICRS
|
|
18
18
|
import matplotlib.gridspec as gridspec
|
|
19
19
|
from astropy.table import Table
|
|
@@ -23,6 +23,8 @@ import warnings
|
|
|
23
23
|
from spectral_cube import SpectralCube
|
|
24
24
|
from spectral_cube.utils import SpectralCubeWarning
|
|
25
25
|
warnings.filterwarnings(action='ignore', category=SpectralCubeWarning, append=True)
|
|
26
|
+
from scipy.stats import mode
|
|
27
|
+
|
|
26
28
|
|
|
27
29
|
def running_mean(x, N):
|
|
28
30
|
cumsum = np.cumsum(np.insert(x, 0, 0))
|
|
@@ -38,7 +40,7 @@ def rotateImage(img, angle, pivot):
|
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
class pymakeplots:
|
|
41
|
-
def __init__(self,cube_flat=None,pb=None,cube=None):
|
|
43
|
+
def __init__(self,cube_flat=None,pb=None,cube=None,rest_value=None):
|
|
42
44
|
self.galname=None
|
|
43
45
|
self.gal_distance=None
|
|
44
46
|
self.posang=None
|
|
@@ -88,24 +90,27 @@ class pymakeplots:
|
|
|
88
90
|
self.flipped=False
|
|
89
91
|
self.make_square=True
|
|
90
92
|
self.useallpixels = False
|
|
93
|
+
self.suppress_subbeam_artifacts=False
|
|
91
94
|
#self.wcs=None
|
|
92
95
|
|
|
93
96
|
if (cube != None)&(pb==None)&(cube_flat==None):
|
|
94
97
|
# only one cube given
|
|
95
|
-
self.input_cube_nopb(cube)
|
|
98
|
+
self.input_cube_nopb(cube,rest_value=rest_value)
|
|
96
99
|
|
|
97
100
|
if (cube != None)&(pb!=None):
|
|
98
101
|
# pbcorred cube and pb given
|
|
99
|
-
self.input_cube_pbcorr(cube,pb)
|
|
102
|
+
self.input_cube_pbcorr(cube,pb,rest_value=rest_value)
|
|
100
103
|
|
|
101
104
|
if (cube_flat != None)&(pb!=None):
|
|
102
105
|
# flat cube and pb given
|
|
103
106
|
if np.any(self.pbcorr_cube) == None: #check if the user gave all three cubes, in which case this call is redundant
|
|
104
|
-
self.input_cube_flat(cube_flat,pb)
|
|
107
|
+
self.input_cube_flat(cube_flat,pb,rest_value=rest_value)
|
|
105
108
|
|
|
106
109
|
if (cube != None)&(pb==None)&(cube_flat!=None):
|
|
107
110
|
# pbcorred cube and flat cube given
|
|
108
|
-
self.input_cube_pbcorr_and_flat(cube,cube_flat)
|
|
111
|
+
self.input_cube_pbcorr_and_flat(cube,cube_flat,rest_value=rest_value)
|
|
112
|
+
|
|
113
|
+
self.cube_for_param_guesses=self.flat_cube
|
|
109
114
|
|
|
110
115
|
def vsystrans_inv(self,val):
|
|
111
116
|
return val +self.vsys
|
|
@@ -129,21 +134,21 @@ class pymakeplots:
|
|
|
129
134
|
def beam_area(self):
|
|
130
135
|
return (np.pi*(self.bmaj/self.cellsize)*(self.bmin/self.cellsize))/(4*np.log(2))
|
|
131
136
|
|
|
132
|
-
def input_cube_pbcorr(self,path_to_pbcorr_cube,path_to_pb):
|
|
137
|
+
def input_cube_pbcorr(self,path_to_pbcorr_cube,path_to_pb,rest_value=None):
|
|
133
138
|
|
|
134
|
-
self.pbcorr_cube = self.read_primary_cube(path_to_pbcorr_cube)
|
|
139
|
+
self.pbcorr_cube = self.read_primary_cube(path_to_pbcorr_cube,rest_value=rest_value)
|
|
135
140
|
|
|
136
|
-
pb,hdr,_= self.read_in_a_cube(path_to_pb)
|
|
141
|
+
pb,hdr,_= self.read_in_a_cube(path_to_pb,rest_value=rest_value)
|
|
137
142
|
if self.flipped: pb=np.flip(pb,axis=2)
|
|
138
143
|
|
|
139
144
|
self.flat_cube = self.pbcorr_cube*pb
|
|
140
145
|
|
|
141
146
|
|
|
142
|
-
def input_cube_flat(self,path_to_flat_cube,path_to_pb):
|
|
147
|
+
def input_cube_flat(self,path_to_flat_cube,path_to_pb,rest_value=None):
|
|
143
148
|
|
|
144
|
-
self.flat_cube = self.read_primary_cube(path_to_flat_cube)
|
|
149
|
+
self.flat_cube = self.read_primary_cube(path_to_flat_cube,rest_value=rest_value)
|
|
145
150
|
|
|
146
|
-
pb,hdr,_= self.read_in_a_cube(path_to_pb)
|
|
151
|
+
pb,hdr,_= self.read_in_a_cube(path_to_pb,rest_value=rest_value)
|
|
147
152
|
if self.flipped: pb=np.flip(pb,axis=2)
|
|
148
153
|
|
|
149
154
|
self.pbcorr_cube = self.flat_cube.copy()*0.0
|
|
@@ -151,25 +156,25 @@ class pymakeplots:
|
|
|
151
156
|
|
|
152
157
|
|
|
153
158
|
|
|
154
|
-
def input_cube_nopb(self,path_to_cube):
|
|
159
|
+
def input_cube_nopb(self,path_to_cube,rest_value=None):
|
|
155
160
|
|
|
156
|
-
self.pbcorr_cube = self.read_primary_cube(path_to_cube)
|
|
161
|
+
self.pbcorr_cube = self.read_primary_cube(path_to_cube,rest_value=rest_value)
|
|
157
162
|
|
|
158
163
|
self.flat_cube = self.pbcorr_cube
|
|
159
164
|
|
|
160
165
|
|
|
161
166
|
|
|
162
|
-
def input_cube_pbcorr_and_flat(self,path_to_pbcorr_cube,path_to_flat_cube):
|
|
167
|
+
def input_cube_pbcorr_and_flat(self,path_to_pbcorr_cube,path_to_flat_cube,rest_value=None):
|
|
163
168
|
|
|
164
|
-
self.pbcorr_cube = self.read_primary_cube(path_to_pbcorr_cube)
|
|
169
|
+
self.pbcorr_cube = self.read_primary_cube(path_to_pbcorr_cube,rest_value=rest_value)
|
|
170
|
+
|
|
171
|
+
self.flat_cube,hdr,_ = self.read_in_a_cube(path_to_flat_cube,rest_value=rest_value)
|
|
165
172
|
|
|
166
|
-
self.flat_cube,hdr,_ = self.read_in_a_cube(path_to_flat_cube)
|
|
167
173
|
if self.flipped: self.flat_cube=np.flip(self.flat_cube,axis=2)
|
|
168
174
|
|
|
169
175
|
def smooth_mask(self,cube):
|
|
170
176
|
"""
|
|
171
177
|
Apply a Gaussian blur, using sigma = 4 in the velocity direction (seems to work best), to the uncorrected cube.
|
|
172
|
-
The mode 'nearest' seems to give the best results.
|
|
173
178
|
:return: (ndarray) mask to apply to the un-clipped cube
|
|
174
179
|
"""
|
|
175
180
|
sigma = 1.5 * self.bmaj / self.cellsize
|
|
@@ -178,9 +183,14 @@ class pymakeplots:
|
|
|
178
183
|
self.cliplevel=self.rms*self.rmsfac
|
|
179
184
|
self.maskcliplevel=newrms*self.rmsfac
|
|
180
185
|
mask=(smooth_cube > self.maskcliplevel)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
|
|
187
|
+
if self.suppress_subbeam_artifacts:
|
|
188
|
+
label,cnt=ndimage.label(mask)#.sum(axis=2))
|
|
189
|
+
hist,lab=np.histogram(label,bins=np.arange(cnt+1))
|
|
190
|
+
beampix=(self.bmaj*self.bmin)/(self.cellsize**2)
|
|
191
|
+
for thelabel in lab[0:-1][hist<(beampix*self.suppress_subbeam_artifacts)]:
|
|
192
|
+
mask[label == thelabel]=False
|
|
193
|
+
|
|
184
194
|
return mask
|
|
185
195
|
|
|
186
196
|
|
|
@@ -322,34 +332,37 @@ class pymakeplots:
|
|
|
322
332
|
|
|
323
333
|
return x1,y1,v1,np.abs(cd1),cd3
|
|
324
334
|
|
|
325
|
-
def read_in_a_cube(self,path):
|
|
326
|
-
|
|
335
|
+
def read_in_a_cube(self,path,rest_value=None,primary=False):
|
|
336
|
+
|
|
337
|
+
scube=SpectralCube.read(path).with_spectral_unit(u.km/u.s, velocity_convention='radio',rest_value=rest_value)
|
|
327
338
|
|
|
328
|
-
hdr=
|
|
329
|
-
cube = np.squeeze(
|
|
339
|
+
hdr=scube.header
|
|
340
|
+
cube = np.squeeze(scube.filled_data[:,:,:].T).value #squeeze to remove singular stokes axis if present
|
|
330
341
|
cube[np.isfinite(cube) == False] = 0.0
|
|
331
342
|
try:
|
|
332
|
-
beamtab=
|
|
343
|
+
beamtab=scube.beam
|
|
333
344
|
except:
|
|
334
345
|
try:
|
|
335
|
-
beamtab=
|
|
346
|
+
beamtab=scube.beams[np.floor(scube.beams.size/2).astype(int)]
|
|
336
347
|
except:
|
|
337
348
|
#try flipping them
|
|
338
349
|
try:
|
|
339
|
-
beamvals=[
|
|
350
|
+
beamvals=[scube.header['bmaj'],scube.header['bmin']]
|
|
340
351
|
beamtab=Beam(major=np.max(beamvals)*u.deg,minor=np.min(beamvals)*u.deg,pa=self.spectralcube.header['bpa']*u.deg)
|
|
341
352
|
except:
|
|
342
|
-
beamtab=False
|
|
343
|
-
|
|
353
|
+
beamtab=False
|
|
354
|
+
if primary:
|
|
355
|
+
self.spectralcube=scube
|
|
356
|
+
self.repfreq=np.median(self.spectralcube.with_spectral_unit(u.GHz).spectral_axis)
|
|
344
357
|
return cube, hdr, beamtab
|
|
345
358
|
|
|
346
359
|
|
|
347
360
|
|
|
348
|
-
def read_primary_cube(self,cube):
|
|
361
|
+
def read_primary_cube(self,cube,rest_value=None):
|
|
349
362
|
|
|
350
363
|
### read in cube ###
|
|
351
|
-
datacube,hdr,beam = self.read_in_a_cube(cube)
|
|
352
|
-
|
|
364
|
+
datacube,hdr,beam = self.read_in_a_cube(cube,rest_value=rest_value,primary=True)
|
|
365
|
+
|
|
353
366
|
self.bmaj=beam.major.to(u.arcsec).value
|
|
354
367
|
self.bmin=beam.minor.to(u.arcsec).value
|
|
355
368
|
self.bpa=beam.pa.value
|
|
@@ -359,15 +372,9 @@ class pymakeplots:
|
|
|
359
372
|
self.galname=hdr['OBJECT']
|
|
360
373
|
except:
|
|
361
374
|
self.galname="Galaxy"
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
375
|
+
|
|
365
376
|
self.xcoord,self.ycoord,self.vcoord,self.cellsize,self.dv = self.get_header_coord_arrays(hdr)
|
|
366
|
-
#breakpoint()
|
|
367
|
-
|
|
368
|
-
|
|
369
377
|
|
|
370
|
-
|
|
371
378
|
if self.dv < 0:
|
|
372
379
|
datacube = np.flip(datacube,axis=2)
|
|
373
380
|
self.dv*=(-1)
|
|
@@ -475,7 +482,6 @@ class pymakeplots:
|
|
|
475
482
|
y2 = s*xpv + c*ypv
|
|
476
483
|
ax2.scatter(0,0,facecolors='none',edgecolors='k')
|
|
477
484
|
ax2.plot(x2,y2,'k--')
|
|
478
|
-
#breakpoint()
|
|
479
485
|
|
|
480
486
|
###### make summary box
|
|
481
487
|
|
|
@@ -503,6 +509,7 @@ class pymakeplots:
|
|
|
503
509
|
|
|
504
510
|
if pdf:
|
|
505
511
|
plt.savefig(self.galname+"_allplots.pdf", bbox_inches = 'tight')
|
|
512
|
+
plt.close()
|
|
506
513
|
else:
|
|
507
514
|
plt.show()
|
|
508
515
|
|
|
@@ -586,19 +593,27 @@ class pymakeplots:
|
|
|
586
593
|
|
|
587
594
|
|
|
588
595
|
|
|
589
|
-
if self.chans2do == None:
|
|
590
|
-
# use the mask to try and guess the channels with signal.
|
|
591
|
-
mask_cumsum=np.nancumsum((self.pbcorr_cube > self.rmsfac*self.rms).sum(axis=0).sum(axis=0))
|
|
592
|
-
w_low,=np.where(mask_cumsum/np.max(mask_cumsum) < 0.02)
|
|
593
|
-
w_high,=np.where(mask_cumsum/np.max(mask_cumsum) > 0.98)
|
|
596
|
+
if np.any(self.chans2do == None):
|
|
594
597
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
598
|
+
clip=4.0
|
|
599
|
+
vwidth=4000
|
|
600
|
+
while vwidth > 1500:
|
|
601
|
+
clip+=0.1
|
|
602
|
+
# use the mask to try and guess the channels with signal.
|
|
603
|
+
mask_cumsum=np.nancumsum((self.cube_for_param_guesses > clip*self.rms).sum(axis=0).sum(axis=0))
|
|
604
|
+
w_low,=np.where(mask_cumsum/np.nanmax(mask_cumsum) < 0.05)
|
|
605
|
+
w_high,=np.where(mask_cumsum/np.nanmax(mask_cumsum) > 0.95)
|
|
606
|
+
|
|
607
|
+
if w_low.size ==0: w_low=np.array([0])
|
|
608
|
+
if w_high.size ==0: w_high=np.array([self.vcoord.size])
|
|
609
|
+
#breakpoint()
|
|
610
|
+
self.chans2do=[np.clip(np.max(w_low)-7,0,self.vcoord.size-1),np.clip(np.min(w_high)+7,0,self.vcoord.size-1)]
|
|
611
|
+
vwidth=self.vcoord[self.chans2do[1]]-self.vcoord[self.chans2do[0]]
|
|
612
|
+
#print(clip)
|
|
613
|
+
|
|
599
614
|
if self.vsys == None:
|
|
600
615
|
# use the cube to try and guess the vsys
|
|
601
|
-
self.vsys=((self.
|
|
616
|
+
self.vsys=((self.cube_for_param_guesses*(self.cube_for_param_guesses > self.rmsfac*self.rms)).sum(axis=0).sum(axis=0)*self.vcoord).sum()/((self.cube_for_param_guesses*(self.cube_for_param_guesses > self.rmsfac*self.rms)).sum(axis=0).sum(axis=0)).sum()
|
|
602
617
|
|
|
603
618
|
if self.imagesize != None:
|
|
604
619
|
if np.array(self.imagesize).size == 1:
|
|
@@ -612,7 +627,7 @@ class pymakeplots:
|
|
|
612
627
|
|
|
613
628
|
if self.spatial_trim == None:
|
|
614
629
|
|
|
615
|
-
mom0=(self.
|
|
630
|
+
mom0=(self.cube_for_param_guesses > self.rmsfac*self.rms).sum(axis=2)
|
|
616
631
|
mom0[mom0>0]=1
|
|
617
632
|
|
|
618
633
|
cumulative_x = np.nancumsum(mom0.sum(axis=1),dtype=float)
|
|
@@ -662,19 +677,16 @@ class pymakeplots:
|
|
|
662
677
|
return cb
|
|
663
678
|
|
|
664
679
|
|
|
665
|
-
def add_beam(self,ax):
|
|
680
|
+
def add_beam(self,ax):
|
|
681
|
+
aux_tr_box = AuxTransformBox(ax.transData)
|
|
682
|
+
|
|
666
683
|
if self.all_axes_physical:
|
|
667
|
-
|
|
668
|
-
loc='lower left', pad=0.5, borderpad=0.4,
|
|
669
|
-
frameon=False)
|
|
684
|
+
aux_tr_box.add_artist(Ellipse((0, 0), width=self.ang2kpctrans(self.bmaj), height=self.ang2kpctrans(self.bmin), angle=self.bpa+90,edgecolor='black',facecolor='none',linewidth=1.5))
|
|
670
685
|
else:
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
ae.ellipse.set_facecolor('none')
|
|
676
|
-
ae.ellipse.set_linewidth(1.5)
|
|
677
|
-
ax.add_artist(ae)
|
|
686
|
+
aux_tr_box.add_artist(Ellipse((0, 0), width=self.bmaj, height=self.bmin, angle=self.bpa+90,edgecolor='black',facecolor='none',linewidth=1.5))
|
|
687
|
+
box = AnchoredOffsetbox(child=aux_tr_box, loc='lower left', pad=0.5, borderpad=0.4,frameon=False)
|
|
688
|
+
ax.add_artist(box)
|
|
689
|
+
|
|
678
690
|
|
|
679
691
|
|
|
680
692
|
|
|
@@ -819,12 +831,13 @@ class pymakeplots:
|
|
|
819
831
|
mom2[i,j]=np.sqrt(np.sum(np.abs(self.pbcorr_cube_trim[i,j,:]*self.mask_trim[i,j,:]) * (self.vcoord_trim - mom1[i,j]) ** 2, axis=0) / np.sum(abs(self.pbcorr_cube_trim[i,j]*self.mask_trim[i,j,:]), axis=0))
|
|
820
832
|
|
|
821
833
|
if self.maxvdisp == None:
|
|
822
|
-
self.maxvdisp=np.ceil(np.clip(np.nanstd(mom2)*4,
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
834
|
+
self.maxvdisp=np.ceil(np.clip(np.nanstd(mom2)*4,20,np.nanmax(mom2))/10.)*10.
|
|
835
|
+
else:
|
|
836
|
+
self.maxvdisp=np.ceil(np.clip(np.nanstd(mom2)*4,20,self.maxvdisp)/10.)*10.
|
|
837
|
+
if np.isfinite(self.maxvdisp)==False:
|
|
838
|
+
self.maxvdisp=50.
|
|
839
|
+
#breakpoint()
|
|
826
840
|
mom2levs=np.linspace(0,self.maxvdisp,10)
|
|
827
|
-
|
|
828
841
|
im1=ax1.contourf(self.xc,self.yc,mom2.T,levels=mom2levs,cmap=sauron,vmax=self.maxvdisp)
|
|
829
842
|
|
|
830
843
|
if self.all_axes_physical:
|
|
@@ -844,7 +857,7 @@ class pymakeplots:
|
|
|
844
857
|
vticks=np.arange(0,5)*dvticks
|
|
845
858
|
|
|
846
859
|
cb=self.colorbar(im1,ticks=vticks)
|
|
847
|
-
cb.set_label(
|
|
860
|
+
cb.set_label('$\\sigma_{obs}$ (km s$^{-1}$)')
|
|
848
861
|
|
|
849
862
|
|
|
850
863
|
self.add_beam(ax1)
|
|
@@ -969,32 +982,67 @@ class pymakeplots:
|
|
|
969
982
|
if self.posang==None:
|
|
970
983
|
# try fitting the moment one to get the kinematic pa
|
|
971
984
|
if not self.silent: print("No position angle given, estimating using the observed moment one.")
|
|
972
|
-
mom0=(self.
|
|
985
|
+
mom0=(self.flat_cube_trim*self.mask_trim).sum(axis=2)
|
|
973
986
|
mom1=mom0.copy()*np.nan
|
|
974
|
-
mom1[mom0 != 0.0] = (((self.
|
|
975
|
-
mom1=mom1.T
|
|
987
|
+
mom1[mom0 != 0.0] = (((self.flat_cube_trim*self.mask_trim)*self.vcoord_trim).sum(axis=2))[mom0 != 0.0]/mom0[mom0 != 0.0]
|
|
988
|
+
mom1=mom1.T
|
|
976
989
|
|
|
977
|
-
|
|
990
|
+
# ### sigma clip
|
|
991
|
+
# mom1[np.abs(mom1/np.nanstd(mom1))>5]=np.nan
|
|
992
|
+
|
|
993
|
+
### select largest contigious structure
|
|
994
|
+
label,cnt=ndimage.label(self.mask_trim.sum(axis=2))
|
|
995
|
+
mode_label= mode(label[label>0])
|
|
996
|
+
|
|
997
|
+
hist,lab=np.histogram(label[label>0],bins=np.arange(cnt+1)+1)
|
|
998
|
+
beampix=(self.bmaj*self.bmin)/(self.cellsize**2)
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
if len(lab[0:-1][hist<beampix]) != len(lab[0:-1]):
|
|
1002
|
+
|
|
1003
|
+
## remove beam size artifacts
|
|
1004
|
+
for thelabel in lab[0:-1][hist<beampix]:
|
|
1005
|
+
mom1[label.T == thelabel]=np.nan
|
|
1006
|
+
|
|
1007
|
+
## keep biggest structures that contain >80% of remaining pixels
|
|
1008
|
+
remainlab=lab[0:-1][hist>beampix]
|
|
1009
|
+
remainhist=hist[hist>beampix]
|
|
1010
|
+
st=np.argsort(remainhist)
|
|
1011
|
+
for thelabel in remainlab[st][np.nancumsum(remainhist[st]/np.sum(remainhist)) < 0.2]:
|
|
1012
|
+
mom1[label.T == thelabel]=np.nan
|
|
1013
|
+
|
|
1014
|
+
else:
|
|
1015
|
+
mom1[label.T != mode_label.mode]=np.nan
|
|
1016
|
+
|
|
1017
|
+
#self.useallpixels=True
|
|
1018
|
+
|
|
1019
|
+
### remove median
|
|
1020
|
+
mom1-=np.nanmedian(mom1)
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
#breakpoint()
|
|
978
1025
|
# if the cube is small, use it directly to estimate posang. If its large, then interpolate down to keep runtime low.
|
|
979
|
-
if (self.pbcorr_cube_trim[:,:,0].size < 50*50) or (self.useallpixels):
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
else:
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
self.posang,_,_ = fit_kinematic_pa(x[np.isfinite(v)],y[np.isfinite(v)],v[np.isfinite(v)],nsteps=36,plot=False,quiet=True)
|
|
1026
|
+
# if (self.pbcorr_cube_trim[:,:,0].size < 50*50) or (self.useallpixels):
|
|
1027
|
+
xv, yv = np.meshgrid(self.xc,self.yc)
|
|
1028
|
+
x,y,v = xv[np.isfinite(mom1)],yv[np.isfinite(mom1)],mom1[np.isfinite(mom1)]
|
|
1029
|
+
# else:
|
|
1030
|
+
# print("Downsampling the observed moment one in PA estimate for speed. Set `useallpixels` to override.")
|
|
1031
|
+
#mom1[np.isfinite(mom1) == False] = self.vsys
|
|
1032
|
+
#breakpoint()
|
|
1033
|
+
# interper = interpolate.RegularGridInterpolator((self.xc,self.yc),(mom1-self.vsys).T,bounds_error=False,fill_value=np.nan)
|
|
1034
|
+
# x=np.linspace(np.min(self.xc),np.max(self.xc),self.xc.size//2)
|
|
1035
|
+
# y=np.linspace(np.min(self.yc),np.max(self.yc),self.yc.size//2)
|
|
1036
|
+
# xv, yv = np.meshgrid(x,y)
|
|
1037
|
+
# v= interper((xv,yv))
|
|
1038
|
+
# x,y,v = xv.flatten(),yv.flatten(),v.flatten()
|
|
994
1039
|
|
|
1040
|
+
#breakpoint()
|
|
1041
|
+
self.posang,_,_ = fit_kinematic_pa(x[np.isfinite(v)],y[np.isfinite(v)],v[np.isfinite(v)],nsteps=36,plot=False,quiet=True)
|
|
1042
|
+
|
|
995
1043
|
if np.sin(np.deg2rad((self.posang+45)*2)) > 0:
|
|
996
1044
|
# do y axis cut
|
|
997
|
-
if np.
|
|
1045
|
+
if np.nansum(mom1[self.yc > 0,:])/(mom1[self.yc > 0,:]).size > np.nansum(mom1[self.yc < 0,:])/(mom1[self.yc < 0,:]).size:
|
|
998
1046
|
# posang should be gt 180
|
|
999
1047
|
if self.posang < 180: self.posang += 180
|
|
1000
1048
|
else:
|
|
@@ -1002,15 +1050,14 @@ class pymakeplots:
|
|
|
1002
1050
|
if self.posang > 180: self.posang -= 180
|
|
1003
1051
|
else:
|
|
1004
1052
|
# do x axis cut
|
|
1005
|
-
if np.
|
|
1053
|
+
if np.nansum(mom1[:,self.xc > 0])/(mom1[:,self.xc > 0]).size > np.nansum(mom1[:,self.xc < 0])/(mom1[:,self.xc < 0]).size:
|
|
1006
1054
|
# posang should be gt 180
|
|
1007
1055
|
if self.posang < 180: self.posang += 180
|
|
1008
1056
|
else:
|
|
1009
1057
|
# posang should be lt 180
|
|
1010
1058
|
if self.posang > 180: self.posang -= 180
|
|
1011
1059
|
if not self.silent: print("PA estimate (degrees): ",np.round(self.posang,1))
|
|
1012
|
-
|
|
1013
|
-
|
|
1060
|
+
|
|
1014
1061
|
centpix_x=np.where(np.isclose(self.xc,0.0,atol=self.cellsize/1.9))[0]
|
|
1015
1062
|
centpix_y=np.where(np.isclose(self.yc,0.0,atol=self.cellsize/1.9))[0]
|
|
1016
1063
|
|
|
@@ -1047,9 +1094,15 @@ class pymakeplots:
|
|
|
1047
1094
|
newcmp = ListedColormap(oldcmp(np.linspace(0.15, 1, 256)))
|
|
1048
1095
|
|
|
1049
1096
|
|
|
1097
|
+
if np.nanmax(pvd) < self.cliplevel:
|
|
1098
|
+
contour_levels=np.linspace(np.nanmax(pvd)/2.,np.nanmax(pvd),10)
|
|
1099
|
+
if np.sum(contour_levels)==0:
|
|
1100
|
+
contour_levels=np.array([self.cliplevel,self.cliplevel+0.1])
|
|
1101
|
+
else:
|
|
1102
|
+
contour_levels=np.linspace(self.cliplevel,np.nanmax(pvd),10)
|
|
1050
1103
|
|
|
1051
|
-
axes.contourf(pvdaxis,vaxis,pvd.T,levels=
|
|
1052
|
-
axes.contour(pvdaxis,vaxis,pvd.T,levels=
|
|
1104
|
+
axes.contourf(pvdaxis,vaxis,pvd.T,levels=contour_levels,cmap=newcmp)
|
|
1105
|
+
axes.contour(pvdaxis,vaxis,pvd.T,levels=contour_levels,colors='black')
|
|
1053
1106
|
|
|
1054
1107
|
if self.all_axes_physical:
|
|
1055
1108
|
axes.set_xlabel('Offset (kpc)')
|
|
@@ -1067,7 +1120,7 @@ class pymakeplots:
|
|
|
1067
1120
|
secax = axes.secondary_yaxis('right', functions=(self.vsystrans, self.vsystrans_inv))
|
|
1068
1121
|
secax.set_ylabel(r'V$_{\rm offset}$ (km s$^{-1}$)')
|
|
1069
1122
|
|
|
1070
|
-
anchored_text = AnchoredText("PA: "+str(round(self.posang,1))+
|
|
1123
|
+
anchored_text = AnchoredText("PA: "+str(round(self.posang,1))+'$^{\\circ}$', loc=loc1,frameon=False)
|
|
1071
1124
|
axes.add_artist(anchored_text)
|
|
1072
1125
|
|
|
1073
1126
|
if self.gal_distance != None and not self.all_axes_physical:
|
|
@@ -1078,6 +1131,7 @@ class pymakeplots:
|
|
|
1078
1131
|
|
|
1079
1132
|
if pdf:
|
|
1080
1133
|
plt.savefig(self.galname+"_pvd.pdf", bbox_inches = 'tight')
|
|
1134
|
+
plt.close()
|
|
1081
1135
|
else:
|
|
1082
1136
|
if not outsideaxis: plt.show()
|
|
1083
1137
|
|
|
@@ -1149,6 +1203,7 @@ class pymakeplots:
|
|
|
1149
1203
|
|
|
1150
1204
|
if pdf:
|
|
1151
1205
|
plt.savefig(self.galname+"_spec.pdf", bbox_inches = 'tight')
|
|
1206
|
+
plt.close()
|
|
1152
1207
|
else:
|
|
1153
1208
|
if not outsideaxis: plt.show()
|
|
1154
1209
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
pymakeplots/__init__.py,sha256=PLKnIm6rIKYjH_b6L9UBCFtv1lKt5GItdBKDbSOhuMU,87
|
|
2
|
+
pymakeplots/pymakeplots.py,sha256=_N8Wp2teEfr6W9SqBi3bb2WV3F7vxzfVhWDnhq_Qa1E,48843
|
|
3
|
+
pymakeplots/sauron_colormap.py,sha256=8APka-_L432wyICcHcySjk3qmjNOynb3iDjjlMuUTU0,4448
|
|
4
|
+
pymakeplots-0.2.2.dist-info/LICENSE.md,sha256=qtvmvajOPCad_5HMY5u49hldzBIXz7tbHbuGSG_HE5o,1077
|
|
5
|
+
pymakeplots-0.2.2.dist-info/METADATA,sha256=YlzzxZMuONkCuzkhi_5tHinfu6TsqW8MzdpB5jG_QTg,1847
|
|
6
|
+
pymakeplots-0.2.2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
7
|
+
pymakeplots-0.2.2.dist-info/top_level.txt,sha256=KgG17vI_D6BsiKRe_81UU5709tXc6Ha7gx1IwjA7ur8,12
|
|
8
|
+
pymakeplots-0.2.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
9
|
+
pymakeplots-0.2.2.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
pymakeplots/__init__.py,sha256=PLKnIm6rIKYjH_b6L9UBCFtv1lKt5GItdBKDbSOhuMU,87
|
|
2
|
-
pymakeplots/pymakeplots.py,sha256=EIeZH1brAg5d9QM9QqaViXFBBDDVCRDWnK1hKZ6ofXg,45950
|
|
3
|
-
pymakeplots/sauron_colormap.py,sha256=8APka-_L432wyICcHcySjk3qmjNOynb3iDjjlMuUTU0,4448
|
|
4
|
-
pymakeplots-0.2.1.dist-info/LICENSE.md,sha256=qtvmvajOPCad_5HMY5u49hldzBIXz7tbHbuGSG_HE5o,1077
|
|
5
|
-
pymakeplots-0.2.1.dist-info/METADATA,sha256=GGL0jJnyhIuv9bmggds2jNoWRTPbXyPU-cQ4jlJJ_3M,1847
|
|
6
|
-
pymakeplots-0.2.1.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
7
|
-
pymakeplots-0.2.1.dist-info/top_level.txt,sha256=KgG17vI_D6BsiKRe_81UU5709tXc6Ha7gx1IwjA7ur8,12
|
|
8
|
-
pymakeplots-0.2.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
9
|
-
pymakeplots-0.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|