plotastrodata 1.6.0__tar.gz → 1.6.2__tar.gz
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.
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/PKG-INFO +1 -1
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/__init__.py +1 -1
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/analysis_utils.py +29 -14
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/other_utils.py +2 -2
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/plot_utils.py +14 -7
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/PKG-INFO +1 -1
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/LICENSE +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/README.md +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/const_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/coord_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/ext_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/fft_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/fits_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/fitting_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/los_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata/matrix_utils.py +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/SOURCES.txt +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/dependency_links.txt +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/not-zip-safe +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/requires.txt +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/plotastrodata.egg-info/top_level.txt +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/setup.cfg +0 -0
- {plotastrodata-1.6.0 → plotastrodata-1.6.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotastrodata
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
4
4
|
Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
|
|
5
5
|
Home-page: https://github.com/yusukeaso-astron/plotastrodata
|
|
6
6
|
Download-URL: https://github.com/yusukeaso-astron/plotastrodata
|
|
@@ -4,7 +4,7 @@ from scipy.interpolate import RegularGridInterpolator as RGI
|
|
|
4
4
|
from scipy.optimize import curve_fit
|
|
5
5
|
from scipy.signal import convolve
|
|
6
6
|
|
|
7
|
-
from plotastrodata.coord_utils import coord2xy, rel2abs
|
|
7
|
+
from plotastrodata.coord_utils import coord2xy, xy2coord, rel2abs
|
|
8
8
|
from plotastrodata.matrix_utils import Mfac, Mrot, dot2d
|
|
9
9
|
from plotastrodata.other_utils import (estimate_rms, trim,
|
|
10
10
|
gaussian2d, isdeg,
|
|
@@ -68,7 +68,7 @@ def filled2d(data: np.ndarray, x: np.ndarray, y: np.ndarray, n: int = 1,
|
|
|
68
68
|
return d, xnew, ynew
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def _need_multipixels(method):
|
|
72
72
|
def wrapper(self, *args, **kwargs):
|
|
73
73
|
singlepixel = self.dx is None or self.dy is None
|
|
74
74
|
if singlepixel:
|
|
@@ -153,9 +153,14 @@ class AstroData():
|
|
|
153
153
|
print(f'width was changed to [{ws}].')
|
|
154
154
|
newsize = size // w
|
|
155
155
|
grid = [None, self.v, self.y, self.x]
|
|
156
|
-
|
|
156
|
+
dgrid = [None, self.dv, self.dy, self.dx]
|
|
157
|
+
for n in range(1, 4):
|
|
157
158
|
if w[n] == 1 or grid[n] is None:
|
|
158
159
|
continue
|
|
160
|
+
if dgrid[n] is None:
|
|
161
|
+
s = ['v', 'y', 'x'][n - 1]
|
|
162
|
+
print(f'Skip binning in the {s}-axis because d{s} is None.')
|
|
163
|
+
continue
|
|
159
164
|
size[n] = newsize[n]
|
|
160
165
|
olddata = np.moveaxis(d, n, 0)
|
|
161
166
|
newdata = np.moveaxis(np.zeros(size), n, 0)
|
|
@@ -166,9 +171,11 @@ class AstroData():
|
|
|
166
171
|
t += grid[n][i:i_stop:i_step]
|
|
167
172
|
newdata += olddata[i:i_stop:i_step]
|
|
168
173
|
grid[n] = t / w[n]
|
|
174
|
+
dgrid[n] = dgrid[n] * w[n]
|
|
169
175
|
d = np.moveaxis(newdata, 0, n) / w[n]
|
|
170
176
|
self.data = np.squeeze(d)
|
|
171
177
|
_, self.v, self.y, self.x = grid
|
|
178
|
+
_, self.dv, self.dy, self.dx = dgrid
|
|
172
179
|
|
|
173
180
|
def centering(self, includexy: bool = True, includev: bool = False,
|
|
174
181
|
**kwargs):
|
|
@@ -206,7 +213,7 @@ class AstroData():
|
|
|
206
213
|
else:
|
|
207
214
|
print('No change because includexy=False and includev=False.')
|
|
208
215
|
|
|
209
|
-
@
|
|
216
|
+
@_need_multipixels
|
|
210
217
|
def circularbeam(self):
|
|
211
218
|
"""Make the beam circular by convolving with 1D Gaussian
|
|
212
219
|
"""
|
|
@@ -259,7 +266,7 @@ class AstroData():
|
|
|
259
266
|
bmin_new = 1 / np.sqrt(alpha + Det)
|
|
260
267
|
self.beam = np.array([bmaj_new, bmin_new, bpa_new])
|
|
261
268
|
|
|
262
|
-
@
|
|
269
|
+
@_need_multipixels
|
|
263
270
|
def fit2d(self, model: object, bounds: np.ndarray,
|
|
264
271
|
progressbar: bool = False,
|
|
265
272
|
kwargs_fit: dict = {}, kwargs_plotcorner: dict = {},
|
|
@@ -307,15 +314,15 @@ class AstroData():
|
|
|
307
314
|
return {'popt': popt, 'plow': plow, 'pmid': pmid, 'phigh': phigh,
|
|
308
315
|
'model': modelopt, 'residual': residual}
|
|
309
316
|
|
|
310
|
-
@
|
|
311
|
-
def gaussfit2d(self, chan: int | None = None):
|
|
317
|
+
@_need_multipixels
|
|
318
|
+
def gaussfit2d(self, chan: int | None = None) -> dict:
|
|
312
319
|
"""Fit a 2D Gaussian function to self.data.
|
|
313
320
|
|
|
314
321
|
Args:
|
|
315
322
|
chan (int): The channel number where the 2D Gaussian is fitted. Defaults to None.
|
|
316
323
|
|
|
317
324
|
Returns:
|
|
318
|
-
dict: The best parameter set (popt), the covariance set (pcov), the best 2D Gaussian array (model),
|
|
325
|
+
dict: The best parameter set (popt), the covariance set (pcov), the best 2D Gaussian array (model), the residual from the model (residual), and the coordinates of the best-fit center (center).
|
|
319
326
|
"""
|
|
320
327
|
d = self.data if chan is None else self.data[chan]
|
|
321
328
|
x = self.x
|
|
@@ -331,12 +338,21 @@ class AstroData():
|
|
|
331
338
|
bounds = [[-amax, xmin, ymin, ds, ds, -90],
|
|
332
339
|
[amax, xmax, ymax, smax, smax, 90]]
|
|
333
340
|
x, y = np.meshgrid(x, y)
|
|
334
|
-
popt, pcov = curve_fit(gaussian2d,
|
|
341
|
+
popt, pcov = curve_fit(gaussian2d,
|
|
342
|
+
(x.ravel(), y.ravel()), d.ravel(),
|
|
335
343
|
p0=p0, bounds=bounds)
|
|
336
344
|
model = gaussian2d((x, y), *popt)
|
|
337
345
|
residual = d - model
|
|
346
|
+
if (center := self.center) is not None:
|
|
347
|
+
xy = popt[1:3] / 3600
|
|
348
|
+
newcenter = xy2coord(xy, coordorg=center)
|
|
349
|
+
if len(c := center.split()) == 3:
|
|
350
|
+
newcenter = f'{c[0]} {newcenter}'
|
|
351
|
+
else:
|
|
352
|
+
newcenter = None
|
|
338
353
|
return {'popt': popt, 'pcov': pcov,
|
|
339
|
-
'model': model, 'residual': residual
|
|
354
|
+
'model': model, 'residual': residual,
|
|
355
|
+
'center': newcenter}
|
|
340
356
|
|
|
341
357
|
def histogram(self, **kwargs) -> tuple:
|
|
342
358
|
"""Output histogram of self.data using numpy.histogram. This method can take the arguments of numpy.histogram.
|
|
@@ -495,7 +511,7 @@ class AstroData():
|
|
|
495
511
|
'sigma': self.sigma, 'center': self.center, 'pv': self.pv}
|
|
496
512
|
return d
|
|
497
513
|
|
|
498
|
-
@
|
|
514
|
+
@_need_multipixels
|
|
499
515
|
def writetofits(self, fitsimage: str = 'out.fits', header: dict = {}):
|
|
500
516
|
"""Write out the AstroData to a FITS file.
|
|
501
517
|
|
|
@@ -629,9 +645,8 @@ class AstroFrame():
|
|
|
629
645
|
Returns:
|
|
630
646
|
np.ndarray: absolute coordinates.
|
|
631
647
|
"""
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
and type(poslist[0]) is not str):
|
|
648
|
+
onexy = np.shape(poslist) == (2,) and type(poslist[0]) is not str
|
|
649
|
+
if np.shape(poslist) == () or onexy:
|
|
635
650
|
poslist = [poslist]
|
|
636
651
|
x, y = [None] * len(poslist), [None] * len(poslist)
|
|
637
652
|
for i, p in enumerate(poslist):
|
|
@@ -12,10 +12,10 @@ def listing(*args) -> list:
|
|
|
12
12
|
Returns:
|
|
13
13
|
list: With a single non-list input, the output is a list like ['a'], rather than [['a']].
|
|
14
14
|
"""
|
|
15
|
-
|
|
15
|
+
strnum = [str, float, int, np.float64, np.int64, np.float32, np.int32]
|
|
16
16
|
b = [None] * len(args)
|
|
17
17
|
for i, a in enumerate(args):
|
|
18
|
-
b[i] = [a] if type(a) in
|
|
18
|
+
b[i] = [a] if type(a) in strnum else a
|
|
19
19
|
if len(args) == 1:
|
|
20
20
|
b = b[0]
|
|
21
21
|
return b
|
|
@@ -513,8 +513,9 @@ class PlotAstroData(AstroFrame):
|
|
|
513
513
|
if patch not in ['rectangle', 'ellipse']:
|
|
514
514
|
print('Only patch=\'rectangle\' or \'ellipse\' supported. ')
|
|
515
515
|
return
|
|
516
|
-
|
|
517
|
-
|
|
516
|
+
|
|
517
|
+
z = listing(*self.pos2xy(poslist), minlist, majlist, palist)
|
|
518
|
+
for x, y, width, height, angle in zip(*z):
|
|
518
519
|
for ch, axnow in enumerate(self.ax):
|
|
519
520
|
if type(self.channelnumber) is int:
|
|
520
521
|
ch = self.channelnumber
|
|
@@ -549,12 +550,15 @@ class PlotAstroData(AstroFrame):
|
|
|
549
550
|
"""
|
|
550
551
|
if not show_beam:
|
|
551
552
|
return
|
|
552
|
-
|
|
553
|
+
|
|
554
|
+
animation = self.channelnumber is not None
|
|
555
|
+
include_chan = self.allchan if animation else self.bottomleft
|
|
553
556
|
patch = 'rectangle' if self.pv else 'ellipse'
|
|
554
557
|
blist = [beam] if np.ndim(beam) == 1 else beam
|
|
555
558
|
n = len(blist)
|
|
556
559
|
bclist = beamcolor if type(beamcolor) is list else [beamcolor] * n
|
|
557
|
-
|
|
560
|
+
islist = beampos == [None] * 3 or np.ndim(beampos) == 2
|
|
561
|
+
bplist = beampos if islist else [beampos] * n
|
|
558
562
|
for (bmaj, bmin, bpa), bc, bp in zip(blist, bclist, bplist):
|
|
559
563
|
if None in [bmaj, bmin, bpa]:
|
|
560
564
|
print('No beam to plot.')
|
|
@@ -613,7 +617,8 @@ class PlotAstroData(AstroFrame):
|
|
|
613
617
|
ch = self.channelnumber
|
|
614
618
|
if ch not in include_chan:
|
|
615
619
|
continue
|
|
616
|
-
|
|
620
|
+
z = listing(*self.pos2xy(poslist), slist)
|
|
621
|
+
for x, y, s in zip(*z):
|
|
617
622
|
axnow.text(x=x, y=y, s=s, **_kw)
|
|
618
623
|
|
|
619
624
|
def add_line(self, poslist: list[str | list[float, float]] = [],
|
|
@@ -639,7 +644,8 @@ class PlotAstroData(AstroFrame):
|
|
|
639
644
|
if ch not in include_chan:
|
|
640
645
|
continue
|
|
641
646
|
alist = np.radians(anglelist)
|
|
642
|
-
|
|
647
|
+
z = listing(*self.pos2xy(poslist), alist, rlist)
|
|
648
|
+
for x, y, a, r in zip(*z):
|
|
643
649
|
axnow.plot([x, x + r * np.sin(a)],
|
|
644
650
|
[y, y + r * np.cos(a)], **_kw)
|
|
645
651
|
|
|
@@ -666,7 +672,8 @@ class PlotAstroData(AstroFrame):
|
|
|
666
672
|
if ch not in include_chan:
|
|
667
673
|
continue
|
|
668
674
|
alist = np.radians(anglelist)
|
|
669
|
-
|
|
675
|
+
z = listing(*self.pos2xy(poslist), alist, rlist)
|
|
676
|
+
for x, y, a, r in zip(*z):
|
|
670
677
|
axnow.quiver(x, y, r * np.sin(a), r * np.cos(a),
|
|
671
678
|
angles='xy', scale_units='xy', scale=1,
|
|
672
679
|
**_kw)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotastrodata
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
4
4
|
Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
|
|
5
5
|
Home-page: https://github.com/yusukeaso-astron/plotastrodata
|
|
6
6
|
Download-URL: https://github.com/yusukeaso-astron/plotastrodata
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|