├── requirements.in ├── stimela ├── cargo │ ├── base │ │ ├── __init__.py │ │ ├── cubical-pgs │ │ │ └── Dockerfile │ │ ├── curl │ │ │ └── Dockerfile │ │ ├── moresane │ │ │ └── Dockerfile │ │ ├── 21cmfast │ │ │ └── Dockerfile │ │ ├── sagecal │ │ │ └── Dockerfile │ │ ├── tigger │ │ │ ├── Dockerfile │ │ │ └── xvfb.init.d │ │ ├── aoflagger │ │ │ └── Dockerfile │ │ ├── aegean │ │ │ └── Dockerfile │ │ ├── lofar │ │ │ └── Dockerfile │ │ ├── casarest │ │ │ └── Dockerfile │ │ ├── pyddi │ │ │ └── Dockerfile │ │ ├── msutils │ │ │ └── Dockerfile │ │ ├── stimela2 │ │ │ ├── casasiteconfig.py │ │ │ ├── xvfb.init.d │ │ │ └── Dockerfile │ │ ├── catdagger │ │ │ └── Dockerfile │ │ ├── eidos │ │ │ └── Dockerfile │ │ ├── sourcery │ │ │ └── Dockerfile │ │ ├── spimple │ │ │ └── Dockerfile │ │ ├── montage │ │ │ └── Dockerfile │ │ ├── astropy │ │ │ └── Dockerfile │ │ ├── politsiyakat │ │ │ └── Dockerfile │ │ ├── pybdsf │ │ │ └── Dockerfile │ │ ├── sharpener │ │ │ └── Dockerfile │ │ ├── rm-tools │ │ │ └── Dockerfile │ │ ├── katdal │ │ │ └── Dockerfile │ │ ├── codex-africanus │ │ │ └── Dockerfile │ │ ├── owlcat │ │ │ └── Dockerfile │ │ ├── rfinder │ │ │ └── Dockerfile │ │ ├── cubical │ │ │ └── Dockerfile │ │ ├── ddfacet │ │ │ ├── Dockerfile │ │ │ └── xvfb.init.d │ │ ├── sunblocker │ │ │ └── Dockerfile │ │ ├── shadems │ │ │ └── Dockerfile │ │ ├── rfimasker │ │ │ └── Dockerfile │ │ ├── equolver │ │ │ └── Dockerfile │ │ ├── ragavi │ │ │ └── Dockerfile │ │ ├── sofia2 │ │ │ └── Dockerfile │ │ ├── breizorro │ │ │ └── Dockerfile │ │ ├── contsub │ │ │ └── Dockerfile │ │ ├── base │ │ │ ├── Dockerfile │ │ │ └── xvfb.init.d │ │ ├── aimfast │ │ │ └── Dockerfile │ │ ├── group.template │ │ ├── halo-fdca │ │ │ └── Dockerfile │ │ ├── meqtrees │ │ │ └── xvfb.init.d │ │ ├── tricolour │ │ │ └── Dockerfile │ │ ├── sofia │ │ │ └── Dockerfile │ │ ├── mosaic-queen │ │ │ └── Dockerfile │ │ ├── wsclean │ │ │ └── Dockerfile │ │ ├── passwd.template │ │ ├── casa │ │ │ └── Dockerfile │ │ └── chgcentre │ │ │ └── Dockerfile │ ├── cab │ │ ├── casa_clean │ │ │ └── src │ │ │ │ ├── imager_params.json │ │ │ │ └── run.py │ │ ├── casa_ft │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_concat │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_fixvis │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_listobs │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_plotcal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_plotms │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_plotuv │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_setjy │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_split │ │ │ └── src │ │ │ │ └── run.py │ │ ├── ragavi │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_applycal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_clearcal │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_exportfits │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_flagdata │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_flagmanager │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_fringefit │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_importfits │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_mstransform │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_oldsplit │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_plotants │ │ │ ├── src │ │ │ │ └── run.py │ │ │ ├── xvfb.init.d │ │ │ └── parameters.json │ │ ├── casa_rmtables │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_uvcontsub │ │ │ └── src │ │ │ │ └── run.py │ │ ├── spimple_binterp │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_polcal │ │ │ ├── run.py │ │ │ └── src │ │ │ │ └── run.py │ │ ├── spimple_imconv │ │ │ └── src │ │ │ │ └── run.py │ │ ├── spimple_spifit │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_polfromgain │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── stimela_runscript │ │ ├── equolver │ │ │ └── src │ │ │ │ └── run.py │ │ ├── owlcat_plotelev │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── rmsynth1d │ │ │ └── src │ │ │ │ └── run.py │ │ ├── simms │ │ │ └── src │ │ │ │ └── run.py │ │ ├── rfimasker │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── mProject │ │ │ └── src │ │ │ │ └── run.py │ │ ├── tricolour │ │ │ └── src │ │ │ │ └── run.py │ │ ├── mProjectCube │ │ │ └── src │ │ │ │ └── run.py │ │ ├── rmclean3d │ │ │ └── src │ │ │ │ └── run.py │ │ ├── rmsynth3d │ │ │ └── src │ │ │ │ └── run.py │ │ ├── shadems_direct │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_fluxscale │ │ │ └── src │ │ │ │ └── run.py │ │ ├── update_casa_version_tag.py │ │ ├── ragavi_vis │ │ │ └── src │ │ │ │ └── run.py │ │ ├── pycasacore │ │ │ ├── parameters.json │ │ │ └── src │ │ │ │ └── run.py │ │ ├── rfinder │ │ │ ├── xvfb.init.d │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_plotuv │ │ │ ├── xvfb.init.d │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_script │ │ │ ├── parameters.json │ │ │ └── src │ │ │ │ └── run.py │ │ ├── cubical_pgs │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_uvsub │ │ │ ├── parameters.json │ │ │ └── src │ │ │ │ └── run.py │ │ ├── simulator │ │ │ └── src │ │ │ │ └── tdlconf.profiles │ │ ├── casa_statwt │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_applycal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_setjy │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_imregrid │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_virtualconcat │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_gencal │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── casa_makemask │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── halo-fdca │ │ │ └── src │ │ │ │ └── run.py │ │ ├── pyddi │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_gaincal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── curl │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── politsiyakat_cal_phase │ │ │ └── src │ │ │ │ └── run.py │ │ ├── politsiyakat_autocorr_amp │ │ │ └── src │ │ │ │ └── run.py │ │ ├── eidos │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── chgcentre │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── cleanmask │ │ │ └── src │ │ │ │ └── run.py │ │ ├── flagstats │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── crystalball │ │ │ └── src │ │ │ │ └── run.py │ │ ├── catdagger │ │ │ └── src │ │ │ │ └── run.py │ │ ├── breizorro │ │ │ └── src │ │ │ │ └── run.py │ │ ├── sunblocker │ │ │ └── src │ │ │ │ └── run.py │ │ ├── autoflagger │ │ │ └── src │ │ │ │ └── run.py │ │ ├── mosaic_queen │ │ │ └── src │ │ │ │ └── run.py │ │ ├── stimela2 │ │ │ ├── parameters.json │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_bandpass │ │ │ └── src │ │ │ │ └── run.py │ │ ├── flagms │ │ │ └── src │ │ │ │ └── run.py │ │ ├── tigger_restore │ │ │ └── src │ │ │ │ └── run.py │ │ ├── mosaicsteward │ │ │ ├── src │ │ │ │ └── run.py │ │ │ └── parameters.json │ │ ├── shadems │ │ │ └── src │ │ │ │ └── run.py │ │ ├── cubical │ │ │ └── src │ │ │ │ └── run.py │ │ ├── mvftoms │ │ │ └── src │ │ │ │ └── run.py │ │ ├── sofia │ │ │ └── src │ │ │ │ └── run.py │ │ ├── imcontsub │ │ │ └── src │ │ │ │ └── run.py │ │ ├── cubical_ddf │ │ │ └── src │ │ │ │ └── run.py │ │ ├── aimfast │ │ │ └── src │ │ │ │ └── run.py │ │ ├── tigger_tag │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_polcal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_gaincal │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa47_bandpass │ │ │ └── src │ │ │ │ └── run.py │ │ ├── tigger_convert │ │ │ └── src │ │ │ │ └── run.py │ │ ├── montage │ │ │ └── src │ │ │ │ └── run.py │ │ ├── fitstool │ │ │ └── src │ │ │ │ └── run.py │ │ ├── sharpener │ │ │ └── src │ │ │ │ └── run.py │ │ ├── casa_immath │ │ │ └── src │ │ │ │ └── run.py │ │ ├── msutils │ │ │ └── src │ │ │ │ └── run.py │ │ └── wsclean │ │ │ └── src │ │ │ └── run.py │ └── __init__.py ├── tests │ ├── acceptance_tests │ │ └── input │ │ │ └── README.md │ └── unit_tests │ │ └── cab │ │ └── custom │ │ ├── src │ │ ├── run.sh │ │ └── run.py │ │ └── parameters.json ├── dismissable.py └── exceptions.py ├── examples └── input │ └── README.md ├── requirements.txt ├── docs └── images │ └── meerkat-layout.png ├── Dockerfile ├── bin └── stimela ├── MANIFEST.in ├── .gitignore ├── pyproject.toml ├── CHANGES.md ├── .github └── workflows │ ├── python-publish.yml │ └── python-package.yml ├── README.rst └── Jenkinsfile.sh /requirements.in: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stimela/cargo/base/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/input/README.md: -------------------------------------------------------------------------------- 1 | ## Place input here 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | future-fstrings 2 | nose 3 | -------------------------------------------------------------------------------- /stimela/tests/acceptance_tests/input/README.md: -------------------------------------------------------------------------------- 1 | ## Place input here 2 | -------------------------------------------------------------------------------- /stimela/cargo/base/cubical-pgs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/cubical:1.5.8 2 | RUN pip install -U scabha -------------------------------------------------------------------------------- /stimela/cargo/base/curl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install curl 3 | -------------------------------------------------------------------------------- /stimela/cargo/base/moresane/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN pip install pymoresane 3 | -------------------------------------------------------------------------------- /stimela/cargo/base/21cmfast/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install 21cmfast 3 | -------------------------------------------------------------------------------- /stimela/cargo/base/sagecal/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install sagecal 3 | -------------------------------------------------------------------------------- /stimela/cargo/base/tigger/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.7.1 2 | RUN pip install astro-tigger-lsm 3 | -------------------------------------------------------------------------------- /stimela/cargo/base/aoflagger/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install aoflagger 3 | -------------------------------------------------------------------------------- /docs/images/meerkat-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratt-ru/Stimela-classic/HEAD/docs/images/meerkat-layout.png -------------------------------------------------------------------------------- /stimela/cargo/base/aegean/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/meqtrees:1.2.0 2 | RUN pip install --upgrade pip 3 | RUN pip install AegeanTools 4 | -------------------------------------------------------------------------------- /stimela/cargo/base/lofar/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install python-astro-tigger-lsm pybdsf 3 | RUN pip install astropy 4 | -------------------------------------------------------------------------------- /stimela/cargo/base/casarest/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install casarest python-owlcat casacore-data 3 | RUN pip install msutils 4 | -------------------------------------------------------------------------------- /stimela/tests/unit_tests/cab/custom/src/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | python /scratch/code/run.py 2>&1 | tee -a $LOGFILE 3 | (exit ${PIPESTATUS[0]}) 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.0.1 2 | ADD . /Stimela 3 | WORKDIR /Stimela 4 | RUN pip install -U pip 5 | RUN pip install /Stimela 6 | ENV USER root 7 | RUN stimela 8 | -------------------------------------------------------------------------------- /stimela/cargo/base/pyddi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.0.1 2 | RUN docker-apt-install python3-numpy python3-pip 3 | RUN apt-get update 4 | RUN pip3 install pyddi 5 | -------------------------------------------------------------------------------- /stimela/cargo/base/msutils/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.4.6 2 | MAINTAINER 3 | RUN pip install msutils 4 | RUN python -c "import MSUtils.msutils" 5 | -------------------------------------------------------------------------------- /stimela/cargo/base/stimela2/casasiteconfig.py: -------------------------------------------------------------------------------- 1 | import casadata 2 | 3 | measurespath = casadata.datapath 4 | measures_auto_update = False 5 | data_auto_update = False 6 | -------------------------------------------------------------------------------- /stimela/cargo/base/catdagger/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/astropy:1.2.0 2 | RUN docker-apt-install python-casacore 3 | 4 | RUN pip install catdagger==0.2.1 5 | 6 | RUN dagger --help -------------------------------------------------------------------------------- /stimela/cargo/base/eidos/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | MAINTAINER 3 | RUN pip3 install -U pip pyyaml "eidos>=1.1.2" 4 | RUN eidos -h 5 | -------------------------------------------------------------------------------- /stimela/cargo/base/sourcery/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install pybdsf python-astro-tigger-lsm 3 | RUN pip install git+git://github.com/radio-astro/sourcery 4 | -------------------------------------------------------------------------------- /stimela/cargo/base/spimple/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | RUN pip3 install -U pip setuptools 3 | RUN pip install scabha spimple 4 | RUN spimple-spifit -h 5 | RUN spimple-binterp -h 6 | RUN spimple-imconv -h -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_clean/src/imager_params.json: -------------------------------------------------------------------------------- 1 | {"weight": "briggs", "npix": 4096, "psf": false, "cellsize": 2, "dirty": true, "clean": false, "robust": 0, "imager": "wsclean", "outdir": "/output", "indir": "/output"} -------------------------------------------------------------------------------- /stimela/cargo/base/montage/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | RUN docker-apt-install montage python3-montagepy vim 3 | RUN pip install --upgrade pip setuptools 4 | RUN pip install -U astroquery>=0.3.8 scabha==0.3.2 5 | -------------------------------------------------------------------------------- /bin/stimela: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | 6 | import stimela 7 | import stimela.main as main 8 | 9 | # Ensure that logging infrastructure exists 10 | 11 | main.main([a for a in sys.argv[1:]]) 12 | -------------------------------------------------------------------------------- /stimela/cargo/base/astropy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.7.1 2 | RUN pip install astropy \ 3 | numpy \ 4 | scipy \ 5 | futures \ 6 | scikit-image 7 | 8 | #RUN pip install git+https://github.com/SpheMakh/cleanmask 9 | -------------------------------------------------------------------------------- /stimela/cargo/base/politsiyakat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install libfreetype6-dev \ 3 | wcslib-dev libcfitsio-dev \ 4 | python-casacore 5 | RUN pip install -U pip setuptools wheel virtualenv 6 | RUN pip install -U politsiyakat>=0.3.7 7 | -------------------------------------------------------------------------------- /stimela/cargo/base/pybdsf/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | RUN docker-apt-install gfortran libboost-python-dev libboost-numpy-dev 3 | RUN pip install pip -U 4 | RUN pip install numpy scipy 5 | RUN pip install astropy astro-tigger-lsm git+https://github.com/lofar-astron/PyBDSF 6 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_ft/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_concat/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_fixvis/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_listobs/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotcal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotms/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotuv/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_setjy/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_split/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/ragavi/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | args = [config.binary] + parse_parameters(repeat=" ") 7 | 8 | # run the command 9 | if prun(args) != 0: 10 | sys.exit(1) 11 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_applycal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_clearcal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_exportfits/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_flagdata/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_flagmanager/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_fringefit/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_importfits/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_mstransform/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_oldsplit/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotants/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_rmtables/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_uvcontsub/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | task = crasa.CasaTask(config.binary, **parameters_dict) 8 | task.run() 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/spimple_binterp/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | args = [config.binary] + parse_parameters(repeat=" ") 7 | 8 | # run the command 9 | if prun(args) != 0: 10 | sys.exit(1) 11 | -------------------------------------------------------------------------------- /stimela/cargo/base/sharpener/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install texmaker \ 3 | dvipng \ 4 | python-tk \ 5 | python-numpy 6 | RUN apt-get update 7 | RUN pip install --upgrade pip 8 | RUN pip install sharpener 9 | -------------------------------------------------------------------------------- /stimela/cargo/base/rm-tools/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | RUN docker-apt-install python3-tk 3 | RUN pip install RM-Tools pymultinest "git+https://github.com/ratt-ru/scabha@local-prefix" 4 | RUN rmsynth1d --help 5 | RUN rmclean1d --help 6 | RUN rmsynth3d --help 7 | RUN rmclean3d --help 8 | #RUN qufit --help 9 | -------------------------------------------------------------------------------- /stimela/cargo/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | ekhaya = os.path.dirname(__file__) 4 | 5 | # Path to base images 6 | BASE_PATH = "{:s}/base".format(ekhaya) 7 | 8 | # Path to executor images 9 | CAB_PATH = "{:s}/cab".format(ekhaya) 10 | 11 | # Path to config templates 12 | CONFIG_TEMPLATES = "{:s}/configs".format(ekhaya) 13 | -------------------------------------------------------------------------------- /stimela/cargo/base/katdal/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | MAINTAINER 3 | RUN docker-apt-install libboost-dev \ 4 | casacore-dev \ 5 | gfortran 6 | RUN pip install -U six numpy 7 | RUN pip install katdal[ms,s3] 8 | RUN export NUMBA_CACHE_DIR=/dat 9 | RUN mvftoms.py -h 10 | RUN python --version 11 | 12 | -------------------------------------------------------------------------------- /stimela/cargo/base/codex-africanus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | mAINTAINER 3 | RUN docker-apt-install casacore-dev \ 4 | libboost-python-dev \ 5 | libcfitsio-dev \ 6 | wcslib-dev 7 | RUN pip install --upgrade pip setuptools astropy pyyaml 8 | RUN pip install crystalball>=0.4.0 9 | RUN crystalball -h 10 | -------------------------------------------------------------------------------- /stimela/cargo/base/owlcat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | RUN docker-apt-install python3-casacore \ 3 | casacore-dev \ 4 | libcfitsio-dev \ 5 | wcslib-dev 6 | RUN pip install -U meqtrees-cattery "python-casacore>=3.3.1" "owlcat>=1.6.3" scabha future-fstrings 7 | ENV MEQTREES_CATTERY_PATH /usr/local/lib/python3.6/dist-packages/Cattery 8 | -------------------------------------------------------------------------------- /stimela/dismissable.py: -------------------------------------------------------------------------------- 1 | class dismissable: 2 | """ 3 | Wrapper for optional parameters to stimela 4 | Initialize with val == None to force stimela to skip 5 | parsing parameter. 6 | """ 7 | 8 | def __init__(self, val=None): 9 | self.__val = val 10 | 11 | def __call__(self): 12 | return self.__val 13 | -------------------------------------------------------------------------------- /stimela/cargo/base/rfinder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install python-casacore \ 3 | xvfb \ 4 | texmaker \ 5 | dvipng \ 6 | python-tk 7 | 8 | RUN pip install --upgrade pip 9 | RUN pip install rfinder -U 10 | RUN pip install pillow --upgrade 11 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include CHANGES.md 4 | include requirements.txt 5 | 6 | recursive-include Dockerfile 7 | recursive-include src run.py run.py 8 | recursive-exclude cargo/base/* Dockerfile xvfb.init.d 9 | recursive-exclude cargo/cab/* Dockerfile xvfb.init.d 10 | recursive-exclude * __pycache__ 11 | recursive-exclude * *.py[co] 12 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_polcal/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | save_result = parameters_dict.pop("save_result", None) 8 | 9 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 10 | task.run() 11 | -------------------------------------------------------------------------------- /stimela/cargo/base/cubical/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/ddfacet:1.7.1 2 | RUN apt install -y \ 3 | casacore-data 4 | RUN . /opt/venv/bin/activate && \ 5 | #python -m pip install 'cubical[lsm-support,degridder-support]==1.6.3' 'scabha==0.3.2' 6 | python -m pip install git+https://github.com/ratt-ru/CubiCal.git scabha==0.3.2 7 | RUN DDF.py --help 8 | RUN gocubical --help 9 | -------------------------------------------------------------------------------- /stimela/cargo/cab/spimple_imconv/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | pars = parse_parameters(repeat=" ") 7 | if "--psf-pars" in pars: 8 | pars = " ".join(pars).split() 9 | 10 | args = [config.binary] + pars 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/spimple_spifit/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | pars = parse_parameters(repeat=" ") 7 | if "--psf-pars" in pars: 8 | pars = " ".join(pars).split() 9 | 10 | args = [config.binary] + pars 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_polfromgain/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | save_result = parameters_dict.pop("save_result", None) 8 | 9 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 10 | task.run() 11 | -------------------------------------------------------------------------------- /stimela/cargo/cab/stimela_runscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -u 4 | 5 | /etc/init.d/xvfb start 2>&1 >/dev/null || echo "Virtual frame buffer not installed. You may not be able to plot with this cab" 6 | 7 | python $STIMELA_MOUNT/code/run.py 2>&1 8 | 9 | EXIT_STAT=${PIPESTATUS[0]} 10 | 11 | /etc/init.d/xvfb stop 2>&1 >/dev/null || echo "" 12 | 13 | exit $EXIT_STAT 14 | -------------------------------------------------------------------------------- /stimela/cargo/base/ddfacet/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bhugo/ddfacet:0.7.0 2 | MAINTAINER Ben Hugo "bhugo@ska.ac.za" 3 | RUN pip3 install pyyaml 4 | RUN apt update -y 5 | RUN apt install xvfb -y 6 | COPY xvfb.init.d /etc/init.d/xvfb 7 | RUN chmod 755 /etc/init.d/xvfb 8 | RUN chmod 777 /var/run 9 | RUN ln -s /usr/bin/python3 /usr/bin/python 10 | ENV DISPLAY :99 11 | RUN DDF.py --help 12 | ENTRYPOINT [] 13 | -------------------------------------------------------------------------------- /stimela/cargo/base/sunblocker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - 3 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 10 4 | RUN apt-get update 5 | RUN apt-get -y install xvfb 6 | RUN pip3 install -U pip setuptools \ 7 | pyyaml 8 | RUN pip install scabha 9 | RUN pip install -I sunblocker==1.0.1 10 | -------------------------------------------------------------------------------- /stimela/cargo/base/shadems/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | MAINTAINER 3 | RUN docker-apt-install python3-casacore \ 4 | casacore-dev \ 5 | libcfitsio-dev \ 6 | wcslib-dev 7 | RUN pip install -I numpy scabha 8 | RUN pip install git+https://github.com/ratt-ru/shadeMS.git@b050 9 | #RUN pip install git+https://github.com/o-smirnov/datashader 10 | RUN shadems -h 11 | -------------------------------------------------------------------------------- /stimela/cargo/base/rfimasker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.5 2 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 10 3 | RUN pip3 install -U --force pip 4 | RUN docker-apt-install python-numpy python-casacore 5 | RUN pip install -U numpy scipy python-casacore 6 | RUN pip install --no-deps git+https://github.com/SpheMakh/RFIMasker@master 7 | ARG SCABHA=scabha 8 | RUN pip install $SCABHA 9 | 10 | -------------------------------------------------------------------------------- /stimela/cargo/cab/equolver/src/run.py: -------------------------------------------------------------------------------- 1 | # config -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | args = [config.binary] + parse_parameters(repeat=" ") 7 | for i in range(len(args)): 8 | if args[i] == "--verb": 9 | val = args.pop(i + 1) 10 | if val == "False": 11 | args.pop(i) 12 | 13 | # run the command 14 | if prun(args) != 0: 15 | sys.exit(1) 16 | -------------------------------------------------------------------------------- /stimela/cargo/base/equolver/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.6.0 2 | RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - 3 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 10 4 | RUN apt-get update 5 | RUN pip3 install -U pip setuptools \ 6 | pyyaml 7 | RUN pip install scabha 8 | RUN pip install -I equolver==0.0.8 9 | RUN pip install https://www.astro.rug.nl/software/kapteyn/kapteyn-3.0.tar.gz 10 | RUN equolver -h -v 11 | -------------------------------------------------------------------------------- /stimela/cargo/cab/owlcat_plotelev/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | from scabha import config, parse_parameters, prun 4 | 5 | # If a list of fields is given, insert them as repeated arguments. 6 | # Other arguments not allowed to be lists. 7 | args = [config.binary] + parse_parameters( 8 | repeat=True, positional=["msname"], mandatory=["msname"] 9 | ) 10 | 11 | # run the command 12 | if prun(args) != 0: 13 | sys.exit(1) 14 | -------------------------------------------------------------------------------- /stimela/cargo/base/ragavi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.5 2 | RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - 3 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 10 4 | RUN apt-get update 5 | RUN pip3 install -U pip setuptools \ 6 | pyyaml \ 7 | python-casacore 8 | RUN pip install numba==0.48 9 | RUN pip install scabha 10 | RUN pip install -I ragavi 11 | RUN ragavi-gains -h 12 | RUN ragavi-vis -h 13 | RUN ragavi-vis -v -------------------------------------------------------------------------------- /stimela/cargo/cab/rmsynth1d/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of fields is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=True, positional=["dataFile"], mandatory=["dataFile"] 10 | ) 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/simms/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of fields is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=True, positional=["antenna-file"], mandatory=["antenna-file"] 10 | ) 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rfimasker/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of MSs is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=None, positional=["ms"], mandatory=["ms"], repeat_dict=dict(ms=True) 10 | ) 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/mProject/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | 3 | from scabha import config, parse_parameters, prun 4 | 5 | # If a list of fields is given, insert them as repeated arguments. 6 | # Other arguments not allowed to be lists. 7 | args = [config.binary] + parse_parameters(repeat=True) 8 | 9 | # run the command 10 | if prun(args) != 0: 11 | raise SystemError( 12 | f" {config.binary} exited with a non-zero code. See logs for details" 13 | ) 14 | -------------------------------------------------------------------------------- /stimela/cargo/cab/tricolour/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of fields is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=None, positional=["ms"], mandatory=["ms"], repeat_dict={"field-names": ","} 10 | ) 11 | 12 | # run the command 13 | if prun(args) != 0: 14 | sys.exit(1) 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/mProjectCube/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | 3 | from scabha import config, parse_parameters, prun 4 | 5 | # If a list of fields is given, insert them as repeated arguments. 6 | # Other arguments not allowed to be lists. 7 | args = [config.binary] + parse_parameters(repeat=True) 8 | 9 | # run the command 10 | if prun(args) != 0: 11 | raise SystemError( 12 | f" {config.binary} exited with a non-zero code. See logs for details" 13 | ) 14 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rmclean3d/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of fields is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=True, 10 | positional=["dirty-pdf", "rmsf-fwhm"], 11 | mandatory=["dirty-pdf", "rmsf-fwhm"], 12 | ) 13 | 14 | # run the command 15 | if prun(args) != 0: 16 | sys.exit(1) 17 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rmsynth3d/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parse_parameters, prun 5 | 6 | # If a list of fields is given, insert them as repeated arguments. 7 | # Other arguments not allowed to be lists. 8 | args = [config.binary] + parse_parameters( 9 | repeat=True, 10 | positional=["fitsq", "fitsu", "freqs"], 11 | mandatory=["fitsq", "fitsu", "freqs"], 12 | ) 13 | 14 | # run the command 15 | if prun(args) != 0: 16 | sys.exit(1) 17 | -------------------------------------------------------------------------------- /stimela/cargo/base/sofia2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | RUN docker-apt-install build-essential \ 3 | casacore-dev \ 4 | python3 \ 5 | python3-pip \ 6 | wcslib-dev 7 | RUN pip install -U setuptools \ 8 | astro-tigger-lsm 9 | RUN git clone https://github.com/SoFiA-Admin/SoFiA-2.git 10 | RUN cd /SoFiA-2 && git fetch && git fetch --tags 11 | RUN cd /SoFiA-2 && git checkout v2.5.0 12 | RUN cd /SoFiA-2 && ./compile.sh -fopenmp 13 | RUN cd /SoFiA-2 && ln sofia /usr/bin/sofia 14 | 15 | -------------------------------------------------------------------------------- /stimela/cargo/base/breizorro/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/meqtrees:1.6.3 2 | RUN docker-apt-install python3-pip \ 3 | python3-numpy \ 4 | python3-matplotlib \ 5 | gfortran \ 6 | python-dev \ 7 | libboost-all-dev \ 8 | libboost-python-dev \ 9 | libboost-numpy-dev \ 10 | python3-setuptools \ 11 | pybdsf 12 | 13 | 14 | RUN pip3 install breizorro 15 | -------------------------------------------------------------------------------- /stimela/cargo/cab/shadems_direct/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | import os 4 | import os.path 5 | 6 | from scabha import log, config, parameters, prun_multi, OUTPUT 7 | 8 | ms = os.path.abspath(parameters.ms) 9 | os.chdir(OUTPUT) 10 | 11 | errors = prun_multi([f"{config.binary} {ms} {args}" for args in parameters.args]) 12 | 13 | for cmd, exc in errors: 14 | log.error(f"{cmd}: failed with return code {exc.returncode}") 15 | 16 | if errors and not parameters.get("ignore_errors"): 17 | sys.exit(1) 18 | -------------------------------------------------------------------------------- /stimela/cargo/base/contsub/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | RUN apt update 3 | RUN apt dist-upgrade -y 4 | RUN apt install -y python3-setuptools \ 5 | libboost-python-dev \ 6 | python3-pip \ 7 | git \ 8 | xvfb \ 9 | curl \ 10 | wget \ 11 | python-is-python3 \ 12 | python3-full \ 13 | pipx 14 | 15 | ENV STIMELA_VENV="/venv" 16 | ENV STIMELA_VENV_BIN="${STIMELA_VENV}/bin" 17 | RUN python -m venv $STIMELA_VENV 18 | ENV PATH="${STIMELA_VENV_BIN}/:$PATH" 19 | 20 | RUN $STIMELA_VENV_BIN/pip install "contsub>=1.0.5" 21 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_fluxscale/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | import os 5 | 6 | print(f"Running CASA task '{config.binary}'") 7 | 8 | save_result = parameters_dict.pop("save_result", None) 9 | overwrite = parameters_dict.pop("overwrite", False) 10 | fluxtable = parameters_dict["fluxtable"] 11 | if overwrite: 12 | os.system(f"rm -fr {fluxtable}") 13 | 14 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 15 | task.run() 16 | -------------------------------------------------------------------------------- /stimela/cargo/cab/update_casa_version_tag.py: -------------------------------------------------------------------------------- 1 | import json 2 | import glob 3 | from collections import OrderedDict 4 | 5 | for cabfile in glob.glob("casa_*/*.json"): 6 | print(cabfile) 7 | with open(cabfile, "rb") as stdr: 8 | cabdict = json.load(stdr, object_pairs_hook=OrderedDict) 9 | cabdict["version"] = ["4.7.2", "5.6.1-8", "5.8.0"] 10 | cabdict["tag"] = ["0.3.0-2", "1.6.3", "1.7.1"] 11 | cabdict["junk"] = ["%s.last" % (cabdict["binary"])] 12 | with open(cabfile, "w") as stdw: 13 | json.dump(cabdict, stdw, indent=2) 14 | -------------------------------------------------------------------------------- /stimela/cargo/cab/ragavi_vis/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | 4 | from scabha import config, parameters, prun 5 | 6 | args = [config.binary] 7 | 8 | # convert arguments to flat list of PrefixName Arguments 9 | for name, value in parameters.items(): 10 | if value in [None, "", " ", False]: 11 | continue 12 | args.append(f"{config.prefix}{name}") 13 | 14 | if not isinstance(value, list): 15 | value = [value] 16 | 17 | args += list(map(str, value)) 18 | 19 | # run the command 20 | if prun(args) != 0: 21 | sys.exit(1) 22 | -------------------------------------------------------------------------------- /stimela/cargo/base/base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM kernsuite/base:dev 2 | RUN docker-apt-upgrade 3 | RUN docker-apt-install \ 4 | python3-setuptools \ 5 | libboost-python-dev \ 6 | python3-pip \ 7 | git \ 8 | xvfb \ 9 | curl \ 10 | wget 11 | RUN ln -s /usr/bin/python3 /usr/bin/python 12 | RUN pip --version 13 | RUN python --version 14 | RUN pip install --upgrade --ignore-installed pip setuptools --break-system-packages 15 | RUN pip install --break-system-packages pyyaml scabha==0.3.2 16 | COPY xvfb.init.d /etc/init.d/xvfb 17 | RUN chmod 755 /etc/init.d/xvfb 18 | RUN chmod 777 /var/run 19 | ENV DISPLAY :99 20 | -------------------------------------------------------------------------------- /stimela/cargo/base/aimfast/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | RUN docker-apt-install python3-pip \ 3 | python3-numpy \ 4 | python3-matplotlib \ 5 | gfortran \ 6 | python-dev \ 7 | libboost-all-dev \ 8 | libboost-python-dev \ 9 | libboost-numpy-dev \ 10 | python3-setuptools \ 11 | pybdsf 12 | 13 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.8 10 14 | RUN pip3 install -U pip bdsf 15 | RUN pip3 install aimfast 16 | -------------------------------------------------------------------------------- /stimela/cargo/base/group.template: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | daemon:x:1: 3 | bin:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mail:x:8: 10 | news:x:9: 11 | uucp:x:10: 12 | man:x:12: 13 | proxy:x:13: 14 | kmem:x:15: 15 | dialout:x:20: 16 | fax:x:21: 17 | voice:x:22: 18 | cdrom:x:24: 19 | floppy:x:25: 20 | tape:x:26: 21 | sudo:x:27: 22 | audio:x:29: 23 | dip:x:30: 24 | www-data:x:33: 25 | backup:x:34: 26 | operator:x:37: 27 | list:x:38: 28 | irc:x:39: 29 | src:x:40: 30 | gnats:x:41: 31 | shadow:x:42: 32 | utmp:x:43: 33 | video:x:44: 34 | sasl:x:45: 35 | plugdev:x:46: 36 | staff:x:50: 37 | games:x:60: 38 | users:x:100: 39 | nogroup:x:65534: 40 | crontab:x:101: 41 | messagebus:x:102: 42 | ssh:x:103: 43 | -------------------------------------------------------------------------------- /stimela/cargo/cab/pycasacore/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "pycasacore", 3 | "base": "stimela/meqtrees", 4 | "tag": "1.2.4", 5 | "description": "Runs a user defined script in a python environment with python-casaore", 6 | "prefix": "", 7 | "binary": "python", 8 | "junk":[], 9 | "msdir": true, 10 | "parameters": [ 11 | { 12 | "info": "MS to process", 13 | "dtype": "file", 14 | "required": true, 15 | "name": "msname", 16 | "io": "msfile" 17 | }, 18 | { 19 | "info": "Custom script (string) to run within CASA", 20 | "dtype": "str", 21 | "name": "script" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /stimela/cargo/base/halo-fdca/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/meqtrees:1.6.3 2 | RUN docker-apt-install python3-pip \ 3 | python3-numpy \ 4 | python3-matplotlib \ 5 | python3-astropy \ 6 | libboost-all-dev \ 7 | libboost-numpy-dev \ 8 | python3-setuptools 9 | 10 | RUN pip3 install astroquery corner emcee pandas pyregion scikit-image tqdm 11 | 12 | RUN git clone https://github.com/JortBox/Halo-FDCA halo-fdca-dir 13 | RUN cd halo-fdca-dir 14 | WORKDIR "halo-fdca-dir" 15 | RUN git checkout v1.5 16 | RUN ls 17 | RUN chmod +x HaloFitting.py 18 | RUN ln -s /halo-fdca-dir/HaloFitting.py /usr/bin/halofitting 19 | RUN halofitting -h 20 | -------------------------------------------------------------------------------- /stimela/cargo/base/base/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/base/ddfacet/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/base/tigger/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rfinder/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/base/meqtrees/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/base/stimela2/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_plotuv/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotants/xvfb.init.d: -------------------------------------------------------------------------------- 1 | XVFB=/usr/bin/Xvfb 2 | XVFBARGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 3 | RGS=":99 -screen 0 1024x768x24 -fbdir /var/run -ac" 4 | PIDFILE=/var/run/xvfb.pid 5 | case "$1" in 6 | start) 7 | echo -n "Starting virtual X frame buffer: Xvfb" 8 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 9 | echo "." 10 | ;; 11 | stop) 12 | echo -n "Stopping virtual X frame buffer: Xvfb" 13 | start-stop-daemon --stop --quiet --pidfile $PIDFILE 14 | echo "." 15 | ;; 16 | restart) 17 | $0 stop 18 | $0 start 19 | ;; 20 | *) 21 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 22 | exit 1 23 | esac 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_script/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_script", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Runs a user defined script within CASA", 10 | "prefix": "", 11 | "binary": "casa", 12 | "junk": [ 13 | "casa.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "MS to process", 19 | "dtype": "file", 20 | "name": "vis", 21 | "io": "msfile" 22 | }, 23 | { 24 | "info": "Custom script (string) to run within CASA", 25 | "default": "print(\"Hello CASA!\")", 26 | "name": "script", 27 | "dtype": "str" 28 | } 29 | ], 30 | "version": [ 31 | "4.7.2", 32 | "5.6.1-8", 33 | "5.8.0" 34 | ] 35 | } -------------------------------------------------------------------------------- /stimela/cargo/base/tricolour/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM kernsuite/base:dev 2 | MAINTAINER 3 | RUN docker-apt-install python3-casacore \ 4 | casacore-dev \ 5 | python3-numpy \ 6 | python3-setuptools \ 7 | libboost-python-dev \ 8 | libcfitsio-dev \ 9 | wcslib-dev \ 10 | python3-pip \ 11 | git \ 12 | xvfb 13 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.6 10 14 | RUN pip3 install -U pip setuptools 15 | RUN pip3 install astropy pyyaml tricolour>=0.1.7 16 | ENV DISPLAY :99 17 | 18 | # so we can use use e.g. docker build --build-arg SCABHA=git+https://github.com/ratt-ru/scabha.git@branch to 19 | # install from a dev version, instead of a release package 20 | ARG SCABHA=scabha 21 | RUN pip install $SCABHA 22 | 23 | 24 | RUN tricolour --help 25 | -------------------------------------------------------------------------------- /stimela/cargo/cab/cubical_pgs/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | from scabha import config, parameters_dict, prun, parse_parameters 4 | 5 | """ 6 | config: 7 | contains the sections before parameters in params.json 8 | .binary has the name of the binary to be executed 9 | parameters_dict: dict 10 | contains all the provided parameters, even the positional ones 11 | parse_parameters: function 12 | Forms a list containing all the provided arguments for execution. 13 | This is a helper function that formats stuff so that you don't have to 14 | prun: function 15 | Execute your binary with the provided arguments 16 | """ 17 | 18 | args = [config.binary] + parse_parameters(parameters_dict) 19 | # run the command 20 | 21 | if prun(args) != 0: 22 | sys.exit(1) 23 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_rmtables/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_rmtables", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "This task removes tables if they are not being currently accessed via the casapy process. Note: if you have multiple sessions running bad things could happen if you remove a table being accessed by another process.", 10 | "prefix": "-", 11 | "binary": "rmtables", 12 | "msdir": true, 13 | "junk": [ 14 | "rmtables.last" 15 | ], 16 | "parameters": [ 17 | { 18 | "info": "Names of tables", 19 | "dtype": "list:file", 20 | "required": true, 21 | "name": "tablenames", 22 | "io": "input" 23 | } 24 | ], 25 | "version": [ 26 | "4.7.2", 27 | "5.6.1-8", 28 | "5.8.0" 29 | ] 30 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_uvsub/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_uvsub", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Subtract/add model from/to the corrected visibility data.", 10 | "prefix": "", 11 | "binary": "uvsub", 12 | "junk": [ 13 | "uvsub.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility file (MS)", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "mapping": "vis" 24 | }, 25 | { 26 | "info": "reverse the operation (add rather than subtract)", 27 | "dtype": "bool", 28 | "default": false, 29 | "name": "reverse" 30 | } 31 | ], 32 | "version": [ 33 | "4.7.2", 34 | "5.6.1-8", 35 | "5.8.0" 36 | ] 37 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotants/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_plotants", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Plot the antenna distribution in the local reference frame", 10 | "prefix": "", 11 | "binary": "plotants", 12 | "junk": [ 13 | "plotants.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of measurement set", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "mapping": "vis" 24 | }, 25 | { 26 | "info": "Save the plotted figure to this file", 27 | "default": null, 28 | "name": "figfile", 29 | "io": "output", 30 | "dtype": "file" 31 | } 32 | ], 33 | "version": [ 34 | "4.7.2", 35 | "5.6.1-8", 36 | "5.8.0" 37 | ] 38 | } -------------------------------------------------------------------------------- /stimela/cargo/base/sofia/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | RUN docker-apt-install python \ 3 | qt5-qmake \ 4 | qt5-default \ 5 | gfortran \ 6 | libgfortran3 \ 7 | gcc \ 8 | zlib1g \ 9 | zlib1g-dev 10 | RUN pip install -U numpy>=1.8 \ 11 | scipy>=0.7 \ 12 | matplotlib>=1.1 \ 13 | astropy>=0.2.5 \ 14 | astro-tigger-lsm 15 | RUN git clone https://github.com/SoFiA-Admin/SoFiA.git /sofia 16 | RUN cd /sofia && git fetch && git fetch --tags 17 | RUN cd /sofia && git checkout v1.3.2 18 | RUN cd /sofia && python setup.py install 19 | ENV SOFIA_MODULE_PATH /sofia/build/lib.linux-x86_64-2.7 20 | ENV SOFIA_PIPELINE_PATH /sofia/sofia_pipeline.py 21 | ENV PATH $PATH:/sofia:/sofia/gui 22 | RUN echo $PATH 23 | #RUN sed -i 's/from sofia import wavelet_finder/# from sofia import wavelet_finder/g' $SOFIA_PIPELINE_PATH 24 | #RUN cat $SOFIA_PIPELINE_PATH 25 | -------------------------------------------------------------------------------- /stimela/cargo/base/mosaic-queen/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.7.1 2 | RUN docker-apt-install montage python3-montagepy vim 3 | # Install Python 3.10 4 | RUN apt-get update && \ 5 | apt-get install -y software-properties-common && \ 6 | add-apt-repository ppa:deadsnakes/ppa && \ 7 | apt-get update && \ 8 | apt-get install -y python3.10 python3.10-distutils python3.10-venv 9 | 10 | # Update alternatives to use Python 3.10 11 | RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 10 && \ 12 | update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10 13 | 14 | # Create a virtual environment for Python 3.10 15 | RUN python3.10 -m venv /opt/venv 16 | 17 | # Activate the virtual environment 18 | ENV PATH="/opt/venv/bin:$PATH" 19 | 20 | RUN pip install --upgrade pip setuptools 21 | RUN pip install -U mosaic-queen astroquery>=0.3.8 scabha==0.3.2 22 | RUN pip show mosaic-queen 23 | RUN mosaic-queen --help 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | .* 60 | log*.txt 61 | .gitignore 62 | -------------------------------------------------------------------------------- /stimela/cargo/base/wsclean/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/stimela/base:1.8.0 2 | MAINTAINER 3 | RUN docker-apt-install cmake \ 4 | wget \ 5 | subversion \ 6 | build-essential \ 7 | cmake \ 8 | gfortran \ 9 | g++ \ 10 | git \ 11 | libncurses5-dev \ 12 | libreadline-dev \ 13 | flex \ 14 | bison \ 15 | libblas-dev \ 16 | liblapack-dev \ 17 | libcfitsio-dev \ 18 | libgsl-dev \ 19 | wcslib-dev \ 20 | libhdf5-serial-dev \ 21 | libfftw3-dev \ 22 | python3-numpy \ 23 | libatlas3-base \ 24 | libboost-python-dev \ 25 | libboost-all-dev \ 26 | libpython3-dev \ 27 | liblog4cplus-dev \ 28 | libhdf5-dev \ 29 | casacore-dev 30 | RUN git clone --depth 1 -b v3.6 https://gitlab.com/aroffringa/wsclean.git wscleandir 31 | RUN mkdir wscleandir/build 32 | RUN cd wscleandir/build && \ 33 | cmake .. -DPORTABLE=Yes -DCMAKE_BUILD_TYPE=Release && \ 34 | make -j 4 && \ 35 | make install 36 | RUN ulimit -p 11000 37 | RUN wsclean 38 | -------------------------------------------------------------------------------- /stimela/cargo/base/passwd.template: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 3 | bin:x:2:2:bin:/bin:/usr/sbin/nologin 4 | sys:x:3:3:sys:/dev:/usr/sbin/nologin 5 | sync:x:4:65534:sync:/bin:/bin/sync 6 | games:x:5:60:games:/usr/games:/usr/sbin/nologin 7 | man:x:6:12:man:/var/cache/man:/usr/sbin/nologin 8 | lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin 9 | mail:x:8:8:mail:/var/mail:/usr/sbin/nologin 10 | news:x:9:9:news:/var/spool/news:/usr/sbin/nologin 11 | uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin 12 | proxy:x:13:13:proxy:/bin:/usr/sbin/nologin 13 | www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin 14 | backup:x:34:34:backup:/var/backups:/usr/sbin/nologin 15 | list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin 16 | irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin 17 | gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin 18 | nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin 19 | _apt:x:100:65534::/nonexistent:/usr/sbin/nologin 20 | messagebus:x:101:102::/nonexistent:/usr/sbin/nologin 21 | -------------------------------------------------------------------------------- /stimela/cargo/base/casa/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.7.1 2 | RUN docker-apt-install libfreetype6 \ 3 | libsm6 \ 4 | libxi6 \ 5 | libxrender1 \ 6 | libxrandr2 \ 7 | libxfixes3 \ 8 | libxcursor1 \ 9 | libxinerama1 \ 10 | libfontconfig1 \ 11 | libxslt1.1 \ 12 | xauth \ 13 | xvfb \ 14 | dbus-x11 \ 15 | python3-tk \ 16 | apt-utils \ 17 | locales 18 | ENV DIRCASA /casa 19 | RUN mkdir $DIRCASA 20 | ENV CASA_VERSION casa-release-5.8.0-109.el7 21 | ENV SUCASA ${DIRCASA}/${CASA_VERSION} 22 | ENV CASAURL https://alma-dl.mtk.nao.ac.jp/ftp/casa/distro/casa/release/el7/casa-release-5.8.0-109.el7.tar.gz 23 | RUN curl -L -o ${SUCASA}.tar.gz $CASAURL 24 | RUN tar xvf ${SUCASA}.tar.gz -C $DIRCASA 25 | RUN rm ${SUCASA}.tar.gz 26 | ENV PATH $PATH:${SUCASA}/bin 27 | RUN pip install git+https://github.com/SpheMakh/crasa.git python-casacore astropy git+https://github.com/ratt-ru/simms.git 28 | RUN python -c "import Crasa.Crasa" 29 | ENV LANGUAGE en_US.UTF-8 30 | ENV LANG en_US.UTF-8 31 | ENV LC_ALL en_US.UTF-8 32 | RUN locale-gen en_US.UTF-8 33 | #RUN casa --nologger --log2term --help --nogui 34 | -------------------------------------------------------------------------------- /stimela/cargo/cab/shadems_direct/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "shadems_direct", 3 | "base": "stimela/shadems", 4 | "tag": "1.7.0", 5 | "description": "Rapid Measurement Set plotting with xarray-ms and datashader.", 6 | "prefix": "--", 7 | "binary": "shadems", 8 | "msdir": true, 9 | "junk": ["log-shadems.txt"], 10 | "wranglers": { 11 | "^ERROR:": "ERROR" 12 | }, 13 | "parameters": [ 14 | { 15 | "info": "Measurement set to plot", 16 | "dtype": "file", 17 | "default": null, 18 | "name": "ms", 19 | "io": "msfile", 20 | "required": true 21 | }, 22 | { 23 | "info": "Plot specification(s)", 24 | "dtype": "list:str", 25 | "name": "args", 26 | "required": true, 27 | "default": null 28 | }, 29 | { 30 | "info": "If true, do not return error code if plot(s) fail", 31 | "dtype": "bool", 32 | "default": false, 33 | "name": "ignore_errors" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /stimela/cargo/cab/simulator/src/tdlconf.profiles: -------------------------------------------------------------------------------- 1 | [sim] 2 | me.e_advanced = 0 3 | me.e_enable = 0 4 | me.epe_enable = 0 5 | me.g_enable = 0 6 | me.l_enable = 0 7 | me.ncorr_enable = 0 8 | me.p_advanced = 0 9 | me.p_enable = 0 10 | me.sky.siamese_agw_azel_sky = 0 11 | me.sky.siamese_oms_fitsimage_sky = 0 12 | me.sky.siamese_oms_gridded_sky = 0 13 | me.sky.siamese_oms_transient_sky = 0 14 | me.sky.tiggerskymodel = 0 15 | me.use_jones_inspectors = 1 16 | me.use_skyjones_visualizers = 0 17 | me.use_smearing = 0 18 | me.z_enable = 0 19 | ms_sel.ms_corr_sel = 2x2 20 | ms_sel.ms_ifr_subset_str = all 21 | ms_sel.ms_taql_str = None 22 | ms_sel.output_column = CORRECTED_DATA 23 | ms_sel.select_channels = 0 24 | ms_sel.tile_size = 8 25 | noise_from_sefd = 0 26 | noise_stddev = None 27 | random_seed = time 28 | read_ms_model = 0 29 | rot_p.enable_pa = None 30 | rot_p.read_ms = 1 31 | rotation.rot_p.feed_angle = 0 32 | run_purr = 0 33 | sim_mode = sim only 34 | tensormeqmaker.psv_class = PSVTensor 35 | tiggerlsm.lsm_subset = all 36 | tiggerlsm.null_subset = None 37 | tiggerlsm.solvable_sources = 0 38 | uvw_refant = default 39 | uvw_source = from MS 40 | -------------------------------------------------------------------------------- /stimela/exceptions.py: -------------------------------------------------------------------------------- 1 | class StimelaCabParameterError(Exception): 2 | pass 3 | 4 | 5 | class StimelaRecipeExecutionError(Exception): 6 | pass 7 | 8 | 9 | class StimelaBaseImageError(Exception): 10 | pass 11 | 12 | 13 | class StimelaCabRuntimeError(RuntimeError): 14 | pass 15 | 16 | 17 | class StimelaProcessRuntimeError(RuntimeError): 18 | pass 19 | 20 | 21 | class PipelineException(Exception): 22 | """ 23 | Encapsulates information about state of pipeline when an 24 | exception occurs 25 | """ 26 | 27 | def __init__(self, exception, completed, failed, remaining): 28 | message = "Job '%s' failed: %s" % (failed.label, str(exception)) 29 | 30 | super(PipelineException, self).__init__(message) 31 | 32 | self._completed = completed 33 | self._failed = failed 34 | self._remaining = remaining 35 | 36 | @property 37 | def completed(self): 38 | return self._completed 39 | 40 | @property 41 | def failed(self): 42 | return self._failed 43 | 44 | @property 45 | def remaining(self): 46 | return self._remaining 47 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_statwt/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_uvsub/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_applycal/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | 15 | junk = cab["junk"] 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_plotuv/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_setjy/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_imregrid/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_virtualconcat/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if value is None: 22 | continue 23 | 24 | args[name] = value 25 | 26 | task = crasa.CasaTask(cab["binary"], **args) 27 | try: 28 | task.run() 29 | finally: 30 | for item in junk: 31 | for dest in [ 32 | OUTPUT, 33 | MSDIR, 34 | ]: # these are the only writable volumes in the container 35 | items = glob.glob("{dest}/{item}".format(**locals())) 36 | for f in items: 37 | if os.path.isfile(f): 38 | os.remove(f) 39 | elif os.path.isdir(f): 40 | shutil.rmtree(f) 41 | # Leave other types 42 | -------------------------------------------------------------------------------- /stimela/cargo/base/chgcentre/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM stimela/base:1.2.0 2 | MAINTAINER 3 | RUN docker-apt-install cmake \ 4 | build-essential \ 5 | cmake \ 6 | gfortran \ 7 | g++ \ 8 | libncurses5-dev \ 9 | libreadline-dev \ 10 | flex \ 11 | bison \ 12 | libblas-dev \ 13 | liblapacke-dev \ 14 | libcfitsio-dev \ 15 | libgsl-dev \ 16 | wcslib-dev \ 17 | libhdf5-serial-dev \ 18 | libfftw3-dev \ 19 | python-numpy \ 20 | libboost-python-dev \ 21 | libboost-all-dev \ 22 | libpython2.7-dev \ 23 | liblog4cplus-dev \ 24 | libhdf5-dev \ 25 | casacore-dev \ 26 | curl 27 | ENV CHGCENTRE_NAME chgcentre-1.6 28 | ENV CHGCENTRE_URL https://ayera.dl.sourceforge.net/project/wsclean/${CHGCENTRE_NAME}/${CHGCENTRE_NAME}.tar.bz2 29 | RUN curl -o ${CHGCENTRE_NAME}.tar.bz2 ${CHGCENTRE_URL} 30 | RUN mkdir /builds && tar xjf ${CHGCENTRE_NAME}.tar.bz2 -C /builds 31 | RUN mkdir /builds/chgcentre/build 32 | RUN cd /builds/chgcentre/build && cmake ../ -DPORTABLE=True 33 | RUN cd /builds/chgcentre/build && make 34 | RUN cd /builds/chgcentre/build && make install 35 | RUN chgcentre 36 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_gencal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | from casacore.table import table 5 | import os 6 | import numpy 7 | 8 | print(f"Running CASA task '{config.binary}'") 9 | 10 | args = parameters_dict 11 | 12 | task = crasa.CasaTask(config.binary, **args) 13 | task.run() 14 | 15 | gtab = args["caltable"] 16 | if not os.path.exists(gtab): 17 | raise RuntimeError( 18 | f"The gaintable was not created. Please refer to CASA {config.binary} logfile for further details" 19 | ) 20 | 21 | tab = table(gtab) 22 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 23 | tab.close() 24 | 25 | tab = table(gtab + "::FIELD") 26 | field_names = tab.getcol("NAME") 27 | tab.close() 28 | 29 | field_in = args["field"].split(",") 30 | 31 | try: 32 | ids = list(map(int, field_in)) 33 | except ValueError: 34 | ids = list(map(lambda a: field_names.index(a), field_in)) 35 | 36 | if not set(ids).issubset(field_ids): 37 | raise RuntimeError( 38 | f"Some field(s) do not have solutions after the calibration. Please refer to CASA {config.binary} logfile for further details" 39 | ) 40 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_makemask/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | 5 | print(f"Running CASA task '{config.binary}'") 6 | 7 | makemask_args = {} 8 | immath_args = {} 9 | for name, value in parameters_dict.items(): 10 | if value is None: 11 | continue 12 | 13 | if name in ["threshold", "inpimage", "output"]: 14 | if name in ["threshold"]: 15 | im_value = " iif( IM0 >=%s, IM0, 0.0) " % value 16 | im_name = "expr" 17 | if name in ["output"]: 18 | im_value = "%s_thresh" % value 19 | im_name = "outfile" 20 | if name in ["inpimage"]: 21 | im_value = value 22 | im_name = "imagename" 23 | immath_args[im_name] = im_value 24 | 25 | if name in ["mode", "inpimage", "inpmask", "output", "overwrite"]: 26 | makemask_args[name] = value 27 | 28 | if "expr" in immath_args: 29 | task = crasa.CasaTask("immath", **immath_args) 30 | task.run() 31 | 32 | if "inpmask" not in makemask_args: 33 | makemask_args["inpmask"] = immath_args["outfile"] 34 | 35 | task = crasa.CasaTask(config.binary, **makemask_args) 36 | task.run() 37 | -------------------------------------------------------------------------------- /stimela/cargo/cab/halo-fdca/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import yaml 6 | import glob 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | if value is None: 24 | continue 25 | elif name in ["object", "d_file"]: 26 | args += [value] 27 | else: 28 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 29 | 30 | _runc = " ".join([cab["binary"]] + args) 31 | 32 | try: 33 | subprocess.check_call(shlex.split(_runc)) 34 | finally: 35 | for item in junk: 36 | for dest in [ 37 | OUTPUT, 38 | MSDIR, 39 | ]: # these are the only writable volumes in the container 40 | items = glob.glob("{dest}/{item}".format(**locals())) 41 | for f in items: 42 | if os.path.isfile(f): 43 | os.remove(f) 44 | elif os.path.isdir(f): 45 | shutil.rmtree(f) 46 | -------------------------------------------------------------------------------- /stimela/cargo/cab/owlcat_plotelev/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "owlcat_plotelev", 3 | "base": "stimela/owlcat", 4 | "tag": "1.6.6", 5 | "version" : "1.6.3", 6 | "description": "Plots elevation tracks from an measurement set", 7 | "prefix": "--", 8 | "binary": "plot-elevation-tracks.py", 9 | "junk":[], 10 | "msdir": true, 11 | "parameters": [ 12 | { 13 | "info": "Name of Measurement set", 14 | "name": "msname", 15 | "io": "msfile", 16 | "default": null, 17 | "dtype": "file", 18 | "required": true 19 | }, 20 | { 21 | "info": "lists fields found in MS, then exits", 22 | "dtype": "bool", 23 | "default": null, 24 | "name": "list" 25 | }, 26 | { 27 | "info": "Output filename", 28 | "io": "output", 29 | "dtype": "file", 30 | "default": "lst-elev.png", 31 | "name": "output-name", 32 | "check_io": false 33 | }, 34 | { 35 | "info": "Display plot on screen", 36 | "dtype": "bool", 37 | "default": false, 38 | "name": "display" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /stimela/cargo/cab/pyddi/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import yaml 4 | import glob 5 | import shutil 6 | import shlex 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | if value is None: 24 | continue 25 | elif value is False: 26 | continue 27 | 28 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 29 | 30 | _runc = " ".join([cab["binary"]] + args) 31 | 32 | try: 33 | subprocess.check_call(shlex.split(_runc)) 34 | finally: 35 | for item in junk: 36 | for dest in [ 37 | OUTPUT, 38 | MSDIR, 39 | ]: # these are the only writable volumes in the container 40 | items = glob.glob("{dest}/{item}".format(**locals())) 41 | for f in items: 42 | if os.path.isfile(f): 43 | os.remove(f) 44 | elif os.path.isdir(f): 45 | shutil.rmtree(f) 46 | # Leave other types 47 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_gaincal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | from pyrap.tables import table 5 | import os 6 | import numpy 7 | 8 | print(f"Running CASA task '{config.binary}'") 9 | 10 | save_result = parameters_dict.pop("save_result", None) 11 | 12 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 13 | task.run() 14 | 15 | gtab = parameters_dict["caltable"] 16 | if not os.path.exists(gtab): 17 | raise RuntimeError( 18 | f"The gaintable was not created. Please refer to CASA {config.binary} logfile for further details" 19 | ) 20 | 21 | tab = table(gtab) 22 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 23 | tab.close() 24 | 25 | tab = table(gtab + "::FIELD") 26 | field_names = tab.getcol("NAME") 27 | tab.close() 28 | 29 | field_in = parameters_dict["field"].split(",") 30 | 31 | try: 32 | ids = list(map(int, field_in)) 33 | except ValueError: 34 | ids = list(map(lambda a: field_names.index(a), field_in)) 35 | 36 | if not set(ids).issubset(field_ids): 37 | raise RuntimeError( 38 | f"Some field(s) do not have solutions after the calibration. Please refer to CASA {config.binary} logfile for further details" 39 | ) 40 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_polcal/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | from pyrap.tables import table 5 | import os 6 | import numpy 7 | 8 | print(f"Running CASA task '{config.binary}'") 9 | 10 | save_result = parameters_dict.pop("save_result", None) 11 | 12 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 13 | task.run() 14 | 15 | gtab = parameters_dict["caltable"] 16 | if not os.path.exists(gtab): 17 | raise RuntimeError( 18 | f"The gaintable was not created. Please refer to CASA {config.binary} logfile for further details" 19 | ) 20 | 21 | tab = table(gtab) 22 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 23 | tab.close() 24 | 25 | tab = table(gtab + "::FIELD") 26 | field_names = tab.getcol("NAME") 27 | tab.close() 28 | 29 | field_in = parameters_dict["field"].split(",") 30 | 31 | try: 32 | ids = list(map(int, field_in)) 33 | except ValueError: 34 | ids = list(map(lambda a: field_names.index(a), field_in)) 35 | 36 | if not set(ids).issubset(field_ids): 37 | raise RuntimeError( 38 | f"Some field(s) do not have solutions after the calibration. Please refer to CASA {config.binary} logfile for further details" 39 | ) 40 | -------------------------------------------------------------------------------- /stimela/cargo/cab/curl/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import shlex 4 | import glob 5 | import subprocess 6 | import yaml 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | INPUT = os.environ["INPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | url = None 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 31 | 32 | _runc = " ".join([cab["binary"]] + args) 33 | try: 34 | subprocess.check_call(shlex.split(_runc)) 35 | finally: 36 | for item in junk: 37 | for dest in [ 38 | OUTPUT, 39 | MSDIR, 40 | ]: # these are the only writable volumes in the container 41 | items = glob.glob("{dest}/{item}".format(**locals())) 42 | for f in items: 43 | if os.path.isfile(f): 44 | os.remove(f) 45 | elif os.path.isdir(f): 46 | shutil.rmtree(f) 47 | -------------------------------------------------------------------------------- /stimela/tests/unit_tests/cab/custom/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | import glob 4 | import shutil 5 | import shlex 6 | import subprocess 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | junk = cab["junk"] 16 | 17 | args = [] 18 | url = None 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | 23 | if value is None: 24 | continue 25 | elif value is False: 26 | continue 27 | elif value is True: 28 | value = "" 29 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 30 | 31 | _runc = " ".join([cab["binary"]] + args) 32 | 33 | try: 34 | subprocess.check_call(shlex.split(_runc)) 35 | finally: 36 | for item in junk: 37 | for dest in [ 38 | OUTPUT, 39 | MSDIR, 40 | ]: # these are the only writable volumes in the container 41 | items = glob.glob("{dest}/{item}".format(**locals())) 42 | for f in items: 43 | if os.path.isfile(f): 44 | os.remove(f) 45 | elif os.path.isdir(f): 46 | shutil.rmtree(f) 47 | -------------------------------------------------------------------------------- /stimela/cargo/cab/politsiyakat_cal_phase/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import yaml 4 | import subprocess 5 | import shlex 6 | import shutil 7 | import glob 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = {} 20 | tasksuite = None 21 | for param in cab["parameters"]: 22 | name = param["name"] 23 | value = param["value"] 24 | 25 | if value is None: 26 | continue 27 | 28 | args[name] = value 29 | 30 | kwargs = "'{}'".format(json.dumps(args)) 31 | 32 | ARGS = ["flag_phase_drifts", "-s antenna_mod", kwargs] 33 | 34 | _runc = " ".join([cab["binary"]] + ARGS) 35 | try: 36 | subprocess.check_call(shlex.split(_runc)) 37 | finally: 38 | for item in junk: 39 | for dest in [ 40 | OUTPUT, 41 | MSDIR, 42 | ]: # these are the only writable volumes in the container 43 | items = glob.glob("{dest}/{item}".format(**locals())) 44 | for f in items: 45 | if os.path.isfile(f): 46 | os.remove(f) 47 | elif os.path.isdir(f): 48 | shutil.rmtree(f) 49 | -------------------------------------------------------------------------------- /stimela/cargo/cab/politsiyakat_autocorr_amp/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import yaml 4 | import subprocess 5 | import shlex 6 | import shutil 7 | import glob 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = {} 20 | tasksuite = None 21 | for param in cab["parameters"]: 22 | name = param["name"] 23 | value = param["value"] 24 | 25 | if value is None: 26 | continue 27 | 28 | args[name] = value 29 | 30 | kwargs = "'{}'".format(json.dumps(args)) 31 | 32 | ARGS = ["flag_autocorr_drifts", "-s antenna_mod", kwargs] 33 | 34 | _runc = " ".join([cab["binary"]] + ARGS) 35 | try: 36 | subprocess.check_call(shlex.split(_runc)) 37 | finally: 38 | for item in junk: 39 | for dest in [ 40 | OUTPUT, 41 | MSDIR, 42 | ]: # these are the only writable volumes in the container 43 | items = glob.glob("{dest}/{item}".format(**locals())) 44 | for f in items: 45 | if os.path.isfile(f): 46 | os.remove(f) 47 | elif os.path.isdir(f): 48 | shutil.rmtree(f) 49 | -------------------------------------------------------------------------------- /stimela/cargo/cab/eidos/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | import shlex 5 | import yaml 6 | import glob 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | msname = None 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | 31 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 32 | 33 | _runc = " ".join([cab["binary"]] + args) 34 | 35 | try: 36 | subprocess.check_call(shlex.split(_runc)) 37 | finally: 38 | for item in junk: 39 | for dest in [ 40 | OUTPUT, 41 | MSDIR, 42 | ]: # these are the only writable volumes in the container 43 | items = glob.glob("{dest}/{item}".format(**locals())) 44 | for f in items: 45 | if os.path.isfile(f): 46 | os.remove(f) 47 | elif os.path.isdir(f): 48 | shutil.rmtree(f) 49 | # Leave other types 50 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "stimela" 3 | version = "1.8.2" 4 | description = "Dockerized radio interferometry scripting framework" 5 | authors = ["Sphesihle Makhathini ", "RATT"] 6 | readme = "README.rst" 7 | license = "GPLv2" 8 | homepage = "https://github.com/ratt-ru/Stimela-classic" 9 | repository = "https://github.com/ratt-ru/Stimela-classic" 10 | keywords = ["radio astronomy", "interferometry", "pipeline", "docker"] 11 | classifiers = [ 12 | "Development Status :: 5 - Production/Stable", 13 | "Intended Audience :: Science/Research", 14 | "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", 15 | "Programming Language :: Python", 16 | "Topic :: Scientific/Engineering :: Astronomy" 17 | ] 18 | packages = [ 19 | { include = "stimela" } 20 | ] 21 | include = ["stimela/cargo/cab/stimela_runscript"] 22 | 23 | [tool.poetry.dependencies] 24 | python = ">=3.9,<=3.13" 25 | pytest = { version = "*", optional=true } 26 | flake8 = { version = "*", optional=true } 27 | pytest-cov = { version = "*", optional=true } 28 | 29 | [tool.poetry.scripts] 30 | stimela = "stimela.main:cli" 31 | 32 | [tool.poetry.extras] 33 | testing = ["pytest", "flake8", "pytest-cov"] 34 | 35 | [build-system] 36 | requires = ["setuptools", "poetry-core"] 37 | build-backend = "poetry.core.masonry.api" 38 | -------------------------------------------------------------------------------- /stimela/cargo/cab/chgcentre/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import yaml 4 | import shutil 5 | import shlex 6 | import subprocess 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | if value is None: 24 | continue 25 | elif value is False: 26 | continue 27 | 28 | if value is bool: 29 | args += ["{0}{1}".format(cab["prefix"], name)] 30 | else: 31 | args += ["{0}".format(value)] 32 | 33 | _runc = " ".join([cab["binary"]] + args) 34 | 35 | try: 36 | subprocess.check_call(shlex.split(_runc)) 37 | finally: 38 | for item in junk: 39 | for dest in [ 40 | OUTPUT, 41 | MSDIR, 42 | ]: # these are the only writable volumes in the container 43 | items = glob.glob("{dest}/{item}".format(**locals())) 44 | for f in items: 45 | if os.path.isfile(f): 46 | os.remove(f) 47 | elif os.path.isdir(f): 48 | shutil.rmtree(f) 49 | # Leave other types 50 | -------------------------------------------------------------------------------- /stimela/cargo/cab/cleanmask/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import yaml 5 | import glob 6 | import subprocess 7 | 8 | OUTPUT = os.environ["OUTPUT"] 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | params = cab["parameters"] 19 | 20 | args = [] 21 | for param in params: 22 | if param["value"] in [False, None]: 23 | continue 24 | elif param["value"] is True: 25 | arg = "{0}{1}".format(cab["prefix"], param["name"]) 26 | else: 27 | arg = "{0}{1} {2}".format(cab["prefix"], param["name"], param["value"]) 28 | 29 | args.append(arg) 30 | 31 | _runc = " ".join([cab["binary"]] + args) 32 | 33 | try: 34 | subprocess.check_call(shlex.split(_runc)) 35 | finally: 36 | for item in junk: 37 | for dest in [ 38 | OUTPUT, 39 | MSDIR, 40 | ]: # these are the only writable volumes in the container 41 | items = glob.glob("{dest}/{item}".format(**locals())) 42 | for f in items: 43 | if os.path.isfile(f): 44 | os.remove(f) 45 | elif os.path.isdir(f): 46 | shutil.rmtree(f) 47 | -------------------------------------------------------------------------------- /stimela/tests/unit_tests/cab/custom/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "custom", 3 | "base": "stimela/base", 4 | "tag": "1.2.4", 5 | "description": "Custom", 6 | "prefix": "--", 7 | "binary": "echo", 8 | "junk":[], 9 | "msdir": true, 10 | "parameters": [ 11 | { 12 | "info": "bla1", 13 | "dtype": "str", 14 | "default": null, 15 | "required": true, 16 | "name": "bla1", 17 | "choices": [ 18 | "a", 19 | "b", 20 | "c" 21 | ] 22 | }, 23 | { 24 | "default": true, 25 | "dtype": "file", 26 | "name": "bla2", 27 | "io": "output", 28 | "check_io": true 29 | }, 30 | { 31 | "info": "bla3", 32 | "dtype": "list:float", 33 | "default": null, 34 | "name": "bla3" 35 | }, 36 | { 37 | "info": "bla4", 38 | "dtype": "list:str", 39 | "default": null, 40 | "name": "bla4" 41 | }, 42 | { 43 | "default": true, 44 | "dtype": "list:file", 45 | "name": "bla5", 46 | "io": "output", 47 | "check_io": false 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /stimela/cargo/cab/flagstats/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | from MSUtils import flag_stats 3 | import glob 4 | import shutil 5 | import yaml 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | 15 | junk = cab["junk"] 16 | args = {} 17 | for param in cab["parameters"]: 18 | name = param["name"] 19 | value = param["value"] 20 | 21 | if name in ["fields", "antennas"] and value is not None: 22 | try: 23 | value = list(map(int, value)) 24 | except ValueError: 25 | pass 26 | args[name] = value 27 | 28 | try: 29 | if args["plot"]: 30 | args.pop("plot") 31 | flag_stats.plot_statistics(**args) 32 | else: 33 | args.pop("plot") 34 | args.pop("htmlfile") 35 | flag_stats.save_statistics(**args) 36 | finally: 37 | for item in junk: 38 | for dest in [ 39 | OUTPUT, 40 | MSDIR, 41 | ]: # these are the only writable volumes in the container 42 | items = glob.glob("{dest}/{item}".format(**locals())) 43 | for f in items: 44 | if os.path.isfile(f): 45 | os.remove(f) 46 | elif os.path.isdir(f): 47 | shutil.rmtree(f) 48 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_clearcal/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_clearcal", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Clears out calibrated data and resets previous predicted model", 10 | "prefix": "-", 11 | "binary": "clearcal", 12 | "junk": [ 13 | "clearcal.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility file", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "required": true, 24 | "mapping": "vis" 25 | }, 26 | { 27 | "info": "Field names or field index numbers. ''==>all, field='0~2,3C286'", 28 | "dtype": "str", 29 | "default": null, 30 | "name": "field" 31 | }, 32 | { 33 | "info": "spectral-window/frequency/channel", 34 | "dtype": "str", 35 | "default": null, 36 | "name": "spw" 37 | }, 38 | { 39 | "info": "Select based on observing intent", 40 | "dtype": "str", 41 | "default": null, 42 | "name": "intent" 43 | }, 44 | { 45 | "info": "Add MODEL_DATA scratch column", 46 | "dtype": "bool", 47 | "default": false, 48 | "name": "addmodel" 49 | } 50 | ], 51 | "version": [ 52 | "4.7.2", 53 | "5.6.1-8", 54 | "5.8.0" 55 | ] 56 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/crystalball/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import shutil 4 | import shlex 5 | import subprocess 6 | import yaml 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | ms = None 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | if name == "ms": 31 | ms = value 32 | continue 33 | 34 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 35 | 36 | _runc = " ".join([cab["binary"]] + args + [ms]) 37 | 38 | try: 39 | subprocess.check_call(shlex.split(_runc)) 40 | finally: 41 | for item in junk: 42 | for dest in [ 43 | OUTPUT, 44 | MSDIR, 45 | ]: # these are the only writable volumes in the container 46 | items = glob.glob("{dest}/{item}".format(**locals())) 47 | for f in items: 48 | if os.path.isfile(f): 49 | os.remove(f) 50 | elif os.path.isdir(f): 51 | shutil.rmtree(f) 52 | # Leave other types 53 | -------------------------------------------------------------------------------- /stimela/cargo/cab/catdagger/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import glob 6 | import yaml 7 | 8 | OUTPUT = os.environ["OUTPUT"] 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | junk = cab["junk"] 16 | 17 | args = [] 18 | 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | if name == "noise-map": 23 | args += [value] 24 | continue 25 | if value is None: 26 | continue 27 | elif value is False: 28 | continue 29 | if param["dtype"] == "bool" and value: 30 | args += ["{0}{1}".format(cab["prefix"], name)] 31 | continue 32 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 33 | 34 | _runc = " ".join([cab["binary"]] + args) 35 | try: 36 | subprocess.check_call(shlex.split(_runc)) 37 | finally: 38 | for item in junk: 39 | for dest in [ 40 | OUTPUT, 41 | MSDIR, 42 | ]: # these are the only writable volumes in the container 43 | items = glob.glob("{dest}/{item}".format(**locals())) 44 | for f in items: 45 | if os.path.isfile(f): 46 | os.remove(f) 47 | elif os.path.isdir(f): 48 | shutil.rmtree(f) 49 | -------------------------------------------------------------------------------- /stimela/cargo/cab/pycasacore/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tempfile 3 | import shlex 4 | import shutil 5 | import yaml 6 | import glob 7 | import subprocess 8 | 9 | 10 | CONFIG = os.environ["CONFIG"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | INPUT = os.environ["INPUT"] 13 | MSDIR = os.environ["MSDIR"] 14 | 15 | with open(CONFIG, "r") as _std: 16 | cab = yaml.safe_load(_std) 17 | 18 | junk = cab["junk"] 19 | 20 | args = [] 21 | msname = None 22 | 23 | custom_script = 'print("Nothing has been done")' 24 | 25 | for param in cab["parameters"]: 26 | name = param["name"] 27 | value = param["value"] 28 | if name == "script": 29 | custom_script = value 30 | continue 31 | 32 | with tempfile.NamedTemporaryFile(suffix=".py") as tfile: 33 | tfile.write(custom_script) 34 | tfile.flush() 35 | 36 | _runc = " ".join([cab["binary"], tfile.name]) 37 | try: 38 | subprocess.check_call(shlex.split(_runc)) 39 | finally: 40 | for item in junk: 41 | for dest in [ 42 | OUTPUT, 43 | MSDIR, 44 | ]: # these are the only writable volumes in the container 45 | items = glob.glob("{dest}/{item}".format(**locals())) 46 | for f in items: 47 | if os.path.isfile(f): 48 | os.remove(f) 49 | elif os.path.isdir(f): 50 | shutil.rmtree(f) 51 | -------------------------------------------------------------------------------- /stimela/cargo/cab/breizorro/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import yaml 6 | import glob 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | 27 | if param["dtype"] in ["list:str", "list:file", "list:int", "list:float"]: 28 | delimiter = param["delimiter"] 29 | args += ["{0}{1} {2}".format(cab["prefix"], name, delimiter.join(value))] 30 | elif param["dtype"] in ["bool"]: 31 | args += ["{0}{1}".format(cab["prefix"], name)] 32 | else: 33 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 34 | 35 | _runc = " ".join([cab["binary"]] + args) 36 | 37 | try: 38 | subprocess.check_call(shlex.split(_runc)) 39 | finally: 40 | for item in junk: 41 | for dest in [ 42 | OUTPUT, 43 | MSDIR, 44 | ]: # these are the only writable volumes in the container 45 | items = glob.glob("{dest}/{item}".format(**locals())) 46 | for f in items: 47 | if os.path.isfile(f): 48 | os.remove(f) 49 | elif os.path.isdir(f): 50 | shutil.rmtree(f) 51 | -------------------------------------------------------------------------------- /stimela/cargo/cab/sunblocker/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | from sunblocker.sunblocker import Sunblocker 3 | import inspect 4 | import yaml 5 | import glob 6 | import shutil 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | junk = cab["junk"] 16 | 17 | args = {} 18 | for param in cab["parameters"]: 19 | name = param["name"] 20 | value = param["value"] 21 | 22 | if name == "command": 23 | function = value 24 | continue 25 | if value is None: 26 | continue 27 | 28 | args[name] = value 29 | 30 | args["showdir"] = OUTPUT 31 | run_func = getattr(Sunblocker(), function, None) 32 | if run_func is None: 33 | raise RuntimeError("Function '{}' is not part of Sunblocker()".format(function)) 34 | 35 | func_args = inspect.getargspec(run_func)[0] 36 | for arg in args.keys(): 37 | if arg not in func_args: 38 | args.pop(arg, None) 39 | 40 | try: 41 | run_func(**args) 42 | finally: 43 | for item in junk: 44 | for dest in [ 45 | OUTPUT, 46 | MSDIR, 47 | ]: # these are the only writable volumes in the container 48 | items = glob.glob("{dest}/{item}".format(**locals())) 49 | for f in items: 50 | if os.path.isfile(f): 51 | os.remove(f) 52 | elif os.path.isdir(f): 53 | shutil.rmtree(f) 54 | -------------------------------------------------------------------------------- /stimela/cargo/cab/flagstats/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "flagstats", 3 | "base": "stimela/msutils", 4 | "tag": "1.6.9", 5 | "version" : "1.2.0", 6 | "description": "Extract flag statistics for a set of fields and antennas from an MS", 7 | "prefix": " ", 8 | "binary": "msutils", 9 | "junk": [], 10 | "msdir": true, 11 | "parameters": [ 12 | { 13 | "info": "MS name", 14 | "dtype": "file", 15 | "required": false, 16 | "name": "msname", 17 | "io": "msfile" 18 | }, 19 | { 20 | "info": "Output file (JSON format)", 21 | "default": null, 22 | "name": "outfile", 23 | "io": "output", 24 | "dtype": "file" 25 | }, 26 | { 27 | "info": "Field(s)", 28 | "dtype": "list:str", 29 | "default": null, 30 | "name": "fields" 31 | }, 32 | { 33 | "info": "Antennas", 34 | "dtype": "list:str", 35 | "default": null, 36 | "name": "antennas" 37 | }, 38 | { 39 | "info": "Plot flag statistic summary", 40 | "dtype": "bool", 41 | "default": null, 42 | "name": "plot" 43 | }, 44 | { 45 | "info": "Output plots html file", 46 | "default": null, 47 | "name": "htmlfile", 48 | "io": "output", 49 | "dtype": "file" 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_script/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | import shlex 4 | import shutil 5 | import subprocess 6 | import glob 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | INPUT = os.environ["INPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = [] 20 | msname = None 21 | 22 | custom_script = 'print("Nothing has been done")' 23 | 24 | for param in cab["parameters"]: 25 | name = param["name"] 26 | value = param["value"] 27 | if name == "script": 28 | custom_script = value 29 | continue 30 | if value is None: 31 | continue 32 | elif value is False: 33 | continue 34 | elif value is True: 35 | value = "" 36 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 37 | 38 | with open("casajob.py.last", "w") as f: 39 | f.write(custom_script) 40 | 41 | 42 | _runc = " ".join([cab["binary"]] + ["-c", "casajob.py.last"] + args) 43 | try: 44 | subprocess.check_call(shlex.split(_runc)) 45 | finally: 46 | for item in junk: 47 | for dest in [ 48 | OUTPUT, 49 | MSDIR, 50 | ]: # these are the only writable volumes in the container 51 | items = glob.glob("{dest}/{item}".format(**locals())) 52 | for f in items: 53 | if os.path.isfile(f): 54 | os.remove(f) 55 | elif os.path.isdir(f): 56 | shutil.rmtree(f) 57 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # 0.1.1 2 | 3 | * Improve logging 4 | * Add moresane 5 | * Add CATTERY Path where needed 6 | 7 | 8 | 9 | # 0.1.0 10 | 11 | * Change package name from *Penthesilea* to *Stimela* 12 | * Start using radioastro docker images 13 | * Add lwimager, wslcean, casa imagers (instead of a single imager image) 14 | * Add owlcat base image 15 | * Add container, docker image, and job loging 16 | 17 | # 0.2.5 18 | - Improve handling of ctrl+c. Send terminate 19 | signal to container. 20 | - Improve handling of FITS images when predicting 21 | visibilities; allow for minimal FITS images. 22 | - Add clean fuction to help clean up after stimela 23 | - Improve/Fx logging of images and containers 24 | 25 | # 0.2.6 26 | - Use correct package(stimel_misc) to get stimel version 27 | 28 | # 0.2.7 29 | - Fix noise only simulation in simulator cab. Don not look for file if skymodel is None 30 | - Allow user to specify gain matrix type in simulator 31 | - Make custom katdal base image 32 | 33 | # 0.2.8 34 | - Parse G Jones solution intervals properly 35 | - Raise exception if user does not specify pixel size in lwimger predict mode 36 | - add CASA listobs, statwt, flagmanager 37 | 38 | # 0.2.9 39 | - display correct options for output-data type [calibrator cab] 40 | - Improve logging system 41 | - Custom cabs can now don't need to be in stimela/cargo/cab 42 | - Various fixes to minor bugs. Especiallly in casa_flagdata cab 43 | - Add DDFacet cab!! 44 | - Fix --us-only option in 'stimela build' 45 | - Upgrade to kern-2 (wsclean is using kern-dev) 46 | 47 | # 1.2.0 48 | - add support for podman 49 | - upgrade CASA to 5.6.0 50 | -------------------------------------------------------------------------------- /stimela/cargo/cab/autoflagger/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import yaml 6 | import glob 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | msname = None 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | elif name == "msname": 31 | if isinstance(value, str): 32 | msname = value 33 | else: 34 | msname = " ".join(value) 35 | continue 36 | 37 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 38 | 39 | if msname is None: 40 | raise RuntimeError("MS name has not be specified") 41 | 42 | _runc = " ".join([cab["binary"]] + args + [msname]) 43 | try: 44 | subprocess.check_call(shlex.split(_runc)) 45 | finally: 46 | for item in junk: 47 | for dest in [ 48 | OUTPUT, 49 | MSDIR, 50 | ]: # these are the only writable volumes in the container 51 | items = glob.glob("{dest}/{item}".format(**locals())) 52 | for f in items: 53 | if os.path.isfile(f): 54 | os.remove(f) 55 | elif os.path.isdir(f): 56 | shutil.rmtree(f) 57 | # Leave other types 58 | -------------------------------------------------------------------------------- /stimela/cargo/cab/mosaic_queen/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import shlex 4 | import glob 5 | import shutil 6 | import yaml 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | dtype = param["dtype"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | elif dtype in ["list:file", "list:str"]: 31 | if os.path.exists(value[0]): 32 | indir = os.path.dirname(value[0]) 33 | value = list(map(os.path.basename, value)) 34 | value = " ".join(value) 35 | 36 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 37 | 38 | args += ["--input {0:s} --output {1:s}".format(indir, OUTPUT)] 39 | 40 | _runc = " ".join([cab["binary"]] + args) 41 | 42 | try: 43 | subprocess.check_call(shlex.split(_runc)) 44 | finally: 45 | for item in junk: 46 | for dest in [ 47 | OUTPUT, 48 | MSDIR, 49 | ]: # these are the only writable volumes in the container 50 | items = glob.glob("{dest}/{item}".format(**locals())) 51 | for f in items: 52 | if os.path.isfile(f): 53 | os.remove(f) 54 | elif os.path.isdir(f): 55 | shutil.rmtree(f) 56 | -------------------------------------------------------------------------------- /stimela/cargo/cab/stimela2/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "stimela2", 3 | "base": "stimela/stimela2", 4 | "tag": "1.7.10", 5 | "description": "a workflow management framework for creating portable and reproducible data processing pipelines", 6 | "prefix": "--", 7 | "binary": "stimela run", 8 | "version":"2.0.0", 9 | "junk":[], 10 | "msdir": true, 11 | "parameters": [ 12 | { 13 | "info": "Recipe file", 14 | "name": "recipe", 15 | "io": "input", 16 | "default": null, 17 | "dtype": "file", 18 | "required": false 19 | }, 20 | { 21 | "info": "Support files", 22 | "name": "support-files", 23 | "io": "output", 24 | "default": null, 25 | "dtype": "list:file", 26 | "required": false 27 | }, 28 | { 29 | "info": "Name of recipe to run", 30 | "name": "recipe-name", 31 | "dtype": "str", 32 | "required": false 33 | }, 34 | { 35 | "info": "Step(s) to run from recipe", 36 | "default": null, 37 | "required": false, 38 | "delimiter": ",", 39 | "name": "step", 40 | "dtype": "list:str" 41 | }, 42 | { 43 | "info": "Parameter(s) to override defaults. e.g. ['ms=foo.ms', 'image_size=2048']", 44 | "default": null, 45 | "required": false, 46 | "delimiter": " ", 47 | "name": "params", 48 | "dtype": "list:str" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_bandpass/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | from pyrap.tables import table 5 | import os 6 | import numpy 7 | 8 | print(f"Running CASA task '{config.binary}'") 9 | 10 | save_result = parameters_dict.pop("save_result", None) 11 | 12 | task = crasa.CasaTask(config.binary, save_result=save_result, **parameters_dict) 13 | task.run() 14 | 15 | gtab = parameters_dict["caltable"] 16 | if not os.path.exists(gtab): 17 | raise RuntimeError( 18 | f"The gaintable was not created. Please refer to CASA {config.binary} logfile for further details" 19 | ) 20 | 21 | tab = table(gtab) 22 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 23 | tab.close() 24 | 25 | field_in = parameters_dict["field"].split(",") 26 | try: 27 | tab = table(gtab + "::FIELD") 28 | field_names = tab.getcol("NAME") 29 | tab.close() 30 | except RuntimeError: 31 | # possible new table format 32 | # sadly Field name and Source name columns are empty 33 | # will need to figure this out, but ignoring the tests for now 34 | tab = table(gtab) 35 | field_names = numpy.unique(tab.getcol("FIELD_NAME")) 36 | tab.close() 37 | pass 38 | 39 | if field_names: 40 | try: 41 | ids = list(map(int, field_in)) 42 | except ValueError: 43 | ids = list(map(lambda a: field_names.index(a), field_in)) 44 | if not set(ids).issubset(field_ids): 45 | raise RuntimeError( 46 | f"Some field(s) do not have solutions after the calibration. Please refer to CASA {config.binary} logfile for further details" 47 | ) 48 | -------------------------------------------------------------------------------- /stimela/cargo/cab/stimela2/src/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import shlex 4 | import shutil 5 | import subprocess 6 | import yaml 7 | import glob 8 | 9 | 10 | CONFIG = os.environ["CONFIG"] 11 | INPUT = os.environ["INPUT"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | MSDIR = os.environ["MSDIR"] 14 | 15 | with open(CONFIG, "r") as _std: 16 | cab = yaml.safe_load(_std) 17 | 18 | junk = cab["junk"] 19 | args = [] 20 | 21 | for param in cab["parameters"]: 22 | name = param["name"] 23 | value = param["value"] 24 | 25 | if value is None: 26 | continue 27 | 28 | if name in ["recipe"]: 29 | recipe = value 30 | continue 31 | 32 | if name in ["recipe-name"]: 33 | recipe_name = value 34 | continue 35 | 36 | if name in ["support-files"]: 37 | continue 38 | 39 | if name in ["step"]: 40 | delimiter = "," # param['delimiter'] 41 | args += ["{0}{1} {2}".format(cab["prefix"], name, delimiter.join(value))] 42 | 43 | if name in ["params"]: 44 | delimiter = " " # param['delimiter'] 45 | args += ["{0}".format(delimiter.join(value))] 46 | 47 | _runc = " ".join([cab["binary"]] + [recipe, recipe_name] + args) 48 | 49 | try: 50 | subprocess.check_call(shlex.split(_runc)) 51 | finally: 52 | for item in junk: 53 | for dest in [ 54 | OUTPUT, 55 | MSDIR, 56 | ]: # these are the only writable volumes in the container 57 | items = glob.glob("{dest}/{item}".format(**locals())) 58 | for f in items: 59 | if os.path.isfile(f): 60 | os.remove(f) 61 | elif os.path.isdir(f): 62 | shutil.rmtree(f) 63 | -------------------------------------------------------------------------------- /stimela/cargo/cab/flagms/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import yaml 6 | import glob 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | 23 | if value in [False, None]: 24 | continue 25 | 26 | if name in "channels timeslots corrs stations ddid field str".split(): 27 | if name in "channels timeslots".split(): 28 | value = ":".join(value) 29 | else: 30 | value = ",".join(value) 31 | if value is True: 32 | value = "" 33 | 34 | if name == "msname": 35 | msname = value 36 | if isinstance(msname, str): 37 | msname = [msname] 38 | continue 39 | 40 | if name == "flagged-any": 41 | args += ["{0}flagged-any {1}".format(cab["prefix"], a) for a in value] 42 | continue 43 | 44 | args.append("{0}{1} {2}".format(cab["prefix"], name, value)) 45 | 46 | _runc = " ".join([cab["binary"]] + args + msname) 47 | 48 | try: 49 | subprocess.check_call(shlex.split(_runc)) 50 | finally: 51 | for item in junk: 52 | for dest in [ 53 | OUTPUT, 54 | MSDIR, 55 | ]: # these are the only writable volumes in the container 56 | items = glob.glob("{dest}/{item}".format(**locals())) 57 | for f in items: 58 | if os.path.isfile(f): 59 | os.remove(f) 60 | elif os.path.isdir(f): 61 | shutil.rmtree(f) 62 | -------------------------------------------------------------------------------- /stimela/cargo/cab/tigger_restore/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import glob 4 | import yaml 5 | import shlex 6 | import shutil 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | 23 | if value in [False, None]: 24 | continue 25 | 26 | if name in "restoring-beam scale".split() and hasattr(value, "__iter__"): 27 | value = ",".join(value) 28 | 29 | if value is True: 30 | value = "" 31 | if name == "f": 32 | args.append("-f") 33 | continue 34 | 35 | # Positional arguments 36 | if name == "input-image": 37 | inim = value 38 | continue 39 | 40 | elif name == "input-skymodel": 41 | inlsm = value 42 | continue 43 | 44 | elif name == "output-image": 45 | outim = value 46 | continue 47 | 48 | args.append("{0}{1} {2}".format(cab["prefix"], name, value)) 49 | 50 | 51 | _runc = " ".join([cab["binary"]] + args + [inim, inlsm, outim]) 52 | 53 | try: 54 | subprocess.check_call(shlex.split(_runc)) 55 | finally: 56 | for item in junk: 57 | for dest in [ 58 | OUTPUT, 59 | MSDIR, 60 | ]: # these are the only writable volumes in the container 61 | items = glob.glob("{dest}/{item}".format(**locals())) 62 | for f in items: 63 | if os.path.isfile(f): 64 | os.remove(f) 65 | elif os.path.isdir(f): 66 | shutil.rmtree(f) 67 | -------------------------------------------------------------------------------- /stimela/cargo/cab/mosaicsteward/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import shlex 4 | import glob 5 | import shutil 6 | import yaml 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | OUTPUT = os.environ["OUTPUT"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | targets = None 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | elif value is False: 27 | continue 28 | elif value is True: 29 | value = "" 30 | elif name == "target-images": 31 | targets = value 32 | continue 33 | 34 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 35 | 36 | indir = os.path.dirname(targets[0]) 37 | target_names = map(os.path.basename, targets) 38 | target_images = "--target-images " + " --target-images ".join(target_names) 39 | 40 | args += ["--input {0:s} {1:s} --output {2:s}".format(indir, target_images, OUTPUT)] 41 | 42 | if not target_images: 43 | raise RuntimeError( 44 | "Filenames of the images to be mosaicked have not been specified." 45 | ) 46 | _runc = " ".join([cab["binary"]] + args) 47 | 48 | try: 49 | subprocess.check_call(shlex.split(_runc)) 50 | finally: 51 | for item in junk: 52 | for dest in [ 53 | OUTPUT, 54 | MSDIR, 55 | ]: # these are the only writable volumes in the container 56 | items = glob.glob("{dest}/{item}".format(**locals())) 57 | for f in items: 58 | if os.path.isfile(f): 59 | os.remove(f) 60 | elif os.path.isdir(f): 61 | shutil.rmtree(f) 62 | -------------------------------------------------------------------------------- /stimela/cargo/cab/shadems/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import yaml 4 | import subprocess 5 | import shutil 6 | import glob 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | args = [] 18 | for param in cab["parameters"]: 19 | name = param["name"] 20 | value = param["value"] 21 | if value is None: 22 | continue 23 | elif value is False: 24 | continue 25 | if name == "ms": 26 | ms = value 27 | continue 28 | elif name in [ 29 | "debug", 30 | "iter-scan", 31 | "iter-field", 32 | "iter-corr", 33 | "iter-spw", 34 | "iter-antenna", 35 | "noconj", 36 | "noflags", 37 | "profile", 38 | ]: 39 | value = "" 40 | 41 | if isinstance(value, list): 42 | val = map(str, value) 43 | args += ["{0}{1} {2}".format(cab["prefix"], name, " ".join(val))] 44 | continue 45 | 46 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 47 | 48 | _runc = " ".join([cab["binary"]] + args + ["--dir", OUTPUT] + [ms]) 49 | 50 | try: 51 | subprocess.check_call(shlex.split(_runc)) 52 | finally: 53 | for item in junk: 54 | for dest in [ 55 | OUTPUT, 56 | MSDIR, 57 | ]: # these are the only writable volumes in the container 58 | items = glob.glob("{dest}/{item}".format(**locals())) 59 | for f in items: 60 | if os.path.isfile(f): 61 | os.remove(f) 62 | elif os.path.isdir(f): 63 | shutil.rmtree(f) 64 | # Leave other types 65 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | release: 13 | types: [published] 14 | 15 | env: 16 | POETRY_VERSION: 2.0.1 17 | 18 | jobs: 19 | deploy: 20 | 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@v3 25 | - name: Set up Python 26 | uses: actions/setup-python@v4 27 | with: 28 | python-version: '3.x' 29 | 30 | - name: Cache Installations 31 | id: cache-installs 32 | uses: actions/cache@v3 33 | with: 34 | path: ~/.local 35 | key: install-${{ env.INSTALL_CACHE_HASH }}-3 36 | 37 | - name: Install Poetry 38 | if: steps.cache-installs.outputs.cache-hit != 'true' 39 | run: | 40 | curl -sSL https://install.python-poetry.org | python3 - --version ${{ env.POETRY_VERSION }} 41 | - name: Test poetry 42 | run: poetry --version 43 | 44 | - name: Checkout source 45 | uses: actions/checkout@v2 46 | with: 47 | fetch-depth: 1 48 | 49 | - name: Install stimela 50 | run: poetry install 51 | 52 | - name: Build distribution 53 | run: poetry build 54 | 55 | - name: Publish distribution 📦 to PyPI 56 | uses: pypa/gh-action-pypi-publish@master 57 | with: 58 | user: __token__ 59 | password: ${{ secrets.PYPI_TOKEN_STIMELA }} 60 | -------------------------------------------------------------------------------- /stimela/cargo/cab/cubical/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import sys 3 | import shlex 4 | import configparser 5 | import ast 6 | from scabha import config, parameters_dict, prun 7 | 8 | args = {} 9 | parset = [] 10 | 11 | for name, value in parameters_dict.items(): 12 | if value is None: 13 | continue 14 | elif value is False: 15 | value = 0 16 | elif value is True: 17 | value = 1 18 | elif name == "parset": 19 | parset = [value] 20 | continue 21 | elif isinstance(value, list): 22 | value = ",".join(map(str, value)) 23 | 24 | args[name] = value 25 | 26 | # available jones terms 27 | joneses = "g b dd".split() 28 | 29 | try: 30 | soljones = args.pop("sol-jones") 31 | except KeyError: 32 | conf = configparser.SafeConfigParser(inline_comment_prefixes="#") 33 | conf.read(parset[0]) 34 | if "jones" in conf.options("sol"): 35 | soljones = conf.get("sol", "jones") 36 | if "[" in soljones: 37 | soljones = ast.literal_eval(soljones) 38 | else: 39 | soljones = soljones.split(",") 40 | else: 41 | soljones = ["g", "de"] 42 | if type(soljones) is list: 43 | soljones = ",".join(soljones) 44 | 45 | for jones in joneses: 46 | if jones.lower() not in soljones.lower(): 47 | jopts = filter(lambda a: a.startswith("{0:s}-".format(jones)), args.keys()) 48 | for item in list(jopts): 49 | del args[item] 50 | 51 | opts = ["{0:s}sol-jones {1:s}".format(config.prefix, soljones)] + [ 52 | "{0}{1} {2}".format(config.prefix, name, value) for name, value in args.items() 53 | ] 54 | 55 | _runc = " ".join([config.binary] + parset + opts) 56 | 57 | argslist = shlex.split(_runc) 58 | 59 | # run the command 60 | if prun(argslist) != 0: 61 | sys.exit(1) 62 | -------------------------------------------------------------------------------- /stimela/cargo/cab/mvftoms/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import subprocess 4 | import shutil 5 | import shlex 6 | import yaml 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | OUTDIR = os.environ["OUTPUT"] 12 | HOME = os.environ["HOME"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = [] 20 | overwrite = False 21 | 22 | for param in cab["parameters"]: 23 | value = param["value"] 24 | name = param["name"] 25 | 26 | if value in [None, False]: 27 | continue 28 | elif name == "overwrite": 29 | overwrite = value 30 | continue 31 | elif value is True: 32 | value = "" 33 | elif name == "mvffiles": 34 | files = value 35 | continue 36 | elif name == "output-ms" and value: 37 | ms = value 38 | elif name == "credentials_dir" and value: 39 | os.system("cp -rf {0:s} {1:s}/.aws".format(value, HOME)) 40 | continue 41 | elif name == "archive-url": 42 | files = value 43 | continue 44 | 45 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 46 | 47 | if overwrite: 48 | os.system("rm -fr {0:s}".format(ms)) 49 | 50 | _runc = " ".join([cab["binary"]] + args + files) 51 | try: 52 | subprocess.check_call(shlex.split(_runc)) 53 | finally: 54 | for item in junk: 55 | for dest in [ 56 | OUTDIR, 57 | MSDIR, 58 | ]: # these are the only writable volumes in the container 59 | items = glob.glob("{dest}/{item}".format(**locals())) 60 | for f in items: 61 | if os.path.isfile(f): 62 | os.remove(f) 63 | elif os.path.isdir(f): 64 | shutil.rmtree(f) 65 | -------------------------------------------------------------------------------- /stimela/cargo/cab/sofia/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import codecs 4 | import shlex 5 | import shutil 6 | import glob 7 | import subprocess 8 | 9 | 10 | 11 | CONFIG = os.environ["CONFIG"] 12 | INPUT = os.environ["INPUT"] 13 | MSDIR = os.environ["MSDIR"] 14 | OUTPUT = os.environ["OUTPUT"] 15 | 16 | with codecs.open(CONFIG, "r", "utf8") as stdr: 17 | cab = json.load(stdr) 18 | 19 | junk = cab["junk"] 20 | args = [] 21 | msname = None 22 | 23 | sofia_file = "sofia_parameters.par" 24 | wstd = open(sofia_file, "w") 25 | 26 | wstd.write("writeCat.outputDir={:s}\n".format(OUTPUT)) 27 | port2tigger = False 28 | image = None 29 | writecat = False 30 | parameterise = False 31 | 32 | for param in cab["parameters"]: 33 | name = param["name"] 34 | value = param["value"] 35 | 36 | if value is None: 37 | continue 38 | if name == "port2tigger": 39 | port2tigger = value 40 | continue 41 | if name == "steps.doWriteCat": 42 | writecat = value 43 | if name == "steps.doParameterise": 44 | parameterise = value 45 | if name == "import.inFile": 46 | image = value 47 | 48 | wstd.write("{0}={1}\n".format(name, value)) 49 | 50 | wstd.close() 51 | 52 | _runc = " ".join(["sofia_pipeline.py", sofia_file]) 53 | 54 | try: 55 | subprocess.check_call(shlex.split(_runc)) 56 | finally: 57 | for item in junk: 58 | for dest in [ 59 | OUTPUT, 60 | MSDIR, 61 | ]: # these are the only writable volumes in the container 62 | items = glob.glob("{dest}/{item}".format(**locals())) 63 | for f in items: 64 | if os.path.isfile(f): 65 | os.remove(f) 66 | elif os.path.isdir(f): 67 | shutil.rmtree(f) 68 | # Leave other types 69 | -------------------------------------------------------------------------------- /stimela/cargo/base/stimela2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM kernsuite/base:9 2 | MAINTAINER 3 | RUN docker-apt-install cmake \ 4 | bison \ 5 | build-essential \ 6 | casacore-dev \ 7 | cmake \ 8 | flex \ 9 | gfortran \ 10 | g++ \ 11 | libncurses5-dev \ 12 | libreadline-dev \ 13 | libblas-dev \ 14 | liblapacke-dev \ 15 | libcfitsio-dev \ 16 | libgsl-dev \ 17 | libhdf5-serial-dev \ 18 | libfftw3-dev \ 19 | libboost-python-dev \ 20 | libboost-all-dev \ 21 | libpython2.7-dev \ 22 | liblog4cplus-dev \ 23 | libhdf5-dev \ 24 | montage \ 25 | subversion \ 26 | wcslib-dev \ 27 | python3-numpy \ 28 | wget \ 29 | wsclean 30 | 31 | RUN docker-apt-install python3-pip 32 | RUN pip install cult-cargo stimela quartical \ 33 | aimfast \ 34 | astro-tigger-lsm \ 35 | bdsf \ 36 | breizorro \ 37 | casaconfig \ 38 | casadata \ 39 | casatasks \ 40 | casatools \ 41 | mosaic-queen 42 | 43 | RUN docker-apt-install \ 44 | git \ 45 | xvfb \ 46 | curl 47 | 48 | RUN pip install -U "git+https://github.com/caracal-pipeline/stimela.git" 49 | RUN pip install -U "git+https://github.com/caracal-pipeline/cult-cargo.git" 50 | 51 | RUN ulimit -p 11000 52 | RUN stimela --help 53 | 54 | RUN ln -s /usr/bin/python3 /usr/bin/python 55 | RUN mkdir -p /opt/casa/data 56 | COPY casasiteconfig.py /opt/casa 57 | ENV CASASITECONFIG /opt/casa/casasiteconfig.py 58 | RUN python -m casaconfig --measurespath /opt/casa/data --update-all 59 | RUN python -m casaconfig --measurespath /opt/casa/data --current-data 60 | # point to CASA data 61 | RUN mkdir -p /usr/local/share/data/ 62 | RUN ln -s /opt/casa/data /usr/local/share/data/casacore 63 | COPY xvfb.init.d /etc/init.d/xvfb 64 | RUN chmod 755 /etc/init.d/xvfb 65 | RUN chmod 777 /var/run 66 | ENV DISPLAY :99 67 | -------------------------------------------------------------------------------- /stimela/cargo/cab/imcontsub/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import glob 6 | from collections import OrderedDict 7 | import json 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "rb") as stdr: 15 | cab = json.load(stdr, object_pairs_hook=OrderedDict) 16 | 17 | junk = cab["junk"] 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | dtype = param["dtype"] 24 | if value is None: 25 | continue 26 | 27 | if name == "infits": 28 | infits = value 29 | continue 30 | 31 | if isinstance(value, list): 32 | values = map(str, value) 33 | args += [f"{cab['prefix']}{name} " + ",".join(values)] 34 | elif name == "output-prefix": 35 | args += [f"{cab['prefix']}{name} {OUTPUT}/{value}"] 36 | elif isinstance(dtype, str) and dtype == "bool": 37 | args += [f"{cab['prefix']}{name}"] 38 | else: 39 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 40 | 41 | binary = f"{os.environ['STIMELA_VENV_BIN']}/{cab['binary']}" 42 | _runc = " ".join([binary] + args + [infits]) 43 | 44 | 45 | subprocess.check_call(shlex.split(f"echo '{_runc}'")) 46 | try: 47 | subprocess.check_call(shlex.split(_runc)) 48 | finally: 49 | for item in junk: 50 | for dest in [ 51 | OUTPUT, 52 | MSDIR, 53 | ]: # these are the only writable volumes in the container 54 | items = glob.glob("{dest}/{item}".format(**locals())) 55 | for f in items: 56 | if os.path.isfile(f): 57 | os.remove(f) 58 | elif os.path.isdir(f): 59 | shutil.rmtree(f) 60 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_polfromgain/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_polfromgain", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "version": [ 10 | "4.7.2", 11 | "5.6.1-8", 12 | "5.8.0" 13 | ], 14 | "description": "Derive linear polarization from gain ratio", 15 | "prefix": "-", 16 | "binary": "polfromgain", 17 | "junk": [ 18 | "polfromgain.last" 19 | ], 20 | "msdir": true, 21 | "wranglers_demo": { 22 | "PIPELINE CASA": [ 23 | "replace:MI CASA ES TU CASA", 24 | "ERROR" 25 | ], 26 | "[tT]elemetry": "SUPPRESS", 27 | "(Begin|End) Task:": [ 28 | "replace:Sisyphus, \\1 your task", 29 | "WARN" 30 | ], 31 | "End Task:": [ 32 | "DECLARE_FAILURE" 33 | ] 34 | }, 35 | "parameters": [ 36 | { 37 | "info": "Name of input visibility file", 38 | "name": "msname", 39 | "io": "msfile", 40 | "default": null, 41 | "dtype": "file", 42 | "required": true, 43 | "mapping": "vis" 44 | }, 45 | { 46 | "info": "Input calibration table", 47 | "dtype": "file", 48 | "default": null, 49 | "name": "tablein", 50 | "required": true, 51 | "io": "input" 52 | }, 53 | { 54 | "info": "Output calibration table (forces polarization correction if specified)", 55 | "dtype": "file", 56 | "default": null, 57 | "name": "caltable", 58 | "io": "output" 59 | }, 60 | { 61 | "info": "Manual position angle offset", 62 | "dtype": "float", 63 | "default": null, 64 | "name": "paoffset" 65 | }, 66 | { 67 | "info": "Output pickle file to the result from task", 68 | "dtype": "file", 69 | "default": null, 70 | "name": "save_result", 71 | "io": "output" 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_makemask/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_makemask", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Makes and manipulates image masks", 10 | "prefix": "-", 11 | "junk": [ 12 | "makemask.last" 13 | ], 14 | "binary": "makemask", 15 | "msdir": false, 16 | "parameters": [ 17 | { 18 | "info": "Mask method", 19 | "name": "mode", 20 | "default": "copy", 21 | "dtype": "str", 22 | "required": true, 23 | "choices": [ 24 | "list", 25 | "copy", 26 | "expand", 27 | "delete", 28 | "setdefaultmask" 29 | ] 30 | }, 31 | { 32 | "info": "Name of input image", 33 | "name": "inpimage", 34 | "io": "input", 35 | "default": null, 36 | "dtype": "file", 37 | "required": true 38 | }, 39 | { 40 | "info": "Mask(s) to be processed: image masks,T/F internal masks(Need to include parent image", 41 | "name": "inpmask", 42 | "io": "input", 43 | "default": null, 44 | "dtype": "file", 45 | "required": false 46 | }, 47 | { 48 | "info": "Name of output mask (imagename or imagename:internal_maskname)", 49 | "name": "output", 50 | "io": "output", 51 | "default": null, 52 | "dtype": "str", 53 | "required": true 54 | }, 55 | { 56 | "info": "overwrite output if exists", 57 | "default": false, 58 | "required": true, 59 | "name": "overwrite", 60 | "dtype": "bool" 61 | }, 62 | { 63 | "info": "Cut-off threshold to mask sources", 64 | "dtype": "float", 65 | "default": null, 66 | "required": false, 67 | "name": "threshold" 68 | } 69 | ], 70 | "version": [ 71 | "4.7.2", 72 | "5.6.1-8", 73 | "5.8.0" 74 | ] 75 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/cubical_ddf/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import glob 6 | import yaml 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = {} 19 | parset = [] 20 | 21 | for param in cab["parameters"]: 22 | name = param["name"] 23 | value = param["value"] 24 | 25 | if value is None: 26 | continue 27 | elif value is False: 28 | value = 0 29 | elif value is True: 30 | value = 1 31 | elif name == "parset": 32 | parset = [value] 33 | continue 34 | elif isinstance(value, list): 35 | value = ",".join(map(str, value)) 36 | 37 | args[name] = value 38 | 39 | # available jones terms 40 | joneses = "g b dd".split() 41 | soljones = args.pop("sol-jones") 42 | 43 | for jones in joneses: 44 | if jones.lower() not in soljones.lower(): 45 | jopts = filter(lambda a: a.startswith("{0:s}-".format(jones)), args.keys()) 46 | for item in list(jopts): 47 | del args[item] 48 | 49 | opts = ["{0:s}sol-jones {1:s}".format(cab["prefix"], soljones)] + [ 50 | "{0}{1} {2}".format(cab["prefix"], name, value) for name, value in args.items() 51 | ] 52 | 53 | _runc = " ".join([cab["binary"]] + parset + opts) 54 | try: 55 | subprocess.check_call(shlex.split(_runc)) 56 | finally: 57 | for item in junk: 58 | for dest in [ 59 | OUTPUT, 60 | MSDIR, 61 | ]: # these are the only writable volumes in the container 62 | items = glob.glob("{dest}/{item}".format(**locals())) 63 | for f in items: 64 | if os.path.isfile(f): 65 | os.remove(f) 66 | elif os.path.isdir(f): 67 | shutil.rmtree(f) 68 | -------------------------------------------------------------------------------- /stimela/cargo/cab/chgcentre/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "chgcentre", 3 | "base": "stimela/chgcentre", 4 | "tag": "1.2.0", 5 | "description": "Tool used to change the phase centre of a measurement set", 6 | "prefix": "-", 7 | "binary": "chgcentre", 8 | "msdir": true, 9 | "junk": [], 10 | "parameters": [ 11 | { 12 | "info": "Name of MS file to change the phase centre", 13 | "check_io": false, 14 | "name": "msname", 15 | "io": "msfile", 16 | "default": null, 17 | "dtype": "file", 18 | "required": true 19 | }, 20 | { 21 | "info": "New RA to change to. The format of RA can either be 00h00m00.0s or 00:00:00.0", 22 | "default": null, 23 | "required": false, 24 | "name": "new-ra", 25 | "dtype": "str" 26 | }, 27 | { 28 | "info": "New DEC to change to. The format of DEC can either be 00h00m00.0s or 00:00:00.0", 29 | "default": null, 30 | "required": false, 31 | "name": "new-dec", 32 | "dtype": "str" 33 | }, 34 | { 35 | "info": "Rephase to the direction orthogonal to the best-fit plane to the antennas", 36 | "default": null, 37 | "required": false, 38 | "name": "minw", 39 | "dtype": "bool" 40 | }, 41 | { 42 | "info": "Rephase to the local array zenith", 43 | "default": null, 44 | "required": false, 45 | "name": "zenith", 46 | "dtype": "bool" 47 | }, 48 | { 49 | "info": "Prepare the measurement set for w-snapshot imaging with WSClean", 50 | "default": null, 51 | "required": false, 52 | "name": "shiftback", 53 | "dtype": "bool" 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /stimela/cargo/cab/aimfast/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shlex 3 | import shutil 4 | import subprocess 5 | import yaml 6 | import glob 7 | 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | args = [] 19 | 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | if value is None: 24 | continue 25 | 26 | if name in ["compare-images", "compare-residuals", "compare-models"]: 27 | compare = [] 28 | for i, val in enumerate(value): 29 | compare.append(val) 30 | # Compare models/images in pairs 31 | if i % 2: 32 | args += ["{0}{1} {2}".format(cab["prefix"], name, " ".join(compare))] 33 | compare = [] 34 | elif name in ["compare-online"]: 35 | for val in value: 36 | args += ["{0}{1} {2}".format(cab["prefix"], name, val)] 37 | elif name in ["compare-residual-subimages", "centre-pixels-size"]: 38 | args += ["{0}{1} {2}".format(cab["prefix"], name, " ".join(value))] 39 | elif param["dtype"] in ["bool"]: 40 | args += ["{0}{1}".format(cab["prefix"], name)] 41 | else: 42 | args += ["{0}{1} {2}".format(cab["prefix"], name, value)] 43 | 44 | _runc = " ".join([cab["binary"]] + args) 45 | 46 | try: 47 | subprocess.check_call(shlex.split(_runc)) 48 | finally: 49 | for item in junk: 50 | for dest in [ 51 | OUTPUT, 52 | MSDIR, 53 | ]: # these are the only writable volumes in the container 54 | items = glob.glob("{dest}/{item}".format(**locals())) 55 | for f in items: 56 | if os.path.isfile(f): 57 | os.remove(f) 58 | elif os.path.isdir(f): 59 | shutil.rmtree(f) 60 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_importfits/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_importfits", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Convert aFITS image to a CASA file", 10 | "prefix": " ", 11 | "binary": "importfits", 12 | "junk": [ 13 | "importfits.last" 14 | ], 15 | "msdir": false, 16 | "parameters": [ 17 | { 18 | "info": "Name of input image FITS file", 19 | "dtype": "file", 20 | "required": true, 21 | "name": "fitsimage", 22 | "io": "input" 23 | }, 24 | { 25 | "info": "Name of output CASA image", 26 | "dtype": "file", 27 | "required": true, 28 | "name": "imagename", 29 | "io": "output" 30 | }, 31 | { 32 | "info": "If fits image has multiple coordinate reps, choose one", 33 | "dtype": "int", 34 | "name": "whichrep" 35 | }, 36 | { 37 | "info": "If its file contains multiple images, choose one (0 = first HDU, -1 = first valid image).", 38 | "dtype": "int", 39 | "name": "whichhdu" 40 | }, 41 | { 42 | "info": "Set blanked pixels to zero (not NaN)", 43 | "dtype": "bool", 44 | "name": "zeroblanks" 45 | }, 46 | { 47 | "info": "Overwrite pre-existing imagename", 48 | "dtype": "bool", 49 | "name": "overwrite" 50 | }, 51 | { 52 | "info": "List of values to assign to added degenerate axes defaultaxes==True (ra,dec,freq,stokes)", 53 | "dtype": [ 54 | "list:str", 55 | "list:float", 56 | "list:int" 57 | ], 58 | "name": "defaultaxesvalues" 59 | }, 60 | { 61 | "info": "List of values to be used to define the synthesized beam [BMAJ,BMIN,BPA] (as in the FITS keywords)", 62 | "dtype": [ 63 | "list:str", 64 | "list:float", 65 | "list:int" 66 | ], 67 | "name": "beam" 68 | } 69 | ], 70 | "version": [ 71 | "4.7.2", 72 | "5.6.1-8", 73 | "5.8.0" 74 | ] 75 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_gencal/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_gencal", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Specify Calibration Values of Various Types", 10 | "prefix": " ", 11 | "binary": "gencal", 12 | "junk": [ 13 | "gencal.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility file", 19 | "name": "msname", 20 | "io": "msfile", 21 | "dtype": "file", 22 | "required": true, 23 | "mapping": "vis" 24 | }, 25 | { 26 | "info": "The new/existing calibration table", 27 | "dtype": "file", 28 | "default": null, 29 | "name": "caltable", 30 | "io": "output" 31 | }, 32 | { 33 | "info": "The calibration type: 'amp','ph', 'sbd','mbd','antpos','antposvla','tsys''evlagain','opac','gc','gceff','eff'", 34 | "dtype": "str", 35 | "default": null, 36 | "name": "caltype", 37 | "choices": [ 38 | "amp", 39 | "ph", 40 | "sbd", 41 | "mbd", 42 | "antpos", 43 | "antposvla", 44 | "tsys", 45 | "evlagain", 46 | "opac", 47 | "gc", 48 | "gceff", 49 | "eff" 50 | ] 51 | }, 52 | { 53 | "info": "Calibration spw(s) selection", 54 | "dtype": "str", 55 | "default": null, 56 | "name": "spw" 57 | }, 58 | { 59 | "info": "Calibration antenna(s) selection", 60 | "dtype": "str", 61 | "default": null, 62 | "name": "antenna" 63 | }, 64 | { 65 | "info": "Calibration polarizations(s) selection", 66 | "dtype": "str", 67 | "default": null, 68 | "name": "pol" 69 | }, 70 | { 71 | "info": "The calibration values", 72 | "dtype": "list:float", 73 | "default": null, 74 | "name": "parameter" 75 | } 76 | ], 77 | "version": [ 78 | "4.7.2", 79 | "5.6.1-8", 80 | "5.8.0" 81 | ] 82 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_flagmanager/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_flagmanager", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "These flag version files are copies of the flag column for a measurement set. They can be restored to the data set to get back to a previous flag version. On running importvla, a flag version call 'Original' is automatically produced.", 10 | "prefix": "-", 11 | "binary": "flagmanager", 12 | "junk": [ 13 | "flagmanager.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility file", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "required": true, 24 | "mapping": "vis" 25 | }, 26 | { 27 | "info": "Name of input visibility file (MS)", 28 | "dtype": "file", 29 | "default": null, 30 | "name": "vis", 31 | "io": "msfile" 32 | }, 33 | { 34 | "info": "Flag version operation", 35 | "dtype": "str", 36 | "default": "list", 37 | "name": "mode", 38 | "choices": [ 39 | "list", 40 | "save", 41 | "restore", 42 | "delete", 43 | "rename" 44 | ] 45 | }, 46 | { 47 | "info": "Flag version name", 48 | "dtype": "str", 49 | "default": null, 50 | "name": "versionname" 51 | }, 52 | { 53 | "info": "Flag version to rename", 54 | "dtype": "str", 55 | "default": null, 56 | "name": "oldname" 57 | }, 58 | { 59 | "info": "Short description of a versionname", 60 | "dtype": "str", 61 | "default": null, 62 | "name": "comment" 63 | }, 64 | { 65 | "info": "Merge option: replace will save or over-write the flags", 66 | "dtype": "str", 67 | "default": "replace", 68 | "name": "merge" 69 | } 70 | ], 71 | "version": [ 72 | "4.7.2", 73 | "5.6.1-8", 74 | "5.8.0" 75 | ] 76 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/tigger_tag/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import subprocess 4 | import yaml 5 | import shutil 6 | import shlex 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | params = {} 19 | for param in cab["parameters"]: 20 | name = param["name"] 21 | value = param["value"] 22 | 23 | if value in [False, None]: 24 | continue 25 | 26 | if value is True: 27 | value = "" 28 | 29 | # Positional arguments 30 | if name == "input-skymodel": 31 | inlsm = value 32 | continue 33 | elif name == "tag": 34 | tag = value 35 | continue 36 | 37 | params[name] = value 38 | 39 | # TODO: Need fix tigger-tag, these kludges are annoying 40 | if params.pop("transfer-tags", False) in [True, ""]: 41 | if params.get("tolerance", None) is None: 42 | raise RuntimeError( 43 | "Parameter 'tolerance' is required when 'transfer-tags' is enables" 44 | ) 45 | args = [ 46 | "{0}transfer-tags {1}:{2}".format(cab["prefix"], inlsm, params.pop("tolerance")) 47 | ] 48 | inlsm = params.get("output") 49 | else: 50 | args = [] 51 | 52 | args += [ 53 | "{0}{1} {2}".format(cab["prefix"], name, value) 54 | for name, value in params.iteritems() 55 | ] 56 | 57 | _runc = " ".join([cab.binary, inlsm, tag] + args) 58 | 59 | try: 60 | subprocess.check_call(shlex.split(_runc)) 61 | finally: 62 | for item in junk: 63 | for dest in [ 64 | OUTPUT, 65 | MSDIR, 66 | ]: # these are the only writable volumes in the container 67 | items = glob.glob("{dest}/{item}".format(**locals())) 68 | for f in items: 69 | if os.path.isfile(f): 70 | os.remove(f) 71 | elif os.path.isdir(f): 72 | shutil.rmtree(f) 73 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_concat/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_concat", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Concatenate several visibility data sets", 10 | "prefix": "", 11 | "binary": "concat", 12 | "junk": [ 13 | "concat.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility files", 19 | "name": "msname", 20 | "io": "msfile", 21 | "dtype": "list:file", 22 | "required": true, 23 | "mapping": "vis" 24 | }, 25 | { 26 | "info": "Name of output measurement set", 27 | "check_io": false, 28 | "name": "output-msname", 29 | "io": "msfile", 30 | "default": null, 31 | "dtype": "file", 32 | "mapping": "concatvis" 33 | }, 34 | { 35 | "info": "Frequency shift tolerance for considering data as the same spwid", 36 | "default": null, 37 | "name": "freqtol", 38 | "dtype": "str" 39 | }, 40 | { 41 | "info": "Direction shift tolerance for considering data as the same field", 42 | "dtype": "str", 43 | "default": null, 44 | "name": "dirtol" 45 | }, 46 | { 47 | "info": "If true, fields with a different name are not merged even if their direction agrees", 48 | "dtype": "bool", 49 | "default": false, 50 | "name": "respectname" 51 | }, 52 | { 53 | "info": "If true, sort by TIME in ascending", 54 | "default": false, 55 | "name": "timesort", 56 | "dtype": "bool" 57 | }, 58 | { 59 | "info": "Copy all rows of the POINTING table", 60 | "default": true, 61 | "name": "copypointing", 62 | "dtype": "bool" 63 | }, 64 | { 65 | "info": "List of the weight scaling factors to be applied to the individual MSs", 66 | "default": null, 67 | "name": "visweightscale", 68 | "dtype": "list" 69 | } 70 | ], 71 | "version": [ 72 | "4.7.2", 73 | "5.6.1-8", 74 | "5.8.0" 75 | ] 76 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/mosaicsteward/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "mosaicsteward", 3 | "base": "stimela/montage", 4 | "tag": "1.2.4", 5 | "version" : "0.0.3", 6 | "description": "A package that allows continuum (2D) images and spectral (3D) images to be mosaicked together, using montage commands.", 7 | "prefix": "--", 8 | "binary": "MosaicSteward", 9 | "junk": [], 10 | "msdir": false, 11 | "parameters": [ 12 | { 13 | "info": "State 'continuum' or 'spectral' as the type of mosaic to be made.", 14 | "default": null, 15 | "required": true, 16 | "name": "mosaic-type", 17 | "dtype": "str" 18 | }, 19 | { 20 | "info": "Include this argument if you wish to use montage for regridding the images and beams (if they have not already been created).", 21 | "default": null, 22 | "required": false, 23 | "name": "domontage", 24 | "dtype": "bool" 25 | }, 26 | { 27 | "info": "The cutoff in the primary beam to use (assuming a Gaussian at the moment). E.g. The default of 0.1 means going down to the 10 percent level for each pointing.", 28 | "default": 0.1, 29 | "required": false, 30 | "name": "cutoff", 31 | "dtype": "float" 32 | }, 33 | { 34 | "info": "The prefix to be used for output files.", 35 | "default": "mymosaic", 36 | "required": false, 37 | "name": "name", 38 | "dtype": "str" 39 | }, 40 | { 41 | "info": "The filenames of each target/pointing image to be mosaicked. A suffix of 'image.fits' is expected, and this is replaced by 'pb.fits' in order to locate the corresponding beams (which are also required as input).", 42 | "name": "target-images", 43 | "io": "input", 44 | "default": null, 45 | "dtype": "list:file", 46 | "required": true 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_polcal/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | from casacore.tables import table 4 | import numpy 5 | import glob 6 | import yaml 7 | import shutil 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = {} 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | 27 | args[name] = value 28 | 29 | task = crasa.CasaTask(cab["binary"], **args) 30 | try: 31 | task.run() 32 | finally: 33 | for item in junk: 34 | for dest in [ 35 | OUTPUT, 36 | MSDIR, 37 | ]: # these are the only writable volumes in the container 38 | items = glob.glob("{dest}/{item}".format(**locals())) 39 | for f in items: 40 | if os.path.isfile(f): 41 | os.remove(f) 42 | elif os.path.isdir(f): 43 | shutil.rmtree(f) 44 | # Leave other types 45 | 46 | gtab = args["caltable"] 47 | if not os.path.exists(gtab): 48 | raise RuntimeError( 49 | "The gaintable was not created. Please refer to CASA {0:s} logfile for further details".format( 50 | cab["binary"] 51 | ) 52 | ) 53 | 54 | tab = table(gtab) 55 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 56 | tab.close() 57 | 58 | tab = table(gtab + "::FIELD") 59 | field_names = tab.getcol("NAME") 60 | tab.close() 61 | 62 | field_in = args["field"].split(",") 63 | 64 | try: 65 | ids = map(int, field_in) 66 | except ValueError: 67 | ids = map(lambda a: field_names.index(a), field_in) 68 | 69 | if not set(ids).intersection(field_ids): 70 | raise RuntimeError( 71 | "None of the fields has solutions after the calibration. Please refer to CASA the {} logfile for further details".format( 72 | cab["binary"] 73 | ) 74 | ) 75 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_gaincal/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | from casacore.tables import table 4 | import numpy 5 | import glob 6 | import yaml 7 | import shutil 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = {} 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | 27 | args[name] = value 28 | 29 | task = crasa.CasaTask(cab["binary"], **args) 30 | try: 31 | task.run() 32 | finally: 33 | for item in junk: 34 | for dest in [ 35 | OUTPUT, 36 | MSDIR, 37 | ]: # these are the only writable volumes in the container 38 | items = glob.glob("{dest}/{item}".format(**locals())) 39 | for f in items: 40 | if os.path.isfile(f): 41 | os.remove(f) 42 | elif os.path.isdir(f): 43 | shutil.rmtree(f) 44 | # Leave other types 45 | 46 | gtab = args["caltable"] 47 | if not os.path.exists(gtab): 48 | raise RuntimeError( 49 | "The gaintable was not created. Please refer to CASA {0:s} logfile for further details".format( 50 | cab["binary"] 51 | ) 52 | ) 53 | 54 | tab = table(gtab) 55 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 56 | tab.close() 57 | 58 | tab = table(gtab + "::FIELD") 59 | field_names = tab.getcol("NAME") 60 | tab.close() 61 | 62 | field_in = args["field"].split(",") 63 | 64 | try: 65 | ids = map(int, field_in) 66 | except ValueError: 67 | ids = map(lambda a: field_names.index(a), field_in) 68 | 69 | if not set(ids).intersection(field_ids): 70 | raise RuntimeError( 71 | "None of the fields has solutions after the calibration. Please refer to CASA the {} logfile for further details".format( 72 | cab["binary"] 73 | ) 74 | ) 75 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_bandpass/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | from casacore.tables import table 4 | import numpy 5 | import yaml 6 | import glob 7 | import shutil 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | junk = cab["junk"] 18 | 19 | args = {} 20 | for param in cab["parameters"]: 21 | name = param["name"] 22 | value = param["value"] 23 | 24 | if value is None: 25 | continue 26 | 27 | args[name] = value 28 | 29 | task = crasa.CasaTask(cab["binary"], **args) 30 | try: 31 | task.run() 32 | finally: 33 | for item in junk: 34 | for dest in [ 35 | OUTPUT, 36 | MSDIR, 37 | ]: # these are the only writable volumes in the container 38 | items = glob.glob("{dest}/{item}".format(**locals())) 39 | for f in items: 40 | if os.path.isfile(f): 41 | os.remove(f) 42 | elif os.path.isdir(f): 43 | shutil.rmtree(f) 44 | # Leave other types 45 | 46 | 47 | gtab = args["caltable"] 48 | if not os.path.exists(gtab): 49 | raise RuntimeError( 50 | "The gaintable was not created. Please refer to CASA {0:s} logfile for further details".format( 51 | cab["binary"] 52 | ) 53 | ) 54 | 55 | tab = table(gtab) 56 | field_ids = numpy.unique(tab.getcol("FIELD_ID")) 57 | tab.close() 58 | 59 | tab = table(gtab + "::FIELD") 60 | field_names = tab.getcol("NAME") 61 | tab.close() 62 | 63 | field_in = args["field"].split(",") 64 | 65 | try: 66 | ids = map(int, field_in) 67 | except ValueError: 68 | ids = map(lambda a: field_names.index(a), field_in) 69 | 70 | if not set(ids).intersection(field_ids): 71 | raise RuntimeError( 72 | "None of the fields has solutions after the calibration. Please refer to the CASA {} logfile for further details".format( 73 | cab["binary"] 74 | ) 75 | ) 76 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_fixvis/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_fixvis", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Recalculates (u, v, w) and/or changes Phase Center", 10 | "prefix": "", 11 | "binary": "fixvis", 12 | "junk": [ 13 | "fixvis.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of the input visibility set.", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "required": true, 24 | "mapping": "vis" 25 | }, 26 | { 27 | "info": "Name of the output visibility set. (Can be the same as vis.)", 28 | "name": "output-msname", 29 | "io": "msfile", 30 | "default": false, 31 | "dtype": "file", 32 | "required": true, 33 | "mapping": "outputvis" 34 | }, 35 | { 36 | "info": "When applying a phase center shift, modify visibilities only in this/these column(s). Comma separated list", 37 | "dtype": "str", 38 | "default": "all", 39 | "name": "datacolumn" 40 | }, 41 | { 42 | "info": "Fields to operate on. '' = all.", 43 | "dtype": "str", 44 | "default": "", 45 | "name": "field" 46 | }, 47 | { 48 | "info": "Reference frame to convert UVW coordinates to", 49 | "dtype": "str", 50 | "default": null, 51 | "name": "refcode" 52 | }, 53 | { 54 | "info": "Base UVW calculation on the old values?", 55 | "dtype": "bool", 56 | "default": true, 57 | "name": "reuse" 58 | }, 59 | { 60 | "info": "Use this direction as phase center", 61 | "dtype": "str", 62 | "default": null, 63 | "name": "phasecenter" 64 | }, 65 | { 66 | "info": "(experimental) List of the distances (as quanta) of the fields selected by field.", 67 | "dtype": "list:str", 68 | "default": null, 69 | "name": "distances" 70 | } 71 | ], 72 | "version": [ 73 | "4.7.2", 74 | "5.6.1-8", 75 | "5.8.0" 76 | ] 77 | } -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | 2 | ======= 3 | Stimela 4 | ======= 5 | 6 | **NOTE** This is the repository for *Stimela Classic* (i.e. version 1.x) which is no longer actively developed -- only maintenance releases are done occasionally. New to Stimela and want to write YaML recipes? Then you're certainly looking for the shiny new `Stimela 2 `. 7 | 8 | 9 | |Pypi Version| 10 | |Build Version| 11 | 12 | To reference *stimela* in a scholary work, please use this citation: 13 | 14 | .. code-block:: latex 15 | 16 | @phdthesis{makhathini2018, 17 | author = {Makhathini, S.}, 18 | title = {Advanced radio interferometric simulation and data reduction techniques}, 19 | school = {Rhodes University}, 20 | year = 2018, 21 | address = {Drosty Rd, Grahamstown, 6139, Eastern Cape, South Africa}, 22 | month = 4, 23 | note = {Available via \url{http://hdl.handle.net/10962/57348}}} 24 | 25 | 26 | `Documentation `_ 27 | =========================================================== 28 | 29 | `Installation `_ 30 | ======================================================================= 31 | 32 | `Tutorials `_ 33 | ================================================================ 34 | 35 | 36 | This project was initially funded by the `SKA/AWS AstroCompute In The Cloud `_ initiative. 37 | 38 | 39 | .. |Pypi Version| image:: https://img.shields.io/pypi/v/stimela.svg 40 | :target: https://pypi.python.org/pypi/stimela 41 | :alt: 42 | .. |Build Version| image:: https://travis-ci.org/SpheMakh/Stimela.svg?branch=master 43 | :target: https://travis-ci.com/Sphemakh/Stimela/ 44 | :alt: 45 | 46 | .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/stimela.svg 47 | :target: https://pypi.python.org/pypi/stimela 48 | :alt: 49 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_ft/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_ft", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Insert a source model a visibility set", 10 | "prefix": "", 11 | "binary": "ft", 12 | "junk": [ 13 | "ft.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input MS. Output goes to vis + '.contsub' (will be overwritten if already exists)", 19 | "name": "msname", 20 | "io": "msfile", 21 | "default": null, 22 | "dtype": "file", 23 | "required": true, 24 | "mapping": "vis" 25 | }, 26 | { 27 | "info": "Select field(s) using id(s) or name(s)", 28 | "dtype": "str", 29 | "default": null, 30 | "name": "field" 31 | }, 32 | { 33 | "info": "Spw selection", 34 | "dtype": "str", 35 | "default": null, 36 | "name": "spw" 37 | }, 38 | { 39 | "info": "Name of input model image(s)", 40 | "dtype": "list:file", 41 | "default": null, 42 | "name": "model", 43 | "io": "input" 44 | }, 45 | { 46 | "info": "Number of terms used to model the sky frequency dependence", 47 | "dtype": "int", 48 | "default": 1, 49 | "name": "nterms" 50 | }, 51 | { 52 | "info": " Reference frequency (e.g. '1.5e+9' or '1.5GHz')", 53 | "dtype": "str", 54 | "default": null, 55 | "name": "reffreq" 56 | }, 57 | { 58 | "info": "Name of component list", 59 | "dtype": "file", 60 | "default": null, 61 | "name": "complist", 62 | "io": "input" 63 | }, 64 | { 65 | "info": "Add to the existing model visibility", 66 | "dtype": "bool", 67 | "default": null, 68 | "name": "incremental" 69 | }, 70 | { 71 | "info": "If True predicted visibility is stored in MODEL_DATA column", 72 | "dtype": "bool", 73 | "default": false, 74 | "name": "usescratch" 75 | } 76 | ], 77 | "version": [ 78 | "4.7.2", 79 | "5.6.1-8", 80 | "5.8.0" 81 | ] 82 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_virtualconcat/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_virtualconcat", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Concatenate several visibility data sets", 10 | "prefix": "", 11 | "binary": "virtualconcat", 12 | "junk": [ 13 | "virtualconcat.last" 14 | ], 15 | "msdir": true, 16 | "parameters": [ 17 | { 18 | "info": "Name of input visibility files", 19 | "name": "msname", 20 | "io": "msfile", 21 | "dtype": "list:file", 22 | "required": true, 23 | "mapping": "vis" 24 | }, 25 | { 26 | "info": "Name of output measurement set", 27 | "check_io": false, 28 | "name": "output-msname", 29 | "io": "msfile", 30 | "default": null, 31 | "dtype": "file", 32 | "mapping": "concatvis" 33 | }, 34 | { 35 | "info": "Frequency shift tolerance for considering data as the same spwid", 36 | "default": null, 37 | "name": "freqtol", 38 | "dtype": "str" 39 | }, 40 | { 41 | "info": "Direction shift tolerance for considering data as the same field", 42 | "dtype": "str", 43 | "default": null, 44 | "name": "dirtol" 45 | }, 46 | { 47 | "info": "If true, fields with a different name are not merged even if their direction agrees", 48 | "dtype": "bool", 49 | "default": false, 50 | "name": "respectname" 51 | }, 52 | { 53 | "info": "Copy all rows of the POINTING table", 54 | "default": true, 55 | "name": "copypointing", 56 | "dtype": "bool" 57 | }, 58 | { 59 | "info": "List of the weight scaling factors to be applied to the individual MSs", 60 | "default": null, 61 | "name": "visweightscale", 62 | "dtype": "list:float" 63 | }, 64 | { 65 | "info": "If true, a copy of the input MSs is kept in their original place", 66 | "default": null, 67 | "name": "keepcopy", 68 | "dtype": "bool" 69 | } 70 | ], 71 | "version": [ 72 | "4.7.2", 73 | "5.6.1-8", 74 | "5.8.0" 75 | ] 76 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/tigger_convert/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import yaml 4 | import glob 5 | import shutil 6 | import shlex 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | mslist = [] 19 | field = [] 20 | 21 | args = [] 22 | for param in cab["parameters"]: 23 | name = param["name"] 24 | value = param["value"] 25 | 26 | if value in [False, None]: 27 | continue 28 | if name == "primary-beam": 29 | value = "'{}'".format(value) 30 | if name == "pa-range" and hasattr(value, "__iter__"): 31 | value = ",".join(value) 32 | if value is True: 33 | value = "" 34 | if name == "pa-from-ms" and hasattr(value, "__iter__"): 35 | mslist = value 36 | continue 37 | if name == "field-id" and hasattr(value, "__iter__"): 38 | field = value 39 | continue 40 | 41 | # Positional arguments 42 | if name == "input-skymodel": 43 | inlsm = value 44 | continue 45 | elif name == "output-skymodel": 46 | outlsm = value 47 | continue 48 | 49 | args.append("{0}{1} {2}".format(cab["prefix"], name, value)) 50 | 51 | if mslist: 52 | if len(field) == 0: 53 | field = [0] * len(mslist) 54 | pa_from_ms = ",".join(["{0}:{1}".format(ms, i) for ms, i in zip(mslist, field)]) 55 | args.append("--pa-from-ms {}".format(pa_from_ms)) 56 | 57 | _runc = " ".join([cab["binary"]] + args + [inlsm, outlsm]) 58 | 59 | try: 60 | subprocess.check_call(shlex.split(_runc)) 61 | finally: 62 | for item in junk: 63 | for dest in [ 64 | OUTPUT, 65 | MSDIR, 66 | ]: # these are the only writable volumes in the container 67 | items = glob.glob("{dest}/{item}".format(**locals())) 68 | for f in items: 69 | if os.path.isfile(f): 70 | os.remove(f) 71 | elif os.path.isdir(f): 72 | shutil.rmtree(f) 73 | -------------------------------------------------------------------------------- /stimela/cargo/cab/eidos/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "eidos", 3 | "base": "stimela/eidos", 4 | "tag": "1.7.10", 5 | "version": "1.1.2", 6 | "description": "Create primary beam model of MeerKAT", 7 | "prefix": "--", 8 | "binary": "eidos", 9 | "junk": [], 10 | "msdir": false, 11 | "parameters": [ 12 | { 13 | "info": "Number of pixels on one side", 14 | "default": 256, 15 | "required": true, 16 | "name": "pixels", 17 | "dtype": "int" 18 | }, 19 | { 20 | "info": "A single freq, or the start, end freqs, and channel width in MHz", 21 | "dtype": "str", 22 | "required": true, 23 | "name": "freq" 24 | }, 25 | { 26 | "info": "Diameter of the required beam", 27 | "dtype": "float", 28 | "default": 6.0, 29 | "name": "diameter" 30 | }, 31 | { 32 | "info": "Coefficients file name", 33 | "dtype": "file", 34 | "required": false, 35 | "name": "coefficients-file", 36 | "io": "input" 37 | }, 38 | { 39 | "info": "Which coefficients to use: mh for MeerKAT holography, me for MeerKAT EM simulation and vh for VLA holography?", 40 | "dtype": "str", 41 | "required": true, 42 | "name": "coeff", 43 | "choices": [ 44 | "me", 45 | "mh" 46 | ] 47 | }, 48 | { 49 | "info": "Prefix for output beam file(s)", 50 | "dtype": "file", 51 | "name": "prefix", 52 | "io": "output" 53 | }, 54 | { 55 | "info": "Output complex volatge beams (8 files)", 56 | "dtype": "bool", 57 | "default": true, 58 | "name": "output-eight" 59 | }, 60 | { 61 | "info": "normalise the E-Jones wrt central pixels", 62 | "dtype": "bool", 63 | "name": "normalise" 64 | } 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_imregrid/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_imregrid", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "All-purpose flagging task based on data-selections and flagging modes/algorithms.", 10 | "prefix": " ", 11 | "binary": "imregrid", 12 | "junk": [ 13 | "imregrid.last" 14 | ], 15 | "msdir": false, 16 | "parameters": [ 17 | { 18 | "info": "Name of the source image", 19 | "dtype": "file", 20 | "required": true, 21 | "name": "imagename", 22 | "io": "input" 23 | }, 24 | { 25 | "info": "A dictionary, refcode, or name of an image that provides the output shape and coordinate system", 26 | "dtype": "file", 27 | "required": true, 28 | "name": "template", 29 | "io": "input" 30 | }, 31 | { 32 | "info": "Name for the regridded image", 33 | "dtype": "file", 34 | "name": "output", 35 | "io": "output" 36 | }, 37 | { 38 | "info": "Regrid spectral axis in velocity space rather than frequency space?", 39 | "dtype": "bool", 40 | "default": true, 41 | "name": "asvelocity" 42 | }, 43 | { 44 | "info": "The pixel axes to regrid", 45 | "dtype": "list:int", 46 | "default": [ 47 | -1 48 | ], 49 | "name": "axes" 50 | }, 51 | { 52 | "info": "The interpolation method", 53 | "dtype": "str", 54 | "default": "linear", 55 | "name": "interpolation", 56 | "choices": [ 57 | "nearest", 58 | "linear", 59 | "cubic" 60 | ] 61 | }, 62 | { 63 | "info": "Decimation factor for coordinate grid computation", 64 | "dtype": "int", 65 | "name": "decimate" 66 | }, 67 | { 68 | "info": "Replicate image rather than regrid", 69 | "dtype": "bool", 70 | "name": "replicate" 71 | }, 72 | { 73 | "info": "verwrite (unprompted) pre-existing output file", 74 | "dtype": "bool", 75 | "name": "overwrite" 76 | } 77 | ], 78 | "version": [ 79 | "4.7.2", 80 | "5.6.1-8", 81 | "5.8.0" 82 | ] 83 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_exportfits/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa_exportfits", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Convert a CASA image to a FITS file", 10 | "prefix": " ", 11 | "binary": "exportfits", 12 | "junk": [ 13 | "exportfits.last" 14 | ], 15 | "msdir": false, 16 | "parameters": [ 17 | { 18 | "info": "Name of input image FITS file", 19 | "dtype": "file", 20 | "required": true, 21 | "name": "fitsimage", 22 | "io": "input" 23 | }, 24 | { 25 | "info": "Name of output CASA image", 26 | "dtype": "file", 27 | "required": true, 28 | "name": "imagename", 29 | "io": "output" 30 | }, 31 | { 32 | "info": "Use velocity (rather than frequency) as spectral axis", 33 | "dtype": "bool", 34 | "name": "velocity" 35 | }, 36 | { 37 | "info": "Use the optical (rather than radio) velocity convention", 38 | "dtype": "bool", 39 | "name": "optical" 40 | }, 41 | { 42 | "info": "Bits per pixel", 43 | "dtype": "int", 44 | "name": "bitpix" 45 | }, 46 | { 47 | "info": "Minimum pixel value (if minpix > maxpix, value is automatically dertermined)", 48 | "dtype": "float", 49 | "name": "minpix" 50 | }, 51 | { 52 | "info": "dropstokes", 53 | "dtype": "bool", 54 | "name": "maxpix" 55 | }, 56 | { 57 | "info": "Drop stokes axis?", 58 | "dtype": "bool", 59 | "name": "dropstokes" 60 | }, 61 | { 62 | "info": "Put Stokes axis last in header?", 63 | "dtype": "bool", 64 | "name": "stokeslast" 65 | }, 66 | { 67 | "info": "Write history to the FITS image?", 68 | "dtype": "bool", 69 | "name": "history" 70 | }, 71 | { 72 | "info": "Drop all degenerate axes (e.g. stokes and/or frequency)", 73 | "dtype": "bool", 74 | "name": "dropdeg" 75 | }, 76 | { 77 | "info": "Overwrite pre-existing imagename", 78 | "dtype": "bool", 79 | "name": "overwrite" 80 | } 81 | ], 82 | "version": [ 83 | "4.7.2", 84 | "5.6.1-8", 85 | "5.8.0" 86 | ] 87 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/spimple_binterp/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "spimple binterp", 3 | "base": "stimela/spimple", 4 | "tag": "1.7.2b", 5 | "description": "Beam intrepolation tool.", 6 | "prefix": "--", 7 | "binary": "spimple-binterp", 8 | "junk":[], 9 | "msdir": true, 10 | "parameters": [ 11 | { 12 | "info": "Input image name", 13 | "dtype": "str", 14 | "required": true, 15 | "name": "image", 16 | "io": "input", 17 | "deprecated": false 18 | }, 19 | { 20 | "info": "Path to output directory", 21 | "dtype": "str", 22 | "required": true, 23 | "name": "output-filename", 24 | "io": "output", 25 | "deprecated": false 26 | }, 27 | { 28 | "info": "Number of threads to use", 29 | "dtype": "int", 30 | "required": false, 31 | "name": "nthreads", 32 | "default": null, 33 | "deprecated": false 34 | }, 35 | { 36 | "info": "Fits beam model to use. Only real and imageinary beam models currently supported", 37 | "dtype": "str", 38 | "required": false, 39 | "name": "beam-model", 40 | "default": null, 41 | "deprecated": false 42 | }, 43 | { 44 | "info": "Add in the convolved residuals before fitting components", 45 | "dtype": "bool", 46 | "required": false, 47 | "name": "add-convolved-residuals", 48 | "default": null, 49 | "deprecated": false 50 | }, 51 | { 52 | "info": "Field Id", 53 | "dtype": "int", 54 | "required": false, 55 | "name": "field", 56 | "default": null, 57 | "deprecated": false 58 | }, 59 | { 60 | "info": "Used to select a subset of time. Default is 10", 61 | "dtype": "int", 62 | "required": false, 63 | "name": "sparsify-time", 64 | "default": null, 65 | "deprecated": false 66 | }, 67 | { 68 | "info": "Correlation typ i.e. linear or circular.", 69 | "dtype": "str", 70 | "required": false, 71 | "name": "corr-type", 72 | "default": null, 73 | "deprecated": false 74 | } 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rfinder/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | import rfinder 4 | import glob 5 | import subprocess 6 | import shlex 7 | import shutil 8 | 9 | 10 | CONFIG = os.environ["CONFIG"] 11 | INPUT = os.environ["INPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | OUTPUT = os.environ["OUTPUT"] 14 | 15 | with open(CONFIG, "r") as _std: 16 | cab = yaml.safe_load(_std) 17 | 18 | junk = cab["junk"] 19 | args = [] 20 | msname = None 21 | 22 | pkg_path = os.path.dirname(os.path.realpath(rfinder.__file__)) 23 | rfinder_file = "{:s}/rfinder_default.yml".format(pkg_path) 24 | 25 | with open(rfinder_file) as f: 26 | list_doc = yaml.safe_load(f) 27 | 28 | list_doc["general"]["outdir"] = "{:s}/".format(OUTPUT) 29 | list_doc["general"]["workdir"] = "{:s}/".format(MSDIR) 30 | 31 | for param in cab["parameters"]: 32 | name = param["name"] 33 | value = param["value"] 34 | 35 | if value is None: 36 | continue 37 | 38 | if name == "msname": 39 | list_doc["general"]["msname"] = value.split("/")[-1] 40 | continue 41 | 42 | for key, val in list_doc.items(): 43 | if isinstance(val, dict): 44 | for k1, v1 in val.items(): 45 | if isinstance(v1, dict): 46 | for k2, v2 in v1.items(): 47 | if k2 == name: 48 | list_doc[key][k1][k2] = value 49 | else: 50 | if k1 == name: 51 | list_doc[key][k1] = value 52 | else: 53 | if key == name: 54 | list_doc[key] = value 55 | 56 | edited_file = "rfinder_default.yml" 57 | with open(edited_file, "w") as f: 58 | yaml.dump(list_doc, f) 59 | 60 | 61 | _runc = "rfinder -c %s" % edited_file 62 | 63 | try: 64 | subprocess.check_call(shlex.split(_runc)) 65 | finally: 66 | for item in junk: 67 | for dest in [ 68 | OUTPUT, 69 | MSDIR, 70 | ]: # these are the only writable volumes in the container 71 | items = glob.glob("{dest}/{item}".format(**locals())) 72 | for f in items: 73 | if os.path.isfile(f): 74 | os.remove(f) 75 | elif os.path.isdir(f): 76 | shutil.rmtree(f) 77 | # Leave other types 78 | -------------------------------------------------------------------------------- /stimela/cargo/cab/curl/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "curl", 3 | "base": "stimela/curl", 4 | "tag": "1.2.0", 5 | "description": "Download data from a remote path", 6 | "prefix": "--", 7 | "binary": "curl", 8 | "junk":[], 9 | "msdir": false, 10 | "parameters": [ 11 | { 12 | "info": "url name", 13 | "dtype": "str", 14 | "default": null, 15 | "required": true, 16 | "name": "url" 17 | }, 18 | { 19 | "default": true, 20 | "dtype": "file", 21 | "name": "output", 22 | "io": "output" 23 | }, 24 | { 25 | "info": " Client certificate file and password (SSL)", 26 | "dtype": "file", 27 | "default": null, 28 | "name": "cert", 29 | "io": "input" 30 | }, 31 | { 32 | "info": "Verify the status of the server certificate", 33 | "dtype": "bool", 34 | "default": null, 35 | "name": "cert-status" 36 | }, 37 | { 38 | "info": "Verify the status of the server certificate", 39 | "dtype": "str", 40 | "default": null, 41 | "name": "cert-type", 42 | "choices": [ 43 | "DER", 44 | "PEM", 45 | "ENG" 46 | ] 47 | }, 48 | { 49 | "info": "SSL ciphers to use", 50 | "dtype": "list", 51 | "default": null, 52 | "name": "ciphers" 53 | }, 54 | { 55 | "info": "Follow redirects", 56 | "dtype": "bool", 57 | "default": true, 58 | "name": "location" 59 | }, 60 | { 61 | "info": "Read config from FILE", 62 | "dtype": "file", 63 | "default": null, 64 | "name": "config", 65 | "io": "input" 66 | }, 67 | { 68 | "info": "Specify number of bytes to resume download from, alternatively specify '-' to tell curl to automatically detect", 69 | "dtype": "str", 70 | "default": "-", 71 | "name": "continue-at" 72 | } 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Ubuntu CI 5 | 6 | on: 7 | push: 8 | branches: 9 | - "*" 10 | tags: 11 | - "*" 12 | pull_request: 13 | branches: [ master ] 14 | schedule: 15 | - cron: '30 2 * * 1,4' # Every Monday and Thursday @ 2h30am UTC 16 | 17 | env: 18 | POETRY_VERSION: 2.0.1 19 | 20 | jobs: 21 | test: 22 | runs-on: ${{ matrix.os }} 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | os: [ ubuntu-22.04, ubuntu-24.04 ] 27 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] 28 | steps: 29 | - name: Set up Python ${{ matrix.python-version }} 30 | uses: actions/setup-python@v4 31 | with: 32 | python-version: ${{ matrix.python-version }} 33 | 34 | - name: Install latest setuptools, wheel, pip 35 | run: python3 -m pip install -U pip setuptools wheel 36 | 37 | - name: Install Poetry 38 | uses: abatilo/actions-poetry@v3 39 | with: 40 | poetry-version: ${{ env.POETRY_VERSION }} 41 | 42 | - name: Checkout source 43 | uses: actions/checkout@v2 44 | with: 45 | fetch-depth: 1 46 | 47 | - name: Install stimela 48 | run: poetry install --extras "testing" 49 | 50 | - name: Check installed version command 51 | run: poetry run stimela --version 52 | 53 | - name: Lint with flake8 54 | run: | 55 | # stop the build if there are Python syntax errors or undefined names 56 | poetry run flake8 . --count --select=E9,F63,F7,F82 --ignore=F824 --show-source --statistics 57 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 58 | poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 59 | 60 | - name: Test stimela command 61 | run: | 62 | poetry run stimela --help 63 | poetry run stimela pull --help 64 | poetry run stimela build --help 65 | poetry run stimela run --help 66 | poetry run stimela cabs 67 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_plotuv/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa47_plotuv", 3 | "base": "stimela/casa", 4 | "tag": [ 5 | "0.3.0-2", 6 | "1.6.3", 7 | "1.7.1" 8 | ], 9 | "description": "Plot the uv distribution", 10 | "prefix": "", 11 | "version": [ 12 | "4.7.2", 13 | "5.6.1-8", 14 | "5.8.0" 15 | ], 16 | "binary": "plotuv", 17 | "junk": [ 18 | "plotuv.last" 19 | ], 20 | "msdir": true, 21 | "parameters": [ 22 | { 23 | "info": "Name of measurement set", 24 | "name": "msname", 25 | "io": "msfile", 26 | "default": null, 27 | "dtype": "file", 28 | "mapping": "vis" 29 | }, 30 | { 31 | "info": "Save the plotted figure to this file", 32 | "default": null, 33 | "name": "figfile", 34 | "io": "output", 35 | "dtype": "file" 36 | }, 37 | { 38 | "info": "Select field using ID(s) or name(s)", 39 | "default": "", 40 | "name": "field", 41 | "dtype": "str" 42 | }, 43 | { 44 | "info": "Select data based on antenna/baseline", 45 | "default": "", 46 | "name": "antenna", 47 | "dtype": "str" 48 | }, 49 | { 50 | "info": "Select spectral window/channels", 51 | "default": "", 52 | "name": "spw", 53 | "dtype": "str" 54 | }, 55 | { 56 | "info": "Select by observation ID(s)", 57 | "default": "", 58 | "name": "observation", 59 | "dtype": "str" 60 | }, 61 | { 62 | "info": "Select (sub)array(s) by array ID number", 63 | "default": "", 64 | "name": "array", 65 | "dtype": "str" 66 | }, 67 | { 68 | "info": "Maximum number of points per plot.", 69 | "default": 100000, 70 | "name": "maxnpts", 71 | "dtype": "int" 72 | }, 73 | { 74 | "info": "a list of matplotlib color codes", 75 | "default": [ 76 | "r", 77 | "y", 78 | "g", 79 | "b" 80 | ], 81 | "name": "colors", 82 | "dtype": "list:str" 83 | }, 84 | { 85 | "info": "A matplotlib plot symbol code", 86 | "default": ",", 87 | "name": "symb", 88 | "dtype": "str" 89 | }, 90 | { 91 | "info": "How many times to cycle through colors per plot.", 92 | "default": 1, 93 | "name": "ncycles", 94 | "dtype": "int" 95 | } 96 | ] 97 | } -------------------------------------------------------------------------------- /stimela/cargo/cab/montage/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import shlex 4 | import shutil 5 | import glob 6 | import yaml 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | junk = cab["junk"] 16 | 17 | args = {} 18 | for param in cab["parameters"]: 19 | name = param["name"] 20 | value = param["value"] 21 | 22 | if value is None: 23 | continue 24 | args[name] = value 25 | 26 | if not os.path.exists(OUTPUT + "/mask_mosaic"): 27 | os.mkdir(OUTPUT + "/mask_mosaic") 28 | 29 | outdir = OUTPUT + "/mask_mosaic" 30 | 31 | try: 32 | make_table = " ".join(["mImgtbl", args["input_dir"], outdir + "/mosaic_table.tbl"]) 33 | subprocess.check_call(shlex.split(make_table)) 34 | 35 | make_header = " ".join( 36 | ["mMakeHdr", outdir + "/mosaic_table.tbl", outdir + "/mosaic_header.hdr"] 37 | ) 38 | subprocess.check_call(shlex.split(make_header)) 39 | 40 | project_mosaic = " ".join( 41 | [ 42 | "mProjExec", 43 | "-p", 44 | args["input_dir"], 45 | outdir + "/mosaic_table.tbl", 46 | outdir + "/mosaic_header.hdr", 47 | outdir, 48 | outdir + "/stats.tbl", 49 | ] 50 | ) 51 | subprocess.check_call(shlex.split(project_mosaic)) 52 | 53 | make_mosaic_table = ["mImgtbl", outdir, outdir + "/mosaic_table2.tbl"] 54 | subprocess.check_call(shlex.split(make_mosaic_table)) 55 | 56 | _runc = " ".join( 57 | [ 58 | "mAdd", 59 | "-p", 60 | args["input_dir"], 61 | outdir + "/mosaic_table2.tbl", 62 | outdir + "/mosaic_header.hdr", 63 | OUTPUT + "/mosaic.fits", 64 | ] 65 | ) 66 | subprocess.check_call(shlex.split(_runc)) 67 | finally: 68 | for item in junk: 69 | for dest in [ 70 | OUTPUT, 71 | MSDIR, 72 | ]: # these are the only writable volumes in the container 73 | items = glob.glob("{dest}/{item}".format(**locals())) 74 | for f in items: 75 | if os.path.isfile(f): 76 | os.remove(f) 77 | elif os.path.isdir(f): 78 | shutil.rmtree(f) 79 | # Leave other types 80 | -------------------------------------------------------------------------------- /stimela/cargo/cab/fitstool/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import shlex 4 | import subprocess 5 | import glob 6 | import yaml 7 | 8 | CONFIG = os.environ["CONFIG"] 9 | INPUT = os.environ["INPUT"] 10 | OUTPUT = os.environ["OUTPUT"] 11 | MSDIR = os.environ["MSDIR"] 12 | 13 | with open(CONFIG, "r") as _std: 14 | cab = yaml.safe_load(_std) 15 | 16 | junk = cab["junk"] 17 | 18 | args = [] 19 | inimage = None 20 | outimage = None 21 | stack = False 22 | unstack = False 23 | axis = None 24 | chunk = 1 25 | file_pattern = False 26 | 27 | for param in cab["parameters"]: 28 | value = param["value"] 29 | name = param["name"] 30 | 31 | if value in [None, False]: 32 | continue 33 | 34 | if name == "image": 35 | inimage = " ".join(value) 36 | continue 37 | elif name == "output": 38 | outimage = value 39 | continue 40 | elif name == "stack": 41 | stack = True 42 | continue 43 | elif name == "unstack": 44 | unstack = True 45 | continue 46 | elif name == "unstack-chunk": 47 | chunk = value 48 | continue 49 | elif name == "fits-axis": 50 | axis = value 51 | continue 52 | elif name == "file_pattern": 53 | value = '"%s"' % value 54 | file_pattern = True 55 | 56 | elif value is True: 57 | value = "" 58 | 59 | args.append("{0}{1} {2}".format(cab["prefix"], name, value)) 60 | 61 | if stack and axis: 62 | args.append("{0}stack {1}:{2}".format(cab["prefix"], outimage, axis)) 63 | outimage = None 64 | elif unstack and axis: 65 | args.append("{0}unstack {1}:{2}:{3}".format(cab["prefix"], outimage, axis, chunk)) 66 | outimage = None 67 | else: 68 | outimage = "{0}output {1}".format(cab["prefix"], outimage) 69 | 70 | if file_pattern: 71 | inimage = "" 72 | 73 | _runc = " ".join([cab["binary"]] + args + [inimage, outimage or ""]) 74 | 75 | try: 76 | subprocess.check_call(shlex.split(_runc)) 77 | finally: 78 | for item in junk: 79 | for dest in [ 80 | OUTPUT, 81 | MSDIR, 82 | ]: # these are the only writable volumes in the container 83 | items = glob.glob("{dest}/{item}".format(**locals())) 84 | for f in items: 85 | if os.path.isfile(f): 86 | os.remove(f) 87 | elif os.path.isdir(f): 88 | shutil.rmtree(f) 89 | -------------------------------------------------------------------------------- /stimela/cargo/cab/sharpener/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | import sharpener 4 | import glob 5 | import shlex 6 | import subprocess 7 | import shutil 8 | 9 | 10 | CONFIG = os.environ["CONFIG"] 11 | INPUT = os.environ["INPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | OUTPUT = os.environ["OUTPUT"] 14 | 15 | with open(CONFIG, "r") as _std: 16 | cab = yaml.safe_load(_std) 17 | 18 | junk = cab["junk"] 19 | args = [] 20 | msname = None 21 | 22 | pkg_path = os.path.dirname(os.path.realpath(sharpener.__file__)) 23 | sharpener_file = "{:s}/sharpener_default.yml".format(pkg_path) 24 | 25 | with open(sharpener_file) as f: 26 | list_doc = yaml.safe_load(f) 27 | 28 | for param in cab["parameters"]: 29 | name = param["name"] 30 | value = param["value"] 31 | 32 | if value is None: 33 | continue 34 | 35 | for key, val in list_doc.items(): 36 | if isinstance(val, dict): 37 | for k1, v1 in val.items(): 38 | if "enable" in name: 39 | if key in name: 40 | list_doc[key]["enable"] = value 41 | elif k1 == name: 42 | list_doc[key][k1] = value 43 | else: 44 | if key == name: 45 | list_doc[key] = value 46 | 47 | # Get the relative path from workdir 48 | list_doc["general"]["contname"] = os.path.relpath( 49 | list_doc["general"]["contname"], list_doc["general"]["workdir"] 50 | ) 51 | list_doc["general"]["cubename"] = os.path.relpath( 52 | list_doc["general"]["cubename"], list_doc["general"]["workdir"] 53 | ) 54 | list_doc["source_catalog"]["catalog_file"] = os.path.relpath( 55 | list_doc["source_catalog"]["catalog_file"], list_doc["general"]["workdir"] 56 | ) 57 | 58 | edited_file = "sharpener_default.yml" 59 | with open(edited_file, "w") as f: 60 | yaml.dump(list_doc, f) 61 | 62 | _runc = "run_sharpener -c %s" % edited_file 63 | try: 64 | subprocess.check_call(shlex.split(_runc)) 65 | finally: 66 | for item in junk: 67 | for dest in [ 68 | OUTPUT, 69 | MSDIR, 70 | ]: # these are the only writable volumes in the container 71 | items = glob.glob("{dest}/{item}".format(**locals())) 72 | for f in items: 73 | if os.path.isfile(f): 74 | os.remove(f) 75 | elif os.path.isdir(f): 76 | shutil.rmtree(f) 77 | # Leave other types 78 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_clean/src/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: future_fstrings -*- 2 | import Crasa.Crasa as crasa 3 | from scabha import config, parameters_dict 4 | import os 5 | import sys 6 | import astropy.io.fits as pyfits 7 | 8 | args = parameters_dict 9 | 10 | print(f"Running CASA task '{config.binary}'") 11 | 12 | noise_image = args.pop("noise_image", False) 13 | if noise_image: 14 | noise_sigma = args.pop("noise_sigma") 15 | noise_hdu = pyfits.open(noise_image) 16 | noise_data = noise_hdu[0].data 17 | noise_std = noise_data.std() 18 | threshold = noise_sigma * noise_std 19 | args["threshold"] = "{}Jy".format(threshold) 20 | else: 21 | args.pop("noise_sigma") 22 | 23 | prefix = args["imagename"] 24 | port2fits = args.pop("port2fits", True) 25 | keep_casa_images = args.pop("keep_casa_images", False) 26 | 27 | task = crasa.CasaTask(config.binary, **args) 28 | task.run() 29 | 30 | nterms = args.get("nterms", 1) 31 | images = ["flux", "model", "residual", "psf", "image"] 32 | STD_IMAGES = images[:4] 33 | 34 | convert = [] 35 | if port2fits: 36 | for image in images: 37 | img = "{:s}.{:s}".format(prefix, image) 38 | if image == "flux": 39 | _images = [img] 40 | elif nterms > 1: 41 | _images = ["%s.tt%d" % (img, d) for d in range(nterms)] 42 | if image == "image": 43 | if nterms == 2: 44 | alpha = img + ".alpha" 45 | alpha_err = img + ".alpha.error" 46 | _images += [alpha, alpha_err] 47 | if nterms == 3: 48 | beta = img + ".beta" 49 | beta_err = img + ".beta.error" 50 | _images += [beta, beta_err] 51 | else: 52 | _images = [img] 53 | convert += _images 54 | 55 | for _image in convert: 56 | sys.stdout.write(_image) 57 | if _image in STD_IMAGES and (not os.path.exists(_image)): 58 | raise RuntimeError( 59 | "Standard output from CASA clean task not found. Something went wrong durring cleaning, take a look at the logs and such" 60 | ) 61 | 62 | elif os.path.exists(_image): 63 | task = crasa.CasaTask( 64 | "exportfits", 65 | **dict(imagename=_image, fitsimage=_image + ".fits", overwrite=True), 66 | ) 67 | task.run() 68 | 69 | if not keep_casa_images: 70 | for _image in convert: 71 | os.system("rm -rf {}".format(_image)) 72 | -------------------------------------------------------------------------------- /Jenkinsfile.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | WORKSPACE_ROOT="$WORKSPACE/$BUILD_NUMBER" 4 | TEST_OUTPUT_DIR="$WORKSPACE_ROOT/test-output" 5 | TEST_DATA_DIR="$WORKSPACE/../../../test-data" 6 | mkdir $TEST_OUTPUT_DIR 7 | function finish { 8 | rm -rf $TMPDIR 9 | } 10 | trap finish EXIT 11 | 12 | #Custom home for this run's temporary stuff 13 | mkdir $WORKSPACE_ROOT/tmp 14 | TMPDIR="$WORKSPACE_ROOT/tmp" 15 | export TMPDIR 16 | rm -rf ~/.stimela 17 | HOME=$WORKSPACE_ROOT 18 | export HOME 19 | SINGULARITY_STORAGE="${WORKSPACE}/../../../.singularity" 20 | ln -s $WORKSPACE/../../../.udocker ${WORKSPACE_ROOT}/.udocker 21 | ln -s ${SINGULARITY_STORAGE} ${WORKSPACE_ROOT}/.singularity 22 | 23 | # setup podman image storage. Using .singularity volume 24 | POD_STORAGE="${WORKSPACE_ROOT}/.local/share/containers/storage" 25 | mkdir -p ${POD_STORAGE} ${SINGULARITY_STORAGE}/podman 26 | ln -s ${SINGULARITY_STORAGE}/podman ${POD_STORAGE} 27 | 28 | # Copy a clean dataset over 29 | mkdir $TEST_OUTPUT_DIR/msdir 30 | tar -xzvf $TEST_DATA_DIR/kat-7-small.ms.tar.gz -C $TEST_OUTPUT_DIR/msdir 31 | tar -xvf $TEST_DATA_DIR/DEEP2.ms.tar.gz -C $TEST_OUTPUT_DIR/msdir 32 | mkdir $TEST_OUTPUT_DIR/input 33 | cp -r $TEST_DATA_DIR/beams $TEST_OUTPUT_DIR/input/beams 34 | 35 | # Load newer version of singularity 36 | source /etc/profile.d/modules.sh 37 | 38 | # TODO(Ben) Singularity seems to be broken; testing with apptainer 39 | #module load singularity/3.8.4 40 | 41 | module load apptainer/1.2.0-rc.1 42 | 43 | # Check version 44 | docker -v 45 | podman -v 46 | singularity version 47 | export STIMELA_PULLFOLDER=${WORKSPACE_ROOT}/singularity_images 48 | mkdir $STIMELA_PULLFOLDER 49 | 50 | ######################################################################### 51 | # PYTHON 3 TEST 52 | ######################################################################### 53 | rm -rf ~/.stimela 54 | OLDPATH=$PATH 55 | OLDLDPATH=$LD_LIBRARY_PATH 56 | 57 | # Install Stimela into a virtual env 58 | virtualenv -p python3 ${WORKSPACE_ROOT}/projects/pyenv 59 | . ${WORKSPACE_ROOT}/projects/pyenv/bin/activate 60 | PATH=${WORKSPACE}/projects/pyenv/bin:$PATH 61 | LD_LIBRARY_PATH=${WORKSPACE}/projects/pyenv/lib:$LD_LIBRARY_PATH 62 | pip install ${WORKSPACE_ROOT}/projects/Stimela[testing] 63 | 64 | stimela --version 65 | stimela pull #--force 66 | 67 | #Run forest run! 68 | cd $TEST_OUTPUT_DIR 69 | export SILENT_STDERR=ON 70 | py.test --cov=stimela \ 71 | --cov-report=term-missing --cov-report=html \ 72 | --junitxml="$WORKSPACE_ROOT/pytest-results.xml" \ 73 | "$WORKSPACE_ROOT/projects/Stimela/stimela/tests" \ 74 | -vvv 75 | -------------------------------------------------------------------------------- /stimela/cargo/cab/rfimasker/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "rfimasker", 3 | "base": "stimela/rfimasker", 4 | "tag": "1.7.0", 5 | "description": "Tiny tool to apply a numpy boolean array to the spectral flags column of a measurement set to mask out known RFI sources like GSM and satelite in L-band. Typically flagging known RFI sources produces much better backgrounds and tools like the mighty AOFlagger RFI hammer needs fewer iterations to converge to good solutions.", 6 | "prefix": "--", 7 | "binary": "mask_ms.py", 8 | "junk": [], 9 | "msdir": true, 10 | "parameters": [ 11 | { 12 | "info": "MS(s) to flagged", 13 | "name": "msname", 14 | "io": "msfile", 15 | "default": null, 16 | "dtype": "list:file", 17 | "mapping": "ms" 18 | }, 19 | { 20 | "info": "A numpy array of chan x (boolean, channel_centre[float64])", 21 | "dtype": "file", 22 | "default": null, 23 | "name": "mask", 24 | "io": "input" 25 | }, 26 | { 27 | "info": "Specifies whether mask should override current flags or be added (or) to the current", 28 | "dtype": "str", 29 | "default": "or", 30 | "name": "accumulation_mode", 31 | "choices": [ 32 | "or", 33 | "overide" 34 | ] 35 | }, 36 | { 37 | "info": "Computes and reports some statistics about the flagged RFI in the MS", 38 | "dtype": "bool", 39 | "default": false, 40 | "name": "statistics" 41 | }, 42 | { 43 | "info": "Maximum memory to consume in MB for the flag buffer", 44 | "dtype": "int", 45 | "default": 50, 46 | "name": "memory" 47 | }, 48 | { 49 | "info": "SPW id (or ids if multiple MSs have been specified)", 50 | "default": 0, 51 | "name": "spwid", 52 | "dtype": "list:int" 53 | }, 54 | { 55 | "info": "UV range to select (CASA style range: lower~upper) for flagging. Leave blank for entire array", 56 | "default": null, 57 | "name": "uvrange", 58 | "dtype": "str" 59 | }, 60 | { 61 | "info": "Simulate only. Do not apply flags - useful for statistics", 62 | "dtype": "bool", 63 | "default": false, 64 | "name": "simulate" 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa_immath/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import Crasa.Crasa as crasa 3 | import yaml 4 | import glob 5 | import shutil 6 | 7 | CONFIG = os.environ["CONFIG"] 8 | INPUT = os.environ["INPUT"] 9 | OUTPUT = os.environ["OUTPUT"] 10 | MSDIR = os.environ["MSDIR"] 11 | 12 | with open(CONFIG, "r") as _std: 13 | cab = yaml.safe_load(_std) 14 | junk = cab["junk"] 15 | 16 | unstack_params = ["unstack", "nchans", "keep_casa_images", "port2fits"] 17 | unstack_args = {} 18 | immath_args = {} 19 | 20 | 21 | def rm_fr(item): 22 | os.system("rm -fr {}".format(item)) 23 | 24 | 25 | for param in cab["parameters"]: 26 | name = param["name"] 27 | value = param["value"] 28 | 29 | if value is None: 30 | continue 31 | 32 | if name in unstack_params: 33 | unstack_args[name] = value 34 | else: 35 | immath_args[name] = value 36 | 37 | unstack = unstack_args.pop(cab["binary"], False) 38 | 39 | if not unstack: 40 | task = crasa.CasaTask("immath", **immath_args) 41 | try: 42 | task.run() 43 | finally: 44 | for item in junk: 45 | for dest in [ 46 | OUTPUT, 47 | MSDIR, 48 | ]: # these are the only writable volumes in the container 49 | items = glob.glob("{dest}/{item}".format(**locals())) 50 | for f in items: 51 | if os.path.isfile(f): 52 | os.remove(f) 53 | elif os.path.isdir(f): 54 | shutil.rmtree(f) 55 | else: 56 | images = immath_args["imagename"] 57 | for image in images: 58 | for i in range(unstack_args["nchans"]): 59 | ext = image.split(".")[-1] 60 | chan_num = str(i) 61 | outfile = "{:s}-{:s}.{:s}".format(immath_args["outfile"], chan_num, ext) 62 | run_immath_args = immath_args.copy() 63 | run_immath_args["imagename"] = image 64 | run_immath_args["outfile"] = outfile 65 | run_immath_args["chans"] = chan_num 66 | task = crasa.CasaTask(cab["binary"], **run_immath_args) 67 | task.run() 68 | if unstack_args["port2fits"]: 69 | print("Converting CASA images to FITS images") 70 | fits = outfile + ".fits" 71 | task = crasa.CasaTask( 72 | "exportfits", 73 | **dict(imagename=outfile, fitsimage=fits, overwrite=True), 74 | ) 75 | task.run() 76 | if not unstack_args["keep_casa_images"]: 77 | rm_fr(outfile) 78 | -------------------------------------------------------------------------------- /stimela/cargo/cab/casa47_plotuv/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "task": "casa47_plotuv", 3 | "base": "stimela/casa47", 4 | "tag": "1.4.2", 5 | "description": "Plot the uv distribution", 6 | "prefix": "", 7 | "version": "4.7.2", 8 | "binary": "plotuv", 9 | "junk":[], 10 | "msdir": true, 11 | "parameters": [ 12 | { 13 | "info": "Name of measurement set", 14 | "name": "msname", 15 | "io": "msfile", 16 | "default": null, 17 | "dtype": "file", 18 | "mapping": "vis" 19 | }, 20 | { 21 | "info": "Save the plotted figure to this file", 22 | "default": null, 23 | "name": "figfile", 24 | "io": "output", 25 | "dtype": "file" 26 | }, 27 | { 28 | "info": "Select field using ID(s) or name(s)", 29 | "default": "", 30 | "name": "field", 31 | "dtype": "str" 32 | }, 33 | { 34 | "info": "Select data based on antenna/baseline", 35 | "default": "", 36 | "name": "antenna", 37 | "dtype": "str" 38 | }, 39 | { 40 | "info": "Select spectral window/channels", 41 | "default": "", 42 | "name": "spw", 43 | "dtype": "str" 44 | }, 45 | { 46 | "info": "Select by observation ID(s)", 47 | "default": "", 48 | "name": "observation", 49 | "dtype": "str" 50 | }, 51 | { 52 | "info": "Select (sub)array(s) by array ID number", 53 | "default": "", 54 | "name": "array", 55 | "dtype": "str" 56 | }, 57 | { 58 | "info": "Maximum number of points per plot.", 59 | "default": 100000, 60 | "name": "maxnpts", 61 | "dtype": "int" 62 | }, 63 | { 64 | "info": "a list of matplotlib color codes", 65 | "default": [ 66 | "r", 67 | "y", 68 | "g", 69 | "b" 70 | ], 71 | "name": "colors", 72 | "dtype": "list:str" 73 | }, 74 | { 75 | "info": "A matplotlib plot symbol code", 76 | "default": ",", 77 | "name": "symb", 78 | "dtype": "str" 79 | }, 80 | { 81 | "info": "How many times to cycle through colors per plot.", 82 | "default": 1, 83 | "name": "ncycles", 84 | "dtype": "int" 85 | } 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /stimela/cargo/cab/msutils/src/run.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | from MSUtils import msutils 4 | import MSUtils.ClassESW as esw 5 | import inspect 6 | from MSUtils.imp_plotter import gain_plotter 7 | import glob 8 | import shutil 9 | import yaml 10 | 11 | 12 | CONFIG = os.environ["CONFIG"] 13 | INPUT = os.environ["INPUT"] 14 | OUTPUT = os.environ["OUTPUT"] 15 | MSDIR = os.environ["MSDIR"] 16 | 17 | with open(CONFIG, "r") as _std: 18 | cab = yaml.safe_load(_std) 19 | 20 | junk = cab["junk"] 21 | args = {} 22 | for param in cab["parameters"]: 23 | name = param["name"] 24 | value = param["value"] 25 | 26 | if name == "command": 27 | function = value 28 | continue 29 | 30 | args[name] = value 31 | 32 | if function == "sumcols": 33 | args["outcol"] = args.pop("colname") 34 | 35 | if function == "estimate_weights": 36 | msnoise = esw.MSNoise(args["msname"]) 37 | if ( 38 | isinstance(args["stats_data"], str) 39 | and args["stats_data"].find("use_package_meerkat_spec") >= 0 40 | ): 41 | args["stats_data"] = esw.MEERKAT_SEFD 42 | 43 | # Calculate noise/weights from spec 44 | noise, weights = msnoise.estimate_weights( 45 | stats_data=args["stats_data"], 46 | smooth=args["smooth"], 47 | fit_order=args["fit_order"], 48 | plot_stats=args.get("plot_stats", None), 49 | ) 50 | 51 | if args["write_to_ms"]: 52 | msnoise.write_toms(noise, columns=args["noise_columns"]) 53 | msnoise.write_toms(weights, columns=args["weight_columns"]) 54 | sys.exit(0) 55 | 56 | if function == "plot_gains": 57 | tab = args["ctable"] 58 | tabtype = args["tabtype"] 59 | dpi = args["plot_dpi"] 60 | scale = args["subplot_scale"] 61 | outfile = args["plot_file"] 62 | gain_plotter(tab, tabtype, outfile, scale, dpi) 63 | sys.exit(0) 64 | 65 | 66 | run_func = getattr(msutils, function, None) 67 | if run_func is None: 68 | raise RuntimeError("Function '{}' is not part of MSUtils".format(function)) 69 | 70 | # Filter default parameters that are part of this function 71 | func_args = inspect.getargspec(run_func)[0] 72 | _args = {} 73 | for arg in args.keys(): 74 | if arg in func_args: 75 | _args[arg] = args[arg] 76 | 77 | try: 78 | run_func(**_args) 79 | finally: 80 | for item in junk: 81 | for dest in [ 82 | OUTPUT, 83 | MSDIR, 84 | ]: # these are the only writable volumes in the container 85 | items = glob.glob("{dest}/{item}".format(**locals())) 86 | for f in items: 87 | if os.path.isfile(f): 88 | os.remove(f) 89 | elif os.path.isdir(f): 90 | shutil.rmtree(f) 91 | -------------------------------------------------------------------------------- /stimela/cargo/cab/wsclean/src/run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import yaml 4 | import subprocess 5 | import shlex 6 | import glob 7 | import shutil 8 | 9 | CONFIG = os.environ["CONFIG"] 10 | INPUT = os.environ["INPUT"] 11 | OUTPUT = os.environ["OUTPUT"] 12 | MSDIR = os.environ["MSDIR"] 13 | 14 | with open(CONFIG, "r") as _std: 15 | cab = yaml.safe_load(_std) 16 | 17 | params = cab["parameters"] 18 | junk = cab["junk"] 19 | args = [] 20 | 21 | for param in params: 22 | name = param["name"] 23 | value = param["value"] 24 | 25 | if name == "msname": 26 | if isinstance(value, str): 27 | mslist = value 28 | else: 29 | mslist = " ".join(value) 30 | continue 31 | 32 | if value in [None, False]: 33 | continue 34 | elif name == "datacolumn": 35 | name = "data-column" 36 | 37 | elif name == "scale": 38 | if isinstance(value, (int, float)): 39 | value = "{0}asec".format(value) 40 | 41 | elif ( 42 | name 43 | in "size trim nwlayers-for-size beam-shape channel-range interval restore restore-list shift".split() 44 | ): 45 | if isinstance(value, int): 46 | value = "{0} {0}".format(value) 47 | elif hasattr(value, "__iter__"): 48 | if len(value) == 1: 49 | value.append(value[0]) 50 | value = " ".join(map(str, value)) 51 | 52 | elif name in "spws multiscale-scales pol".split(): 53 | if hasattr(value, "__iter__"): 54 | value = ",".join(map(str, value)) 55 | 56 | if value is True: 57 | arg = "{0}{1}".format(cab["prefix"], name) 58 | else: 59 | arg = "{0}{1} {2}".format(cab["prefix"], name, value) 60 | 61 | args.append(arg) 62 | 63 | _runc = " ".join([cab["binary"]] + args + [mslist]) 64 | 65 | # This line must never be deleted again. Empires will rise and fall, and certain students will graduate, but this line MUST LIVE ON. When Stimela, 66 | # Caracal, MeerKAT and SKA are long forgotten ancient history, this line MUST REMAIN. Let it be the last remaining line of Python in history, but let it remain! 67 | print("running WSClean: " + _runc) 68 | sys.stdout.flush() 69 | 70 | try: 71 | subprocess.check_call(shlex.split(_runc)) 72 | finally: 73 | for item in junk: 74 | for dest in [ 75 | OUTPUT, 76 | MSDIR, 77 | ]: # these are the only writable volumes in the container 78 | items = glob.glob("{dest}/{item}".format(**locals())) 79 | for f in items: 80 | if os.path.isfile(f): 81 | os.remove(f) 82 | elif os.path.isdir(f): 83 | shutil.rmtree(f) 84 | # Leave other types 85 | --------------------------------------------------------------------------------