casa-formats-io-0.1/0000755000175100001640000000000013752204627015150 5ustar runnerdocker00000000000000casa-formats-io-0.1/.github/0000755000175100001640000000000013752204627016510 5ustar runnerdocker00000000000000casa-formats-io-0.1/.github/workflows/0000755000175100001640000000000013752204627020545 5ustar runnerdocker00000000000000casa-formats-io-0.1/.github/workflows/main.yml0000644000175100001640000000315613752204621022213 0ustar runnerdocker00000000000000name: Run tests on: [push, pull_request] jobs: tests: name: Python ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.6, 3.7, 3.8, 3.9] include: # Build in which CASA can be installed - os: ubuntu-18.04 python-version: 3.6 steps: - uses: actions/checkout@v2 - name: Set up library dependencies if: ${{ matrix.python-version == '3.6' && matrix.os == 'ubuntu-18.04' }} run: sudo apt update && sudo apt install -y libgfortran3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install testing dependencies run: python -m pip install tox codecov - name: Run tests with latest stable version of dependencies if: ${{ matrix.python-version != '3.9' }} run: tox -v -e test - name: Run tests with latest developer version of dependencies if: ${{ matrix.python-version == '3.9' }} run: tox -v -e test-devdeps - name: Run tests with CASA if: ${{ matrix.python-version == '3.6' && matrix.os == 'ubuntu-18.04' }} run: tox -v -e test-casa - name: Run tests with CASA (and oldest version of dependencies) if: ${{ matrix.python-version == '3.6' && matrix.os == 'ubuntu-18.04' }} run: tox -v -e test-casa-oldestdeps - name: Upload coverage to codecov uses: codecov/codecov-action@v1.0.13 with: file: ./coverage.xml casa-formats-io-0.1/.github/workflows/publish.yml0000644000175100001640000000326713752204621022740 0ustar runnerdocker00000000000000name: Build and upload to PyPI on: [push, pull_request] jobs: build_wheels: name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-18.04, windows-latest, macos-latest] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 name: Install Python with: python-version: '3.7' - name: Install cibuildwheel run: python -m pip install cibuildwheel - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse env: CIBW_BUILD: cp36-* cp37-* cp38-* CIBW_TEST_EXTRAS: test CIBW_TEST_COMMAND: pytest --pyargs casa_formats_io - uses: actions/upload-artifact@v2 with: path: ./wheelhouse/*.whl build_sdist: name: Build source distribution runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 name: Install Python with: python-version: '3.7' - name: Install build run: python -m pip install build - name: Build sdist run: python -m build --sdist --outdir dist/ . - uses: actions/upload-artifact@v2 with: path: dist/*.tar.gz upload_pypi: name: Upload to PyPI needs: [build_wheels, build_sdist] runs-on: ubuntu-latest if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') steps: - uses: actions/download-artifact@v2 with: name: artifact path: dist - uses: pypa/gh-action-pypi-publish@master with: user: __token__ password: ${{ secrets.pypi_password }} casa-formats-io-0.1/.gitignore0000644000175100001640000000117013752204621017131 0ustar runnerdocker00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] # C extensions *.so # Distribution / packaging .Python env/ bin/ build/ develop-eggs/ dist/ eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .cache nosetests.xml coverage.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # Rope .ropeproject # Django stuff: *.log *.pot # Sphinx documentation docs/_build/ docs/api *.fits # Other generated stuff casa_formats_io/version.py .coverage* .vscode casa-formats-io-0.1/.readthedocs.yml0000644000175100001640000000021713752204621020230 0ustar runnerdocker00000000000000version: 2 build: image: latest python: version: 3.7 install: - method: pip path: . extra_requirements: - docs casa-formats-io-0.1/CHANGES.rst0000644000175100001640000000022613752204621016744 0ustar runnerdocker000000000000000.1 (2020-11-08) ---------------- - Initial version which includes ``image_to_dask``, ``getdesc``, ``getdminfo``, and ``coordsys_to_astropy_wcs``. casa-formats-io-0.1/LICENSE0000644000175100001640000000273113752204621016152 0ustar runnerdocker00000000000000Copyright (c) 2020, casa-formats-io developers All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. casa-formats-io-0.1/MANIFEST.in0000644000175100001640000000047413752204621016705 0ustar runnerdocker00000000000000include README.md include CHANGES.rst include LICENSE.rst include pyproject.toml include setup.cfg recursive-include *.pyx *.c *.pxd recursive-include docs * recursive-include licenses * recursive-include cextern * recursive-include scripts * prune build prune docs/_build prune docs/api global-exclude *.pyc *.o casa-formats-io-0.1/PKG-INFO0000644000175100001640000000103313752204627016242 0ustar runnerdocker00000000000000Metadata-Version: 2.1 Name: casa-formats-io Version: 0.1 Summary: Dask-based reader for CASA data Home-page: http://casa-formats-io.readthedocs.org Author: Thomas Robitaille, Adam Ginsburg, and Eric Koch Author-email: thomas.robitaille@gmail.com License: BSD Description: casa-formats-io --------------- A small package implementing I/O for CASA data formats - see https://casa-formats-io.readthedocs.io for more details. Platform: UNKNOWN Requires-Python: >=3.6 Provides-Extra: test Provides-Extra: docs casa-formats-io-0.1/README.rst0000644000175100001640000000022713752204621016632 0ustar runnerdocker00000000000000casa-formats-io --------------- A small package implementing I/O for CASA data formats - see https://casa-formats-io.readthedocs.io for more details. casa-formats-io-0.1/casa_formats_io/0000755000175100001640000000000013752204627020301 5ustar runnerdocker00000000000000casa-formats-io-0.1/casa_formats_io/__init__.py0000644000175100001640000000022613752204621022404 0ustar runnerdocker00000000000000from .casa_dask import * # noqa from .casa_low_level_io import * # noqa from .casa_wcs import * # noqa from .version import version as __version__ casa-formats-io-0.1/casa_formats_io/_casa_chunking.c0000644000175100001640000001210413752204621023371 0ustar runnerdocker00000000000000#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include #include /* Define docstrings */ static char module_docstring[] = "Functions to help with CASA chunking"; static char _combine_chunks_docstring[] = "Combine multiple chunks into a single one"; /* Declare the C functions here. */ static PyObject *_combine_chunks(PyObject *self, PyObject *args); /* Define the methods that will be available on the module. */ static PyMethodDef module_methods[] = { {"_combine_chunks", _combine_chunks, METH_VARARGS, _combine_chunks_docstring}, {NULL, NULL, 0, NULL}}; /* This is the function that is called on import. */ #define MOD_ERROR_VAL NULL #define MOD_SUCCESS_VAL(val) val #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) #define MOD_DEF(ob, name, doc, methods) \ static struct PyModuleDef moduledef = { \ PyModuleDef_HEAD_INIT, \ name, \ doc, \ -1, \ methods, \ }; \ ob = PyModule_Create(&moduledef); MOD_INIT(_casa_chunking) { PyObject *m; MOD_DEF(m, "_casa_chunking", module_docstring, module_methods); if (m == NULL) return MOD_ERROR_VAL; import_array(); return MOD_SUCCESS_VAL(m); } static PyObject *_combine_chunks(PyObject *self, PyObject *args) { long n; PyObject *input_obj, *output_obj; PyArrayObject *input_array, *output_array; int ox, oy, oz, ow, nx, ny, nz, nw; npy_intp dims[1]; uint8_t *input, *output; int index_in, index_out; int itempos; int bx, by, bz, bw, i, j, k, l, i_o, j_o, k_o, l_o, i_f, j_f, k_f, l_f, itemsize; // NOTE: this function is written in a way to work with 4-d data as it can // then easily be called with 3-d data and have a dimension removed. We also // take a byte array as input, assume the data is contiguous, and take the size // of each elements in bytes - this allows us to reuse the same function for // mask and data of different types. /* Parse the input tuple */ if (!PyArg_ParseTuple(args, "Oiiiiiiiii", &input_obj, &itemsize, &nx, &ny, &nz, &nw, &ox, &oy, &oz, &ow)) { PyErr_SetString(PyExc_TypeError, "Error parsing input"); return NULL; } /* Interpret the input objects as `numpy` arrays. */ input_array = (PyArrayObject *)PyArray_FROM_O(input_obj); /* If that didn't work, throw an `Exception`. */ if (input_array == NULL) { PyErr_SetString(PyExc_TypeError, "Couldn't parse the input array."); Py_XDECREF(input_array); return NULL; } /* How many bytes are there? */ n = (long)PyArray_DIM(input_array, 0); /* Build the output array */ dims[0] = n; output_obj = PyArray_SimpleNew(1, dims, NPY_UINT8); if (output_obj == NULL) { PyErr_SetString(PyExc_RuntimeError, "Couldn't build output array"); Py_DECREF(input_array); Py_XDECREF(output_obj); return NULL; } output_array = (PyArrayObject *)output_obj; if (n == 0) { Py_DECREF(input_array); return output_obj; } /* Get C array for input and output arrays */ input = (uint8_t *)PyArray_DATA(input_array); output = (uint8_t *)PyArray_DATA(output_array); Py_BEGIN_ALLOW_THREADS index_in = 0; for (bw = 0; bw < ow; ++bw) { l_o = bw * nw; for (bz = 0; bz < oz; ++bz) { k_o = bz * nz; for (by = 0; by < oy; ++by) { j_o = by * ny; for (bx = 0; bx < ox; ++bx) { i_o = bx * nx; for (l = 0; l < nw; ++l) { for (k = 0; k < nz; ++k) { for (j = 0; j < ny; ++j) { for (i = 0; i < nx; ++i) { i_f = i_o + i; j_f = j_o + j; k_f = k_o + k; l_f = l_o + l; index_out = (i_f + j_f * (nx * ox) + k_f * (nx * ox * ny * oy) + l_f * (nx * ox * ny * oy * nz * oz)) * itemsize; for (itempos=0; itempos target_chunksize: chunkoversample = previous_chunkoversample finished = True break previous_chunkoversample = chunkoversample if finished: break chunkshape = [c * o for (c, o) in zip(chunkshape, chunkoversample)] # Create a wrapper that takes slices and returns the appropriate CASA data wrapper = CASAArrayWrapper(img_fn, totalshape, chunkshape, chunkoversample=chunkoversample, dtype=dtype, itemsize=itemsize, memmap=memmap) # Convert to a dask array dask_array = dask.array.from_array(wrapper, name='CASA Data ' + str(uuid.uuid4()), chunks=chunkshape[::-1]) # Since the chunks may not divide the array exactly, all the chunks put # together may be larger than the array, so we need to get rid of any # extraneous padding. final_slice = tuple([slice(dim) for dim in totalshape[::-1]]) return dask_array[final_slice] casa-formats-io-0.1/casa_formats_io/casa_low_level_io.py0000644000175100001640000003137413752204621024323 0ustar runnerdocker00000000000000# Pure Python + Numpy implementation of CASA's getdminfo() and getdesc() # functions for reading metadata about .image files. import os import struct from io import BytesIO from collections import OrderedDict import numpy as np __all__ = ['getdminfo', 'getdesc'] TYPES = ['bool', 'char', 'uchar', 'short', 'ushort', 'int', 'uint', 'float', 'double', 'complex', 'dcomplex', 'string', 'table', 'arraybool', 'arraychar', 'arrayuchar', 'arrayshort', 'arrayushort', 'arrayint', 'arrayuint', 'arrayfloat', 'arraydouble', 'arraycomplex', 'arraydcomplex', 'arraystr', 'record', 'other'] def with_nbytes_prefix(func): def wrapper(f, *args): start = f.tell() nbytes = int(read_int32(f)) if nbytes == 0: return b = BytesIO(f.read(nbytes - 4)) result = func(b, *args) end = f.tell() if end - start != nbytes: raise IOError('Function {0} read {1} bytes instead of {2}' .format(func, end - start, nbytes)) return result return wrapper def read_bool(f): return f.read(1) == b'\x01' def read_int32(f): return np.int32(struct.unpack('>i', f.read(4))[0]) def read_int64(f): return np.int64(struct.unpack('>q', f.read(8))[0]) def read_float32(f): return np.float32(struct.unpack('>f', f.read(4))[0]) def read_float64(f): return np.float64(struct.unpack('>d', f.read(8))[0]) def read_complex64(f): return np.complex64(read_float32(f) + 1j * read_float32(f)) def read_complex128(f): return np.complex128(read_float64(f) + 1j * read_float64(f)) def read_string(f): value = read_int32(f) return f.read(int(value)).replace(b'\x00', b'').decode('ascii') @with_nbytes_prefix def read_iposition(f): stype, sversion = read_type(f) if stype != 'IPosition' or sversion != 1: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) nelem = read_int32(f) return np.array([read_int32(f) for i in range(nelem)], dtype=int) ARRAY_ITEM_READERS = { 'float': ('float', read_float32, np.float32), 'double': ('double', read_float64, np.float64), 'dcomplex': ('void', read_complex128, np.complex128), 'string': ('String', read_string, '' or sversion != 3: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) ndim = read_int32(f) shape = [read_int32(f) for i in range(ndim)] size = read_int32(f) values = [reader(f) for i in range(size)] return np.array(values, dtype=dtype).reshape(shape) def read_type(f): tp = read_string(f) version = read_int32(f) return tp, version @with_nbytes_prefix def read_record(f): stype, sversion = read_type(f) if stype != 'Record' or sversion != 1: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) read_record_desc(f) # Not sure what the following value is read_int32(f) @with_nbytes_prefix def read_record_desc(f): stype, sversion = read_type(f) if stype != 'RecordDesc' or sversion != 2: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) # Not sure what the following value is nrec = read_int32(f) records = OrderedDict() for i in range(nrec): name = read_string(f) rectype = TYPES[read_int32(f)] records[name] = {'type': rectype} # Here we don't actually load in the data for may of the types - hence # why we don't do anything with the values we read in. if rectype in ('bool', 'int', 'uint', 'float', 'double', 'complex', 'dcomplex', 'string'): f.read(4) elif rectype == 'table': f.read(8) elif rectype.startswith('array'): read_iposition(f) f.read(4) elif rectype == 'record': read_record_desc(f) read_int32(f) else: raise NotImplementedError("Support for type {0} in RecordDesc not implemented".format(rectype)) return records @with_nbytes_prefix def read_table_record(f, image_path): stype, sversion = read_type(f) if stype != 'TableRecord' or sversion != 1: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) records = read_record_desc(f) unknown = read_int32(f) # noqa for name, values in records.items(): rectype = values['type'] if rectype == 'bool': records[name] = read_bool(f) elif rectype == 'int': records[name] = int(read_int32(f)) elif rectype == 'uint': records[name] = int(read_int32(f)) elif rectype == 'float': records[name] = float(read_float32(f)) elif rectype == 'double': records[name] = float(read_float64(f)) elif rectype == 'complex': records[name] = complex(read_complex64(f)) elif rectype == 'dcomplex': records[name] = complex(read_complex128(f)) elif rectype == 'string': records[name] = read_string(f) elif rectype == 'table': records[name] = 'Table: ' + os.path.abspath(os.path.join(image_path, read_string(f))) elif rectype == 'arrayint': records[name] = read_array(f, 'int') elif rectype == 'arrayfloat': records[name] = read_array(f, 'float') elif rectype == 'arraydouble': records[name] = read_array(f, 'double') elif rectype == 'arraycomplex': records[name] = read_array(f, 'complex') elif rectype == 'arraydcomplex': records[name] = read_array(f, 'dcomplex') elif rectype == 'arraystr': records[name] = read_array(f, 'string') elif rectype == 'record': records[name] = read_table_record(f, image_path) else: raise NotImplementedError("Support for type {0} in TableRecord not implemented".format(rectype)) return dict(records) @with_nbytes_prefix def read_table(f, image_path): stype, sversion = read_type(f) if stype != 'Table' or sversion != 2: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) nrow = read_int32(f) fmt = read_int32(f) # noqa name = read_string(f) # noqa big_endian = fmt == 0 # noqa table_desc = read_table_desc(f, nrow, image_path) return table_desc def read_column_desc(f, image_path): unknown = read_int32(f) # noqa stype, sversion = read_type(f) if not stype.startswith(('ScalarColumnDesc', 'ArrayColumnDesc')) or sversion != 1: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) desc = {} name = read_string(f) desc['comment'] = read_string(f) desc['dataManagerType'] = read_string(f).replace('Shape', 'Cell') desc['dataManagerGroup'] = read_string(f) desc['valueType'] = TYPES[read_int32(f)] desc['maxlen'] = read_int32(f) ndim = read_int32(f) if ndim > 0: ipos = read_iposition(f) # noqa desc['ndim'] = ndim desc['option'] = read_int32(f) desc['keywords'] = read_table_record(f, image_path) if desc['valueType'] in ('ushort', 'short'): f.read(2) if desc['valueType'] in ('uint', 'int', 'float', 'string'): f.read(4) elif desc['valueType'] in ('double', 'complex'): f.read(8) elif desc['valueType'] in ('dcomplex'): f.read(16) return {name: desc} @with_nbytes_prefix def read_table_desc(f, nrow, image_path): stype, sversion = read_type(f) if stype != 'TableDesc' or sversion != 2: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) unknown1 = read_int32(f) # noqa unknown2 = read_int32(f) # noqa unknown3 = read_int32(f) # noqa desc = {} desc['_keywords_'] = read_table_record(f, image_path) desc['_define_hypercolumn_'] = {} hypercolumn = read_table_record(f, image_path) desc['_private_keywords_'] = hypercolumn if hypercolumn: name = list(hypercolumn)[0].split('_')[1] value = list(hypercolumn.values())[0] desc['_define_hypercolumn_'][name] = {'HCcoordnames': value['coord'], 'HCdatanames': value['data'], 'HCidnames': value['id'], 'HCndim': value['ndim']} ncol = read_int32(f) for icol in range(ncol): if icol > 0: read_int32(f) array_column_desc = read_column_desc(f, image_path) desc.update(array_column_desc) return desc @with_nbytes_prefix def read_tiled_st_man(f): # The code in this function corresponds to TiledStMan::headerFileGet # https://github.com/casacore/casacore/blob/75b358be47039250e03e5042210cbc60beaaf6e4/tables/DataMan/TiledStMan.cc#L1086 stype, sversion = read_type(f) if stype != 'TiledStMan' or sversion != 2: raise NotImplementedError('Support for {0} version {1} not implemented'.format(stype, sversion)) st_man = {} st_man['SPEC'] = {} st_man['BIGENDIAN'] = f.read(1) == b'\x01' # noqa seqnr = read_int32(f) if seqnr != 0: raise ValueError("Expected seqnr to be 0, got {0}".format(seqnr)) st_man['SEQNR'] = seqnr st_man['SPEC']['SEQNR'] = seqnr nrows = read_int32(f) if nrows != 1: raise ValueError("Expected nrows to be 1, got {0}".format(nrows)) ncols = read_int32(f) if ncols != 1: raise ValueError("Expected ncols to be 1, got {0}".format(ncols)) dtype = read_int32(f) # noqa column_name = read_string(f) st_man['COLUMNS'] = np.array([column_name], dtype='?-!W?"Wi TableRecord RecordDesctype refer m2 RecordDescm1 RecordDescm0 RecordDescpositionITRFc TableRecord; RecordDescvalueunit AXVjS me TableRecord; RecordDescunit valueradِ[e TableRecord; RecordDescunit valuerad  TableRecord RecordDesc system projection projection_parameters IPositioncrval IPositioncrpix IPositioncdelt IPositionpc IPositionaxes IPositionunits IPositionconversionSystem longpolelatpoleICRSSIN5 Array5 Array?-!W?"Wi5 Array@p@p5 ArrayU>UI Array??G ArrayRight Ascension Declination3 ArrayradradICRS@f@>Ng* Array5 Array?EvJ?+B* Array5 ArrayW TableRecord+ RecordDescaxes IPositionstokes IPositioncrval IPositioncrpix IPositioncdelt IPositionpc IPosition/ ArrayStokes* ArrayI- Array?- Array- Array?1 Array?& Array- Array?& Array- Array TableRecordd RecordDesc versionsystem restfreq restfreqs IPositionvelType nativeTypevelUnit waveUnit formatUnit wcs RecordDescunit name conversion RecordDescLSRKBJ֑[@- ArrayBJ֑[@km/smm TableRecordl RecordDesccrvalcrpixcdeltpcctype BJ!\7w? FREQHz Frequency^ TableRecord RecordDesc direction RecordDescposition RecordDescepoch RecordDescsystem  TableRecord RecordDesctype refer m1 RecordDescm0 RecordDesc directionJ2000e TableRecord; RecordDescvalueunit ?!TD-rade TableRecord; RecordDescunit valuerad TableRecord RecordDesctype refer m2 RecordDescm1 RecordDescm0 RecordDescpositionITRFc TableRecord; RecordDescvalueunit me TableRecord; RecordDescunit valuerade TableRecord; RecordDescunit valuerad TableRecordc RecordDesctype refer m0 RecordDescepochLASTc TableRecord; RecordDescvalueunit dLSRK& Array- ArrayBJ!\& Array- Array TableRecord\ RecordDescINSTRUME distanceuseweightimageALMA TableRecordE RecordDescmask0 RecordDesc} TableRecord RecordDescisRegionname comment mask box RecordDesc LCPagedMask ././mask0 TableRecord RecordDescisRegionname comment oneRelblc IPositiontrc IPositionshape IPositionLCBox4 Array????4 ArrayDD?B2 Arraydmask0Jy/beam TableRecordx RecordDesc imagetype objectname perplanebeams RecordDesc IntensityM33K TableRecord< RecordDescf nChannelsnStokes*0 RecordDesc*1 RecordDesc*2 RecordDesc*3 RecordDesc*4 RecordDesc*5 RecordDesc*6 RecordDesc*7 RecordDesc*8 RecordDesc*9 RecordDesc*10 RecordDesc*11 RecordDesc*12 RecordDesc*13 RecordDesc*14 RecordDesc*15 RecordDesc*16 RecordDesc*17 RecordDesc*18 RecordDesc*19 RecordDesc*20 RecordDesc*21 RecordDesc*22 RecordDesc*23 RecordDesc*24 RecordDesc*25 RecordDesc*26 RecordDesc*27 RecordDesc*28 RecordDesc*29 RecordDesc*30 RecordDesc*31 RecordDesc*32 RecordDesc*33 RecordDesc*34 RecordDesc*35 RecordDesc*36 RecordDesc*37 RecordDesc*38 RecordDesc*39 RecordDesc*40 RecordDesc*41 RecordDesc*42 RecordDesc*43 RecordDesc*44 RecordDesc*45 RecordDesc*46 RecordDesc*47 RecordDesc*48 RecordDesc*49 RecordDesc*50 RecordDesc*51 RecordDesc*52 RecordDesc*53 RecordDesc*54 RecordDesc*55 RecordDesc*56 RecordDesc*57 RecordDesc*58 RecordDesc*59 RecordDesc*60 RecordDesc*61 RecordDesc*62 RecordDesc*63 RecordDesc*64 RecordDesc*65 RecordDesc*66 RecordDesc*67 RecordDesc*68 RecordDesc*69 RecordDesc*70 RecordDesc*71 RecordDesc*72 RecordDesc*73 RecordDesc*74 RecordDesc*75 RecordDesc*76 RecordDesc*77 RecordDesc*78 RecordDesc*79 RecordDesc*80 RecordDesc*81 RecordDesc*82 RecordDesc*83 RecordDesc*84 RecordDesc*85 RecordDesc*86 RecordDesc*87 RecordDesc*88 RecordDesc*89 RecordDesc*90 RecordDesc*91 RecordDesc*92 RecordDesc*93 RecordDesc*94 RecordDesc*95 RecordDesc*96 RecordDesc*97 RecordDesc*98 RecordDesc*99 RecordDescd TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@d@e TableRecord; RecordDescunit valuedegAOd TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedeg@@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@z e TableRecord; RecordDescunit valuedeg@\@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @carcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @}arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @Carcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAe  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA%  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ `arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA6 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @/arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedeg@t@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @]arcsech TableRecord; RecordDescunit valuearcsec@Ơe TableRecord; RecordDescunit valuedeg@f TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedeg@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@te TableRecord; RecordDescunit valuedeg@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @Z@arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedeg@` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ m`arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA9ɀ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ 7`arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA?ـ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ <arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegAA TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ Marcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAA5@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@=@e TableRecord; RecordDescunit valuedegA@0@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@Be TableRecord; RecordDescunit valuedegA< TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ @arcsech TableRecord; RecordDescunit valuearcsec@> e TableRecord; RecordDescunit valuedegA;@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @׀arcsech TableRecord; RecordDescunit valuearcsec@ՠe TableRecord; RecordDescunit valuedegA({ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @Aarcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA @ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegA0 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA7 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA: TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @S@arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegAd  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@A@e TableRecord; RecordDescunit valuedegAH@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@Āe TableRecord; RecordDescunit valuedegA7 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @+arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA!w TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA5  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA5 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @*arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA5B TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @Harcsech TableRecord; RecordDescunit valuearcsec@Ze TableRecord; RecordDescunit valuedegA3  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegA0!  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA0  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA/@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@3e TableRecord; RecordDescunit valuedegA.` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @`arcsech TableRecord; RecordDescunit valuearcsec@1e TableRecord; RecordDescunit valuedegA.@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA. TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @@arcsech TableRecord; RecordDescunit valuearcsec@~`e TableRecord; RecordDescunit valuedegA.r TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @`arcsech TableRecord; RecordDescunit valuearcsec@_e TableRecord; RecordDescunit valuedegA.  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@7 e TableRecord; RecordDescunit valuedegA-  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA-Y` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @@arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA,f TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ɀarcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA+ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@(`e TableRecord; RecordDescunit valuedegA+ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegA0  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ 2@arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA4 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA4 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ c arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA3 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA9 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@T e TableRecord; RecordDescunit valuedegA7 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@7`e TableRecord; RecordDescunit valuedegA7 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @@arcsech TableRecord; RecordDescunit valuearcsec@Ve TableRecord; RecordDescunit valuedegA8 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @`arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegABq TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@"e TableRecord; RecordDescunit valuedegAB TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @0arcsech TableRecord; RecordDescunit valuearcsec@:e TableRecord; RecordDescunit valuedegABX TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @@arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAI@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@_e TableRecord; RecordDescunit valuedegAO@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAO` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAD@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @-arcsech TableRecord; RecordDescunit valuearcsec@pe TableRecord; RecordDescunit valuedegA2  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@̀e TableRecord; RecordDescunit valuedegA/q TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA+@ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@Q e TableRecord; RecordDescunit valuedegA8M TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @h arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA< TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @`arcsech TableRecord; RecordDescunit valuearcsec@9e TableRecord; RecordDescunit valuedegA?5 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ce TableRecord; RecordDescunit valuedegA? TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @oarcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegAA  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegAE ` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAEk  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @@arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA9  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @)arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA> TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAA` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@;e TableRecord; RecordDescunit valuedegAH TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @5arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAE` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAE TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAAz  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@.`e TableRecord; RecordDescunit valuedegAA' TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@>e TableRecord; RecordDescunit valuedegA@ޠ TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @ arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegA< TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @arcsech TableRecord; RecordDescunit valuearcsec@/e TableRecord; RecordDescunit valuedegA<` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @"`arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegAD TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @"Xarcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAg TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @"}@arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @8`arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA$  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @6arcsech TableRecord; RecordDescunit valuearcsec@2 e TableRecord; RecordDescunit valuedegA) TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @'! arcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAA` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @2garcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegA5 TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @+@arcsech TableRecord; RecordDescunit valuearcsec@`e TableRecord; RecordDescunit valuedegAQ` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @/4 arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAE` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @/Barcsech TableRecord; RecordDescunit valuearcsec@e TableRecord; RecordDescunit valuedegAIE` TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @,$arcsech TableRecord; RecordDescunit valuearcsec@te TableRecord; RecordDescunit valuedegAV  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @,@arcsech TableRecord; RecordDescunit valuearcsec@ne TableRecord; RecordDescunit valuedegAW TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @,΀arcsech TableRecord; RecordDescunit valuearcsec@ e TableRecord; RecordDescunit valuedegAd  TableRecord RecordDescmajor RecordDescminor RecordDesc positionangle RecordDesch TableRecord; RecordDescvalueunit @*arcsech TableRecord; RecordDescunit valuearcsec@@e TableRecord; RecordDescunit valuedegA]@ TableRecordO RecordDescHypercolumn_map RecordDescE TableRecord RecordDescndimdata IPositioncoord IPositionid IPosition, Arraymap% Array% ArrayArrayColumnDesc0.5. To avoid this, we filter out random # values close to the boundaries that we use below. reference[np.isclose(reference, 0.2)] += 0.05 reference[np.isclose(reference, 0.5)] += 0.05 reference[np.isclose(reference, 0.8)] += 0.05 os.chdir(tmpdir.strpath) # Start off with a simple example with no mask. Note that CASA requires # the array to be transposed in order to match what we would expect. ia = image() ia.fromarray('basic.image', pixels=reference.T, log=False) ia.close() array1 = image_to_dask('basic.image', memmap=memmap) assert array1.dtype == np.float32 assert_allclose(array1, reference) # Check slicing assert_allclose(array1[:2, :1, :3], reference[:2, :1, :3]) # Try and get a mask - this should fail since there isn't one. with pytest.raises(FileNotFoundError): image_to_dask('basic.image', mask=True, memmap=memmap) # Now create an array with a simple uniform mask. ia = image() ia.fromarray('scalar_mask.image', pixels=reference.T, log=False) ia.calcmask(mask='T') ia.close() array2 = image_to_dask('scalar_mask.image', memmap=memmap) assert_allclose(array2, reference) mask2 = image_to_dask('scalar_mask.image', mask=True, memmap=memmap) assert mask2.dtype is np.dtype('bool') assert mask2.shape == array2.shape assert np.all(mask2) # Check with a full 3-d mask ia = image() ia.fromarray('array_mask.image', pixels=reference.T, log=False) ia.calcmask(mask='array_mask.image>0.5') ia.close() array3 = image_to_dask('array_mask.image', memmap=memmap) assert_allclose(array3, reference) mask3 = image_to_dask('array_mask.image', mask=True, memmap=memmap) assert_allclose(mask3, reference > 0.5) # Check slicing assert_allclose(mask3[:2, :1, :3], (reference > 0.5)[:2, :1, :3]) # Test specifying the mask name ia = image() ia.fromarray('array_masks.image', pixels=reference.T, log=False) ia.calcmask(mask='array_masks.image>0.5') ia.calcmask(mask='array_masks.image>0.2') ia.calcmask(mask='array_masks.image>0.8', name='gt08') ia.close() array4 = image_to_dask('array_masks.image', memmap=memmap) assert_allclose(array4, reference) mask4 = image_to_dask('array_masks.image', mask=True, memmap=memmap) assert_allclose(mask4, reference > 0.5) mask5 = image_to_dask('array_masks.image', mask='mask0', memmap=memmap) assert_allclose(mask5, reference > 0.5) mask6 = image_to_dask('array_masks.image', mask='mask1', memmap=memmap) assert_allclose(mask6, reference > 0.2) mask7 = image_to_dask('array_masks.image', mask='gt08', memmap=memmap) assert_allclose(mask7, reference > 0.8) # Check that things still work if we write the array out with doubles reference = np.random.random(shape).astype(np.float64) ia = image() ia.fromarray('double.image', pixels=reference.T, type='d', log=False) ia.close() array8 = image_to_dask('double.image', memmap=memmap) assert array8.dtype == np.float64 assert_allclose(array8, reference) casa-formats-io-0.1/casa_formats_io/tests/test_casa_low_level_io.py0000644000175100001640000001141113752204621026512 0ustar runnerdocker00000000000000from __future__ import print_function, absolute_import, division import os import pytest import numpy as np from numpy.testing import assert_equal from astropy.table import Table from pprint import pformat from ..casa_low_level_io import getdminfo, getdesc # from ...tests.test_casafuncs import make_casa_testimage try: from casatools import table, image CASATOOLS_INSTALLED = True except ImportError: CASATOOLS_INSTALLED = False DATA = os.path.join(os.path.dirname(__file__), 'data') SHAPES = [(3,), (5, 3), (8, 4, 2), (4, 8, 3, 1), (133, 400), (100, 211, 201), (50, 61, 72, 83), (4, 8, 10, 20, 40)] @pytest.mark.skipif('not CASATOOLS_INSTALLED') @pytest.mark.parametrize('shape', SHAPES) def test_getdminfo(tmp_path, shape): filename = str(tmp_path / 'test.image') data = np.random.random(shape) ia = image() ia.fromarray(outfile=filename, pixels=data, log=False) ia.close() tb = table() tb.open(filename) reference = tb.getdminfo() tb.close() actual = getdminfo(filename) # We include information about endian-ness in the dminfo but CASA doesn't actual['*1'].pop('BIGENDIAN') # The easiest way to compare the output is simply to compare the output # from pformat (checking for dictionary equality doesn't work because of # the Numpy arrays inside). Older versions of casatools represent some of # the vectors as int32 instead of native int but our implementation uses # native int so strip any mention of int32 from reference output assert pformat(actual) == pformat(reference).replace(', dtype=int32', '') def test_getdminfo_large(): # Check that things continue to work fine when we cross the threshold from # a dataset with a size that can be represented by a 32-bit integer to one # where the size requires a 64-bit integer. We use pre-generated # table.f0 files here since generating these kinds of datasets is otherwise # slow and consumes a lot of memory. lt32bit = getdminfo(os.path.join(DATA, 'lt32bit.image')) assert_equal(lt32bit['*1']['SPEC']['HYPERCUBES']['*1']['CubeShape'], (320, 320, 1, 1920)) gt32bit = getdminfo(os.path.join(DATA, 'gt32bit.image')) assert_equal(gt32bit['*1']['SPEC']['HYPERCUBES']['*1']['CubeShape'], (640, 640, 1, 1920)) @pytest.fixture def filename(request): return request.getfixturevalue(request.param) @pytest.mark.openfiles_ignore @pytest.mark.skipif('not CASATOOLS_INSTALLED') def test_generic_table_read(tmp_path): # NOTE: for now, this doesn't check that we can read the data - just # the metadata about the table. filename_fits = str(tmp_path / 'generic.fits') filename_casa = str(tmp_path / 'generic.image') t = Table() t['short'] = np.arange(3, dtype=np.int16) t['ushort'] = np.arange(3, dtype=np.uint16) t['int'] = np.arange(3, dtype=np.int32) t['uint'] = np.arange(3, dtype=np.uint32) t['float'] = np.arange(3, dtype=np.float32) t['double'] = np.arange(3, dtype=np.float64) t['complex'] = np.array([1 + 2j, 3.3 + 8.2j, -1.2 - 4.2j], dtype=np.complex64) t['dcomplex'] = np.array([3.33 + 4.22j, 3.3 + 8.2j, -1.2 - 4.2j], dtype=np.complex128) t['str'] = np.array(['reading', 'casa', 'images']) # Repeat this at the end to make sure we correctly finished reading # the complex column metadata t['int2'] = np.arange(3, dtype=np.int32) t.write(filename_fits) tb = table() tb.fromfits(filename_casa, filename_fits) tb.close() # Use the arrays in the table to also generate keywords of various types keywords = {'scalars': {}, 'arrays': {}} for name in t.colnames: keywords['scalars']['s_' + name] = t[name][0] keywords['arrays']['a_' + name] = t[name] tb.open(filename_casa) tb.putkeywords(keywords) tb.flush() tb.close() desc_actual = getdesc(filename_casa) tb.open(filename_casa) desc_reference = tb.getdesc() tb.close() # Older versions of casatools represent some of the vectors as int32 # instead of native int but our implementation uses native int so strip any # mention of int32 from reference output assert pformat(desc_actual) == pformat(desc_reference).replace(', dtype=int32', '') # TODO: for now the following fails because we haven't implemented # non-tiled data I/O # getdminfo(filename_casa) def test_getdesc_floatarray(): # There doesn't seem to be an easy way to create CASA images # with float (not double) arrays. In test_getdesc, all the floats # end up getting converted to double. So instead we use a table.dat # file that was found in the wild. desc = getdesc(os.path.join(DATA, 'floatarray.image')) trc = desc['_keywords_']['masks']['mask0']['box']['trc'] assert trc.dtype == np.float32 assert_equal(trc, [512, 512, 1, 100]) casa-formats-io-0.1/casa_formats_io/tests/test_casa_wcs.py0000644000175100001640000000761013752204621024635 0ustar runnerdocker00000000000000from __future__ import print_function, absolute_import, division import os import tempfile import pytest import numpy as np from astropy.wcs import WCS from astropy.io import fits from numpy.testing import assert_allclose from ..casa_low_level_io import getdesc from ..casa_wcs import coordsys_to_astropy_wcs HEADER_FILENAME = os.path.join(os.path.dirname(__file__), 'data', 'header_jybeam.hdr') try: from casatools import image CASATOOLS_INSTALLED = True except ImportError: CASATOOLS_INSTALLED = False @pytest.fixture def filename(request): return request.getfixturevalue(request.param) def assert_header_correct(casa_filename): fits_filename = tempfile.mktemp() # Use CASA to convert back to FITS and use that header as the reference ia = image() ia.open(casa_filename) ia.tofits(fits_filename, stokeslast=False) ia.done() ia.close() # Parse header with WCS - for the purposes of this function # we are not interested in keywords/values not in WCS reference_wcs = WCS(fits_filename) reference_header = reference_wcs.to_header() # Now use our coordsys_to_astropy_wcs function to create the header and compare # the results. desc = getdesc(casa_filename) actual_wcs = coordsys_to_astropy_wcs(desc['_keywords_']['coords']) actual_header = actual_wcs.to_header() assert sorted(actual_header) == sorted(reference_header) for key in reference_header: if isinstance(actual_header[key], str): assert actual_header[key] == reference_header[key] else: assert_allclose(actual_header[key], reference_header[key]) @pytest.mark.skipif('not CASATOOLS_INSTALLED') def test_coordsys_to_astropy_wcs_linear(tmp_path): # Test that things work properly when the WCS coordinates aren't set casa_filename = str(tmp_path / 'test.image') data = np.random.random((3, 4, 5, 6, 7)) ia = image() ia.fromarray(outfile=casa_filename, pixels=data, log=False) ia.close() assert_header_correct(casa_filename) def header_copy_with(**kwargs): header = fits.Header.fromtextfile(HEADER_FILENAME).copy() header.update(kwargs) return header ALL_HEADERS = [ header_copy_with(), header_copy_with(CTYPE1='GLON-TAN', CTYPE2='GLAT-TAN'), header_copy_with(CTYPE1='SLON-TAN', CTYPE2='SLAT-TAN'), header_copy_with(CTYPE1='ELON-TAN', CTYPE2='ELAT-TAN'), header_copy_with(CTYPE1='HLON-TAN', CTYPE2='HLAT-TAN'), header_copy_with(SPECSYS=''), header_copy_with(SPECSYS='TOPOCENT'), header_copy_with(SPECSYS='GEOCENTR'), header_copy_with(SPECSYS='BARYCENT'), header_copy_with(SPECSYS='HELIOCEN'), header_copy_with(SPECSYS='LSRK'), header_copy_with(SPECSYS='LSRD'), header_copy_with(SPECSYS='GALACTOC'), header_copy_with(SPECSYS='LOCALGRP'), header_copy_with(SPECSYS='CMBDIPOL'), header_copy_with(SPECSYS='SOURCE'), header_copy_with(RADESYS='FK4'), header_copy_with(RADESYS='FK4-NO-E'), header_copy_with(RADESYS='FK5'), header_copy_with(RADESYS='ICRS'), header_copy_with(EQUINOX=1950.), header_copy_with(EQUINOX=1979.9), header_copy_with(EQUINOX=2000), header_copy_with(EQUINOX=2010), header_copy_with(CTYPE3='FREQ', CUNIT3='GHz', CRVAL3=100., CDELT3=1.), header_copy_with(CTYPE3='WAVE', CUNIT3='m', CRVAL3=1e-6, CDELT3=1e-8), header_copy_with(CTYPE3='VOPT'), header_copy_with(CTYPE3='VRAD') ] @pytest.mark.skipif('not CASATOOLS_INSTALLED') @pytest.mark.parametrize('header', ALL_HEADERS) def test_coordsys_to_astropy_wcs_additional(tmp_path, header): # More cases to improve coverage casa_filename = str(tmp_path / 'casa.image') fits_filename = str(tmp_path / 'casa.fits') fits.writeto(fits_filename, np.ones((2, 3, 4, 5)), header) ia = image() ia.fromfits(infile=fits_filename, outfile=casa_filename) ia.unlock() ia.close() ia.done() assert_header_correct(casa_filename) casa-formats-io-0.1/casa_formats_io/version.py0000644000175100001640000000016213752204627022337 0ustar runnerdocker00000000000000# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control version = '0.1' casa-formats-io-0.1/casa_formats_io.egg-info/0000755000175100001640000000000013752204627021773 5ustar runnerdocker00000000000000casa-formats-io-0.1/casa_formats_io.egg-info/PKG-INFO0000644000175100001640000000103313752204627023065 0ustar runnerdocker00000000000000Metadata-Version: 2.1 Name: casa-formats-io Version: 0.1 Summary: Dask-based reader for CASA data Home-page: http://casa-formats-io.readthedocs.org Author: Thomas Robitaille, Adam Ginsburg, and Eric Koch Author-email: thomas.robitaille@gmail.com License: BSD Description: casa-formats-io --------------- A small package implementing I/O for CASA data formats - see https://casa-formats-io.readthedocs.io for more details. Platform: UNKNOWN Requires-Python: >=3.6 Provides-Extra: test Provides-Extra: docs casa-formats-io-0.1/casa_formats_io.egg-info/SOURCES.txt0000644000175100001640000000174713752204627023670 0ustar runnerdocker00000000000000.gitignore .readthedocs.yml CHANGES.rst LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py tox.ini .github/workflows/main.yml .github/workflows/publish.yml casa_formats_io/__init__.py casa_formats_io/_casa_chunking.c casa_formats_io/casa_dask.py casa_formats_io/casa_low_level_io.py casa_formats_io/casa_wcs.py casa_formats_io/version.py casa_formats_io.egg-info/PKG-INFO casa_formats_io.egg-info/SOURCES.txt casa_formats_io.egg-info/dependency_links.txt casa_formats_io.egg-info/not-zip-safe casa_formats_io.egg-info/requires.txt casa_formats_io.egg-info/top_level.txt casa_formats_io/tests/__init__.py casa_formats_io/tests/test_casa_dask.py casa_formats_io/tests/test_casa_low_level_io.py casa_formats_io/tests/test_casa_wcs.py casa_formats_io/tests/data/header_jybeam.hdr casa_formats_io/tests/data/floatarray.image/table.dat casa_formats_io/tests/data/gt32bit.image/table.f0 casa_formats_io/tests/data/lt32bit.image/table.f0 docs/Makefile docs/conf.py docs/index.rst docs/make.batcasa-formats-io-0.1/casa_formats_io.egg-info/dependency_links.txt0000644000175100001640000000000113752204627026041 0ustar runnerdocker00000000000000 casa-formats-io-0.1/casa_formats_io.egg-info/not-zip-safe0000644000175100001640000000000113752204627024221 0ustar runnerdocker00000000000000 casa-formats-io-0.1/casa_formats_io.egg-info/requires.txt0000644000175100001640000000017013752204627024371 0ustar runnerdocker00000000000000astropy>=4.0 numpy>=1.17 dask[array]>=1.0 [docs] numpydoc sphinx-automodapi [test] pytest pytest-cov pytest-openfiles casa-formats-io-0.1/casa_formats_io.egg-info/top_level.txt0000644000175100001640000000002013752204627024515 0ustar runnerdocker00000000000000casa_formats_io casa-formats-io-0.1/docs/0000755000175100001640000000000013752204627016100 5ustar runnerdocker00000000000000casa-formats-io-0.1/docs/Makefile0000644000175100001640000000117213752204621017533 0ustar runnerdocker00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) casa-formats-io-0.1/docs/conf.py0000644000175100001640000000434013752204621017372 0ustar runnerdocker00000000000000# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'casa-formats-io' copyright = '2020, Thomas Robitaille, Adam Ginsburg, and Eric Koch' author = 'Thomas Robitaille, Adam Ginsburg, and Eric Koch' # The full version, including alpha/beta/rc tags release = '0.0' # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['numpydoc', 'sphinx_automodapi.automodapi'] numpydoc_show_class_members = False # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), 'numpy': ('https://numpy.org/doc/stable/', None), 'astropy': ('https://docs.astropy.org/en/stable/', None)} casa-formats-io-0.1/docs/index.rst0000644000175100001640000000431713752204621017740 0ustar runnerdocker00000000000000casa-formats-io documentation ============================= Scope ----- The **casa-formats-io** package is a small package which implements functionality to read data stored in CASA formats (such as .image datasets). This implementation is independent of and does not use `casacore `_. The motivation for this package is to provide: * Efficient data access via `dask `_ arrays * Cross-platform data access, supporting Linux, MacOS X and Windows * Data access with all modern Python versions, from 3.6 to the latest Python version At this time (November 2020), only reading .image datasets is supported. Reading measurement sets (.ms) or writing data of any kind are not yet supported. Using casa-formats-io --------------------- To construct a dask array backed by a .image dataset, use the :func:`~casa_io_formats.image_to_dask` function:: >>> from casa_formats_io.casa_dask import image_to_dask >>> dask_array = image_to_dask('my_dataset.image/') dask.array Note that rather than use the native CASA chunk size as the size of dask chunks, which is extremely inefficient for large datasets (for which there may be a million CASA chunks or more), the :func:`casa_io_formats.image_to_dask` function will automatically join neighbouring chunks together on-the-fly which then provides significantly better performance. In addition to :func:`~casa_io_formats.image_to_dask`, this package implements :func:`~casa_formats_io.getdesc` and :func:`~casa_formats_io.getdminfo` which aim to return the same results as CASA's `getdesc `__ and `getdminfo `__ respectively. Finally, this package provides :func:`~casa_formats_io.coordsys_to_astropy_wcs`) which can be used to convert CASA WCS information to :class:`~astropy.wcs.WCS` objects. Reference/API ------------- .. automodapi:: casa_formats_io :no-inheritance-diagram: :inherited-members: casa-formats-io-0.1/docs/make.bat0000644000175100001640000000143313752204621017500 0ustar runnerdocker00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd casa-formats-io-0.1/pyproject.toml0000644000175100001640000000025213752204621020055 0ustar runnerdocker00000000000000[build-system] requires = ["setuptools", "setuptools_scm", "oldest-supported-numpy", "wheel"] build-backend = 'setuptools.build_meta' casa-formats-io-0.1/setup.cfg0000644000175100001640000000262113752204627016772 0ustar runnerdocker00000000000000[metadata] name = casa-formats-io description = Dask-based reader for CASA data long_description = file: README.rst author = Thomas Robitaille, Adam Ginsburg, and Eric Koch author_email = thomas.robitaille@gmail.com license = BSD url = http://casa-formats-io.readthedocs.org edit_on_github = False github_project = radio-astro-tools/casa-formats-io [options] zip_safe = False packages = find: install_requires = astropy>=4.0 numpy>=1.17 dask[array]>=1.0 python_requires = >=3.6 [options.extras_require] test = pytest pytest-cov pytest-openfiles docs = numpydoc sphinx-automodapi [options.package_data] casa_formats_io.tests = data/*, data/*/* [tool:pytest] minversion = 3.0 norecursedirs = build docs/_build doctest_plus = enabled [coverage:run] omit = casa_formats_io/_astropy_init* casa_formats_io/conftest.py casa_formats_io/*setup_package* casa_formats_io/tests/* casa_formats_io/*/tests/* casa_formats_io/extern/* casa_formats_io/version* */casa_formats_io/_astropy_init* */casa_formats_io/conftest.py */casa_formats_io/*setup_package* */casa_formats_io/tests/* */casa_formats_io/*/tests/* */casa_formats_io/extern/* */casa_formats_io/version* [coverage:report] exclude_lines = pragma: no cover except ImportError raise AssertionError raise NotImplementedError def main\(.*\): pragma: py{ignore_python_version} def _ipython_key_completions_ [egg_info] tag_build = tag_date = 0 casa-formats-io-0.1/setup.py0000755000175100001640000000065513752204621016665 0ustar runnerdocker00000000000000#!/usr/bin/env python import os import sys import numpy from setuptools import setup from setuptools.extension import Extension setup(use_scm_version={'write_to': os.path.join('casa_formats_io', 'version.py')}, ext_modules=[Extension("casa_formats_io._casa_chunking", [os.path.join('casa_formats_io', '_casa_chunking.c')], include_dirs=[numpy.get_include()])]) casa-formats-io-0.1/tox.ini0000644000175100001640000000261113752204621016455 0ustar runnerdocker00000000000000[tox] envlist = py{36,37,38}-test{,-oldestdeps,-devdeps,-casa} build_docs codestyle requires = setuptools >= 30.3.0 pip >= 19.3.1 isolated_build = true indexserver = NRAO = https://casa-pip.nrao.edu/repository/pypi-group/simple NUMPY_NIGHTLY = https://pypi.anaconda.org/scipy-wheels-nightly/simple ASTROPY_NIGHTLY = https://pkgs.dev.azure.com/astropy-project/astropy/_packaging/nightly/pypi/simple/ [testenv] passenv = HOME DISPLAY LC_ALL LC_CTYPE ON_TRAVIS changedir = .tmp/{envname} description = run tests with pytest deps = oldestdeps: astropy==4.0.* oldestdeps: numpy==1.17.* oldestdeps: dask[array]==1.0.* devdeps: :NUMPY_NIGHTLY:numpy devdeps: pyerfa devdeps: :ASTROPY_NIGHTLY:astropy casa-oldestdeps: :NRAO:casatools==6.0.0.27 casa-!oldestdeps: :NRAO:casatools extras = test commands = python --version pip freeze pytest --open-files --pyargs casa_formats_io {toxinidir}/docs --cov casa_formats_io --cov-config={toxinidir}/setup.cfg {posargs} coverage xml -o {toxinidir}/coverage.xml [testenv:build_docs] changedir = docs description = invoke sphinx-build to build the HTML docs extras = docs commands = sphinx-build -W -b html . _build/html {posargs} [testenv:codestyle] changedir = deps = flake8 skip_install = true commands = flake8 --max-line-length=110 casa_formats_io