psimager 0.2__tar.gz → 0.3__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.
- {psimager-0.2 → psimager-0.3}/PKG-INFO +7 -4
- {psimager-0.2 → psimager-0.3}/README.md +2 -0
- {psimager-0.2 → psimager-0.3}/psimager/cli.py +22 -2
- {psimager-0.2 → psimager-0.3}/psimager/imager.py +2 -0
- {psimager-0.2 → psimager-0.3}/pyproject.toml +1 -1
- {psimager-0.2 → psimager-0.3}/LICENSE +0 -0
- {psimager-0.2 → psimager-0.3}/psimager/__init__.py +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: psimager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3
|
|
4
4
|
Summary: Fast dirty imaging of measurement sets for power spectrum analyses, with the ducc0 w-gridder and WSClean's options
|
|
5
|
-
License: GPL-3.0-or-later
|
|
5
|
+
License-Expression: GPL-3.0-or-later
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Author: Florent Mertens
|
|
7
8
|
Author-email: florent.mertens@gmail.com
|
|
8
9
|
Requires-Python: >=3.10,<4.0
|
|
9
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
16
|
Provides-Extra: dev
|
|
16
17
|
Requires-Dist: astropy (>=5.0)
|
|
17
18
|
Requires-Dist: click (>=8.0)
|
|
@@ -66,6 +67,8 @@ Differences with WSClean:
|
|
|
66
67
|
|
|
67
68
|
- `-even-odd` images the even and the odd time steps in one pass, as `NAME-even-*` and
|
|
68
69
|
`NAME-odd-*`.
|
|
70
|
+
- `-fits-keyword KEY=VALUE` (repeatable) adds a header keyword to every output file, written
|
|
71
|
+
with the file instead of updating it afterwards.
|
|
69
72
|
- `-parallel-gridding` defaults to `-j`: one thread per output channel, which is the fastest.
|
|
70
73
|
- No deconvolution and no `-MFS-` images.
|
|
71
74
|
- WSClean's gridding options (`-oversampling`, `-kernel-size`, `-nwlayers`, `-grid-mode`,
|
|
@@ -38,6 +38,8 @@ Differences with WSClean:
|
|
|
38
38
|
|
|
39
39
|
- `-even-odd` images the even and the odd time steps in one pass, as `NAME-even-*` and
|
|
40
40
|
`NAME-odd-*`.
|
|
41
|
+
- `-fits-keyword KEY=VALUE` (repeatable) adds a header keyword to every output file, written
|
|
42
|
+
with the file instead of updating it afterwards.
|
|
41
43
|
- `-parallel-gridding` defaults to `-j`: one thread per output channel, which is the fastest.
|
|
42
44
|
- No deconvolution and no `-MFS-` images.
|
|
43
45
|
- WSClean's gridding options (`-oversampling`, `-kernel-size`, `-nwlayers`, `-grid-mode`,
|
|
@@ -44,6 +44,23 @@ def parse_scale(ctx, param, text):
|
|
|
44
44
|
return value
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
def parse_keywords(ctx, param, texts):
|
|
48
|
+
"""(KEY, value) of each KEY=VALUE, the value as an integer, a float or a string."""
|
|
49
|
+
keywords = []
|
|
50
|
+
for text in texts:
|
|
51
|
+
key, sep, value = text.partition('=')
|
|
52
|
+
if not sep or not re.fullmatch(r'[A-Z0-9_-]{1,8}', key.strip().upper()):
|
|
53
|
+
raise click.BadParameter(f'{text!r}: expected KEY=VALUE, KEY of at most 8 characters')
|
|
54
|
+
for cast in (int, float):
|
|
55
|
+
try:
|
|
56
|
+
value = cast(value)
|
|
57
|
+
break
|
|
58
|
+
except ValueError:
|
|
59
|
+
pass
|
|
60
|
+
keywords.append((key.strip().upper(), value))
|
|
61
|
+
return tuple(keywords)
|
|
62
|
+
|
|
63
|
+
|
|
47
64
|
def ignored_options(f):
|
|
48
65
|
for name, nargs in IGNORED.items():
|
|
49
66
|
if nargs:
|
|
@@ -89,12 +106,14 @@ def ignored_options(f):
|
|
|
89
106
|
'30, or -mem % of the RAM if smaller]')
|
|
90
107
|
@click.option('-make-psf', is_flag=True, help='Also write the PSF.')
|
|
91
108
|
@click.option('-no-dirty', is_flag=True, help='Write only the -image files.')
|
|
109
|
+
@click.option('-fits-keyword', 'keywords', multiple=True, callback=parse_keywords,
|
|
110
|
+
help='Header keyword of every output file, KEY=VALUE (repeatable).')
|
|
92
111
|
@click.version_option(__version__, '-version')
|
|
93
112
|
@ignored_options
|
|
94
113
|
def main(ms, name, data_column, pol, size, scale, channel_range, channels_out, interval,
|
|
95
114
|
intervals_out, even_timesteps, odd_timesteps, even_odd, minuv_l, maxuv_l, minuvw_m,
|
|
96
115
|
maxuvw_m, weight, visibility_weighting_mode, taper_edge, padding, wgridder_accuracy,
|
|
97
|
-
threads, parallel_gridding, mem, abs_mem, make_psf, no_dirty, **wsclean_options):
|
|
116
|
+
threads, parallel_gridding, mem, abs_mem, make_psf, no_dirty, keywords, **wsclean_options):
|
|
98
117
|
"""Dirty Stokes and PSF images of the measurement sets MS with the ducc0 w-gridder, with the
|
|
99
118
|
options, file names and FITS keywords of WSClean."""
|
|
100
119
|
if even_timesteps + odd_timesteps + even_odd > 1:
|
|
@@ -113,7 +132,8 @@ def main(ms, name, data_column, pol, size, scale, channel_range, channels_out, i
|
|
|
113
132
|
minuvw_m=minuvw_m, maxuvw_m=maxuvw_m, weight=mode, robust=float(robust or 0),
|
|
114
133
|
visibility_weighting=visibility_weighting_mode, taper_edge=taper_edge, padding=padding,
|
|
115
134
|
epsilon=wgridder_accuracy, threads=threads, parallel_gridding=parallel_gridding,
|
|
116
|
-
mem_percent=mem, abs_mem_gb=abs_mem, make_psf=make_psf, write_dirty=not no_dirty
|
|
135
|
+
mem_percent=mem, abs_mem_gb=abs_mem, make_psf=make_psf, write_dirty=not no_dirty,
|
|
136
|
+
keywords=keywords)
|
|
117
137
|
imager = Imager(ms, settings, log=click.echo)
|
|
118
138
|
start = time.time()
|
|
119
139
|
paths = imager.run()
|
|
@@ -62,6 +62,7 @@ class Settings:
|
|
|
62
62
|
abs_mem_gb: float = None
|
|
63
63
|
make_psf: bool = False
|
|
64
64
|
write_dirty: bool = True
|
|
65
|
+
keywords: tuple = () # extra (KEY, value) header cards of every file
|
|
65
66
|
|
|
66
67
|
def __post_init__(self):
|
|
67
68
|
self.pols = self.pols.upper()
|
|
@@ -469,6 +470,7 @@ class Imager:
|
|
|
469
470
|
'WSCCHANS': self.chans[0], 'WSCCHANE': self.chans[1], 'WSCNVIS': nvis,
|
|
470
471
|
'WSCENVIS': wsum ** 2 / w2sum if w2sum > 0 else 0., 'WSCVWSUM': vwsum,
|
|
471
472
|
'WSCIMGWG': imgwsum, 'WSCNORMF': wsum, 'PSIVERSI': __version__})
|
|
473
|
+
h.update(dict(s.keywords))
|
|
472
474
|
return h
|
|
473
475
|
|
|
474
476
|
def weight_name(self):
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "psimager"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3"
|
|
8
8
|
description = "Fast dirty imaging of measurement sets for power spectrum analyses, with the ducc0 w-gridder and WSClean's options"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
File without changes
|
|
File without changes
|