msutils 1.1.4__tar.gz → 2.0.0b1__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.
@@ -0,0 +1,18 @@
1
+ # Build artifacts
2
+ build/
3
+ dist/
4
+ *.egg-info/
5
+ .eggs/
6
+
7
+ # Python
8
+ __pycache__/
9
+ *.py[cod]
10
+ *.so
11
+
12
+ # Test / tooling caches
13
+ .pytest_cache/
14
+ .ruff_cache/
15
+
16
+ # Virtual environments
17
+ .venv/
18
+ venv/
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: msutils
3
+ Version: 2.0.0b1
4
+ Summary: Tools for playing with Measurement sets.
5
+ Project-URL: Homepage, https://github.com/SpheMakh/msutils
6
+ Project-URL: Repository, https://github.com/SpheMakh/msutils
7
+ Project-URL: Issues, https://github.com/SpheMakh/msutils/issues
8
+ Author-email: Sphesihle Makhathini <sphemakh@gmail.com>
9
+ License-Expression: GPL-2.0-or-later
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.8
18
+ Requires-Dist: click>=8.0
19
+ Requires-Dist: numpy
20
+ Requires-Dist: python-casacore
21
+ Provides-Extra: all
22
+ Requires-Dist: dask-ms; extra == 'all'
23
+ Requires-Dist: matplotlib; extra == 'all'
24
+ Requires-Dist: scipy; extra == 'all'
25
+ Provides-Extra: flagstats
26
+ Requires-Dist: dask-ms; extra == 'flagstats'
27
+ Requires-Dist: matplotlib; extra == 'flagstats'
28
+ Provides-Extra: plots
29
+ Requires-Dist: matplotlib; extra == 'plots'
30
+ Requires-Dist: scipy; extra == 'plots'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # msutils
34
+
35
+ Tools for manipulating CASA Measurement Sets (MS), for radio-astronomy pipelines.
36
+
37
+ [![Python package](https://github.com/sphemakh/msutils/actions/workflows/installation.yml/badge.svg)](https://github.com/sphemakh/msutils/actions/workflows/installation.yml)
38
+ [![PyPI](https://img.shields.io/pypi/v/msutils.svg)](https://pypi.org/project/msutils/)
39
+
40
+ ## Features
41
+
42
+ - Summarise an MS — fields, spectral windows, antennas, scans, correlations — to a dict / JSON.
43
+ - Add, copy, and sum/subtract visibility columns, chunked by spectral window.
44
+ - Add Gaussian noise to a column (from a stddev, or computed from an SEFD).
45
+ - Verify / fix antenna Y-position sign conventions.
46
+ - Flag statistics per antenna / scan / field / correlation, with a matplotlib summary plot (`flagstats` extra).
47
+ - Per-channel visibility weight estimation from an SEFD profile (`plots` extra).
48
+ - A `msutils` command-line tool wrapping the above.
49
+
50
+ ## Install
51
+
52
+ Requires Python >= 3.8. `python-casacore` is pulled in automatically (its wheels bundle the casacore libraries).
53
+
54
+ ```bash
55
+ pip install msutils # core column operations + CLI
56
+ pip install "msutils[flagstats]" # + flag statistics & plots (dask-ms, matplotlib)
57
+ pip install "msutils[plots]" # + weight estimation (matplotlib, scipy)
58
+ pip install "msutils[all]" # everything
59
+ ```
60
+
61
+ ## Python API
62
+
63
+ The core operations are exposed directly on the package:
64
+
65
+ ```python
66
+ import msutils
67
+
68
+ # Metadata summary (returns a JSON-serialisable dict)
69
+ info = msutils.summary("obs.ms")
70
+
71
+ # Column operations
72
+ msutils.addcol("obs.ms", "MODEL_DATA", clone="DATA")
73
+ msutils.copycol("obs.ms", "DATA", "CORRECTED_DATA")
74
+ msutils.sumcols("obs.ms", cols=["DATA", "MODEL_DATA"], outcol="CORRECTED_DATA")
75
+
76
+ # Add noise (computed from an SEFD, or a fixed stddev)
77
+ msutils.addnoise("obs.ms", column="MODEL_DATA", sefd=551)
78
+ ```
79
+
80
+ Flag statistics and weight estimation live in optional submodules:
81
+
82
+ ```python
83
+ from msutils import flagstats # needs msutils[flagstats]
84
+ flagstats.plot_statistics("obs.ms", plotfile="flags.png", outfile="flags.json")
85
+
86
+ from msutils.weights import MSNoise # needs msutils[plots]
87
+ ```
88
+
89
+ ## Command line
90
+
91
+ ```bash
92
+ msutils summary obs.ms --json summary.json
93
+ msutils addcol obs.ms MODEL_DATA --clone DATA
94
+ msutils copycol obs.ms DATA CORRECTED_DATA
95
+ msutils sumcols obs.ms DATA MODEL_DATA --out CORRECTED_DATA
96
+ msutils addnoise obs.ms --column MODEL_DATA --sefd 551
97
+ msutils flagstats obs.ms --plot flags.png --json flags.json # needs msutils[flagstats]
98
+ ```
99
+
100
+ Run `msutils --help` or `msutils <command> --help` for all options.
101
+
102
+ ## Migrating from 1.x / `MSUtils`
103
+
104
+ - The import package is now lowercase **`msutils`** (the capitalised `MSUtils` still works, with a deprecation warning).
105
+ - The core functions are on the package root — use `msutils.summary(...)` instead of `from msutils import msutils`.
106
+ - Modules renamed: `flag_stats` → `flagstats`, `ClassESW` → `weights` (old names still importable, deprecated).
107
+ - `imp_plotter` (gain/calibration-table plotting) was removed — use [ragavi](https://github.com/ratt-ru/ragavi) (`ragavi-gains`) instead.
108
+ - The defunct `prep()` and its external-binary dependencies were removed.
109
+
110
+ ## License
111
+
112
+ GNU GPL v2 or later. See [LICENSE](LICENSE).
@@ -0,0 +1,80 @@
1
+ # msutils
2
+
3
+ Tools for manipulating CASA Measurement Sets (MS), for radio-astronomy pipelines.
4
+
5
+ [![Python package](https://github.com/sphemakh/msutils/actions/workflows/installation.yml/badge.svg)](https://github.com/sphemakh/msutils/actions/workflows/installation.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/msutils.svg)](https://pypi.org/project/msutils/)
7
+
8
+ ## Features
9
+
10
+ - Summarise an MS — fields, spectral windows, antennas, scans, correlations — to a dict / JSON.
11
+ - Add, copy, and sum/subtract visibility columns, chunked by spectral window.
12
+ - Add Gaussian noise to a column (from a stddev, or computed from an SEFD).
13
+ - Verify / fix antenna Y-position sign conventions.
14
+ - Flag statistics per antenna / scan / field / correlation, with a matplotlib summary plot (`flagstats` extra).
15
+ - Per-channel visibility weight estimation from an SEFD profile (`plots` extra).
16
+ - A `msutils` command-line tool wrapping the above.
17
+
18
+ ## Install
19
+
20
+ Requires Python >= 3.8. `python-casacore` is pulled in automatically (its wheels bundle the casacore libraries).
21
+
22
+ ```bash
23
+ pip install msutils # core column operations + CLI
24
+ pip install "msutils[flagstats]" # + flag statistics & plots (dask-ms, matplotlib)
25
+ pip install "msutils[plots]" # + weight estimation (matplotlib, scipy)
26
+ pip install "msutils[all]" # everything
27
+ ```
28
+
29
+ ## Python API
30
+
31
+ The core operations are exposed directly on the package:
32
+
33
+ ```python
34
+ import msutils
35
+
36
+ # Metadata summary (returns a JSON-serialisable dict)
37
+ info = msutils.summary("obs.ms")
38
+
39
+ # Column operations
40
+ msutils.addcol("obs.ms", "MODEL_DATA", clone="DATA")
41
+ msutils.copycol("obs.ms", "DATA", "CORRECTED_DATA")
42
+ msutils.sumcols("obs.ms", cols=["DATA", "MODEL_DATA"], outcol="CORRECTED_DATA")
43
+
44
+ # Add noise (computed from an SEFD, or a fixed stddev)
45
+ msutils.addnoise("obs.ms", column="MODEL_DATA", sefd=551)
46
+ ```
47
+
48
+ Flag statistics and weight estimation live in optional submodules:
49
+
50
+ ```python
51
+ from msutils import flagstats # needs msutils[flagstats]
52
+ flagstats.plot_statistics("obs.ms", plotfile="flags.png", outfile="flags.json")
53
+
54
+ from msutils.weights import MSNoise # needs msutils[plots]
55
+ ```
56
+
57
+ ## Command line
58
+
59
+ ```bash
60
+ msutils summary obs.ms --json summary.json
61
+ msutils addcol obs.ms MODEL_DATA --clone DATA
62
+ msutils copycol obs.ms DATA CORRECTED_DATA
63
+ msutils sumcols obs.ms DATA MODEL_DATA --out CORRECTED_DATA
64
+ msutils addnoise obs.ms --column MODEL_DATA --sefd 551
65
+ msutils flagstats obs.ms --plot flags.png --json flags.json # needs msutils[flagstats]
66
+ ```
67
+
68
+ Run `msutils --help` or `msutils <command> --help` for all options.
69
+
70
+ ## Migrating from 1.x / `MSUtils`
71
+
72
+ - The import package is now lowercase **`msutils`** (the capitalised `MSUtils` still works, with a deprecation warning).
73
+ - The core functions are on the package root — use `msutils.summary(...)` instead of `from msutils import msutils`.
74
+ - Modules renamed: `flag_stats` → `flagstats`, `ClassESW` → `weights` (old names still importable, deprecated).
75
+ - `imp_plotter` (gain/calibration-table plotting) was removed — use [ragavi](https://github.com/ratt-ru/ragavi) (`ragavi-gains`) instead.
76
+ - The defunct `prep()` and its external-binary dependencies were removed.
77
+
78
+ ## License
79
+
80
+ GNU GPL v2 or later. See [LICENSE](LICENSE).
@@ -0,0 +1,92 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "msutils"
7
+ version = "2.0.0b1"
8
+ description = "Tools for playing with Measurement sets."
9
+ readme = "README.md"
10
+ license = "GPL-2.0-or-later"
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ { name = "Sphesihle Makhathini", email = "sphemakh@gmail.com" },
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python",
20
+ "Topic :: Software Development :: Libraries :: Python Modules",
21
+ "Topic :: Scientific/Engineering :: Astronomy",
22
+ ]
23
+ # Base install covers the core column operations in msutils.msutils only.
24
+ # Heavier, feature-specific stacks live in optional extras below.
25
+ dependencies = [
26
+ "numpy",
27
+ "python-casacore",
28
+ "click>=8.0",
29
+ ]
30
+
31
+ [project.scripts]
32
+ msutils = "msutils.cli:cli"
33
+
34
+ [project.optional-dependencies]
35
+ # msutils.flagstats: out-of-core flag statistics + matplotlib summary plots
36
+ flagstats = [
37
+ "dask-ms",
38
+ "matplotlib",
39
+ ]
40
+ # msutils.weights: matplotlib/scipy noise-weight estimation + diagnostic plot
41
+ plots = [
42
+ "matplotlib",
43
+ "scipy",
44
+ ]
45
+ all = [
46
+ "msutils[flagstats,plots]",
47
+ ]
48
+
49
+ [dependency-groups]
50
+ dev = [
51
+ "pytest>=8.0",
52
+ "ruff>=0.5",
53
+ ]
54
+ # `simms` generates the synthetic MS used by the behavioural tests. It is a
55
+ # heavy, git-installed dependency (kept out of the published package metadata);
56
+ # MS-backed tests skip when it is not importable.
57
+ test = [
58
+ "pytest>=8.0",
59
+ "simms @ git+https://github.com/wits-cfa/simms.git",
60
+ ]
61
+
62
+ [project.urls]
63
+ Homepage = "https://github.com/SpheMakh/msutils"
64
+ Repository = "https://github.com/SpheMakh/msutils"
65
+ Issues = "https://github.com/SpheMakh/msutils/issues"
66
+
67
+ [tool.hatch.build.targets.wheel]
68
+ # `MSUtils` is a deprecated alias shim that re-exports `msutils`.
69
+ packages = ["src/msutils", "src/MSUtils"]
70
+
71
+ [tool.hatch.build.targets.sdist]
72
+ include = [
73
+ "/src/msutils",
74
+ "/src/MSUtils",
75
+ "/README.md",
76
+ "/LICENSE",
77
+ "/pyproject.toml",
78
+ ]
79
+
80
+ [tool.pytest.ini_options]
81
+ testpaths = ["tests"]
82
+ pythonpath = ["src"]
83
+ addopts = "--import-mode=importlib"
84
+ consider_namespace_packages = true
85
+
86
+ [tool.ruff]
87
+ line-length = 180
88
+
89
+ [tool.ruff.lint]
90
+ # Mirror the pre-refactor flake8 hard-fail gate: syntax errors and
91
+ # undefined names only. `# noqa: F821` markers in the source are load-bearing.
92
+ select = ["E9", "F63", "F7", "F82"]
@@ -0,0 +1,25 @@
1
+ """Deprecated import alias for :mod:`msutils`.
2
+
3
+ ``MSUtils`` was renamed to the lowercase ``msutils``. This shim keeps
4
+ ``import MSUtils`` / ``from MSUtils import msutils`` working while emitting a
5
+ :class:`FutureWarning` (shown by default, unlike ``DeprecationWarning``), then
6
+ aliases itself to the real package so that attribute and submodule access
7
+ transparently resolve to ``msutils``.
8
+ """
9
+ import sys
10
+ import warnings
11
+
12
+ warnings.warn(
13
+ "The 'MSUtils' package has been renamed to 'msutils'. Importing 'MSUtils' "
14
+ "is deprecated and will be removed in a future release; use 'msutils' "
15
+ "(e.g. 'from msutils import msutils') instead.",
16
+ FutureWarning,
17
+ stacklevel=2,
18
+ )
19
+
20
+ import msutils as _msutils
21
+
22
+ # Replace this shim module with the real package so that any subsequent
23
+ # attribute or submodule access (e.g. ``from MSUtils import msutils``) resolves
24
+ # against ``msutils`` rather than this empty stub.
25
+ sys.modules[__name__] = _msutils
@@ -0,0 +1,12 @@
1
+ """Deprecated module alias: use :mod:`msutils.weights` instead."""
2
+ import warnings
3
+
4
+ warnings.warn(
5
+ "`msutils.ClassESW` has been renamed to `msutils.weights`; the old name is "
6
+ "deprecated and will be removed in a future release.",
7
+ FutureWarning,
8
+ stacklevel=2,
9
+ )
10
+
11
+ from .weights import * # noqa: E402,F401,F403 (re-export the public API)
12
+ from .weights import __all__ # noqa: E402,F401
@@ -0,0 +1,43 @@
1
+ """msutils: CASA Measurement Set manipulation utilities.
2
+
3
+ The core column operations are exposed directly on the package, e.g.::
4
+
5
+ import msutils
6
+ msutils.summary(msname)
7
+ msutils.addcol(msname, "MODEL_DATA")
8
+
9
+ Feature-specific modules (``flagstats``, ``weights``) require optional
10
+ extras -- ``pip install msutils[flagstats]`` / ``msutils[plots]``.
11
+ """
12
+ from ._ms import (
13
+ STOKES_TYPES,
14
+ summary,
15
+ addcol,
16
+ sumcols,
17
+ copycol,
18
+ compute_vis_noise,
19
+ verify_antpos,
20
+ addnoise,
21
+ )
22
+
23
+ __all__ = [
24
+ "STOKES_TYPES",
25
+ "summary",
26
+ "addcol",
27
+ "sumcols",
28
+ "copycol",
29
+ "compute_vis_noise",
30
+ "verify_antpos",
31
+ "addnoise",
32
+ ]
33
+
34
+
35
+ def __getattr__(name):
36
+ # Lazily expose the deprecated `msutils.msutils` alias (emits a warning on
37
+ # import) without pulling it in on every package import. Import via
38
+ # importlib rather than `from . import msutils` to avoid recursing back
39
+ # through this __getattr__.
40
+ if name == "msutils":
41
+ import importlib
42
+ return importlib.import_module(__name__ + ".msutils")
43
+ raise AttributeError("module {0!r} has no attribute {1!r}".format(__name__, name))
@@ -0,0 +1,15 @@
1
+ """Shared logging helper for the msutils package."""
2
+ import logging
3
+
4
+
5
+ def create_logger(name):
6
+ """Return a console logger, attaching a handler only once per logger."""
7
+ log = logging.getLogger(name)
8
+ if not log.handlers:
9
+ cfmt = logging.Formatter("%(name)s - %(asctime)s %(levelname)s - %(message)s")
10
+ log.setLevel(logging.DEBUG)
11
+ console = logging.StreamHandler()
12
+ console.setLevel(logging.INFO)
13
+ console.setFormatter(cfmt)
14
+ log.addHandler(console)
15
+ return log