Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changes/30.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
added command line tool for uvfits to measurement set conversion using casa
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ dev = [
[project.scripts]
radiotools-info = "radiotools.info:main"
radiotools-vis = "radiotools.cli_tools.vis:main"
radiotools-fits2ms = "radiotools.cli_tools.fits2ms:main"

[tool.hatch.version]
source = "vcs"
Expand Down
52 changes: 52 additions & 0 deletions src/radiotools/cli_tools/fits2ms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Tool to convert uvfits files into measurement sets.
Single files or all files inside a directory can be converted.
"""

from pathlib import Path

import click
import numpy as np
from natsort import natsorted
from tqdm.auto import tqdm

from radiotools.utils import rmtree, uvfits2ms


@click.command()
@click.argument("fits_path", type=click.Path(exists=True, dir_okay=True))
@click.argument("ms_path", type=click.Path(exists=True, dir_okay=True))
@click.option("--log", default=False)
def main(fits_path, ms_path, log=False):
"""Convert uvfits files into measurement sets.

Parameters
----------
fits_path : str
Path to fits file or directory with fits files
ms_path : str
Path to store ms file or directory for ms files
"""
fits_path = Path(fits_path)
ms_path = Path(ms_path)

if ".ms" not in ms_path.name:
ms_path.mkdir(parents=True, exist_ok=True)

if fits_path.is_dir():
fits_files = natsorted(np.array([x for x in fits_path.iterdir()]))
else:
fits_files = fits_path

for i, path in enumerate(tqdm(fits_files)):
if fits_path.is_dir():
file_name = "vis_" + str(i) + ".ms"
out = ms_path / file_name
else:
out = ms_path.parent + "/vis_" + str(i) + ".ms"
if out.exists():
rmtree(out)
uvfits2ms(path, out)


if __name__ == "__main__":
main()
4 changes: 3 additions & 1 deletion src/radiotools/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .utils import get_array_names, img2jansky, rms
from .utils import get_array_names, img2jansky, rms, rmtree, uvfits2ms

__all__ = [
"get_array_names",
"img2jansky",
"rms",
"uvfits2ms",
"rmtree",
]
47 changes: 47 additions & 0 deletions src/radiotools/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import re
import subprocess
from pathlib import Path

import numpy as np
import requests
Expand Down Expand Up @@ -73,3 +75,48 @@ def img2jansky(image: ArrayLike, header: fits.Header):
* np.power(header["CDELT1"], 2)
/ (np.pi * header["BMIN"] * header["BMAJ"])
)


def uvfits2ms(fits_path, ms_path):
"""Converts a uvfits_file into a measurement set (ms file).

Parameters
----------
fits_path : str
path to fits_file
ms_path : str
path to store ms_file
"""
casa = "casa --quiet --nologger --nologfile --nogui --norc --agg -c "
arg = (
"importuvfits(fitsfile='"
+ str(fits_path)
+ "'"
+ ", vis="
+ "'"
+ str(ms_path)
+ "'"
+ ")"
)

command = casa + '"' + arg + '"'

subprocess.run(command, shell=True)


def rmtree(root: Path):
"""Recursively remove directories and files
starting from root directory.

Parameters
----------
root : Path
Root path of the directories you want to delete.
"""
for p in root.iterdir():
if p.is_dir():
rmtree(p)
else:
p.unlink()

root.rmdir()